5762841 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056]$ cat -n backuppcd-tar.c
  1 #include "compat.h"
  2 #include "backuppcd.h"
  3 #include "backuppcd-common.h"
  4 #include "net.h"
  5 
  6 typedef enum {
  7         BPC_CDT_END,
  8         BPC_CDT_UINT8,
  9         BPC_CDT_UINT16,
 10         BPC_CDT_UINT32,
 11         BPC_CDT_UINT64,
 12         BPC_CDT_BYTEARRAY,
 13         BPC_CDT_STRING,
 14         BPC_CDT_STRING_PTR,
 15 } backuppc_clntdt_t;
 16 
 17 #ifndef MSG_WAITALL
 18 #define MSG_WAITALL 0
 19 #endif
 20 
 21 #ifndef BPC_MAXPATH_LEN
 22 #define BPC_MAXPATH_LEN 4096
 23 #endif                                                                                                                  
	                 
 24 
 25 /*
 26  * Example BackupPCd client with USTAR output.
 27  */
 28 
 29 int backuppcd_client(const char *host, const int port, const char *username, const char *password, const char *root);
 30 
 31 int main(int argc, char **argv) {
 32     char *host, *rootpath, *username, *password;
 33     int port;
 34     int cmd_ret = -1;
 35 
 36     if (argc < 3) {
 37         fprintf(stderr, "Usage: backuppcd-tar -xOf hostname:/path [... ignored...]\n");
 38         return(EXIT_FAILURE);
 39     }
 40 
 41     password = getenv("PASSWD");
 42 
 43     if (!password) {
 44         fprintf(stderr, "Must supply password in the environment variable \"PASSWD\"\n");
 45         return(EXIT_FAILURE);
 46     }
 47 
 48     host = strdup(argv[2]);
 49     rootpath = strchr(host, ':');
 50     if (rootpath) {
 51         *rootpath = '\0';
 52         rootpath++;
 53     } else {
 54         rootpath = "/";
 55     }
 56 
 57     port = 874;
 58     username = "backuppc-tar";
 59 
 60     cmd_ret = backuppcd_client(host, port, username, password, rootpath);
 61 
 62     if (cmd_ret < 0) {
 63         return(EXIT_FAILURE);
 64     }
 65 
 66     return(EXIT_SUCCESS);
 67 }
 68 
 69 
 70 int backuppcd_client_read(const int sockid, ...) {
 71     backuppc_clntdt_t typeid;
 72     va_list ap;
 73     uint8_t *u8v;
 74     uint16_t *u16v;
 75     uint32_t *u32v;
 76     uint64_t *u64v;
 77     char *cpv, **cppv;
 78     void *vpv = NULL, *vpv_s;
 79     size_t vpv_len;
 80     ssize_t read_ret;
 81 
 82     va_start(ap, sockid);
 83     while (1) {
 84         typeid = va_arg(ap, backuppc_clntdt_t);
 85 
 86         if (typeid == BPC_CDT_END) {
 87             break;
 88         }
 89 
 90         switch (typeid) {
 91             case BPC_CDT_UINT8:
 92                 u8v = va_arg(ap, uint8_t *);
 93                 vpv_len = sizeof(*u8v);
 94                 vpv = u8v;
 95                 break;
 96             case BPC_CDT_UINT16:
 97                 u16v = va_arg(ap, uint16_t *);
 98                 vpv_len = sizeof(*u16v);
 99                 vpv = u16v;
100                 break;
101             case BPC_CDT_UINT32:
102                 u32v = va_arg(ap, uint32_t *);
103                 vpv_len = sizeof(*u32v);
104                 vpv = u32v;
105                 break;
106             case BPC_CDT_UINT64:
107                 u64v = va_arg(ap, uint64_t *);
108                 vpv_len = sizeof(*u64v);
109                 vpv = u64v;
110                 break;
111             case BPC_CDT_BYTEARRAY:
112                 vpv_len = va_arg(ap, size_t);
113                 vpv = va_arg(ap, void *);
114                 break;
115             case BPC_CDT_STRING:
116                 vpv_len = va_arg(ap, size_t);
117                 vpv_len--;
118                 cpv = va_arg(ap, char *);
119                 cpv[vpv_len] = '\0';
120                 vpv = cpv;
121                 break;
122             case BPC_CDT_STRING_PTR:
123                 vpv_len = va_arg(ap, size_t);
124                 cppv = va_arg(ap, char **);
125                 if (*cppv == NULL) {
126                     cpv = *cppv = malloc(vpv_len + 1);
127                     cpv[vpv_len] = '\0';
128                 } else {
129                     cpv = *cppv;
130                 }
131                 vpv = cpv;
132                 break;
133             default:
134                 return(0);
135         }
136 
137         vpv_s = vpv;
138         while (vpv_len) {
139             read_ret = recv(sockid, vpv, vpv_len, MSG_WAITALL);
140 
141             if (read_ret <= 0) {
142                 return(0);
143             }
144 
145             vpv_len -= read_ret;
146             vpv += read_ret;
147         }
148         vpv = vpv_s;
149 
150         switch (typeid) {
151             case BPC_CDT_UINT16:
152                 u16v = vpv;
153                 *u16v = ntohs(*u16v);
154                 break;
155             case BPC_CDT_UINT32:
156                 u32v = vpv;
157                 *u32v = ntohl(*u32v);
158                 break;
159             case BPC_CDT_UINT64:
160                 u64v = vpv;
161                 *u64v = ntohll(*u64v);
162                 break;
163             default:
164                 break;
165         }
166     }
167     va_end(ap);
168 
169     return(1);
170 }
171 
172 int backuppcd_client_write(const int sockid, ...) {
173     backuppc_clntdt_t typeid;
174     va_list ap;
175     uint8_t u8v;
176     uint16_t u16v;
177     uint32_t u32v;
178     uint64_t u64v;
179     void *vpv;
180     char *cpv;
181     size_t vpv_len;
182     ssize_t write_ret;
183 
184     va_start(ap, sockid);
185     while (1) {
186         typeid = va_arg(ap, backuppc_clntdt_t);
187 
188         if (typeid == BPC_CDT_END) {
189             break;
190         }
191 
192         switch (typeid) {
193             case BPC_CDT_UINT8:
194                 u8v = va_arg(ap, int);
195                 vpv_len = sizeof(u8v);
196                 vpv = &u8v;
197                 break;
198             case BPC_CDT_UINT16:
199                 u16v = va_arg(ap, int);
200                 u16v = htons(u16v);
201                 vpv_len = sizeof(u16v);
202                 vpv = &u16v;
203                 break;
204             case BPC_CDT_UINT32:
205                 u32v = va_arg(ap, uint32_t);
206                 u32v = htonl(u32v);
207                 vpv_len = sizeof(u32v);
208                 vpv = &u32v;
209                 break;
210             case BPC_CDT_UINT64:
211                 u64v = va_arg(ap, uint64_t);
212                 u64v = htonll(u64v);
213                 vpv_len = sizeof(u64v);
214                 vpv = &u64v;
215                 break;
216             case BPC_CDT_BYTEARRAY:
217                 vpv_len = va_arg(ap, size_t);
218                 vpv = va_arg(ap, void *);
219                 break;
220             case BPC_CDT_STRING:
221                 cpv = va_arg(ap, char *);
222                 vpv_len = strlen(cpv);
223                 vpv = cpv;
224                 break;
225             case BPC_CDT_STRING_PTR:
226             default:
227                 return(0);
228         }
229 
230         while (vpv_len) {
231             write_ret = send(sockid, vpv, vpv_len, 0);
232 
233             if (write_ret < 0) {
234                 return(0);
235             }
236 
237             vpv_len -= write_ret;
238             vpv += write_ret;
239         }
240     }
241     va_end(ap);
242 
243     return(1);
244 }
245 
246 
247 
248 int backuppcd_client_auth(const int sockid, const char *username, const char *password) {
249     uint8_t cmd_reply;
250     uint8_t status;
251 
252     if (!backuppcd_client_write(sockid,
253                                 BPC_CDT_UINT8, (uint8_t) BPC_CMD_AUTH,
254                                 BPC_CDT_UINT16, (uint16_t) strlen(username),
255                                 BPC_CDT_UINT16, (uint16_t) strlen(password),
256                                 BPC_CDT_STRING, username,
257                                 BPC_CDT_STRING, password,
258                                 BPC_CDT_END)) {
259         return(0);
260     }
261 
262     if (!backuppcd_client_read(sockid,
263                                BPC_CDT_UINT8, (uint8_t *) &cmd_reply,
264                                BPC_CDT_UINT8, (uint8_t *) &status,
265                                BPC_CDT_END)) {
266         return(0);
267     }
268 
269     if (cmd_reply != BPC_CMD_AUTH_REPLY) {
270         return(0);
271     }
272 
273     if (status != BPC_STATUS_OKAY) {
274         return(0);
275     }
276 
277     return(1);
278 }
279 
280 int backuppcd_client_target(const int sockid, const char *rootpath, const int opt_verbosity, const int opt_totals) {
281     backuppc_cmd_t sendcmd;
282     unsigned char pathbuf[8192], *outpathbuf = NULL, tarbuf[512], *shortname, *dirname;
283     unsigned char *buf = NULL;
284     uint32_t attr_sect_len, blocksize, pathnamelen, blocknum = 0;
285     uint64_t filesize, byteswritten = 0;
286     uint32_t bufsize = 0;
287     uint32_t attr_uid, attr_gid, attr_ctime, attr_mtime, attr_devmajor, attr_devminor;
288     uint32_t attrlen;
289     uint32_t tar_checksum;
290     uint32_t tarblocks = 0;
291     uint16_t attrid;
292     uint16_t attr_mode;
293     uint8_t filetype, cmd;
294     ssize_t write_ret;
295     size_t writelen, bytes_to_copy;
296     time_t totaltime, starttime;
297     mode_t modeval;
298     char *attr_linkdest, *attr_username, *attr_groupname, *attr_hrdlinkdest;
299     char type_string[][7] = {"dir", "file", "syml", "sock", "fifo", "blk", "chr", "hrdl"};
300     int tar_type;
301     int i, x, skipfile;
302 
303     starttime = time(NULL);
304 
305     sendcmd = BPC_CMD_GET;
306 
307     if (!backuppcd_client_write(sockid,
308                                 BPC_CDT_UINT8, (uint8_t) sendcmd,
309                                 BPC_CDT_UINT8, (uint8_t) BPC_OPT_RECURSIVE,
310                                 BPC_CDT_UINT32, (uint32_t) 0, /* exclude section length */
311                                 BPC_CDT_UINT32, (uint32_t) 0, /* include section length */
312                                 BPC_CDT_UINT32, (uint32_t) strlen(rootpath),
313                                 BPC_CDT_STRING, (char *) rootpath,
314                                 /* Exclude section is 0 bytes (XXX) */
315                                 /* Include section is 0 bytes (XXX) */
316                                 BPC_CDT_END)) {
317         CHECKPOINT;
318         return(0);
319     }
320 
321     if (!backuppcd_client_read(sockid,
322                                BPC_CDT_UINT8, (uint8_t *) &cmd,
323                                BPC_CDT_END)) {
324         CHECKPOINT;
325         return(0);
326     }
327 
328     /*
329      * If the server sends us a reply for something other than what we
330      * asked for, something went wrong, abort.
331      */
332     if (cmd != (sendcmd | 0x80)) {
333         CHECKPOINT;
334         return(0);
335     }
336 
337     /*
338      * Process every file entry in the reply.
339      */
340     while (1) {
341         if (!backuppcd_client_read(sockid,
342                                    BPC_CDT_UINT8, (uint8_t *) &filetype,
343                                    BPC_CDT_END)) {
344             CHECKPOINT;
345             return(0);
346         }
347 
348         for (i = 0; i < sizeof(tarbuf); i++) {
349             tarbuf[i] = 0;
350         }
351 
352         if (filetype == 0xff) {
353             break;
354         }
355 
356         if (!backuppcd_client_read(sockid,
357                                    BPC_CDT_UINT32, (uint32_t *) &attr_sect_len,
358                                    BPC_CDT_UINT64, (uint64_t *) &filesize,
359                                    BPC_CDT_UINT32, (uint32_t *) &blocksize,
360                                    BPC_CDT_UINT32, (uint32_t *) &pathnamelen,
361                                    BPC_CDT_END)) {
362             CHECKPOINT;
363             return(0);
364         }
365 
366 
367         if (pathnamelen >= sizeof(pathbuf)) {
368             SPOTVAR_I(pathnamelen);
369             CHECKPOINT;
370             return(0);
371         }
372 
373         if (!backuppcd_client_read(sockid,
374                                    BPC_CDT_STRING, (size_t) (pathnamelen + 1), &pathbuf,
375                                    BPC_CDT_END)) {
376             CHECKPOINT;
377             return(0);
378         }
379 
380         attr_uid = 0;
381         attr_gid = 0;
382         attr_mode = 0;
383         attr_ctime = 0;
384         attr_mtime = 0;
385         attr_devmajor = 0;
386         attr_devminor = 0;
387         attr_username = NULL;
388         attr_groupname = NULL;
389         attr_linkdest = NULL;
390         attr_hrdlinkdest = NULL;
391 
392         /*
393          * Read the sent attributes.
394          * Currently this does not handle all attributes and any
395          * attribute that is not handled is not properly sunk, instead
396          * the data remains in the buffer to be mis-processed later.
397          * Fix this (XXX)
398          */
399         if (attr_sect_len != 0) {
400             while (1) {
401                 if (!backuppcd_client_read(sockid,
402                                            BPC_CDT_UINT16, (uint16_t *) &attrid,
403                                            BPC_CDT_END)) {
404                     CHECKPOINT;
405                     return(0);
406                 }
407 
408                 if (attrid == 0xffff) {
409                     break;
410                 }
411 
412                 if (!backuppcd_client_read(sockid,
413                                            BPC_CDT_UINT32, (uint32_t *) &attrlen,
414                                            BPC_CDT_END)) {
415                     CHECKPOINT;
416                     return(0);
417                 }
418 
419                 switch ((backuppc_attrid_t) attrid) {
420                     case BPC_ATTRID_NOP:
421                         if (attrlen != 0) {
422                             CHECKPOINT;
423                             return(0);
424                         }
425                         break;
426                     case BPC_ATTRID_MTIME:
427                         if (!backuppcd_client_read(sockid,
428                                                    BPC_CDT_UINT32, (uint32_t *) &attr_mtime,
429                                                    BPC_CDT_END)) {
430                             CHECKPOINT;
431                             return(0);
432                         }
433                         break;
434                     case BPC_ATTRID_CTIME:
435                         if (!backuppcd_client_read(sockid,
436                                                    BPC_CDT_UINT32, (uint32_t *) &attr_ctime,
437                                                    BPC_CDT_END)) {
438                             CHECKPOINT;
439                             return(0);
440                         }
441                         break;
442                     case BPC_ATTRID_UID:
443                         if (!backuppcd_client_read(sockid,
444                                                    BPC_CDT_UINT32, (uint32_t *) &attr_uid,
445                                                    BPC_CDT_END)) {
446                             CHECKPOINT;
447                             return(0);
448                         }
449                         break;
450                     case BPC_ATTRID_GID:
451                         if (!backuppcd_client_read(sockid,
452                                                    BPC_CDT_UINT32, (uint32_t *) &attr_gid,
453                                                    BPC_CDT_END)) {
454                             CHECKPOINT;
455                             return(0);
456                         }
457                         break;
458                     case BPC_ATTRID_ACL:
459                         if (!backuppcd_client_read(sockid,
460                                                    BPC_CDT_UINT16, (uint16_t *) &attr_mode,
461                                                    BPC_CDT_END)) {
462                             CHECKPOINT;
463                             return(0);
464                         }
465 
466                         break;
467                     case BPC_ATTRID_USER:
468                         if (attrlen > BPC_MAXPATH_LEN) {
469                             CHECKPOINT;
470                             return(0);
471                         }
472 
473                         if (attr_username) {
474                             free(attr_username);
475                         }
476 
477                         attr_username = NULL;
478 
479                         if (!backuppcd_client_read(sockid,
480                                                    BPC_CDT_STRING_PTR, (size_t) attrlen, (char **) &attr_username,
481                                                    BPC_CDT_END)) {
482                             CHECKPOINT;
483                             return(0);
484                         }
485                         break;
486                     case BPC_ATTRID_GROUP:
487                         if (attrlen > BPC_MAXPATH_LEN) {
488                             CHECKPOINT;
489                             return(0);
490                         }
491 
492                         if (attr_groupname) {
493                             free(attr_groupname);
494                         }
495 
496                         attr_groupname = NULL;
497 
498                         if (!backuppcd_client_read(sockid,
499                                                    BPC_CDT_STRING_PTR, (size_t) attrlen, (char **) &attr_groupname,
500                                                    BPC_CDT_END)) {
501                             CHECKPOINT;
502                             return(0);
503                         }
504                         break;
505                     case BPC_ATTRID_SYMLINKDEST:
506                         if (attrlen > BPC_MAXPATH_LEN) {
507                             CHECKPOINT;
508                             return(0);
509                         }
510 
511                         if (attr_linkdest) {
512                             free(attr_linkdest);
513                         }
514 
515                         attr_linkdest = NULL;
516 
517                         if (!backuppcd_client_read(sockid,
518                                                    BPC_CDT_STRING_PTR, (size_t) attrlen, (char **) &attr_linkdest,
519                                                    BPC_CDT_END)) {
520                             CHECKPOINT;
521                             return(0);
522                         }
523                         break;
524                     case BPC_ATTRID_HRDLINKDEST:
525                         if (attrlen > BPC_MAXPATH_LEN) {
526                             CHECKPOINT;
527                             return(0);
528                         }
529 
530                         if (attr_hrdlinkdest) {
531                             free(attr_hrdlinkdest);
532                         }
533 
534                         attr_hrdlinkdest = NULL;
535 
536                         if (!backuppcd_client_read(sockid,
537                                                    BPC_CDT_STRING_PTR, (size_t) attrlen, (char **) &attr_hrdlinkdest,
538                                                    BPC_CDT_END)) {
539                             CHECKPOINT;
540                             return(0);
541                         }
542                         break;
543                 }
544             }
545         }
546 
547         /*
548          * Split the filename into 2 parts, the directory name and
549          * the file name.  USTAR allows us to fit longer file names
550          * if we do this.
551          */
552         shortname = strrchr(pathbuf, '/');
553         if (shortname) {
554             *shortname = '\0';
555             shortname++;
556             dirname = pathbuf;
557         } else {
558             shortname = pathbuf;
559             dirname = "";
560         }
561 
562         /*
563          * Do not attempt to fill the USTAR header with data that will
564          * not fit.  If an overflow condition is found, mark the file
565          * to be skipped and print a warning.
566          */
567         skipfile = 0;
568         if (strlen(shortname) >= 100 || strlen(dirname) >= 155) {
569             fprintf(stderr, "Skipping %s/%s, pathname too long.\n", dirname, shortname);
570             skipfile = 1;
571         }
572         if (filesize >= 0x200000000LLU) {
573             fprintf(stderr, "Skipping %s/%s, file too large.\n", dirname, shortname);
574             skipfile = 1;
575         }
576 
577         /*
578          * Determine the POSIX "mode" value from the ACL attrs.
579          */
580         modeval = 0;
581         if (attr_mode) {
582             if ((attr_mode & BPC_ACL_XUSR) == BPC_ACL_XUSR) {
583                 modeval |= S_IXUSR;
584             }
585             if ((attr_mode & BPC_ACL_WUSR) == BPC_ACL_WUSR) {
586                 modeval |= S_IWUSR;
587             }
588             if ((attr_mode & BPC_ACL_RUSR) == BPC_ACL_RUSR) {
589                 modeval |= S_IRUSR;
590             }
591 #ifndef _USE_WIN32_
592             if ((attr_mode & BPC_ACL_XGRP) == BPC_ACL_XGRP) {
593                 modeval |= S_IXGRP;
594             }
595             if ((attr_mode & BPC_ACL_WGRP) == BPC_ACL_WGRP) {
596                 modeval |= S_IWGRP;
597             }
598             if ((attr_mode & BPC_ACL_RGRP) == BPC_ACL_RGRP) {
599                 modeval |= S_IRGRP;
600             }
601             if ((attr_mode & BPC_ACL_XOTH) == BPC_ACL_XOTH) {
602                 modeval |= S_IXOTH;
603             }
604             if ((attr_mode & BPC_ACL_WOTH) == BPC_ACL_WOTH) {
605                 modeval |= S_IWOTH;
606             }
607             if ((attr_mode & BPC_ACL_ROTH) == BPC_ACL_ROTH) {
608                 modeval |= S_IROTH;
609             }
610             if ((attr_mode & BPC_ACL_STCK) == BPC_ACL_STCK) {
611                 modeval |= S_ISVTX;
612             }
613             if ((attr_mode & BPC_ACL_SGID) == BPC_ACL_SGID) {
614                 modeval |= S_ISGID;
615             }
616             if ((attr_mode & BPC_ACL_SUID) == BPC_ACL_SUID) {
617                 modeval |= S_ISUID;
618             }
619 #endif
620         }
621 
622         /*
623          * Determine the USTAR "type" flag from the file type, and
624          * continue adding bits to the POSIX "mode" value.
625          */
626         tar_type = 0;
627         if (filetype == BPC_FILE_REG) {
628             modeval |= S_IFREG;
629             tar_type = 0;
630         }
631 #ifndef _USE_WIN32_
632         if (filetype == BPC_FILE_SYMLINK) {
633             modeval |= S_IFLNK;
634             tar_type = 1;
635         }
636         if (filetype == BPC_FILE_SOCKET) {
637             modeval |= S_IFSOCK;
638             tar_type = 2; /* ??? */
639         }
640 #endif
641         if (filetype == BPC_FILE_DIR) {
642             modeval |= S_IFDIR;
643             tar_type = 5;
644         }
645         if (filetype == BPC_FILE_BDEV) {
646             modeval |= S_IFBLK;
647             tar_type = 4;
648         }
649         if (filetype == BPC_FILE_CDEV) {
650             modeval |= S_IFCHR;
651             tar_type = 3;
652         }
653         if (filetype == BPC_FILE_FIFO) {
654             modeval |= S_IFIFO;
655             tar_type = 6;
656         }
657 
658         /*
659          * Only send a header for this file if we intend to send the
660          * data for it.
661          */
662         if (!skipfile) {
663             /*
664              * Generate the USTAR header in the buffer.
665              */
666             memcpy(tarbuf, shortname, strlen(shortname));
667             sprintf(tarbuf + 100, "%07o", modeval);
668             sprintf(tarbuf + 108, "%07o", attr_uid);
669             sprintf(tarbuf + 116, "%07o", attr_gid);
670             sprintf(tarbuf + 124, "%011o", (unsigned int) filesize);
671             sprintf(tarbuf + 136, "%011o", attr_mtime);
672             sprintf(tarbuf + 148, "        ");
673             sprintf(tarbuf + 156, "%i", tar_type);
674             if (filetype == BPC_FILE_SYMLINK) {
675                 sprintf(tarbuf + 157, attr_linkdest);
676             }
677             sprintf(tarbuf + 257, "ustar");
678             sprintf(tarbuf + 263, "  ");
679             if (attr_username) {
680                 sprintf(tarbuf + 265, "%s", attr_username);
681             }
682             if (attr_groupname) {
683                 sprintf(tarbuf + 297, "%s", attr_groupname);
684             }
685             if (attr_devmajor) {
686                 sprintf(tarbuf + 329, "%07o", attr_devmajor);
687             }
688             if (attr_devminor) {
689                 sprintf(tarbuf + 337, "%07o", attr_devminor);
690             }
691             sprintf(tarbuf + 345, "%s", dirname);
692 
693             /* Calculate checksum. */
694             tar_checksum = 0;
695             for (i = 0; i < sizeof(tarbuf); i++) {
696                 tar_checksum += tarbuf[i];
697             }
698             sprintf(tarbuf + 148, "%06o", tar_checksum);
699 
700             write_ret = write(STDOUT_FILENO, tarbuf, sizeof(tarbuf));
701             if (write_ret != sizeof(tarbuf)) {
702                 CHECKPOINT;
703                 return(0);
704             }
705 
706             /*
707              * Calculate the number of blocks this file will need
708              * including the 1-block header.
709              */
710             tarblocks += 1 + ((filesize + sizeof(tarbuf) - 1) / sizeof(tarbuf));
711         }
712 
713         switch (opt_verbosity) {
714             case 0:
715                 break;
716             case 1:
717                 fprintf(stderr, ".%s/%s\n", dirname, shortname);
718                 break;
719             case 2:
720                 fprintf(stderr, "[%4s] %04o %6lu %6lu %10llu %12lu %s/%s",
721                        type_string[filetype],
722                        (unsigned int) attr_mode,
723                        (unsigned long) attr_uid,
724                        (unsigned long) attr_gid,
725                        (unsigned long long) filesize,
726                        (unsigned long) attr_mtime,
727                        dirname,
728                        shortname);
729                 if (filetype == BPC_FILE_SYMLINK) {
730                     fprintf(stderr, " -> %s", attr_linkdest);
731                 }
732                 fprintf(stderr, "\n");
733                 break;
734         }
735 
736         outpathbuf = pathbuf + 1;
737 
738         byteswritten = 0;
739 
740         /*
741          * Ensure the buffer is large enough to hold all the data.
742          * If the buffer starts changing a lot between files, we
743          * should make this grow-only.  It's fine for now.
744          */
745         if (bufsize != blocksize) {
746             if (buf) {
747                 free(buf);
748             }
749 
750             bufsize = blocksize;
751 
752             buf = malloc(bufsize);
753 
754             if (!buf) {
755                 CHECKPOINT;
756                 return(0);
757             }
758         }
759 
760         /*
761          * Read the file data from the server.  We must do this even
762          * if we are not planning on sending it in USTAR format.
763          * The data comes in "blocksize" sized blocks and may be
764          * larger than the actual file.
765          */
766         while (1) {
767             if (!backuppcd_client_read(sockid,
768                                       BPC_CDT_UINT32, (uint32_t *) &blocknum,
769                                       BPC_CDT_END)) {
770                 CHECKPOINT;
771                 return(0);
772             }
773 
774             if (blocknum == 0xffffffff) {
775                 break;
776             }
777 
778             if (!backuppcd_client_read(sockid,
779                                       BPC_CDT_BYTEARRAY, (size_t) blocksize, (void *) buf,
780                                       BPC_CDT_END)) {
781 
782                 CHECKPOINT;
783                 return(0);
784             }
785 
786             /*
787              * Determine the amount of data in this block that we
788              * should write.  Currently this fails to deal with
789              * sparse files and assumes that an entire file is
790              * with all blocks in order.  This will need to change.
791              * (XXX)
792              */
793             if ((byteswritten + blocksize) > filesize) {
794                 if (filesize > byteswritten) {
795                     writelen = filesize - byteswritten;
796                 } else {
797                     writelen = 0;
798                 }
799             } else {
800                 writelen = blocksize;
801             }
802 
803             if (!skipfile) {
804                 /*
805                  * Send the file data if there is any.
806                  */
807                 if (writelen > 0) {
808                     x = 0;
809                     while (x < writelen) {
810                         write_ret = write(STDOUT_FILENO, buf + x, writelen - x);
811 
812                         if (write_ret <= 0) {
813                             CHECKPOINT;
814                             return(0);
815                         }
816 
817                         x += write_ret;
818                     }
819                 }
820             }
821 
822             byteswritten += blocksize;
823         }
824 
825         if (!skipfile) {
826             /*
827              * Round the file to 512-byte blocks.
828              */
829             bytes_to_copy = sizeof(tarbuf) - (filesize % sizeof(tarbuf));
830             if (bytes_to_copy != sizeof(tarbuf)) {
831                 for (i = 0; i < bytes_to_copy; i++) {
832                     tarbuf[i] = 0;
833                 }
834                 write_ret = write(STDOUT_FILENO, tarbuf, bytes_to_copy);
835                 if (write_ret != bytes_to_copy) {
836                     CHECKPOINT;
837                     return(0);
838                 }
839             }
840         }
841 
842         /* Clean up any allocated memory, if needed. */
843         if (attr_linkdest) {
844             free(attr_linkdest);
845         }
846         if (attr_username) {
847             free(attr_username);
848         }
849         if (attr_groupname) {
850             free(attr_groupname);
851         }
852         if (attr_hrdlinkdest) {
853             free(attr_hrdlinkdest);
854         }
855     }
856 
857     /*
858      * USTAR end of archive is two empty blocks.
859      */
860     write(STDOUT_FILENO, tarbuf, sizeof(tarbuf));
861     write(STDOUT_FILENO, tarbuf, sizeof(tarbuf));
862     tarblocks += 2;
863 
864     if (opt_totals) {
865         totaltime = time(NULL) - starttime;
866         if (totaltime == 0) {
867             totaltime = 1;
868         }
869 
870         fprintf(stderr, "Total bytes written: %lu (%luKiB, %fKiB/s)\n", (unsigned long) (tarblocks * sizeof(tarbuf)),
	(unsigned long) (tarblocks * sizeof(tarbuf) / 1024), (((double) tarblocks * sizeof(tarbuf)) / 1024.0) / ((double)
	totaltime));
871     }
872  
873     CHECKPOINT;
874     return(1);
875 }
876 
877 int backuppcd_client(const char *host, const int port, const char *username, const char *password, const char *rootpath)
	{
878     int sockid;
879 
880     sockid = net_connect_tcp(host, port);
881 
882     if (sockid < 0) {
883         return(-1);
884     }
885 
886     if (!backuppcd_client_auth(sockid, username, password)) {
887         return(-1);
888     }
889 
890     if (!backuppcd_client_target(sockid, rootpath, 1, 1)) {
891         return(-1);
892     }
893 
894     return(0);
895 }
5762842 [rkeene@sledge /home/rkeene/devel/backuppcd/all/backuppcd-200601171056]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2005-08-10 18:37:16