00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "includes.h"
00039 #include "clitar.h"
00040 #include "client/client_proto.h"
00041
00042 static int clipfind(char **aret, int ret, char *tok);
00043
00044 typedef struct file_info_struct file_info2;
00045
00046 struct file_info_struct {
00047 SMB_OFF_T size;
00048 uint16 mode;
00049 uid_t uid;
00050 gid_t gid;
00051
00052 struct timespec mtime_ts;
00053 struct timespec atime_ts;
00054 struct timespec ctime_ts;
00055 char *name;
00056
00057 file_info2 *next, *prev;
00058 };
00059
00060 typedef struct {
00061 file_info2 *top;
00062 int items;
00063 } stack;
00064
00065 #define SEPARATORS " \t\n\r"
00066 extern time_t newer_than;
00067 extern struct cli_state *cli;
00068
00069
00070
00071 #define ATTRSET 1
00072 #define ATTRRESET 0
00073
00074 static uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
00075
00076 #ifndef CLIENT_TIMEOUT
00077 #define CLIENT_TIMEOUT (30*1000)
00078 #endif
00079
00080 static char *tarbuf, *buffer_p;
00081 static int tp, ntarf, tbufsiz;
00082 static double ttarf;
00083
00084 static BOOL tar_inc=False;
00085
00086 static BOOL tar_reset=False;
00087
00088 static BOOL tar_excl=True;
00089
00090 static BOOL tar_re_search=False;
00091
00092 static BOOL dry_run=False;
00093
00094 static BOOL tar_system=True;
00095
00096 static BOOL tar_hidden=True;
00097
00098 static BOOL tar_noisy=True;
00099 static BOOL tar_real_noisy=False;
00100
00101 char tar_type='\0';
00102 static char **cliplist=NULL;
00103 static int clipn=0;
00104 static BOOL must_free_cliplist = False;
00105
00106 extern file_info def_finfo;
00107 extern BOOL lowercase;
00108 extern uint16 cnum;
00109 extern BOOL readbraw_supported;
00110 extern int max_xmit;
00111 extern pstring cur_dir;
00112 extern int get_total_time_ms;
00113 extern int get_total_size;
00114
00115 static int blocksize=20;
00116 static int tarhandle;
00117
00118 static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
00119 const char *amode, unsigned char ftype);
00120 static void do_atar(char *rname,char *lname,file_info *finfo1);
00121 static void do_tar(file_info *finfo);
00122 static void oct_it(SMB_BIG_UINT value, int ndgs, char *p);
00123 static void fixtarname(char *tptr, const char *fp, size_t l);
00124 static int dotarbuf(int f, char *b, int n);
00125 static void dozerobuf(int f, int n);
00126 static void dotareof(int f);
00127 static void initarbuf(void);
00128
00129
00130 static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix);
00131 static long unoct(char *p, int ndgs);
00132 static void do_tarput(void);
00133 static void unfixtarname(char *tptr, char *fp, int l, BOOL first);
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static char *string_create_s(int size)
00144 {
00145 char *tmp;
00146
00147 tmp = (char *)SMB_MALLOC(size+1);
00148
00149 if (tmp == NULL) {
00150 DEBUG(0, ("Out of memory in string_create_s\n"));
00151 }
00152
00153 return(tmp);
00154 }
00155
00156
00157
00158
00159
00160 static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
00161 const char *amode, unsigned char ftype)
00162 {
00163 union hblock hb;
00164 int i, chk, l;
00165 char *jp;
00166
00167 DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
00168
00169 memset(hb.dummy, 0, sizeof(hb.dummy));
00170
00171 l=strlen(aname);
00172
00173
00174
00175 if (l+2 >= NAMSIZ) {
00176
00177 char *b;
00178 b = (char *)SMB_MALLOC(l+TBLOCK+100);
00179 if (!b) {
00180 DEBUG(0,("out of memory\n"));
00181 exit(1);
00182 }
00183 writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
00184 memset(b, 0, l+TBLOCK+100);
00185 fixtarname(b, aname, l+2);
00186 i = strlen(b)+1;
00187 DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
00188 dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
00189 SAFE_FREE(b);
00190 }
00191
00192 fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2);
00193
00194 if (lowercase)
00195 strlower_m(hb.dbuf.name);
00196
00197
00198
00199 hb.dbuf.name[NAMSIZ-1]='\0';
00200 safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
00201 oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
00202 oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
00203 oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
00204 #ifdef HAVE_LONGLONG
00205 if (size > (SMB_BIG_UINT)077777777777LL) {
00206 #else
00207 if (size > (SMB_BIG_UINT)077777777777) {
00208 #endif
00209
00210
00211
00212
00213 memset(hb.dbuf.size, 0, 4);
00214 hb.dbuf.size[0]=128;
00215 for (i = 8, jp=(char*)&size; i; i--)
00216 hb.dbuf.size[i+3] = *(jp++);
00217 }
00218 oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
00219 memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
00220 memset(hb.dbuf.linkname, 0, NAMSIZ);
00221 hb.dbuf.linkflag=ftype;
00222
00223 for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;)
00224 chk+=(0xFF & *jp++);
00225
00226 oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
00227 hb.dbuf.chksum[6] = '\0';
00228
00229 (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
00230 }
00231
00232
00233
00234
00235
00236 static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
00237 {
00238 long chk, fchk;
00239 int i;
00240 char *jp;
00241
00242
00243
00244
00245
00246
00247
00248 for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;)
00249 chk+=(0xFF & *jp++);
00250
00251 if (chk == 0)
00252 return chk;
00253
00254
00255 for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
00256 chk-=(0xFF & *jp++);
00257
00258 chk += ' ' * sizeof(hb->dbuf.chksum);
00259
00260 fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
00261
00262 DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
00263 chk, fchk, hb->dbuf.chksum));
00264
00265 if (fchk != chk) {
00266 DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
00267 dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
00268 return -1;
00269 }
00270
00271 if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
00272 DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
00273 return(-1);
00274 }
00275
00276 safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3);
00277
00278
00279 unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
00280 strlen(hb->dbuf.name) + 1, True);
00281
00282
00283 if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
00284 if (hb->dbuf.linkflag == 0) {
00285 DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
00286 finfo->name));
00287 } else {
00288 if (hb -> dbuf.linkflag == 'L') {
00289
00290
00291
00292 } else {
00293 DEBUG(0, ("this tar file appears to contain some kind \
00294 of link other than a GNUtar Longlink - ignoring\n"));
00295 return -2;
00296 }
00297 }
00298 }
00299
00300 if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
00301 (*(finfo->name+strlen(finfo->name)-1) == '\\')) {
00302 finfo->mode=aDIR;
00303 } else {
00304 finfo->mode=0;
00305
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315 finfo->mtime_ts = finfo->ctime_ts =
00316 convert_time_t_to_timespec((time_t)strtol(hb->dbuf.mtime, NULL, 8));
00317 finfo->atime_ts = convert_time_t_to_timespec(time(NULL));
00318 finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
00319
00320 return True;
00321 }
00322
00323
00324
00325
00326
00327 static int dotarbuf(int f, char *b, int n)
00328 {
00329 int fail=1, writ=n;
00330
00331 if (dry_run) {
00332 return writ;
00333 }
00334
00335 if (tp + n >= tbufsiz) {
00336 int diff;
00337
00338 diff=tbufsiz-tp;
00339 memcpy(tarbuf + tp, b, diff);
00340 fail=fail && (1+write(f, tarbuf, tbufsiz));
00341 n-=diff;
00342 b+=diff;
00343 tp=0;
00344
00345 while (n >= tbufsiz) {
00346 fail=fail && (1 + write(f, b, tbufsiz));
00347 n-=tbufsiz;
00348 b+=tbufsiz;
00349 }
00350 }
00351
00352 if (n>0) {
00353 memcpy(tarbuf+tp, b, n);
00354 tp+=n;
00355 }
00356
00357 return(fail ? writ : 0);
00358 }
00359
00360
00361
00362
00363
00364 static void dozerobuf(int f, int n)
00365 {
00366
00367
00368
00369
00370 if (dry_run)
00371 return;
00372
00373 if (n+tp >= tbufsiz) {
00374 memset(tarbuf+tp, 0, tbufsiz-tp);
00375 write(f, tarbuf, tbufsiz);
00376 memset(tarbuf, 0, (tp+=n-tbufsiz));
00377 } else {
00378 memset(tarbuf+tp, 0, n);
00379 tp+=n;
00380 }
00381 }
00382
00383
00384
00385
00386
00387 static void initarbuf(void)
00388 {
00389
00390 tbufsiz=blocksize*TBLOCK;
00391 tarbuf=(char *)SMB_MALLOC(tbufsiz);
00392
00393
00394 tp=0; ntarf=0; ttarf=0;
00395 }
00396
00397
00398
00399
00400
00401 static void dotareof(int f)
00402 {
00403 SMB_STRUCT_STAT stbuf;
00404
00405
00406 if (dry_run)
00407 return;
00408
00409 (void) dozerobuf(f, TBLOCK);
00410 (void) dozerobuf(f, TBLOCK);
00411
00412 if (sys_fstat(f, &stbuf) == -1) {
00413 DEBUG(0, ("Couldn't stat file handle\n"));
00414 return;
00415 }
00416
00417
00418
00419 if (tp > 0)
00420 write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
00421 }
00422
00423
00424
00425
00426
00427 static void fixtarname(char *tptr, const char *fp, size_t l)
00428 {
00429
00430
00431 *tptr++='.';
00432 l--;
00433
00434 StrnCpy(tptr, fp, l-1);
00435 string_replace(tptr, '\\', '/');
00436 }
00437
00438
00439
00440
00441
00442 static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
00443 {
00444
00445
00446
00447 --ndgs;
00448 p[--ndgs] = ' ';
00449
00450
00451 do {
00452 p[--ndgs] = '0' + (char) (value & 7);
00453 value >>= 3;
00454 } while (ndgs > 0 && value != 0);
00455
00456
00457 while (ndgs > 0)
00458 p[--ndgs] = '0';
00459 }
00460
00461
00462
00463
00464
00465 static long unoct(char *p, int ndgs)
00466 {
00467 long value=0;
00468
00469
00470 while (--ndgs) {
00471 if (isdigit((int)*p))
00472 value = (value << 3) | (long) (*p - '0');
00473
00474 p++;
00475 }
00476
00477 return value;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486 static int strslashcmp(char *s1, char *s2)
00487 {
00488 char *s1_0=s1;
00489
00490 while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) ||
00491 (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
00492 s1++; s2++;
00493 }
00494
00495
00496
00497
00498 if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\'))
00499 return 0;
00500
00501
00502 if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1))
00503 return 0;
00504
00505
00506 if ((*s2 == '/' || *s2 == '\\') && !*s1)
00507 return 0;
00508
00509 return *s1-*s2;
00510 }
00511
00512
00513
00514
00515
00516 static BOOL ensurepath(char *fname)
00517 {
00518
00519
00520
00521 char *partpath, *ffname;
00522 char *p=fname, *basehack;
00523
00524 DEBUG(5, ( "Ensurepath called with: %s\n", fname));
00525
00526 partpath = string_create_s(strlen(fname));
00527 ffname = string_create_s(strlen(fname));
00528
00529 if ((partpath == NULL) || (ffname == NULL)){
00530 DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
00531 SAFE_FREE(partpath);
00532 SAFE_FREE(ffname);
00533 return(False);
00534 }
00535
00536 *partpath = 0;
00537
00538
00539
00540 safe_strcpy(ffname, fname, strlen(fname));
00541
00542
00543 if ((basehack=strrchr_m(ffname, '\\')) == NULL)
00544 return True;
00545 else
00546 *basehack='\0';
00547
00548 p=strtok(ffname, "\\");
00549
00550 while (p) {
00551 safe_strcat(partpath, p, strlen(fname) + 1);
00552
00553 if (!cli_chkpath(cli, partpath)) {
00554 if (!cli_mkdir(cli, partpath)) {
00555 DEBUG(0, ("Error mkdirhiering\n"));
00556 return False;
00557 } else {
00558 DEBUG(3, ("mkdirhiering %s\n", partpath));
00559 }
00560 }
00561
00562 safe_strcat(partpath, "\\", strlen(fname) + 1);
00563 p = strtok(NULL,"/\\");
00564 }
00565
00566 return True;
00567 }
00568
00569 static int padit(char *buf, SMB_BIG_UINT bufsize, SMB_BIG_UINT padsize)
00570 {
00571 int berr= 0;
00572 int bytestowrite;
00573
00574 DEBUG(5, ("Padding with %0.f zeros\n", (double)padsize));
00575 memset(buf, 0, (size_t)bufsize);
00576 while( !berr && padsize > 0 ) {
00577 bytestowrite= (int)MIN(bufsize, padsize);
00578 berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
00579 padsize -= bytestowrite;
00580 }
00581
00582 return berr;
00583 }
00584
00585 static void do_setrattr(char *name, uint16 attr, int set)
00586 {
00587 uint16 oldattr;
00588
00589 if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return;
00590
00591 if (set == ATTRSET) {
00592 attr |= oldattr;
00593 } else {
00594 attr = oldattr & ~attr;
00595 }
00596
00597 if (!cli_setatr(cli, name, attr, 0)) {
00598 DEBUG(1,("setatr failed: %s\n", cli_errstr(cli)));
00599 }
00600 }
00601
00602
00603
00604
00605
00606 static void do_atar(char *rname,char *lname,file_info *finfo1)
00607 {
00608 int fnum;
00609 SMB_BIG_UINT nread=0;
00610 char ftype;
00611 file_info2 finfo;
00612 BOOL shallitime=True;
00613 char data[65520];
00614 int read_size = 65520;
00615 int datalen=0;
00616
00617 struct timeval tp_start;
00618
00619 GetTimeOfDay(&tp_start);
00620
00621 ftype = '0';
00622
00623 if (finfo1) {
00624 finfo.size = finfo1 -> size;
00625 finfo.mode = finfo1 -> mode;
00626 finfo.uid = finfo1 -> uid;
00627 finfo.gid = finfo1 -> gid;
00628 finfo.mtime_ts = finfo1 -> mtime_ts;
00629 finfo.atime_ts = finfo1 -> atime_ts;
00630 finfo.ctime_ts = finfo1 -> ctime_ts;
00631 finfo.name = finfo1 -> name;
00632 } else {
00633 finfo.size = def_finfo.size;
00634 finfo.mode = def_finfo.mode;
00635 finfo.uid = def_finfo.uid;
00636 finfo.gid = def_finfo.gid;
00637 finfo.mtime_ts = def_finfo.mtime_ts;
00638 finfo.atime_ts = def_finfo.atime_ts;
00639 finfo.ctime_ts = def_finfo.ctime_ts;
00640 finfo.name = def_finfo.name;
00641 }
00642
00643 if (dry_run) {
00644 DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name,
00645 (double)finfo.size));
00646 shallitime=0;
00647 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
00648 ntarf++;
00649 return;
00650 }
00651
00652 fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
00653
00654 clean_name(rname);
00655
00656 if (fnum == -1) {
00657 DEBUG(0,("%s opening remote file %s (%s)\n",
00658 cli_errstr(cli),rname, cur_dir));
00659 return;
00660 }
00661
00662 finfo.name = string_create_s(strlen(rname));
00663 if (finfo.name == NULL) {
00664 DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
00665 return;
00666 }
00667
00668 safe_strcpy(finfo.name,rname, strlen(rname));
00669 if (!finfo1) {
00670 time_t atime, mtime;
00671 if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &atime, &mtime)) {
00672 DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
00673 return;
00674 }
00675 finfo.atime_ts = convert_time_t_to_timespec(atime);
00676 finfo.mtime_ts = convert_time_t_to_timespec(mtime);
00677 finfo.ctime_ts = finfo.mtime_ts;
00678 }
00679
00680 DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
00681
00682 if (tar_inc && !(finfo.mode & aARCH)) {
00683 DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
00684 shallitime=0;
00685 } else if (!tar_system && (finfo.mode & aSYSTEM)) {
00686 DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
00687 shallitime=0;
00688 } else if (!tar_hidden && (finfo.mode & aHIDDEN)) {
00689 DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
00690 shallitime=0;
00691 } else {
00692 BOOL wrote_tar_header = False;
00693
00694 DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
00695 finfo.name, (double)finfo.size, lname));
00696
00697 do {
00698
00699 DEBUG(3,("nread=%.0f\n",(double)nread));
00700
00701 datalen = cli_read(cli, fnum, data, nread, read_size);
00702
00703 if (datalen == -1) {
00704 DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
00705 break;
00706 }
00707
00708 nread += datalen;
00709
00710
00711 if (!wrote_tar_header) {
00712
00713 writetarheader(tarhandle, rname, finfo.size,
00714 finfo.mtime_ts.tv_sec, "100644 \0", ftype);
00715 wrote_tar_header = True;
00716 }
00717
00718
00719
00720
00721
00722 if (nread > finfo.size) {
00723 datalen -= nread - finfo.size;
00724 DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
00725 finfo.name, (double)finfo.size));
00726 }
00727
00728
00729
00730
00731 if (dotarbuf(tarhandle,data,datalen) != datalen) {
00732 DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
00733 break;
00734 }
00735
00736 if ( (datalen == 0) && (finfo.size != 0) ) {
00737 DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
00738 break;
00739 }
00740
00741 datalen=0;
00742 } while ( nread < finfo.size );
00743
00744 if (wrote_tar_header) {
00745
00746 if (nread < finfo.size) {
00747 DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
00748 (double)finfo.size, (int)nread));
00749 if (padit(data, (SMB_BIG_UINT)sizeof(data), finfo.size - nread))
00750 DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
00751 }
00752
00753
00754 if (finfo.size % TBLOCK)
00755 dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
00756
00757 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
00758 ntarf++;
00759 } else {
00760 DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name));
00761 shallitime=0;
00762 }
00763 }
00764
00765 cli_close(cli, fnum);
00766
00767 if (shallitime) {
00768 struct timeval tp_end;
00769 int this_time;
00770
00771
00772 if (tar_reset && !dry_run)
00773 (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
00774
00775 GetTimeOfDay(&tp_end);
00776 this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000;
00777 get_total_time_ms += this_time;
00778 get_total_size += finfo.size;
00779
00780 if (tar_noisy) {
00781 DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
00782 (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
00783 finfo.name));
00784 }
00785
00786
00787 DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
00788 finfo.size / MAX(0.001, (1.024*this_time)),
00789 get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
00790 }
00791 }
00792
00793
00794
00795
00796
00797 static void do_tar(file_info *finfo)
00798 {
00799 pstring rname;
00800
00801 if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
00802 return;
00803
00804
00805 if (!tar_excl && clipn) {
00806 pstring exclaim;
00807
00808 DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
00809
00810 pstrcpy(exclaim, cur_dir);
00811 *(exclaim+strlen(exclaim)-1)='\0';
00812
00813 pstrcat(exclaim, "\\");
00814 pstrcat(exclaim, finfo->name);
00815
00816 DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
00817
00818 if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
00819 (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
00820 DEBUG(3,("Skipping file %s\n", exclaim));
00821 return;
00822 }
00823 }
00824
00825 if (finfo->mode & aDIR) {
00826 pstring saved_curdir;
00827 pstring mtar_mask;
00828
00829 pstrcpy(saved_curdir, cur_dir);
00830
00831 DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \
00832 strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
00833 (int)sizeof(cur_dir), (int)strlen(cur_dir),
00834 (int)strlen(finfo->name), finfo->name, cur_dir));
00835
00836 pstrcat(cur_dir,finfo->name);
00837 pstrcat(cur_dir,"\\");
00838
00839 DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
00840
00841
00842
00843 writetarheader(tarhandle, cur_dir, 0, finfo->mtime_ts.tv_sec, "040755 \0", '5');
00844 if (tar_noisy) {
00845 DEBUG(0,(" directory %s\n", cur_dir));
00846 }
00847 ntarf++;
00848 pstrcpy(mtar_mask,cur_dir);
00849 pstrcat(mtar_mask,"*");
00850 DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
00851 do_list(mtar_mask, attribute, do_tar, False, True);
00852 pstrcpy(cur_dir,saved_curdir);
00853 } else {
00854 pstrcpy(rname,cur_dir);
00855 pstrcat(rname,finfo->name);
00856 do_atar(rname,finfo->name,finfo);
00857 }
00858 }
00859
00860
00861
00862
00863
00864 static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
00865 {
00866
00867
00868
00869
00870 DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l));
00871
00872 if (first) {
00873 if (*fp == '.') {
00874 fp++;
00875 l--;
00876 }
00877 if (*fp == '\\' || *fp == '/') {
00878 fp++;
00879 l--;
00880 }
00881 }
00882
00883 safe_strcpy(tptr, fp, l);
00884 string_replace(tptr, '/', '\\');
00885 }
00886
00887
00888
00889
00890
00891
00892 static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
00893 {
00894 int bufread, total = 0;
00895
00896 DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
00897 *bufferp += TBLOCK;
00898 total = TBLOCK;
00899
00900 if (*bufferp >= (ltarbuf + bufsiz)) {
00901
00902 DEBUG(5, ("Reading more data into ltarbuf ...\n"));
00903
00904
00905
00906
00907
00908
00909
00910 bufread = read(tarhandle, ltarbuf, bufsiz);
00911 total = bufread;
00912
00913 while (total < bufsiz) {
00914 if (bufread < 0) {
00915 return (total > 0 ? -2 : bufread);
00916 }
00917 if (bufread == 0) {
00918 if (total <= 0) {
00919 return -2;
00920 }
00921 break;
00922 }
00923 bufread = read(tarhandle, <arbuf[total], bufsiz - total);
00924 total += bufread;
00925 }
00926
00927 DEBUG(5, ("Total bytes read ... %i\n", total));
00928
00929 *bufferp = ltarbuf;
00930 }
00931
00932 return(total);
00933 }
00934
00935
00936 static int skip_file(int skipsize)
00937 {
00938 int dsize = skipsize;
00939
00940 DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
00941
00942
00943
00944 while (dsize > 0) {
00945 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
00946 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
00947 return(False);
00948 }
00949 dsize -= TBLOCK;
00950 }
00951
00952 return(True);
00953 }
00954
00955
00956
00957
00958
00959
00960
00961 static int get_file(file_info2 finfo)
00962 {
00963 int fnum = -1, pos = 0, dsize = 0, bpos = 0;
00964 SMB_BIG_UINT rsize = 0;
00965
00966 DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
00967
00968 if (ensurepath(finfo.name) &&
00969 (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
00970 DEBUG(0, ("abandoning restore\n"));
00971 return(False);
00972 }
00973
00974
00975
00976 rsize = finfo.size;
00977
00978 while (rsize > 0) {
00979
00980
00981 dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520);
00982 dsize = MIN(dsize, rsize);
00983 DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
00984
00985 if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
00986 DEBUG(0, ("Error writing remote file\n"));
00987 return 0;
00988 }
00989
00990 rsize -= dsize;
00991 pos += dsize;
00992
00993
00994
00995
00996
00997
00998
00999
01000 if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
01001 dsize -= (TBLOCK - bpos);
01002 bpos = 0;
01003
01004 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
01005 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
01006 return False;
01007 }
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 while (((rsize != 0) && (dsize >= TBLOCK)) ||
01019 ((rsize == 0) && (dsize > TBLOCK))) {
01020
01021 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
01022 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
01023 return False;
01024 }
01025
01026 dsize -= TBLOCK;
01027 }
01028 bpos = dsize;
01029 }
01030
01031
01032
01033 if (!cli_close(cli, fnum)) {
01034 DEBUG(0, ("Error closing remote file\n"));
01035 return(False);
01036 }
01037
01038
01039 DEBUG(5, ("Updating creation date on %s\n", finfo.name));
01040
01041 if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec)) {
01042 if (tar_real_noisy) {
01043 DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
01044
01045 }
01046 }
01047
01048 ntarf++;
01049 DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
01050 return(True);
01051 }
01052
01053
01054
01055
01056 static int get_dir(file_info2 finfo)
01057 {
01058 DEBUG(0, ("restore directory %s\n", finfo.name));
01059
01060 if (!ensurepath(finfo.name)) {
01061 DEBUG(0, ("Problems creating directory\n"));
01062 return(False);
01063 }
01064 ntarf++;
01065 return(True);
01066 }
01067
01068
01069
01070
01071
01072 static char *get_longfilename(file_info2 finfo)
01073 {
01074
01075
01076 int namesize = finfo.size + strlen(cur_dir) + 2;
01077 char *longname = (char *)SMB_MALLOC(namesize);
01078 int offset = 0, left = finfo.size;
01079 BOOL first = True;
01080
01081 DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
01082 DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
01083
01084 if (longname == NULL) {
01085 DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize));
01086 return(NULL);
01087 }
01088
01089
01090
01091 if (strlen(cur_dir) > 0) {
01092 strncpy(longname, cur_dir, namesize);
01093 offset = strlen(cur_dir);
01094 }
01095
01096
01097
01098 while (left > 0) {
01099 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
01100 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
01101 SAFE_FREE(longname);
01102 return(NULL);
01103 }
01104
01105 unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
01106 DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
01107
01108 offset += TBLOCK;
01109 left -= TBLOCK;
01110 }
01111
01112 return(longname);
01113 }
01114
01115 static void do_tarput(void)
01116 {
01117 file_info2 finfo;
01118 struct timeval tp_start;
01119 char *longfilename = NULL, linkflag;
01120 int skip = False;
01121
01122 ZERO_STRUCT(finfo);
01123
01124 GetTimeOfDay(&tp_start);
01125 DEBUG(5, ("RJS do_tarput called ...\n"));
01126
01127 buffer_p = tarbuf + tbufsiz;
01128
01129
01130 while (True) {
01131
01132 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
01133 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
01134 SAFE_FREE(longfilename);
01135 return;
01136 }
01137
01138 DEBUG(5, ("Reading the next header ...\n"));
01139
01140 switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
01141 case -2:
01142 DEBUG(0, ("Skipping %s...\n", finfo.name));
01143 if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) {
01144 DEBUG(0, ("Short file, bailing out...\n"));
01145 return;
01146 }
01147 break;
01148
01149 case -1:
01150 DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
01151 return;
01152
01153 case 0:
01154 DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
01155 return;
01156
01157 default:
01158
01159 break;
01160 }
01161
01162
01163 if (longfilename != NULL) {
01164 SAFE_FREE(finfo.name);
01165 finfo.name = longfilename;
01166 longfilename = NULL;
01167 }
01168
01169
01170
01171 skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) ||
01172 (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True)));
01173
01174 DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
01175 if (skip) {
01176 skip_file(finfo.size);
01177 continue;
01178 }
01179
01180
01181 linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
01182 switch (linkflag) {
01183 case '0':
01184
01185
01186
01187
01188
01189
01190 if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
01191 DEBUG(0, ("Short file, bailing out...\n"));
01192 return;
01193 }
01194 if (!get_file(finfo)) {
01195 DEBUG(0, ("Abandoning restore\n"));
01196 return;
01197 }
01198 break;
01199 case '5':
01200 if (!get_dir(finfo)) {
01201 DEBUG(0, ("Abandoning restore \n"));
01202 return;
01203 }
01204 break;
01205 case 'L':
01206 SAFE_FREE(longfilename);
01207 longfilename = get_longfilename(finfo);
01208 if (!longfilename) {
01209 DEBUG(0, ("abandoning restore\n"));
01210 return;
01211 }
01212 DEBUG(5, ("Long file name: %s\n", longfilename));
01213 break;
01214
01215 default:
01216 skip_file(finfo.size);
01217 break;
01218 }
01219 }
01220 }
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 int cmd_block(void)
01231 {
01232 fstring buf;
01233 int block;
01234
01235 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01236 DEBUG(0, ("blocksize <n>\n"));
01237 return 1;
01238 }
01239
01240 block=atoi(buf);
01241 if (block < 0 || block > 65535) {
01242 DEBUG(0, ("blocksize out of range"));
01243 return 1;
01244 }
01245
01246 blocksize=block;
01247 DEBUG(2,("blocksize is now %d\n", blocksize));
01248
01249 return 0;
01250 }
01251
01252
01253
01254
01255
01256 int cmd_tarmode(void)
01257 {
01258 fstring buf;
01259
01260 while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01261 if (strequal(buf, "full"))
01262 tar_inc=False;
01263 else if (strequal(buf, "inc"))
01264 tar_inc=True;
01265 else if (strequal(buf, "reset"))
01266 tar_reset=True;
01267 else if (strequal(buf, "noreset"))
01268 tar_reset=False;
01269 else if (strequal(buf, "system"))
01270 tar_system=True;
01271 else if (strequal(buf, "nosystem"))
01272 tar_system=False;
01273 else if (strequal(buf, "hidden"))
01274 tar_hidden=True;
01275 else if (strequal(buf, "nohidden"))
01276 tar_hidden=False;
01277 else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
01278 tar_noisy=True;
01279 else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
01280 tar_noisy=False;
01281 else
01282 DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
01283 }
01284
01285 DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
01286 tar_inc ? "incremental" : "full",
01287 tar_system ? "system" : "nosystem",
01288 tar_hidden ? "hidden" : "nohidden",
01289 tar_reset ? "reset" : "noreset",
01290 tar_noisy ? "verbose" : "quiet"));
01291 return 0;
01292 }
01293
01294
01295
01296
01297
01298 int cmd_setmode(void)
01299 {
01300 char *q;
01301 fstring buf;
01302 pstring fname;
01303 uint16 attra[2];
01304 int direct=1;
01305
01306 attra[0] = attra[1] = 0;
01307
01308 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01309 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
01310 return 1;
01311 }
01312
01313 pstrcpy(fname, cur_dir);
01314 pstrcat(fname, buf);
01315
01316 while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01317 q=buf;
01318
01319 while(*q) {
01320 switch (*q++) {
01321 case '+':
01322 direct=1;
01323 break;
01324 case '-':
01325 direct=0;
01326 break;
01327 case 'r':
01328 attra[direct]|=aRONLY;
01329 break;
01330 case 'h':
01331 attra[direct]|=aHIDDEN;
01332 break;
01333 case 's':
01334 attra[direct]|=aSYSTEM;
01335 break;
01336 case 'a':
01337 attra[direct]|=aARCH;
01338 break;
01339 default:
01340 DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
01341 return 1;
01342 }
01343 }
01344 }
01345
01346 if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) {
01347 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
01348 return 1;
01349 }
01350
01351 DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
01352 do_setrattr(fname, attra[ATTRSET], ATTRSET);
01353 do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
01354 return 0;
01355 }
01356
01357
01358
01359
01360
01361 int cmd_tar(void)
01362 {
01363 fstring buf;
01364 char **argl = NULL;
01365 int argcl = 0;
01366 int ret;
01367
01368 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01369 DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
01370 return 1;
01371 }
01372
01373 argl=toktocliplist(&argcl, NULL);
01374 if (!tar_parseargs(argcl, argl, buf, 0))
01375 return 1;
01376
01377 ret = process_tar();
01378 SAFE_FREE(argl);
01379 return ret;
01380 }
01381
01382
01383
01384
01385
01386 int process_tar(void)
01387 {
01388 int rc = 0;
01389 initarbuf();
01390 switch(tar_type) {
01391 case 'x':
01392
01393 #if 0
01394 do_tarput2();
01395 #else
01396 do_tarput();
01397 #endif
01398 SAFE_FREE(tarbuf);
01399 close(tarhandle);
01400 break;
01401 case 'r':
01402 case 'c':
01403 if (clipn && tar_excl) {
01404 int i;
01405 pstring tarmac;
01406
01407 for (i=0; i<clipn; i++) {
01408 DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
01409
01410 if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
01411 *(cliplist[i]+strlen(cliplist[i])-1)='\0';
01412 }
01413
01414 if (strrchr_m(cliplist[i], '\\')) {
01415 pstring saved_dir;
01416
01417 pstrcpy(saved_dir, cur_dir);
01418
01419 if (*cliplist[i]=='\\') {
01420 pstrcpy(tarmac, cliplist[i]);
01421 } else {
01422 pstrcpy(tarmac, cur_dir);
01423 pstrcat(tarmac, cliplist[i]);
01424 }
01425 pstrcpy(cur_dir, tarmac);
01426 *(strrchr_m(cur_dir, '\\')+1)='\0';
01427
01428 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
01429 do_list(tarmac,attribute,do_tar, False, True);
01430 pstrcpy(cur_dir,saved_dir);
01431 } else {
01432 pstrcpy(tarmac, cur_dir);
01433 pstrcat(tarmac, cliplist[i]);
01434 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
01435 do_list(tarmac,attribute,do_tar, False, True);
01436 }
01437 }
01438 } else {
01439 pstring mask;
01440 pstrcpy(mask,cur_dir);
01441 DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
01442 pstrcat(mask,"\\*");
01443 do_list(mask,attribute,do_tar,False, True);
01444 }
01445
01446 if (ntarf)
01447 dotareof(tarhandle);
01448 close(tarhandle);
01449 SAFE_FREE(tarbuf);
01450
01451 DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
01452 DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
01453 break;
01454 }
01455
01456 if (must_free_cliplist) {
01457 int i;
01458 for (i = 0; i < clipn; ++i) {
01459 SAFE_FREE(cliplist[i]);
01460 }
01461 SAFE_FREE(cliplist);
01462 cliplist = NULL;
01463 clipn = 0;
01464 must_free_cliplist = False;
01465 }
01466 return rc;
01467 }
01468
01469
01470
01471
01472
01473 static int clipfind(char **aret, int ret, char *tok)
01474 {
01475 if (aret==NULL)
01476 return 0;
01477
01478
01479 while(strchr_m("/\\.", *tok))
01480 tok++;
01481
01482 while(ret--) {
01483 char *pkey=*aret++;
01484
01485
01486 while(strchr_m("/\\.", *pkey))
01487 pkey++;
01488
01489 if (!strslashcmp(pkey, tok))
01490 return 1;
01491 }
01492 return 0;
01493 }
01494
01495
01496
01497
01498
01499
01500 static int read_inclusion_file(char *filename)
01501 {
01502 XFILE *inclusion = NULL;
01503 char buf[PATH_MAX + 1];
01504 char *inclusion_buffer = NULL;
01505 int inclusion_buffer_size = 0;
01506 int inclusion_buffer_sofar = 0;
01507 char *p;
01508 char *tmpstr;
01509 int i;
01510 int error = 0;
01511
01512 clipn = 0;
01513 buf[PATH_MAX] = '\0';
01514 if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
01515
01516
01517
01518 DEBUG(0,("Unable to open inclusion file %s\n", filename));
01519 return 0;
01520 }
01521
01522 while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
01523 if (inclusion_buffer == NULL) {
01524 inclusion_buffer_size = 1024;
01525 if ((inclusion_buffer = (char *)SMB_MALLOC(inclusion_buffer_size)) == NULL) {
01526 DEBUG(0,("failure allocating buffer to read inclusion file\n"));
01527 error = 1;
01528 break;
01529 }
01530 }
01531
01532 if (buf[strlen(buf)-1] == '\n') {
01533 buf[strlen(buf)-1] = '\0';
01534 }
01535
01536 if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
01537 inclusion_buffer_size *= 2;
01538 inclusion_buffer = (char *)SMB_REALLOC(inclusion_buffer,inclusion_buffer_size);
01539 if (!inclusion_buffer) {
01540 DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
01541 inclusion_buffer_size));
01542 error = 1;
01543 break;
01544 }
01545 }
01546
01547 safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
01548 inclusion_buffer_sofar += strlen(buf) + 1;
01549 clipn++;
01550 }
01551 x_fclose(inclusion);
01552
01553 if (! error) {
01554
01555 cliplist = SMB_MALLOC_ARRAY(char *, clipn + 1);
01556 if (cliplist == NULL) {
01557 DEBUG(0,("failure allocating memory for cliplist\n"));
01558 error = 1;
01559 } else {
01560 cliplist[clipn] = NULL;
01561 p = inclusion_buffer;
01562 for (i = 0; (! error) && (i < clipn); i++) {
01563
01564
01565 cliplist[i] = NULL;
01566 if ((tmpstr = (char *)SMB_MALLOC(strlen(p)+1)) == NULL) {
01567 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
01568 error = 1;
01569 } else {
01570 unfixtarname(tmpstr, p, strlen(p) + 1, True);
01571 cliplist[i] = tmpstr;
01572 if ((p = strchr_m(p, '\000')) == NULL) {
01573 DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
01574 abort();
01575 }
01576 }
01577 ++p;
01578 }
01579 must_free_cliplist = True;
01580 }
01581 }
01582
01583 SAFE_FREE(inclusion_buffer);
01584 if (error) {
01585 if (cliplist) {
01586 char **pp;
01587
01588 for (pp = cliplist; *pp; ++pp) {
01589 SAFE_FREE(*pp);
01590 }
01591 SAFE_FREE(cliplist);
01592 cliplist = NULL;
01593 must_free_cliplist = False;
01594 }
01595 return 0;
01596 }
01597
01598
01599 return 1;
01600 }
01601
01602
01603
01604
01605
01606 int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
01607 {
01608 int newOptind = Optind;
01609 char tar_clipfl='\0';
01610
01611
01612
01613
01614 tar_type='\0';
01615 tar_excl=True;
01616 dry_run=False;
01617
01618 while (*Optarg) {
01619 switch(*Optarg++) {
01620 case 'c':
01621 tar_type='c';
01622 break;
01623 case 'x':
01624 if (tar_type=='c') {
01625 printf("Tar must be followed by only one of c or x.\n");
01626 return 0;
01627 }
01628 tar_type='x';
01629 break;
01630 case 'b':
01631 if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
01632 DEBUG(0,("Option b must be followed by valid blocksize\n"));
01633 return 0;
01634 } else {
01635 Optind++;
01636 newOptind++;
01637 }
01638 break;
01639 case 'g':
01640 tar_inc=True;
01641 break;
01642 case 'N':
01643 if (Optind>=argc) {
01644 DEBUG(0,("Option N must be followed by valid file name\n"));
01645 return 0;
01646 } else {
01647 SMB_STRUCT_STAT stbuf;
01648
01649 if (sys_stat(argv[Optind], &stbuf) == 0) {
01650 newer_than = stbuf.st_mtime;
01651 DEBUG(1,("Getting files newer than %s",
01652 time_to_asc(newer_than)));
01653 newOptind++;
01654 Optind++;
01655 } else {
01656 DEBUG(0,("Error setting newer-than time\n"));
01657 return 0;
01658 }
01659 }
01660 break;
01661 case 'a':
01662 tar_reset=True;
01663 break;
01664 case 'q':
01665 tar_noisy=False;
01666 break;
01667 case 'I':
01668 if (tar_clipfl) {
01669 DEBUG(0,("Only one of I,X,F must be specified\n"));
01670 return 0;
01671 }
01672 tar_clipfl='I';
01673 break;
01674 case 'X':
01675 if (tar_clipfl) {
01676 DEBUG(0,("Only one of I,X,F must be specified\n"));
01677 return 0;
01678 }
01679 tar_clipfl='X';
01680 break;
01681 case 'F':
01682 if (tar_clipfl) {
01683 DEBUG(0,("Only one of I,X,F must be specified\n"));
01684 return 0;
01685 }
01686 tar_clipfl='F';
01687 break;
01688 case 'r':
01689 DEBUG(0, ("tar_re_search set\n"));
01690 tar_re_search = True;
01691 break;
01692 case 'n':
01693 if (tar_type == 'c') {
01694 DEBUG(0, ("dry_run set\n"));
01695 dry_run = True;
01696 } else {
01697 DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
01698 return 0;
01699 }
01700 break;
01701 default:
01702 DEBUG(0,("Unknown tar option\n"));
01703 return 0;
01704 }
01705 }
01706
01707 if (!tar_type) {
01708 printf("Option T must be followed by one of c or x.\n");
01709 return 0;
01710 }
01711
01712
01713
01714 tar_excl=tar_clipfl!='X';
01715
01716 if (tar_clipfl=='F') {
01717 if (argc-Optind-1 != 1) {
01718 DEBUG(0,("Option F must be followed by exactly one filename.\n"));
01719 return 0;
01720 }
01721 newOptind++;
01722
01723 if (! read_inclusion_file(argv[Optind+1])) {
01724 return 0;
01725 }
01726 } else if (Optind+1<argc && !tar_re_search) {
01727 char *tmpstr;
01728 char **tmplist;
01729 int clipcount;
01730
01731 cliplist=argv+Optind+1;
01732 clipn=argc-Optind-1;
01733 clipcount = clipn;
01734
01735 if ((tmplist=SMB_MALLOC_ARRAY(char *,clipn)) == NULL) {
01736 DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));
01737 return 0;
01738 }
01739
01740 for (clipcount = 0; clipcount < clipn; clipcount++) {
01741
01742 DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
01743
01744 if ((tmpstr = (char *)SMB_MALLOC(strlen(cliplist[clipcount])+1)) == NULL) {
01745 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));
01746 SAFE_FREE(tmplist);
01747 return 0;
01748 }
01749
01750 unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
01751 tmplist[clipcount] = tmpstr;
01752 DEBUG(5, ("Processed an item, %s\n", tmpstr));
01753
01754 DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
01755 }
01756
01757 cliplist = tmplist;
01758 must_free_cliplist = True;
01759
01760 newOptind += clipn;
01761 }
01762
01763 if (Optind+1<argc && tar_re_search && tar_clipfl != 'F') {
01764
01765 clipn=argc-Optind-1;
01766 cliplist=argv+Optind+1;
01767 newOptind += clipn;
01768 }
01769
01770 if (Optind>=argc || !strcmp(argv[Optind], "-")) {
01771
01772 tarhandle=(tar_type=='c');
01773
01774
01775
01776
01777 if (tarhandle == 1) {
01778 dbf = x_stderr;
01779 }
01780 if (!argv[Optind]) {
01781 DEBUG(0,("Must specify tar filename\n"));
01782 return 0;
01783 }
01784 if (!strcmp(argv[Optind], "-")) {
01785 newOptind++;
01786 }
01787
01788 } else {
01789 if (tar_type=='c' && dry_run) {
01790 tarhandle=-1;
01791 } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
01792 || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {
01793 DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno)));
01794 return(0);
01795 }
01796 newOptind++;
01797 }
01798
01799 return newOptind;
01800 }