2 Unix SMB/CIFS implementation.
4 Copyright (C) Ricky Poulten 1995-1998
5 Copyright (C) Richard Sharpe 1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 /* The following changes developed by Richard Sharpe for Canon Information
22 Systems Research Australia (CISRA)
24 1. Restore can now restore files with long file names
25 2. Save now saves directory information so that we can restore
26 directory creation times
27 3. tar now accepts both UNIX path names and DOS path names. I prefer
28 those lovely /'s to those UGLY \'s :-)
29 4. the files to exclude can be specified as a regular expression by adding
30 an r flag to the other tar flags. Eg:
32 -TcrX file.tar "*.(obj|exe)"
34 will skip all .obj and .exe files
40 #include "client/client_proto.h"
42 static int clipfind(char **aret
, int ret
, char *tok
);
44 typedef struct file_info_struct file_info2
;
46 struct file_info_struct
{
51 /* These times are normally kept in GMT */
55 char *name
; /* This is dynamically allocate */
57 file_info2
*next
, *prev
; /* Used in the stack ... */
65 #define SEPARATORS " \t\n\r"
66 extern time_t newer_than
;
67 extern struct cli_state
*cli
;
69 /* These defines are for the do_setrattr routine, to indicate
70 * setting and reseting of file attributes in the function call */
74 static uint16 attribute
= aDIR
| aSYSTEM
| aHIDDEN
;
76 #ifndef CLIENT_TIMEOUT
77 #define CLIENT_TIMEOUT (30*1000)
80 static char *tarbuf
, *buffer_p
;
81 static int tp
, ntarf
, tbufsiz
;
83 /* Incremental mode */
84 static BOOL tar_inc
=False
;
85 /* Reset archive bit */
86 static BOOL tar_reset
=False
;
87 /* Include / exclude mode (true=include, false=exclude) */
88 static BOOL tar_excl
=True
;
89 /* use regular expressions for search on file names */
90 static BOOL tar_re_search
=False
;
91 /* Do not dump anything, just calculate sizes */
92 static BOOL dry_run
=False
;
93 /* Dump files with System attribute */
94 static BOOL tar_system
=True
;
95 /* Dump files with Hidden attribute */
96 static BOOL tar_hidden
=True
;
97 /* Be noisy - make a catalogue */
98 static BOOL tar_noisy
=True
;
99 static BOOL tar_real_noisy
=False
; /* Don't want to be really noisy by default */
102 static char **cliplist
=NULL
;
104 static BOOL must_free_cliplist
= False
;
106 extern file_info def_finfo
;
107 extern BOOL lowercase
;
109 extern BOOL readbraw_supported
;
111 extern pstring cur_dir
;
112 extern int get_total_time_ms
;
113 extern int get_total_size
;
115 static int blocksize
=20;
116 static int tarhandle
;
118 static void writetarheader(int f
, const char *aname
, SMB_BIG_UINT size
, time_t mtime
,
119 const char *amode
, unsigned char ftype
);
120 static void do_atar(char *rname
,char *lname
,file_info
*finfo1
);
121 static void do_tar(file_info
*finfo
);
122 static void oct_it(SMB_BIG_UINT value
, int ndgs
, char *p
);
123 static void fixtarname(char *tptr
, const char *fp
, size_t l
);
124 static int dotarbuf(int f
, char *b
, int n
);
125 static void dozerobuf(int f
, int n
);
126 static void dotareof(int f
);
127 static void initarbuf(void);
129 /* restore functions */
130 static long readtarheader(union hblock
*hb
, file_info2
*finfo
, char *prefix
);
131 static long unoct(char *p
, int ndgs
);
132 static void do_tarput(void);
133 static void unfixtarname(char *tptr
, char *fp
, int l
, BOOL first
);
136 * tar specific utitlities
139 /*******************************************************************
140 Create a string of size size+1 (for the null)
141 *******************************************************************/
143 static char *string_create_s(int size
)
147 tmp
= (char *)SMB_MALLOC(size
+1);
150 DEBUG(0, ("Out of memory in string_create_s\n"));
156 /****************************************************************************
157 Write a tar header to buffer
158 ****************************************************************************/
160 static void writetarheader(int f
, const char *aname
, SMB_BIG_UINT size
, time_t mtime
,
161 const char *amode
, unsigned char ftype
)
167 DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype
, (double)size
, aname
));
169 memset(hb
.dummy
, 0, sizeof(hb
.dummy
));
172 /* We will be prepending a '.' in fixtarheader so use +2 to
173 * take care of the . and terminating zero. JRA.
176 /* write a GNU tar style long header */
178 b
= (char *)SMB_MALLOC(l
+TBLOCK
+100);
180 DEBUG(0,("out of memory\n"));
183 writetarheader(f
, "/./@LongLink", l
+2, 0, " 0 \0", 'L');
184 memset(b
, 0, l
+TBLOCK
+100);
185 fixtarname(b
, aname
, l
+2);
187 DEBUG(5, ("File name in tar file: %s, size=%d, \n", b
, (int)strlen(b
)));
188 dotarbuf(f
, b
, TBLOCK
*(((i
-1)/TBLOCK
)+1));
192 fixtarname(hb
.dbuf
.name
, aname
, (l
+2 >= NAMSIZ
) ? NAMSIZ
: l
+ 2);
195 strlower_m(hb
.dbuf
.name
);
197 /* write out a "standard" tar format header */
199 hb
.dbuf
.name
[NAMSIZ
-1]='\0';
200 safe_strcpy(hb
.dbuf
.mode
, amode
, sizeof(hb
.dbuf
.mode
)-1);
201 oct_it((SMB_BIG_UINT
)0, 8, hb
.dbuf
.uid
);
202 oct_it((SMB_BIG_UINT
)0, 8, hb
.dbuf
.gid
);
203 oct_it((SMB_BIG_UINT
) size
, 13, hb
.dbuf
.size
);
204 if (size
> (SMB_BIG_UINT
)077777777777LL) {
206 /* This is a non-POSIX compatible extention to store files
209 memset(hb
.dbuf
.size
, 0, 4);
211 for (i
= 8, jp
=(char*)&size
; i
; i
--)
212 hb
.dbuf
.size
[i
+3] = *(jp
++);
214 oct_it((SMB_BIG_UINT
) mtime
, 13, hb
.dbuf
.mtime
);
215 memcpy(hb
.dbuf
.chksum
, " ", sizeof(hb
.dbuf
.chksum
));
216 memset(hb
.dbuf
.linkname
, 0, NAMSIZ
);
217 hb
.dbuf
.linkflag
=ftype
;
219 for (chk
=0, i
=sizeof(hb
.dummy
), jp
=hb
.dummy
; --i
>=0;)
222 oct_it((SMB_BIG_UINT
) chk
, 8, hb
.dbuf
.chksum
);
223 hb
.dbuf
.chksum
[6] = '\0';
225 (void) dotarbuf(f
, hb
.dummy
, sizeof(hb
.dummy
));
228 /****************************************************************************
229 Read a tar header into a hblock structure, and validate
230 ***************************************************************************/
232 static long readtarheader(union hblock
*hb
, file_info2
*finfo
, char *prefix
)
239 * read in a "standard" tar format header - we're not that interested
240 * in that many fields, though
243 /* check the checksum */
244 for (chk
=0, i
=sizeof(hb
->dummy
), jp
=hb
->dummy
; --i
>=0;)
250 /* compensate for blanks in chksum header */
251 for (i
=sizeof(hb
->dbuf
.chksum
), jp
=hb
->dbuf
.chksum
; --i
>=0;)
254 chk
+= ' ' * sizeof(hb
->dbuf
.chksum
);
256 fchk
=unoct(hb
->dbuf
.chksum
, sizeof(hb
->dbuf
.chksum
));
258 DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
259 chk
, fchk
, hb
->dbuf
.chksum
));
262 DEBUG(0, ("checksums don't match %ld %ld\n", fchk
, chk
));
263 dump_data(5, (char *)hb
- TBLOCK
, TBLOCK
*3);
267 if ((finfo
->name
= string_create_s(strlen(prefix
) + strlen(hb
-> dbuf
.name
) + 3)) == NULL
) {
268 DEBUG(0, ("Out of space creating file_info2 for %s\n", hb
-> dbuf
.name
));
272 safe_strcpy(finfo
->name
, prefix
, strlen(prefix
) + strlen(hb
-> dbuf
.name
) + 3);
274 /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
275 unfixtarname(finfo
->name
+ strlen(prefix
), hb
->dbuf
.name
,
276 strlen(hb
->dbuf
.name
) + 1, True
);
278 /* can't handle some links at present */
279 if ((hb
->dbuf
.linkflag
!= '0') && (hb
-> dbuf
.linkflag
!= '5')) {
280 if (hb
->dbuf
.linkflag
== 0) {
281 DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
284 if (hb
-> dbuf
.linkflag
== 'L') { /* We have a longlink */
285 /* Do nothing here at the moment. do_tarput will handle this
286 as long as the longlink gets back to it, as it has to advance
287 the buffer pointer, etc */
289 DEBUG(0, ("this tar file appears to contain some kind \
290 of link other than a GNUtar Longlink - ignoring\n"));
296 if ((unoct(hb
->dbuf
.mode
, sizeof(hb
->dbuf
.mode
)) & S_IFDIR
) ||
297 (*(finfo
->name
+strlen(finfo
->name
)-1) == '\\')) {
300 finfo
->mode
=0; /* we don't care about mode at the moment, we'll
301 * just make it a regular file */
305 * Bug fix by richard@sj.co.uk
307 * REC: restore times correctly (as does tar)
308 * We only get the modification time of the file; set the creation time
309 * from the mod. time, and the access time to current time
311 finfo
->mtime
= finfo
->ctime
= strtol(hb
->dbuf
.mtime
, NULL
, 8);
312 finfo
->atime
= time(NULL
);
313 finfo
->size
= unoct(hb
->dbuf
.size
, sizeof(hb
->dbuf
.size
));
318 /****************************************************************************
319 Write out the tar buffer to tape or wherever
320 ****************************************************************************/
322 static int dotarbuf(int f
, char *b
, int n
)
329 /* This routine and the next one should be the only ones that do write()s */
330 if (tp
+ n
>= tbufsiz
) {
334 memcpy(tarbuf
+ tp
, b
, diff
);
335 fail
=fail
&& (1+write(f
, tarbuf
, tbufsiz
));
340 while (n
>= tbufsiz
) {
341 fail
=fail
&& (1 + write(f
, b
, tbufsiz
));
348 memcpy(tarbuf
+tp
, b
, n
);
352 return(fail
? writ
: 0);
355 /****************************************************************************
356 Write zeros to buffer / tape
357 ****************************************************************************/
359 static void dozerobuf(int f
, int n
)
361 /* short routine just to write out n zeros to buffer -
362 * used to round files to nearest block
363 * and to do tar EOFs */
368 if (n
+tp
>= tbufsiz
) {
369 memset(tarbuf
+tp
, 0, tbufsiz
-tp
);
370 write(f
, tarbuf
, tbufsiz
);
371 memset(tarbuf
, 0, (tp
+=n
-tbufsiz
));
373 memset(tarbuf
+tp
, 0, n
);
378 /****************************************************************************
380 ****************************************************************************/
382 static void initarbuf(void)
384 /* initialize tar buffer */
385 tbufsiz
=blocksize
*TBLOCK
;
386 tarbuf
=SMB_MALLOC(tbufsiz
); /* FIXME: We might not get the buffer */
388 /* reset tar buffer pointer and tar file counter and total dumped */
389 tp
=0; ntarf
=0; ttarf
=0;
392 /****************************************************************************
393 Write two zero blocks at end of file
394 ****************************************************************************/
396 static void dotareof(int f
)
398 SMB_STRUCT_STAT stbuf
;
399 /* Two zero blocks at end of file, write out full buffer */
404 (void) dozerobuf(f
, TBLOCK
);
405 (void) dozerobuf(f
, TBLOCK
);
407 if (sys_fstat(f
, &stbuf
) == -1) {
408 DEBUG(0, ("Couldn't stat file handle\n"));
412 /* Could be a pipe, in which case S_ISREG should fail,
413 * and we should write out at full size */
415 write(f
, tarbuf
, S_ISREG(stbuf
.st_mode
) ? tp
: tbufsiz
);
418 /****************************************************************************
419 (Un)mangle DOS pathname, make nonabsolute
420 ****************************************************************************/
422 static void fixtarname(char *tptr
, const char *fp
, size_t l
)
424 /* add a '.' to start of file name, convert from ugly dos \'s in path
425 * to lovely unix /'s :-} */
429 StrnCpy(tptr
, fp
, l
-1);
430 string_replace(tptr
, '\\', '/');
433 /****************************************************************************
434 Convert from decimal to octal string
435 ****************************************************************************/
437 static void oct_it (SMB_BIG_UINT value
, int ndgs
, char *p
)
439 /* Converts long to octal string, pads with leading zeros */
441 /* skip final null, but do final space */
445 /* Loop does at least one digit */
447 p
[--ndgs
] = '0' + (char) (value
& 7);
449 } while (ndgs
> 0 && value
!= 0);
451 /* Do leading zeros */
456 /****************************************************************************
457 Convert from octal string to long
458 ***************************************************************************/
460 static long unoct(char *p
, int ndgs
)
463 /* Converts octal string to long, ignoring any non-digit */
466 if (isdigit((int)*p
))
467 value
= (value
<< 3) | (long) (*p
- '0');
475 /****************************************************************************
476 Compare two strings in a slash insensitive way, allowing s1 to match s2
477 if s1 is an "initial" string (up to directory marker). Thus, if s2 is
478 a file in any subdirectory of s1, declare a match.
479 ***************************************************************************/
481 static int strslashcmp(char *s1
, char *s2
)
485 while(*s1
&& *s2
&& (*s1
== *s2
|| tolower_ascii(*s1
) == tolower_ascii(*s2
) ||
486 (*s1
== '\\' && *s2
=='/') || (*s1
== '/' && *s2
=='\\'))) {
490 /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
493 if (!*s1
&& s1
!= s1_0
&& (*(s1
-1) == '/' || *(s1
-1) == '\\'))
496 /* ignore trailing slash on s1 */
497 if (!*s2
&& (*s1
== '/' || *s1
== '\\') && !*(s1
+1))
500 /* check for s1 is an "initial" string of s2 */
501 if ((*s2
== '/' || *s2
== '\\') && !*s1
)
507 /****************************************************************************
508 Ensure a remote path exists (make if necessary)
509 ***************************************************************************/
511 static BOOL
ensurepath(char *fname
)
513 /* *must* be called with buffer ready malloc'ed */
514 /* ensures path exists */
516 char *partpath
, *ffname
;
517 char *p
=fname
, *basehack
;
519 DEBUG(5, ( "Ensurepath called with: %s\n", fname
));
521 partpath
= string_create_s(strlen(fname
));
522 ffname
= string_create_s(strlen(fname
));
524 if ((partpath
== NULL
) || (ffname
== NULL
)){
525 DEBUG(0, ("Out of memory in ensurepath: %s\n", fname
));
531 /* fname copied to ffname so can strtok */
533 safe_strcpy(ffname
, fname
, strlen(fname
));
535 /* do a `basename' on ffname, so don't try and make file name directory */
536 if ((basehack
=strrchr_m(ffname
, '\\')) == NULL
)
541 p
=strtok(ffname
, "\\");
544 safe_strcat(partpath
, p
, strlen(fname
) + 1);
546 if (!cli_chkpath(cli
, partpath
)) {
547 if (!cli_mkdir(cli
, partpath
)) {
548 DEBUG(0, ("Error mkdirhiering\n"));
551 DEBUG(3, ("mkdirhiering %s\n", partpath
));
555 safe_strcat(partpath
, "\\", strlen(fname
) + 1);
556 p
= strtok(NULL
,"/\\");
562 static int padit(char *buf
, int bufsize
, int padsize
)
567 DEBUG(5, ("Padding with %d zeros\n", padsize
));
568 memset(buf
, 0, bufsize
);
569 while( !berr
&& padsize
> 0 ) {
570 bytestowrite
= MIN(bufsize
, padsize
);
571 berr
= dotarbuf(tarhandle
, buf
, bytestowrite
) != bytestowrite
;
572 padsize
-= bytestowrite
;
578 static void do_setrattr(char *name
, uint16 attr
, int set
)
582 if (!cli_getatr(cli
, name
, &oldattr
, NULL
, NULL
)) return;
584 if (set
== ATTRSET
) {
587 attr
= oldattr
& ~attr
;
590 if (!cli_setatr(cli
, name
, attr
, 0)) {
591 DEBUG(1,("setatr failed: %s\n", cli_errstr(cli
)));
595 /****************************************************************************
596 append one remote file to the tar file
597 ***************************************************************************/
599 static void do_atar(char *rname
,char *lname
,file_info
*finfo1
)
602 SMB_BIG_UINT nread
=0;
605 BOOL close_done
= False
;
606 BOOL shallitime
=True
;
608 int read_size
= 65520;
611 struct timeval tp_start
;
613 GetTimeOfDay(&tp_start
);
615 ftype
= '0'; /* An ordinary file ... */
618 finfo
.size
= finfo1
-> size
;
619 finfo
.mode
= finfo1
-> mode
;
620 finfo
.uid
= finfo1
-> uid
;
621 finfo
.gid
= finfo1
-> gid
;
622 finfo
.mtime
= finfo1
-> mtime
;
623 finfo
.atime
= finfo1
-> atime
;
624 finfo
.ctime
= finfo1
-> ctime
;
625 finfo
.name
= finfo1
-> name
;
627 finfo
.size
= def_finfo
.size
;
628 finfo
.mode
= def_finfo
.mode
;
629 finfo
.uid
= def_finfo
.uid
;
630 finfo
.gid
= def_finfo
.gid
;
631 finfo
.mtime
= def_finfo
.mtime
;
632 finfo
.atime
= def_finfo
.atime
;
633 finfo
.ctime
= def_finfo
.ctime
;
634 finfo
.name
= def_finfo
.name
;
638 DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo
.name
,
639 (double)finfo
.size
));
641 ttarf
+=finfo
.size
+ TBLOCK
- (finfo
.size
% TBLOCK
);
646 fnum
= cli_open(cli
, rname
, O_RDONLY
, DENY_NONE
);
648 dos_clean_name(rname
);
651 DEBUG(0,("%s opening remote file %s (%s)\n",
652 cli_errstr(cli
),rname
, cur_dir
));
656 finfo
.name
= string_create_s(strlen(rname
));
657 if (finfo
.name
== NULL
) {
658 DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
662 safe_strcpy(finfo
.name
,rname
, strlen(rname
));
664 if (!cli_getattrE(cli
, fnum
, &finfo
.mode
, &finfo
.size
, NULL
, &finfo
.atime
, &finfo
.mtime
)) {
665 DEBUG(0, ("getattrE: %s\n", cli_errstr(cli
)));
668 finfo
.ctime
= finfo
.mtime
;
671 DEBUG(3,("file %s attrib 0x%X\n",finfo
.name
,finfo
.mode
));
673 if (tar_inc
&& !(finfo
.mode
& aARCH
)) {
674 DEBUG(4, ("skipping %s - archive bit not set\n", finfo
.name
));
676 } else if (!tar_system
&& (finfo
.mode
& aSYSTEM
)) {
677 DEBUG(4, ("skipping %s - system bit is set\n", finfo
.name
));
679 } else if (!tar_hidden
&& (finfo
.mode
& aHIDDEN
)) {
680 DEBUG(4, ("skipping %s - hidden bit is set\n", finfo
.name
));
683 DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
684 finfo
.name
, (double)finfo
.size
, lname
));
686 /* write a tar header, don't bother with mode - just set to 100644 */
687 writetarheader(tarhandle
, rname
, finfo
.size
, finfo
.mtime
, "100644 \0", ftype
);
689 while (nread
< finfo
.size
&& !close_done
) {
691 DEBUG(3,("nread=%.0f\n",(double)nread
));
693 datalen
= cli_read(cli
, fnum
, data
, nread
, read_size
);
696 DEBUG(0,("Error reading file %s : %s\n", rname
, cli_errstr(cli
)));
702 /* if file size has increased since we made file size query, truncate
703 read so tar header for this file will be correct.
706 if (nread
> finfo
.size
) {
707 datalen
-= nread
- finfo
.size
;
708 DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
709 finfo
.name
, (double)finfo
.size
));
712 /* add received bits of file to buffer - dotarbuf will
713 * write out in 512 byte intervals */
715 if (dotarbuf(tarhandle
,data
,datalen
) != datalen
) {
716 DEBUG(0,("Error writing to tar file - %s\n", strerror(errno
)));
721 DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname
));
728 /* pad tar file with zero's if we couldn't get entire file */
729 if (nread
< finfo
.size
) {
730 DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
731 (double)finfo
.size
, (int)nread
));
732 if (padit(data
, sizeof(data
), finfo
.size
- nread
))
733 DEBUG(0,("Error writing tar file - %s\n", strerror(errno
)));
736 /* round tar file to nearest block */
737 if (finfo
.size
% TBLOCK
)
738 dozerobuf(tarhandle
, TBLOCK
- (finfo
.size
% TBLOCK
));
740 ttarf
+=finfo
.size
+ TBLOCK
- (finfo
.size
% TBLOCK
);
744 cli_close(cli
, fnum
);
747 struct timeval tp_end
;
750 /* if shallitime is true then we didn't skip */
751 if (tar_reset
&& !dry_run
)
752 (void) do_setrattr(finfo
.name
, aARCH
, ATTRRESET
);
754 GetTimeOfDay(&tp_end
);
755 this_time
= (tp_end
.tv_sec
- tp_start
.tv_sec
)*1000 + (tp_end
.tv_usec
- tp_start
.tv_usec
)/1000;
756 get_total_time_ms
+= this_time
;
757 get_total_size
+= finfo
.size
;
760 DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
761 (double)finfo
.size
, finfo
.size
/ MAX(0.001, (1.024*this_time
)),
765 /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
766 DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
767 finfo
.size
/ MAX(0.001, (1.024*this_time
)),
768 get_total_size
/ MAX(0.001, (1.024*get_total_time_ms
))));
772 /****************************************************************************
773 Append single file to tar file (or not)
774 ***************************************************************************/
776 static void do_tar(file_info
*finfo
)
780 if (strequal(finfo
->name
,"..") || strequal(finfo
->name
,"."))
783 /* Is it on the exclude list ? */
784 if (!tar_excl
&& clipn
) {
787 DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir
)));
789 pstrcpy(exclaim
, cur_dir
);
790 *(exclaim
+strlen(exclaim
)-1)='\0';
792 pstrcat(exclaim
, "\\");
793 pstrcat(exclaim
, finfo
->name
);
795 DEBUG(5, ("...tar_re_search: %d\n", tar_re_search
));
797 if ((!tar_re_search
&& clipfind(cliplist
, clipn
, exclaim
)) ||
798 (tar_re_search
&& mask_match_list(exclaim
, cliplist
, clipn
, True
))) {
799 DEBUG(3,("Skipping file %s\n", exclaim
));
804 if (finfo
->mode
& aDIR
) {
805 pstring saved_curdir
;
808 pstrcpy(saved_curdir
, cur_dir
);
810 DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \
811 strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
812 (int)sizeof(cur_dir
), (int)strlen(cur_dir
),
813 (int)strlen(finfo
->name
), finfo
->name
, cur_dir
));
815 pstrcat(cur_dir
,finfo
->name
);
816 pstrcat(cur_dir
,"\\");
818 DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir
));
820 /* write a tar directory, don't bother with mode - just set it to
822 writetarheader(tarhandle
, cur_dir
, 0, finfo
->mtime
, "040755 \0", '5');
824 DEBUG(0,(" directory %s\n", cur_dir
));
826 ntarf
++; /* Make sure we have a file on there */
827 pstrcpy(mtar_mask
,cur_dir
);
828 pstrcat(mtar_mask
,"*");
829 DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask
));
830 do_list(mtar_mask
, attribute
, do_tar
, False
, True
);
831 pstrcpy(cur_dir
,saved_curdir
);
833 pstrcpy(rname
,cur_dir
);
834 pstrcat(rname
,finfo
->name
);
835 do_atar(rname
,finfo
->name
,finfo
);
839 /****************************************************************************
840 Convert from UNIX to DOS file names
841 ***************************************************************************/
843 static void unfixtarname(char *tptr
, char *fp
, int l
, BOOL first
)
845 /* remove '.' from start of file name, convert from unix /'s to
846 * dos \'s in path. Kill any absolute path names. But only if first!
849 DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr
, (long)fp
, l
));
856 if (*fp
== '\\' || *fp
== '/') {
862 safe_strcpy(tptr
, fp
, l
);
863 string_replace(tptr
, '/', '\\');
866 /****************************************************************************
867 Move to the next block in the buffer, which may mean read in another set of
868 blocks. FIXME, we should allow more than one block to be skipped.
869 ****************************************************************************/
871 static int next_block(char *ltarbuf
, char **bufferp
, int bufsiz
)
873 int bufread
, total
= 0;
875 DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp
));
879 if (*bufferp
>= (ltarbuf
+ bufsiz
)) {
881 DEBUG(5, ("Reading more data into ltarbuf ...\n"));
884 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
885 * Fixes bug where read can return short if coming from
889 bufread
= read(tarhandle
, ltarbuf
, bufsiz
);
892 while (total
< bufsiz
) {
893 if (bufread
< 0) { /* An error, return false */
894 return (total
> 0 ? -2 : bufread
);
902 bufread
= read(tarhandle
, <arbuf
[total
], bufsiz
- total
);
906 DEBUG(5, ("Total bytes read ... %i\n", total
));
914 /* Skip a file, even if it includes a long file name? */
915 static int skip_file(int skipsize
)
917 int dsize
= skipsize
;
919 DEBUG(5, ("Skiping file. Size = %i\n", skipsize
));
921 /* FIXME, we should skip more than one block at a time */
924 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
925 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
934 /*************************************************************
935 Get a file from the tar file and store it.
936 When this is called, tarbuf already contains the first
937 file block. This is a bit broken & needs fixing.
938 **************************************************************/
940 static int get_file(file_info2 finfo
)
942 int fnum
= -1, pos
= 0, dsize
= 0, bpos
= 0;
943 SMB_BIG_UINT rsize
= 0;
945 DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo
.name
, (double)finfo
.size
));
947 if (ensurepath(finfo
.name
) &&
948 (fnum
=cli_open(cli
, finfo
.name
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
)) == -1) {
949 DEBUG(0, ("abandoning restore\n"));
953 /* read the blocks from the tar file and write to the remote file */
955 rsize
= finfo
.size
; /* This is how much to write */
959 /* We can only write up to the end of the buffer */
960 dsize
= MIN(tbufsiz
- (buffer_p
- tarbuf
) - bpos
, 65520); /* Calculate the size to write */
961 dsize
= MIN(dsize
, rsize
); /* Should be only what is left */
962 DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize
, bpos
));
964 if (cli_write(cli
, fnum
, 0, buffer_p
+ bpos
, pos
, dsize
) != dsize
) {
965 DEBUG(0, ("Error writing remote file\n"));
972 /* Now figure out how much to move in the buffer */
974 /* FIXME, we should skip more than one block at a time */
976 /* First, skip any initial part of the part written that is left over */
977 /* from the end of the first TBLOCK */
979 if ((bpos
) && ((bpos
+ dsize
) >= TBLOCK
)) {
980 dsize
-= (TBLOCK
- bpos
); /* Get rid of the end of the first block */
983 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) { /* and skip the block */
984 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
990 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
991 * If the file being extracted is an exact multiple of
992 * TBLOCK bytes then we don't want to extract the next
993 * block from the tarfile here, as it will be done in
994 * the caller of get_file().
997 while (((rsize
!= 0) && (dsize
>= TBLOCK
)) ||
998 ((rsize
== 0) && (dsize
> TBLOCK
))) {
1000 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) {
1001 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1010 /* Now close the file ... */
1012 if (!cli_close(cli
, fnum
)) {
1013 DEBUG(0, ("Error closing remote file\n"));
1017 /* Now we update the creation date ... */
1018 DEBUG(5, ("Updating creation date on %s\n", finfo
.name
));
1020 if (!cli_setatr(cli
, finfo
.name
, finfo
.mode
, finfo
.mtime
)) {
1021 if (tar_real_noisy
) {
1022 DEBUG(0, ("Could not set time on file: %s\n", finfo
.name
));
1023 /*return(False); */ /* Ignore, as Win95 does not allow changes */
1028 DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo
.name
, (double)finfo
.size
));
1032 /* Create a directory. We just ensure that the path exists and return as there
1033 is no file associated with a directory
1035 static int get_dir(file_info2 finfo
)
1037 DEBUG(0, ("restore directory %s\n", finfo
.name
));
1039 if (!ensurepath(finfo
.name
)) {
1040 DEBUG(0, ("Problems creating directory\n"));
1047 /* Get a file with a long file name ... first file has file name, next file
1048 has the data. We only want the long file name, as the loop in do_tarput
1049 will deal with the rest.
1051 static char *get_longfilename(file_info2 finfo
)
1053 /* finfo.size here is the length of the filename as written by the "/./@LongLink" name
1055 int namesize
= finfo
.size
+ strlen(cur_dir
) + 2;
1056 char *longname
= SMB_MALLOC(namesize
);
1057 int offset
= 0, left
= finfo
.size
;
1060 DEBUG(5, ("Restoring a long file name: %s\n", finfo
.name
));
1061 DEBUG(5, ("Len = %.0f\n", (double)finfo
.size
));
1063 if (longname
== NULL
) {
1064 DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize
));
1068 /* First, add cur_dir to the long file name */
1070 if (strlen(cur_dir
) > 0) {
1071 strncpy(longname
, cur_dir
, namesize
);
1072 offset
= strlen(cur_dir
);
1075 /* Loop through the blocks picking up the name */
1078 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
1079 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1083 unfixtarname(longname
+ offset
, buffer_p
, MIN(TBLOCK
, finfo
.size
), first
--);
1084 DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname
, buffer_p
));
1093 static void do_tarput(void)
1096 struct timeval tp_start
;
1097 char *longfilename
= NULL
, linkflag
;
1102 GetTimeOfDay(&tp_start
);
1103 DEBUG(5, ("RJS do_tarput called ...\n"));
1105 buffer_p
= tarbuf
+ tbufsiz
; /* init this to force first read */
1107 /* Now read through those files ... */
1109 /* Get us to the next block, or the first block first time around */
1110 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
1111 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1115 DEBUG(5, ("Reading the next header ...\n"));
1117 switch (readtarheader((union hblock
*) buffer_p
, &finfo
, cur_dir
)) {
1118 case -2: /* Hmm, not good, but not fatal */
1119 DEBUG(0, ("Skipping %s...\n", finfo
.name
));
1120 if ((next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) && !skip_file(finfo
.size
)) {
1121 DEBUG(0, ("Short file, bailing out...\n"));
1127 DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
1130 case 0: /* chksum is zero - looks like an EOF */
1131 DEBUG(0, ("tar: restored %d files and directories\n", ntarf
));
1132 return; /* Hmmm, bad here ... */
1139 /* Now, do we have a long file name? */
1140 if (longfilename
!= NULL
) {
1141 SAFE_FREE(finfo
.name
); /* Free the space already allocated */
1142 finfo
.name
= longfilename
;
1143 longfilename
= NULL
;
1146 /* Well, now we have a header, process the file ... */
1147 /* Should we skip the file? We have the long name as well here */
1148 skip
= clipn
&& ((!tar_re_search
&& clipfind(cliplist
, clipn
, finfo
.name
) ^ tar_excl
) ||
1149 (tar_re_search
&& mask_match_list(finfo
.name
, cliplist
, clipn
, True
)));
1151 DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip
, (cliplist
?cliplist
[0]:NULL
), finfo
.name
));
1153 skip_file(finfo
.size
);
1157 /* We only get this far if we should process the file */
1158 linkflag
= ((union hblock
*)buffer_p
) -> dbuf
.linkflag
;
1160 case '0': /* Should use symbolic names--FIXME */
1162 * Skip to the next block first, so we can get the file, FIXME, should
1163 * be in get_file ...
1164 * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
1165 * Fixes bug where file size in tarfile is zero.
1167 if ((finfo
.size
!= 0) && next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) {
1168 DEBUG(0, ("Short file, bailing out...\n"));
1171 if (!get_file(finfo
)) {
1172 DEBUG(0, ("Abandoning restore\n"));
1177 if (!get_dir(finfo
)) {
1178 DEBUG(0, ("Abandoning restore \n"));
1183 longfilename
= get_longfilename(finfo
);
1184 if (!longfilename
) {
1185 DEBUG(0, ("abandoning restore\n"));
1188 DEBUG(5, ("Long file name: %s\n", longfilename
));
1192 skip_file(finfo
.size
); /* Don't handle these yet */
1199 * samba interactive commands
1202 /****************************************************************************
1204 ***************************************************************************/
1211 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1212 DEBUG(0, ("blocksize <n>\n"));
1217 if (block
< 0 || block
> 65535) {
1218 DEBUG(0, ("blocksize out of range"));
1223 DEBUG(2,("blocksize is now %d\n", blocksize
));
1228 /****************************************************************************
1229 command to set incremental / reset mode
1230 ***************************************************************************/
1232 int cmd_tarmode(void)
1236 while (next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1237 if (strequal(buf
, "full"))
1239 else if (strequal(buf
, "inc"))
1241 else if (strequal(buf
, "reset"))
1243 else if (strequal(buf
, "noreset"))
1245 else if (strequal(buf
, "system"))
1247 else if (strequal(buf
, "nosystem"))
1249 else if (strequal(buf
, "hidden"))
1251 else if (strequal(buf
, "nohidden"))
1253 else if (strequal(buf
, "verbose") || strequal(buf
, "noquiet"))
1255 else if (strequal(buf
, "quiet") || strequal(buf
, "noverbose"))
1258 DEBUG(0, ("tarmode: unrecognised option %s\n", buf
));
1261 DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
1262 tar_inc
? "incremental" : "full",
1263 tar_system
? "system" : "nosystem",
1264 tar_hidden
? "hidden" : "nohidden",
1265 tar_reset
? "reset" : "noreset",
1266 tar_noisy
? "verbose" : "quiet"));
1270 /****************************************************************************
1271 Feeble attrib command
1272 ***************************************************************************/
1274 int cmd_setmode(void)
1282 attra
[0] = attra
[1] = 0;
1284 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1285 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1289 pstrcpy(fname
, cur_dir
);
1290 pstrcat(fname
, buf
);
1292 while (next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1304 attra
[direct
]|=aRONLY
;
1307 attra
[direct
]|=aHIDDEN
;
1310 attra
[direct
]|=aSYSTEM
;
1313 attra
[direct
]|=aARCH
;
1316 DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
1322 if (attra
[ATTRSET
]==0 && attra
[ATTRRESET
]==0) {
1323 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1327 DEBUG(2, ("\nperm set %d %d\n", attra
[ATTRSET
], attra
[ATTRRESET
]));
1328 do_setrattr(fname
, attra
[ATTRSET
], ATTRSET
);
1329 do_setrattr(fname
, attra
[ATTRRESET
], ATTRRESET
);
1333 /****************************************************************************
1334 Principal command for creating / extracting
1335 ***************************************************************************/
1344 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1345 DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
1349 argl
=toktocliplist(&argcl
, NULL
);
1350 if (!tar_parseargs(argcl
, argl
, buf
, 0))
1353 ret
= process_tar();
1358 /****************************************************************************
1359 Command line (option) version
1360 ***************************************************************************/
1362 int process_tar(void)
1379 if (clipn
&& tar_excl
) {
1383 for (i
=0; i
<clipn
; i
++) {
1384 DEBUG(5,("arg %d = %s\n", i
, cliplist
[i
]));
1386 if (*(cliplist
[i
]+strlen(cliplist
[i
])-1)=='\\') {
1387 *(cliplist
[i
]+strlen(cliplist
[i
])-1)='\0';
1390 if (strrchr_m(cliplist
[i
], '\\')) {
1393 pstrcpy(saved_dir
, cur_dir
);
1395 if (*cliplist
[i
]=='\\') {
1396 pstrcpy(tarmac
, cliplist
[i
]);
1398 pstrcpy(tarmac
, cur_dir
);
1399 pstrcat(tarmac
, cliplist
[i
]);
1401 pstrcpy(cur_dir
, tarmac
);
1402 *(strrchr_m(cur_dir
, '\\')+1)='\0';
1404 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac
));
1405 do_list(tarmac
,attribute
,do_tar
, False
, True
);
1406 pstrcpy(cur_dir
,saved_dir
);
1408 pstrcpy(tarmac
, cur_dir
);
1409 pstrcat(tarmac
, cliplist
[i
]);
1410 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac
));
1411 do_list(tarmac
,attribute
,do_tar
, False
, True
);
1416 pstrcpy(mask
,cur_dir
);
1417 DEBUG(5, ("process_tar, do_list with mask: %s\n", mask
));
1418 pstrcat(mask
,"\\*");
1419 do_list(mask
,attribute
,do_tar
,False
, True
);
1423 dotareof(tarhandle
);
1427 DEBUG(0, ("tar: dumped %d files and directories\n", ntarf
));
1428 DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf
));
1432 if (must_free_cliplist
) {
1434 for (i
= 0; i
< clipn
; ++i
) {
1435 SAFE_FREE(cliplist
[i
]);
1437 SAFE_FREE(cliplist
);
1440 must_free_cliplist
= False
;
1445 /****************************************************************************
1446 Find a token (filename) in a clip list
1447 ***************************************************************************/
1449 static int clipfind(char **aret
, int ret
, char *tok
)
1454 /* ignore leading slashes or dots in token */
1455 while(strchr_m("/\\.", *tok
))
1461 /* ignore leading slashes or dots in list */
1462 while(strchr_m("/\\.", *pkey
))
1465 if (!strslashcmp(pkey
, tok
))
1471 /****************************************************************************
1472 Read list of files to include from the file and initialize cliplist
1474 ***************************************************************************/
1476 static int read_inclusion_file(char *filename
)
1478 XFILE
*inclusion
= NULL
;
1479 char buf
[PATH_MAX
+ 1];
1480 char *inclusion_buffer
= NULL
;
1481 int inclusion_buffer_size
= 0;
1482 int inclusion_buffer_sofar
= 0;
1489 buf
[PATH_MAX
] = '\0'; /* guarantee null-termination */
1490 if ((inclusion
= x_fopen(filename
, O_RDONLY
, 0)) == NULL
) {
1491 /* XXX It would be better to include a reason for failure, but without
1492 * autoconf, it's hard to use strerror, sys_errlist, etc.
1494 DEBUG(0,("Unable to open inclusion file %s\n", filename
));
1498 while ((! error
) && (x_fgets(buf
, sizeof(buf
)-1, inclusion
))) {
1499 if (inclusion_buffer
== NULL
) {
1500 inclusion_buffer_size
= 1024;
1501 if ((inclusion_buffer
= SMB_MALLOC(inclusion_buffer_size
)) == NULL
) {
1502 DEBUG(0,("failure allocating buffer to read inclusion file\n"));
1508 if (buf
[strlen(buf
)-1] == '\n') {
1509 buf
[strlen(buf
)-1] = '\0';
1512 if ((strlen(buf
) + 1 + inclusion_buffer_sofar
) >= inclusion_buffer_size
) {
1514 inclusion_buffer_size
*= 2;
1515 ib
= SMB_REALLOC(inclusion_buffer
,inclusion_buffer_size
);
1517 DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
1518 inclusion_buffer_size
));
1522 inclusion_buffer
= ib
;
1526 safe_strcpy(inclusion_buffer
+ inclusion_buffer_sofar
, buf
, inclusion_buffer_size
- inclusion_buffer_sofar
);
1527 inclusion_buffer_sofar
+= strlen(buf
) + 1;
1530 x_fclose(inclusion
);
1533 /* Allocate an array of clipn + 1 char*'s for cliplist */
1534 cliplist
= SMB_MALLOC_ARRAY(char *, clipn
+ 1);
1535 if (cliplist
== NULL
) {
1536 DEBUG(0,("failure allocating memory for cliplist\n"));
1539 cliplist
[clipn
] = NULL
;
1540 p
= inclusion_buffer
;
1541 for (i
= 0; (! error
) && (i
< clipn
); i
++) {
1542 /* set current item to NULL so array will be null-terminated even if
1543 * malloc fails below. */
1545 if ((tmpstr
= (char *)SMB_MALLOC(strlen(p
)+1)) == NULL
) {
1546 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i
));
1549 unfixtarname(tmpstr
, p
, strlen(p
) + 1, True
);
1550 cliplist
[i
] = tmpstr
;
1551 if ((p
= strchr_m(p
, '\000')) == NULL
) {
1552 DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
1558 must_free_cliplist
= True
;
1562 SAFE_FREE(inclusion_buffer
);
1566 /* We know cliplist is always null-terminated */
1567 for (pp
= cliplist
; *pp
; ++pp
) {
1570 SAFE_FREE(cliplist
);
1572 must_free_cliplist
= False
;
1577 /* cliplist and its elements are freed at the end of process_tar. */
1581 /****************************************************************************
1582 Parse tar arguments. Sets tar_type, tar_excl, etc.
1583 ***************************************************************************/
1585 int tar_parseargs(int argc
, char *argv
[], const char *Optarg
, int Optind
)
1587 int newOptind
= Optind
;
1588 char tar_clipfl
='\0';
1590 /* Reset back to defaults - could be from interactive version
1591 * reset mode and archive mode left as they are though
1603 if (tar_type
=='c') {
1604 printf("Tar must be followed by only one of c or x.\n");
1610 if (Optind
>=argc
|| !(blocksize
=atoi(argv
[Optind
]))) {
1611 DEBUG(0,("Option b must be followed by valid blocksize\n"));
1623 DEBUG(0,("Option N must be followed by valid file name\n"));
1626 SMB_STRUCT_STAT stbuf
;
1628 if (sys_stat(argv
[Optind
], &stbuf
) == 0) {
1629 newer_than
= stbuf
.st_mtime
;
1630 DEBUG(1,("Getting files newer than %s",
1631 asctime(localtime(&newer_than
))));
1635 DEBUG(0,("Error setting newer-than time\n"));
1648 DEBUG(0,("Only one of I,X,F must be specified\n"));
1655 DEBUG(0,("Only one of I,X,F must be specified\n"));
1662 DEBUG(0,("Only one of I,X,F must be specified\n"));
1668 DEBUG(0, ("tar_re_search set\n"));
1669 tar_re_search
= True
;
1672 if (tar_type
== 'c') {
1673 DEBUG(0, ("dry_run set\n"));
1676 DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
1681 DEBUG(0,("Unknown tar option\n"));
1687 printf("Option T must be followed by one of c or x.\n");
1691 /* tar_excl is true if cliplist lists files to be included.
1692 * Both 'I' and 'F' mean include. */
1693 tar_excl
=tar_clipfl
!='X';
1695 if (tar_clipfl
=='F') {
1696 if (argc
-Optind
-1 != 1) {
1697 DEBUG(0,("Option F must be followed by exactly one filename.\n"));
1701 /* Optind points at the tar output file, Optind+1 at the inclusion file. */
1702 if (! read_inclusion_file(argv
[Optind
+1])) {
1705 } else if (Optind
+1<argc
&& !tar_re_search
) { /* For backwards compatibility */
1710 cliplist
=argv
+Optind
+1;
1711 clipn
=argc
-Optind
-1;
1714 if ((tmplist
=SMB_MALLOC_ARRAY(char *,clipn
)) == NULL
) {
1715 DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn
));
1719 for (clipcount
= 0; clipcount
< clipn
; clipcount
++) {
1721 DEBUG(5, ("Processing an item, %s\n", cliplist
[clipcount
]));
1723 if ((tmpstr
= (char *)SMB_MALLOC(strlen(cliplist
[clipcount
])+1)) == NULL
) {
1724 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount
));
1728 unfixtarname(tmpstr
, cliplist
[clipcount
], strlen(cliplist
[clipcount
]) + 1, True
);
1729 tmplist
[clipcount
] = tmpstr
;
1730 DEBUG(5, ("Processed an item, %s\n", tmpstr
));
1732 DEBUG(5, ("Cliplist is: %s\n", cliplist
[0]));
1736 must_free_cliplist
= True
;
1741 if (Optind
+1<argc
&& tar_re_search
&& tar_clipfl
!= 'F') {
1742 /* Doing regular expression seaches not from an inclusion file. */
1743 clipn
=argc
-Optind
-1;
1744 cliplist
=argv
+Optind
+1;
1748 if (Optind
>=argc
|| !strcmp(argv
[Optind
], "-")) {
1749 /* Sets tar handle to either 0 or 1, as appropriate */
1750 tarhandle
=(tar_type
=='c');
1752 * Make sure that dbf points to stderr if we are using stdout for
1755 if (tarhandle
== 1) {
1758 if (!argv
[Optind
]) {
1759 DEBUG(0,("Must specify tar filename\n"));
1762 if (!strcmp(argv
[Optind
], "-")) {
1767 if (tar_type
=='c' && dry_run
) {
1769 } else if ((tar_type
=='x' && (tarhandle
= sys_open(argv
[Optind
], O_RDONLY
, 0)) == -1)
1770 || (tar_type
=='c' && (tarhandle
=sys_creat(argv
[Optind
], 0644)) < 0)) {
1771 DEBUG(0,("Error opening local file %s - %s\n", argv
[Optind
], strerror(errno
)));