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
52 /* These times are normally kept in GMT */
56 char *name
; /* This is dynamically allocate */
58 file_info2
*next
, *prev
; /* Used in the stack ... */
69 #define SEPARATORS " \t\n\r"
70 extern struct cli_state
*cli
;
72 /* These defines are for the do_setrattr routine, to indicate
73 * setting and reseting of file attributes in the function call */
77 static uint16 attribute
= aDIR
| aSYSTEM
| aHIDDEN
;
79 #ifndef CLIENT_TIMEOUT
80 #define CLIENT_TIMEOUT (30*1000)
83 static char *tarbuf
, *buffer_p
;
84 static int tp
, ntarf
, tbufsiz
;
86 /* Incremental mode */
87 static BOOL tar_inc
=False
;
88 /* Reset archive bit */
89 static BOOL tar_reset
=False
;
90 /* Include / exclude mode (true=include, false=exclude) */
91 static BOOL tar_excl
=True
;
92 /* use regular expressions for search on file names */
93 static BOOL tar_re_search
=False
;
97 /* Do not dump anything, just calculate sizes */
98 static BOOL dry_run
=False
;
99 /* Dump files with System attribute */
100 static BOOL tar_system
=True
;
101 /* Dump files with Hidden attribute */
102 static BOOL tar_hidden
=True
;
103 /* Be noisy - make a catalogue */
104 static BOOL tar_noisy
=True
;
105 static BOOL tar_real_noisy
=False
; /* Don't want to be really noisy by default */
108 static char **cliplist
=NULL
;
110 static BOOL must_free_cliplist
= False
;
112 extern file_info def_finfo
;
113 extern BOOL lowercase
;
115 extern BOOL readbraw_supported
;
117 extern pstring cur_dir
;
118 extern int get_total_time_ms
;
119 extern int get_total_size
;
121 static int blocksize
=20;
122 static int tarhandle
;
124 static void writetarheader(int f
, const char *aname
, SMB_BIG_UINT size
, time_t mtime
,
125 const char *amode
, unsigned char ftype
);
126 static void do_atar(char *rname
,char *lname
,file_info
*finfo1
);
127 static void do_tar(file_info
*finfo
);
128 static void oct_it(SMB_BIG_UINT value
, int ndgs
, char *p
);
129 static void fixtarname(char *tptr
, const char *fp
, int l
);
130 static int dotarbuf(int f
, char *b
, int n
);
131 static void dozerobuf(int f
, int n
);
132 static void dotareof(int f
);
133 static void initarbuf(void);
135 /* restore functions */
136 static long readtarheader(union hblock
*hb
, file_info2
*finfo
, char *prefix
);
137 static long unoct(char *p
, int ndgs
);
138 static void do_tarput(void);
139 static void unfixtarname(char *tptr
, char *fp
, int l
, BOOL first
);
142 * tar specific utitlities
145 /*******************************************************************
146 Create a string of size size+1 (for the null)
147 *******************************************************************/
148 static char *string_create_s(int size
)
152 tmp
= (char *)malloc(size
+1);
156 DEBUG(0, ("Out of memory in string_create_s\n"));
164 /****************************************************************************
165 Write a tar header to buffer
166 ****************************************************************************/
167 static void writetarheader(int f
, const char *aname
, SMB_BIG_UINT size
, time_t mtime
,
168 const char *amode
, unsigned char ftype
)
174 DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype
, (double)size
, aname
));
176 memset(hb
.dummy
, 0, sizeof(hb
.dummy
));
179 if (l
>= NAMSIZ
- 1) {
180 /* write a GNU tar style long header */
182 b
= (char *)malloc(l
+TBLOCK
+100);
184 DEBUG(0,("out of memory\n"));
187 writetarheader(f
, "/./@LongLink", l
+2, 0, " 0 \0", 'L');
188 memset(b
, 0, l
+TBLOCK
+100);
189 fixtarname(b
, aname
, l
);
191 DEBUG(5, ("File name in tar file: %s, size=%d, \n", b
, (int)strlen(b
)));
192 dotarbuf(f
, b
, TBLOCK
*(((i
-1)/TBLOCK
)+1));
196 /* use l + 1 to do the null too */
197 fixtarname(hb
.dbuf
.name
, aname
, (l
>= NAMSIZ
) ? NAMSIZ
: l
+ 1);
200 strlower(hb
.dbuf
.name
);
202 /* write out a "standard" tar format header */
204 hb
.dbuf
.name
[NAMSIZ
-1]='\0';
205 safe_strcpy(hb
.dbuf
.mode
, amode
, strlen(amode
));
206 oct_it((SMB_BIG_UINT
)0, 8, hb
.dbuf
.uid
);
207 oct_it((SMB_BIG_UINT
)0, 8, hb
.dbuf
.gid
);
208 oct_it((SMB_BIG_UINT
) size
, 13, hb
.dbuf
.size
);
209 oct_it((SMB_BIG_UINT
) mtime
, 13, hb
.dbuf
.mtime
);
210 memcpy(hb
.dbuf
.chksum
, " ", sizeof(hb
.dbuf
.chksum
));
211 memset(hb
.dbuf
.linkname
, 0, NAMSIZ
);
212 hb
.dbuf
.linkflag
=ftype
;
214 for (chk
=0, i
=sizeof(hb
.dummy
), jp
=hb
.dummy
; --i
>=0;) chk
+=(0xFF & *jp
++);
216 oct_it((SMB_BIG_UINT
) chk
, 8, hb
.dbuf
.chksum
);
217 hb
.dbuf
.chksum
[6] = '\0';
219 (void) dotarbuf(f
, hb
.dummy
, sizeof(hb
.dummy
));
222 /****************************************************************************
223 Read a tar header into a hblock structure, and validate
224 ***************************************************************************/
225 static long readtarheader(union hblock
*hb
, file_info2
*finfo
, char *prefix
)
232 * read in a "standard" tar format header - we're not that interested
233 * in that many fields, though
236 /* check the checksum */
237 for (chk
=0, i
=sizeof(hb
->dummy
), jp
=hb
->dummy
; --i
>=0;) chk
+=(0xFF & *jp
++);
242 /* compensate for blanks in chksum header */
243 for (i
=sizeof(hb
->dbuf
.chksum
), jp
=hb
->dbuf
.chksum
; --i
>=0;)
246 chk
+= ' ' * sizeof(hb
->dbuf
.chksum
);
248 fchk
=unoct(hb
->dbuf
.chksum
, sizeof(hb
->dbuf
.chksum
));
250 DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
251 chk
, fchk
, hb
->dbuf
.chksum
));
255 DEBUG(0, ("checksums don't match %ld %ld\n", fchk
, chk
));
256 dump_data(5, (char *)hb
- TBLOCK
, TBLOCK
*3);
260 if ((finfo
->name
= string_create_s(strlen(prefix
) + strlen(hb
-> dbuf
.name
) + 3)) == NULL
) {
262 DEBUG(0, ("Out of space creating file_info2 for %s\n", hb
-> dbuf
.name
));
267 safe_strcpy(finfo
->name
, prefix
, strlen(prefix
) + strlen(hb
-> dbuf
.name
) + 3);
269 /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
270 unfixtarname(finfo
->name
+ strlen(prefix
), hb
->dbuf
.name
,
271 strlen(hb
->dbuf
.name
) + 1, True
);
273 /* can't handle some links at present */
274 if ((hb
->dbuf
.linkflag
!= '0') && (hb
-> dbuf
.linkflag
!= '5')) {
275 if (hb
->dbuf
.linkflag
== 0) {
276 DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
279 if (hb
-> dbuf
.linkflag
== 'L') { /* We have a longlink */
280 /* Do nothing here at the moment. do_tarput will handle this
281 as long as the longlink gets back to it, as it has to advance
282 the buffer pointer, etc */
285 DEBUG(0, ("this tar file appears to contain some kind of link other than a GNUtar Longlink - ignoring\n"));
291 if ((unoct(hb
->dbuf
.mode
, sizeof(hb
->dbuf
.mode
)) & S_IFDIR
)
292 || (*(finfo
->name
+strlen(finfo
->name
)-1) == '\\'))
297 finfo
->mode
=0; /* we don't care about mode at the moment, we'll
298 * just make it a regular file */
300 * Bug fix by richard@sj.co.uk
302 * REC: restore times correctly (as does tar)
303 * We only get the modification time of the file; set the creation time
304 * from the mod. time, and the access time to current time
306 finfo
->mtime
= finfo
->ctime
= strtol(hb
->dbuf
.mtime
, NULL
, 8);
307 finfo
->atime
= time(NULL
);
308 finfo
->size
= unoct(hb
->dbuf
.size
, sizeof(hb
->dbuf
.size
));
313 /****************************************************************************
314 Write out the tar buffer to tape or wherever
315 ****************************************************************************/
316 static int dotarbuf(int f
, char *b
, int n
)
323 /* This routine and the next one should be the only ones that do write()s */
324 if (tp
+ n
>= tbufsiz
)
329 memcpy(tarbuf
+ tp
, b
, diff
);
330 fail
=fail
&& (1+write(f
, tarbuf
, tbufsiz
));
337 fail
=fail
&& (1 + write(f
, b
, tbufsiz
));
343 memcpy(tarbuf
+tp
, b
, n
);
347 return(fail
? writ
: 0);
350 /****************************************************************************
351 Write zeros to buffer / tape
352 ****************************************************************************/
353 static void dozerobuf(int f
, int n
)
355 /* short routine just to write out n zeros to buffer -
356 * used to round files to nearest block
357 * and to do tar EOFs */
364 memset(tarbuf
+tp
, 0, tbufsiz
-tp
);
366 write(f
, tarbuf
, tbufsiz
);
367 memset(tarbuf
, 0, (tp
+=n
-tbufsiz
));
371 memset(tarbuf
+tp
, 0, n
);
376 /****************************************************************************
378 ****************************************************************************/
379 static void initarbuf(void)
381 /* initialize tar buffer */
382 tbufsiz
=blocksize
*TBLOCK
;
383 tarbuf
=malloc(tbufsiz
); /* FIXME: We might not get the buffer */
385 /* reset tar buffer pointer and tar file counter and total dumped */
386 tp
=0; ntarf
=0; ttarf
=0;
389 /****************************************************************************
390 Write two zero blocks at end of file
391 ****************************************************************************/
392 static void dotareof(int f
)
394 SMB_STRUCT_STAT stbuf
;
395 /* Two zero blocks at end of file, write out full buffer */
400 (void) dozerobuf(f
, TBLOCK
);
401 (void) dozerobuf(f
, TBLOCK
);
403 if (sys_fstat(f
, &stbuf
) == -1)
405 DEBUG(0, ("Couldn't stat file handle\n"));
409 /* Could be a pipe, in which case S_ISREG should fail,
410 * and we should write out at full size */
411 if (tp
> 0) write(f
, tarbuf
, S_ISREG(stbuf
.st_mode
) ? tp
: tbufsiz
);
414 /****************************************************************************
415 (Un)mangle DOS pathname, make nonabsolute
416 ****************************************************************************/
417 static void fixtarname(char *tptr
, const char *fp
, int l
)
419 /* add a '.' to start of file name, convert from ugly dos \'s in path
420 * to lovely unix /'s :-} */
423 safe_strcpy(tptr
, fp
, l
);
424 string_replace(tptr
, '\\', '/');
427 /****************************************************************************
428 Convert from decimal to octal string
429 ****************************************************************************/
430 static void oct_it (SMB_BIG_UINT value
, int ndgs
, char *p
)
432 /* Converts long to octal string, pads with leading zeros */
434 /* skip final null, but do final space */
438 /* Loop does at least one digit */
440 p
[--ndgs
] = '0' + (char) (value
& 7);
443 while (ndgs
> 0 && value
!= 0);
445 /* Do leading zeros */
450 /****************************************************************************
451 Convert from octal string to long
452 ***************************************************************************/
453 static long unoct(char *p
, int ndgs
)
456 /* Converts octal string to long, ignoring any non-digit */
460 if (isdigit((int)*p
))
461 value
= (value
<< 3) | (long) (*p
- '0');
469 /****************************************************************************
470 Compare two strings in a slash insensitive way, allowing s1 to match s2
471 if s1 is an "initial" string (up to directory marker). Thus, if s2 is
472 a file in any subdirectory of s1, declare a match.
473 ***************************************************************************/
474 static int strslashcmp(char *s1
, char *s2
)
480 || tolower(*s1
) == tolower(*s2
)
481 || (*s1
== '\\' && *s2
=='/')
482 || (*s1
== '/' && *s2
=='\\'))) {
486 /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
489 if (!*s1
&& s1
!= s1_0
&& (*(s1
-1) == '/' || *(s1
-1) == '\\')) return 0;
491 /* ignore trailing slash on s1 */
492 if (!*s2
&& (*s1
== '/' || *s1
== '\\') && !*(s1
+1)) return 0;
494 /* check for s1 is an "initial" string of s2 */
495 if ((*s2
== '/' || *s2
== '\\') && !*s1
) return 0;
501 /****************************************************************************
502 Ensure a remote path exists (make if necessary)
503 ***************************************************************************/
504 static BOOL
ensurepath(char *fname
)
506 /* *must* be called with buffer ready malloc'ed */
507 /* ensures path exists */
509 char *partpath
, *ffname
;
510 char *p
=fname
, *basehack
;
512 DEBUG(5, ( "Ensurepath called with: %s\n", fname
));
514 partpath
= string_create_s(strlen(fname
));
515 ffname
= string_create_s(strlen(fname
));
517 if ((partpath
== NULL
) || (ffname
== NULL
)){
519 DEBUG(0, ("Out of memory in ensurepath: %s\n", fname
));
526 /* fname copied to ffname so can strtok */
528 safe_strcpy(ffname
, fname
, strlen(fname
));
530 /* do a `basename' on ffname, so don't try and make file name directory */
531 if ((basehack
=strrchr_m(ffname
, '\\')) == NULL
)
536 p
=strtok(ffname
, "\\");
540 safe_strcat(partpath
, p
, strlen(fname
) + 1);
542 if (!cli_chkpath(cli
, partpath
)) {
543 if (!cli_mkdir(cli
, partpath
))
545 DEBUG(0, ("Error mkdirhiering\n"));
549 DEBUG(3, ("mkdirhiering %s\n", partpath
));
553 safe_strcat(partpath
, "\\", strlen(fname
) + 1);
554 p
= strtok(NULL
,"/\\");
560 static int padit(char *buf
, int bufsize
, int padsize
)
565 DEBUG(5, ("Padding with %d zeros\n", padsize
));
566 memset(buf
, 0, bufsize
);
567 while( !berr
&& padsize
> 0 ) {
568 bytestowrite
= MIN(bufsize
, padsize
);
569 berr
= dotarbuf(tarhandle
, buf
, bytestowrite
) != bytestowrite
;
570 padsize
-= bytestowrite
;
577 static void do_setrattr(char *name
, uint16 attr
, int set
)
581 if (!cli_getatr(cli
, name
, &oldattr
, NULL
, NULL
)) return;
583 if (set
== ATTRSET
) {
586 attr
= oldattr
& ~attr
;
589 if (!cli_setatr(cli
, name
, attr
, 0)) {
590 DEBUG(1,("setatr failed: %s\n", cli_errstr(cli
)));
595 /****************************************************************************
596 append one remote file to the tar file
597 ***************************************************************************/
598 static void do_atar(char *rname
,char *lname
,file_info
*finfo1
)
601 SMB_BIG_UINT nread
=0;
604 BOOL close_done
= False
;
605 BOOL shallitime
=True
;
607 int read_size
= 65520;
610 struct timeval tp_start
;
611 GetTimeOfDay(&tp_start
);
613 ftype
= '0'; /* An ordinary file ... */
616 finfo
.size
= finfo1
-> size
;
617 finfo
.mode
= finfo1
-> mode
;
618 finfo
.uid
= finfo1
-> uid
;
619 finfo
.gid
= finfo1
-> gid
;
620 finfo
.mtime
= finfo1
-> mtime
;
621 finfo
.atime
= finfo1
-> atime
;
622 finfo
.ctime
= finfo1
-> ctime
;
623 finfo
.name
= finfo1
-> name
;
626 finfo
.size
= def_finfo
.size
;
627 finfo
.mode
= def_finfo
.mode
;
628 finfo
.uid
= def_finfo
.uid
;
629 finfo
.gid
= def_finfo
.gid
;
630 finfo
.mtime
= def_finfo
.mtime
;
631 finfo
.atime
= def_finfo
.atime
;
632 finfo
.ctime
= def_finfo
.ctime
;
633 finfo
.name
= def_finfo
.name
;
638 DEBUG(3,("skipping file %s of size %12.0f bytes\n",
640 (double)finfo
.size
));
642 ttarf
+=finfo
.size
+ TBLOCK
- (finfo
.size
% TBLOCK
);
647 fnum
= cli_open(cli
, rname
, O_RDONLY
, DENY_NONE
);
649 dos_clean_name(rname
);
652 DEBUG(0,("%s opening remote file %s (%s)\n",
653 cli_errstr(cli
),rname
, cur_dir
));
657 finfo
.name
= string_create_s(strlen(rname
));
658 if (finfo
.name
== NULL
) {
659 DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
663 safe_strcpy(finfo
.name
,rname
, strlen(rname
));
665 if (!cli_getattrE(cli
, fnum
, &finfo
.mode
, &finfo
.size
, NULL
, &finfo
.atime
, &finfo
.mtime
)) {
666 DEBUG(0, ("getattrE: %s\n", cli_errstr(cli
)));
669 finfo
.ctime
= finfo
.mtime
;
672 DEBUG(3,("file %s attrib 0x%X\n",finfo
.name
,finfo
.mode
));
674 if (tar_inc
&& !(finfo
.mode
& aARCH
))
676 DEBUG(4, ("skipping %s - archive bit not set\n", finfo
.name
));
679 else if (!tar_system
&& (finfo
.mode
& aSYSTEM
))
681 DEBUG(4, ("skipping %s - system bit is set\n", finfo
.name
));
684 else if (!tar_hidden
&& (finfo
.mode
& aHIDDEN
))
686 DEBUG(4, ("skipping %s - hidden bit is set\n", finfo
.name
));
691 DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
696 /* write a tar header, don't bother with mode - just set to 100644 */
697 writetarheader(tarhandle
, rname
, finfo
.size
, finfo
.mtime
, "100644 \0", ftype
);
699 while (nread
< finfo
.size
&& !close_done
) {
701 DEBUG(3,("nread=%.0f\n",(double)nread
));
703 datalen
= cli_read(cli
, fnum
, data
, nread
, read_size
);
706 DEBUG(0,("Error reading file %s : %s\n", rname
, cli_errstr(cli
)));
712 /* if file size has increased since we made file size query, truncate
713 read so tar header for this file will be correct.
716 if (nread
> finfo
.size
) {
717 datalen
-= nread
- finfo
.size
;
718 DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo
.name
, (double)finfo
.size
));
721 /* add received bits of file to buffer - dotarbuf will
722 * write out in 512 byte intervals */
723 if (dotarbuf(tarhandle
,data
,datalen
) != datalen
) {
724 DEBUG(0,("Error writing to tar file - %s\n", strerror(errno
)));
729 DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname
));
736 /* pad tar file with zero's if we couldn't get entire file */
737 if (nread
< finfo
.size
) {
738 DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo
.size
, (int)nread
));
739 if (padit(data
, sizeof(data
), finfo
.size
- nread
))
740 DEBUG(0,("Error writing tar file - %s\n", strerror(errno
)));
743 /* round tar file to nearest block */
744 if (finfo
.size
% TBLOCK
)
745 dozerobuf(tarhandle
, TBLOCK
- (finfo
.size
% TBLOCK
));
747 ttarf
+=finfo
.size
+ TBLOCK
- (finfo
.size
% TBLOCK
);
751 cli_close(cli
, fnum
);
755 struct timeval tp_end
;
758 /* if shallitime is true then we didn't skip */
759 if (tar_reset
&& !dry_run
)
760 (void) do_setrattr(finfo
.name
, aARCH
, ATTRRESET
);
762 GetTimeOfDay(&tp_end
);
764 (tp_end
.tv_sec
- tp_start
.tv_sec
)*1000 +
765 (tp_end
.tv_usec
- tp_start
.tv_usec
)/1000;
766 get_total_time_ms
+= this_time
;
767 get_total_size
+= finfo
.size
;
771 DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
772 (double)finfo
.size
, finfo
.size
/ MAX(0.001, (1.024*this_time
)),
776 /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
777 DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
778 finfo
.size
/ MAX(0.001, (1.024*this_time
)),
779 get_total_size
/ MAX(0.001, (1.024*get_total_time_ms
))));
783 /****************************************************************************
784 Append single file to tar file (or not)
785 ***************************************************************************/
786 static void do_tar(file_info
*finfo
)
790 if (strequal(finfo
->name
,"..") || strequal(finfo
->name
,"."))
793 /* Is it on the exclude list ? */
794 if (!tar_excl
&& clipn
) {
797 DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir
)));
799 safe_strcpy(exclaim
, cur_dir
, sizeof(pstring
));
800 *(exclaim
+strlen(exclaim
)-1)='\0';
802 safe_strcat(exclaim
, "\\", sizeof(pstring
));
803 safe_strcat(exclaim
, finfo
->name
, sizeof(exclaim
));
805 DEBUG(5, ("...tar_re_search: %d\n", tar_re_search
));
807 if ((!tar_re_search
&& clipfind(cliplist
, clipn
, exclaim
)) ||
809 (tar_re_search
&& !regexec(preg
, exclaim
, 0, NULL
, 0))) {
811 (tar_re_search
&& mask_match(exclaim
, cliplist
[0], True
))) {
813 DEBUG(3,("Skipping file %s\n", exclaim
));
818 if (finfo
->mode
& aDIR
)
820 pstring saved_curdir
;
823 safe_strcpy(saved_curdir
, cur_dir
, sizeof(saved_curdir
));
825 DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir
), (int)strlen(cur_dir
), (int)strlen(finfo
->name
), finfo
->name
, cur_dir
));
827 safe_strcat(cur_dir
,finfo
->name
, sizeof(cur_dir
));
828 safe_strcat(cur_dir
,"\\", sizeof(cur_dir
));
830 DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir
));
832 /* write a tar directory, don't bother with mode - just set it to
834 writetarheader(tarhandle
, cur_dir
, 0, finfo
->mtime
, "040755 \0", '5');
836 DEBUG(0,(" directory %s\n", cur_dir
));
838 ntarf
++; /* Make sure we have a file on there */
839 safe_strcpy(mtar_mask
,cur_dir
, sizeof(pstring
));
840 safe_strcat(mtar_mask
,"*", sizeof(pstring
));
841 DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask
));
842 do_list(mtar_mask
, attribute
, do_tar
, False
, True
);
843 safe_strcpy(cur_dir
,saved_curdir
, sizeof(pstring
));
847 safe_strcpy(rname
,cur_dir
, sizeof(pstring
));
848 safe_strcat(rname
,finfo
->name
, sizeof(pstring
));
849 do_atar(rname
,finfo
->name
,finfo
);
853 /****************************************************************************
854 Convert from UNIX to DOS file names
855 ***************************************************************************/
856 static void unfixtarname(char *tptr
, char *fp
, int l
, BOOL first
)
858 /* remove '.' from start of file name, convert from unix /'s to
859 * dos \'s in path. Kill any absolute path names. But only if first!
862 DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr
, (long)fp
, l
));
869 if (*fp
== '\\' || *fp
== '/') {
875 safe_strcpy(tptr
, fp
, l
);
876 string_replace(tptr
, '/', '\\');
880 /****************************************************************************
881 Move to the next block in the buffer, which may mean read in another set of
882 blocks. FIXME, we should allow more than one block to be skipped.
883 ****************************************************************************/
884 static int next_block(char *ltarbuf
, char **bufferp
, int bufsiz
)
886 int bufread
, total
= 0;
888 DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp
));
892 if (*bufferp
>= (ltarbuf
+ bufsiz
)) {
894 DEBUG(5, ("Reading more data into ltarbuf ...\n"));
897 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
898 * Fixes bug where read can return short if coming from
902 bufread
= read(tarhandle
, ltarbuf
, bufsiz
);
905 while (total
< bufsiz
) {
906 if (bufread
< 0) { /* An error, return false */
907 return (total
> 0 ? -2 : bufread
);
915 bufread
= read(tarhandle
, <arbuf
[total
], bufsiz
- total
);
919 DEBUG(5, ("Total bytes read ... %i\n", total
));
929 /* Skip a file, even if it includes a long file name? */
930 static int skip_file(int skipsize
)
932 int dsize
= skipsize
;
934 DEBUG(5, ("Skiping file. Size = %i\n", skipsize
));
936 /* FIXME, we should skip more than one block at a time */
940 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
942 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
954 /*************************************************************
955 Get a file from the tar file and store it.
956 When this is called, tarbuf already contains the first
957 file block. This is a bit broken & needs fixing.
958 **************************************************************/
960 static int get_file(file_info2 finfo
)
962 int fnum
= -1, pos
= 0, dsize
= 0, bpos
= 0;
963 SMB_BIG_UINT rsize
= 0;
965 DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo
.name
, (double)finfo
.size
));
967 if (ensurepath(finfo
.name
) &&
968 (fnum
=cli_open(cli
, finfo
.name
, O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
)) == -1) {
969 DEBUG(0, ("abandoning restore\n"));
973 /* read the blocks from the tar file and write to the remote file */
975 rsize
= finfo
.size
; /* This is how much to write */
979 /* We can only write up to the end of the buffer */
981 dsize
= MIN(tbufsiz
- (buffer_p
- tarbuf
) - bpos
, 65520); /* Calculate the size to write */
982 dsize
= MIN(dsize
, rsize
); /* Should be only what is left */
983 DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize
, bpos
));
985 if (cli_write(cli
, fnum
, 0, buffer_p
+ bpos
, pos
, dsize
) != dsize
) {
986 DEBUG(0, ("Error writing remote file\n"));
993 /* Now figure out how much to move in the buffer */
995 /* FIXME, we should skip more than one block at a time */
997 /* First, skip any initial part of the part written that is left over */
998 /* from the end of the first TBLOCK */
1000 if ((bpos
) && ((bpos
+ dsize
) >= TBLOCK
)) {
1002 dsize
-= (TBLOCK
- bpos
); /* Get rid of the end of the first block */
1005 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) { /* and skip the block */
1006 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1014 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
1015 * If the file being extracted is an exact multiple of
1016 * TBLOCK bytes then we don't want to extract the next
1017 * block from the tarfile here, as it will be done in
1018 * the caller of get_file().
1021 while (((rsize
!= 0) && (dsize
>= TBLOCK
)) ||
1022 ((rsize
== 0) && (dsize
> TBLOCK
))) {
1024 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) {
1025 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1036 /* Now close the file ... */
1038 if (!cli_close(cli
, fnum
)) {
1039 DEBUG(0, ("Error closing remote file\n"));
1043 /* Now we update the creation date ... */
1045 DEBUG(5, ("Updating creation date on %s\n", finfo
.name
));
1047 if (!cli_setatr(cli
, finfo
.name
, finfo
.mode
, finfo
.mtime
)) {
1048 if (tar_real_noisy
) {
1049 DEBUG(0, ("Could not set time on file: %s\n", finfo
.name
));
1050 /*return(False); */ /* Ignore, as Win95 does not allow changes */
1056 DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo
.name
, (double)finfo
.size
));
1061 /* Create a directory. We just ensure that the path exists and return as there
1062 is no file associated with a directory
1064 static int get_dir(file_info2 finfo
)
1067 DEBUG(0, ("restore directory %s\n", finfo
.name
));
1069 if (!ensurepath(finfo
.name
)) {
1071 DEBUG(0, ("Problems creating directory\n"));
1080 /* Get a file with a long file name ... first file has file name, next file
1081 has the data. We only want the long file name, as the loop in do_tarput
1082 will deal with the rest.
1084 static char * get_longfilename(file_info2 finfo
)
1086 int namesize
= strlen(finfo
.name
) + strlen(cur_dir
) + 2;
1087 char *longname
= malloc(namesize
);
1088 int offset
= 0, left
= finfo
.size
;
1091 DEBUG(5, ("Restoring a long file name: %s\n", finfo
.name
));
1092 DEBUG(5, ("Len = %d\n", (int)finfo
.size
));
1094 if (longname
== NULL
) {
1096 DEBUG(0, ("could not allocate buffer of size %d for longname\n",
1101 /* First, add cur_dir to the long file name */
1103 if (strlen(cur_dir
) > 0) {
1104 strncpy(longname
, cur_dir
, namesize
);
1105 offset
= strlen(cur_dir
);
1108 /* Loop through the blocks picking up the name */
1112 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
1114 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1119 unfixtarname(longname
+ offset
, buffer_p
, MIN(TBLOCK
, finfo
.size
), first
--);
1120 DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname
, buffer_p
));
1131 static void do_tarput(void)
1134 struct timeval tp_start
;
1135 char *longfilename
= NULL
, linkflag
;
1138 GetTimeOfDay(&tp_start
);
1140 DEBUG(5, ("RJS do_tarput called ...\n"));
1142 buffer_p
= tarbuf
+ tbufsiz
; /* init this to force first read */
1144 /* Now read through those files ... */
1148 /* Get us to the next block, or the first block first time around */
1150 if (next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) {
1152 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno
)));
1158 DEBUG(5, ("Reading the next header ...\n"));
1160 switch (readtarheader((union hblock
*) buffer_p
, &finfo
, cur_dir
)) {
1162 case -2: /* Hmm, not good, but not fatal */
1163 DEBUG(0, ("Skipping %s...\n", finfo
.name
));
1164 if ((next_block(tarbuf
, &buffer_p
, tbufsiz
) <= 0) &&
1165 !skip_file(finfo
.size
)) {
1167 DEBUG(0, ("Short file, bailing out...\n"));
1175 DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
1178 case 0: /* chksum is zero - looks like an EOF */
1179 DEBUG(0, ("tar: restored %d files and directories\n", ntarf
));
1180 return; /* Hmmm, bad here ... */
1189 /* Now, do we have a long file name? */
1191 if (longfilename
!= NULL
) {
1193 SAFE_FREE(finfo
.name
); /* Free the space already allocated */
1194 finfo
.name
= longfilename
;
1195 longfilename
= NULL
;
1199 /* Well, now we have a header, process the file ... */
1201 /* Should we skip the file? We have the long name as well here */
1204 ((!tar_re_search
&& clipfind(cliplist
, clipn
, finfo
.name
) ^ tar_excl
)
1206 || (tar_re_search
&& !regexec(preg
, finfo
.name
, 0, NULL
, 0)));
1208 || (tar_re_search
&& mask_match(finfo
.name
, cliplist
[0], True
)));
1211 DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip
, (cliplist
?cliplist
[0]:NULL
), finfo
.name
));
1215 skip_file(finfo
.size
);
1220 /* We only get this far if we should process the file */
1221 linkflag
= ((union hblock
*)buffer_p
) -> dbuf
.linkflag
;
1225 case '0': /* Should use symbolic names--FIXME */
1228 * Skip to the next block first, so we can get the file, FIXME, should
1229 * be in get_file ...
1230 * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
1231 * Fixes bug where file size in tarfile is zero.
1234 if ((finfo
.size
!= 0) && next_block(tarbuf
, &buffer_p
, tbufsiz
) <=0) {
1235 DEBUG(0, ("Short file, bailing out...\n"));
1238 if (!get_file(finfo
)) {
1239 DEBUG(0, ("Abandoning restore\n"));
1246 if (!get_dir(finfo
)) {
1247 DEBUG(0, ("Abandoning restore \n"));
1253 longfilename
= get_longfilename(finfo
);
1254 if (!longfilename
) {
1255 DEBUG(0, ("abandoning restore\n"));
1259 DEBUG(5, ("Long file name: %s\n", longfilename
));
1263 skip_file(finfo
.size
); /* Don't handle these yet */
1275 * samba interactive commands
1278 /****************************************************************************
1280 ***************************************************************************/
1286 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
)))
1288 DEBUG(0, ("blocksize <n>\n"));
1293 if (block
< 0 || block
> 65535)
1295 DEBUG(0, ("blocksize out of range"));
1300 DEBUG(2,("blocksize is now %d\n", blocksize
));
1305 /****************************************************************************
1306 command to set incremental / reset mode
1307 ***************************************************************************/
1308 int cmd_tarmode(void)
1312 while (next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1313 if (strequal(buf
, "full"))
1315 else if (strequal(buf
, "inc"))
1317 else if (strequal(buf
, "reset"))
1319 else if (strequal(buf
, "noreset"))
1321 else if (strequal(buf
, "system"))
1323 else if (strequal(buf
, "nosystem"))
1325 else if (strequal(buf
, "hidden"))
1327 else if (strequal(buf
, "nohidden"))
1329 else if (strequal(buf
, "verbose") || strequal(buf
, "noquiet"))
1331 else if (strequal(buf
, "quiet") || strequal(buf
, "noverbose"))
1333 else DEBUG(0, ("tarmode: unrecognised option %s\n", buf
));
1336 DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
1337 tar_inc
? "incremental" : "full",
1338 tar_system
? "system" : "nosystem",
1339 tar_hidden
? "hidden" : "nohidden",
1340 tar_reset
? "reset" : "noreset",
1341 tar_noisy
? "verbose" : "quiet"));
1346 /****************************************************************************
1347 Feeble attrib command
1348 ***************************************************************************/
1349 int cmd_setmode(void)
1357 attra
[0] = attra
[1] = 0;
1359 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
)))
1361 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1365 safe_strcpy(fname
, cur_dir
, sizeof(pstring
));
1366 safe_strcat(fname
, buf
, sizeof(pstring
));
1368 while (next_token_nr(NULL
,buf
,NULL
,sizeof(buf
))) {
1377 case 'r': attra
[direct
]|=aRONLY
;
1379 case 'h': attra
[direct
]|=aHIDDEN
;
1381 case 's': attra
[direct
]|=aSYSTEM
;
1383 case 'a': attra
[direct
]|=aARCH
;
1385 default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
1390 if (attra
[ATTRSET
]==0 && attra
[ATTRRESET
]==0)
1392 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1396 DEBUG(2, ("\nperm set %d %d\n", attra
[ATTRSET
], attra
[ATTRRESET
]));
1397 do_setrattr(fname
, attra
[ATTRSET
], ATTRSET
);
1398 do_setrattr(fname
, attra
[ATTRRESET
], ATTRRESET
);
1403 /****************************************************************************
1404 Principal command for creating / extracting
1405 ***************************************************************************/
1412 if (!next_token_nr(NULL
,buf
,NULL
,sizeof(buf
)))
1414 DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
1418 argl
=toktocliplist(&argcl
, NULL
);
1419 if (!tar_parseargs(argcl
, argl
, buf
, 0))
1429 /****************************************************************************
1430 Command line (option) version
1431 ***************************************************************************/
1432 int process_tar(void)
1448 if (clipn
&& tar_excl
) {
1452 for (i
=0; i
<clipn
; i
++) {
1453 DEBUG(5,("arg %d = %s\n", i
, cliplist
[i
]));
1455 if (*(cliplist
[i
]+strlen(cliplist
[i
])-1)=='\\') {
1456 *(cliplist
[i
]+strlen(cliplist
[i
])-1)='\0';
1459 if (strrchr_m(cliplist
[i
], '\\')) {
1462 safe_strcpy(saved_dir
, cur_dir
, sizeof(pstring
));
1464 if (*cliplist
[i
]=='\\') {
1465 safe_strcpy(tarmac
, cliplist
[i
], sizeof(pstring
));
1467 safe_strcpy(tarmac
, cur_dir
, sizeof(pstring
));
1468 safe_strcat(tarmac
, cliplist
[i
], sizeof(pstring
));
1470 safe_strcpy(cur_dir
, tarmac
, sizeof(pstring
));
1471 *(strrchr_m(cur_dir
, '\\')+1)='\0';
1473 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac
));
1474 do_list(tarmac
,attribute
,do_tar
, False
, True
);
1475 safe_strcpy(cur_dir
,saved_dir
, sizeof(pstring
));
1477 safe_strcpy(tarmac
, cur_dir
, sizeof(pstring
));
1478 safe_strcat(tarmac
, cliplist
[i
], sizeof(pstring
));
1479 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac
));
1480 do_list(tarmac
,attribute
,do_tar
, False
, True
);
1485 safe_strcpy(mask
,cur_dir
, sizeof(pstring
));
1486 DEBUG(5, ("process_tar, do_list with mask: %s\n", mask
));
1487 safe_strcat(mask
,"\\*", sizeof(pstring
));
1488 do_list(mask
,attribute
,do_tar
,False
, True
);
1491 if (ntarf
) dotareof(tarhandle
);
1495 DEBUG(0, ("tar: dumped %d files and directories\n", ntarf
));
1496 DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf
));
1500 if (must_free_cliplist
) {
1502 for (i
= 0; i
< clipn
; ++i
) {
1503 SAFE_FREE(cliplist
[i
]);
1505 SAFE_FREE(cliplist
);
1508 must_free_cliplist
= False
;
1514 /****************************************************************************
1515 Find a token (filename) in a clip list
1516 ***************************************************************************/
1517 static int clipfind(char **aret
, int ret
, char *tok
)
1519 if (aret
==NULL
) return 0;
1521 /* ignore leading slashes or dots in token */
1522 while(strchr_m("/\\.", *tok
)) tok
++;
1527 /* ignore leading slashes or dots in list */
1528 while(strchr_m("/\\.", *pkey
)) pkey
++;
1530 if (!strslashcmp(pkey
, tok
)) return 1;
1536 /****************************************************************************
1537 Read list of files to include from the file and initialize cliplist
1539 ***************************************************************************/
1540 static int read_inclusion_file(char *filename
)
1542 XFILE
*inclusion
= NULL
;
1543 char buf
[MAXPATHLEN
+ 1];
1544 char *inclusion_buffer
= NULL
;
1545 int inclusion_buffer_size
= 0;
1546 int inclusion_buffer_sofar
= 0;
1553 buf
[MAXPATHLEN
] = '\0'; /* guarantee null-termination */
1554 if ((inclusion
= x_fopen(filename
, O_RDONLY
, 0)) == NULL
) {
1555 /* XXX It would be better to include a reason for failure, but without
1556 * autoconf, it's hard to use strerror, sys_errlist, etc.
1558 DEBUG(0,("Unable to open inclusion file %s\n", filename
));
1562 while ((! error
) && (x_fgets(buf
, sizeof(buf
)-1, inclusion
))) {
1563 if (inclusion_buffer
== NULL
) {
1564 inclusion_buffer_size
= 1024;
1565 if ((inclusion_buffer
= malloc(inclusion_buffer_size
)) == NULL
) {
1566 DEBUG(0,("failure allocating buffer to read inclusion file\n"));
1572 if (buf
[strlen(buf
)-1] == '\n') {
1573 buf
[strlen(buf
)-1] = '\0';
1576 if ((strlen(buf
) + 1 + inclusion_buffer_sofar
) >= inclusion_buffer_size
) {
1578 inclusion_buffer_size
*= 2;
1579 ib
= Realloc(inclusion_buffer
,inclusion_buffer_size
);
1581 DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
1582 inclusion_buffer_size
));
1586 else inclusion_buffer
= ib
;
1589 safe_strcpy(inclusion_buffer
+ inclusion_buffer_sofar
, buf
, inclusion_buffer_size
- inclusion_buffer_sofar
);
1590 inclusion_buffer_sofar
+= strlen(buf
) + 1;
1593 x_fclose(inclusion
);
1596 /* Allocate an array of clipn + 1 char*'s for cliplist */
1597 cliplist
= malloc((clipn
+ 1) * sizeof(char *));
1598 if (cliplist
== NULL
) {
1599 DEBUG(0,("failure allocating memory for cliplist\n"));
1602 cliplist
[clipn
] = NULL
;
1603 p
= inclusion_buffer
;
1604 for (i
= 0; (! error
) && (i
< clipn
); i
++) {
1605 /* set current item to NULL so array will be null-terminated even if
1606 * malloc fails below. */
1608 if ((tmpstr
= (char *)malloc(strlen(p
)+1)) == NULL
) {
1609 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i
));
1612 unfixtarname(tmpstr
, p
, strlen(p
) + 1, True
);
1613 cliplist
[i
] = tmpstr
;
1614 if ((p
= strchr_m(p
, '\000')) == NULL
) {
1615 DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
1621 must_free_cliplist
= True
;
1625 SAFE_FREE(inclusion_buffer
);
1629 /* We know cliplist is always null-terminated */
1630 for (pp
= cliplist
; *pp
; ++pp
) {
1633 SAFE_FREE(cliplist
);
1635 must_free_cliplist
= False
;
1640 /* cliplist and its elements are freed at the end of process_tar. */
1644 /****************************************************************************
1645 Parse tar arguments. Sets tar_type, tar_excl, etc.
1646 ***************************************************************************/
1647 int tar_parseargs(int argc
, char *argv
[], char *Optarg
, int Optind
)
1649 char tar_clipfl
='\0';
1651 /* Reset back to defaults - could be from interactive version
1652 * reset mode and archive mode left as they are though
1664 if (tar_type
=='c') {
1665 printf("Tar must be followed by only one of c or x.\n");
1671 if (Optind
>=argc
|| !(blocksize
=atoi(argv
[Optind
]))) {
1672 DEBUG(0,("Option b must be followed by valid blocksize\n"));
1683 DEBUG(0,("Option N must be followed by valid file name\n"));
1686 SMB_STRUCT_STAT stbuf
;
1687 extern time_t newer_than
;
1689 if (sys_stat(argv
[Optind
], &stbuf
) == 0) {
1690 newer_than
= stbuf
.st_mtime
;
1691 DEBUG(1,("Getting files newer than %s",
1692 asctime(LocalTime(&newer_than
))));
1695 DEBUG(0,("Error setting newer-than time\n"));
1708 DEBUG(0,("Only one of I,X,F must be specified\n"));
1715 DEBUG(0,("Only one of I,X,F must be specified\n"));
1722 DEBUG(0,("Only one of I,X,F must be specified\n"));
1728 DEBUG(0, ("tar_re_search set\n"));
1729 tar_re_search
= True
;
1732 if (tar_type
== 'c') {
1733 DEBUG(0, ("dry_run set\n"));
1736 DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
1741 DEBUG(0,("Unknown tar option\n"));
1746 printf("Option T must be followed by one of c or x.\n");
1750 /* tar_excl is true if cliplist lists files to be included.
1751 * Both 'I' and 'F' mean include. */
1752 tar_excl
=tar_clipfl
!='X';
1754 if (tar_clipfl
=='F') {
1755 if (argc
-Optind
-1 != 1) {
1756 DEBUG(0,("Option F must be followed by exactly one filename.\n"));
1759 if (! read_inclusion_file(argv
[Optind
+1])) {
1762 } else if (Optind
+1<argc
&& !tar_re_search
) { /* For backwards compatibility */
1767 cliplist
=argv
+Optind
+1;
1768 clipn
=argc
-Optind
-1;
1771 if ((tmplist
=malloc(clipn
*sizeof(char *))) == NULL
) {
1772 DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n",
1778 for (clipcount
= 0; clipcount
< clipn
; clipcount
++) {
1780 DEBUG(5, ("Processing an item, %s\n", cliplist
[clipcount
]));
1782 if ((tmpstr
= (char *)malloc(strlen(cliplist
[clipcount
])+1)) == NULL
) {
1783 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n",
1788 unfixtarname(tmpstr
, cliplist
[clipcount
], strlen(cliplist
[clipcount
]) + 1, True
);
1789 tmplist
[clipcount
] = tmpstr
;
1790 DEBUG(5, ("Processed an item, %s\n", tmpstr
));
1792 DEBUG(5, ("Cliplist is: %s\n", cliplist
[0]));
1795 must_free_cliplist
= True
;
1798 if (Optind
+1<argc
&& tar_re_search
) { /* Doing regular expression seaches */
1802 if ((preg
= (regex_t
*)malloc(65536)) == NULL
) {
1804 DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
1809 if (errcode
= regcomp(preg
, argv
[Optind
+ 1], REG_EXTENDED
)) {
1813 errlen
= regerror(errcode
, preg
, errstr
, sizeof(errstr
) - 1);
1815 DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv
[Optind
+ 1], errstr
));
1821 clipn
=argc
-Optind
-1;
1822 cliplist
=argv
+Optind
+1;
1826 if (Optind
>=argc
|| !strcmp(argv
[Optind
], "-")) {
1827 /* Sets tar handle to either 0 or 1, as appropriate */
1828 tarhandle
=(tar_type
=='c');
1830 * Make sure that dbf points to stderr if we are using stdout for
1836 if (tar_type
=='c' && (dry_run
|| strcmp(argv
[Optind
], "/dev/null")==0))
1839 DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
1844 if ((tar_type
=='x' && (tarhandle
= sys_open(argv
[Optind
], O_RDONLY
, 0)) == -1)
1845 || (tar_type
=='c' && (tarhandle
=sys_creat(argv
[Optind
], 0644)) < 0))
1847 DEBUG(0,("Error opening local file %s - %s\n",
1848 argv
[Optind
], strerror(errno
)));