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 3 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, see <http://www.gnu.org/licenses/>.
20 /* The following changes developed by Richard Sharpe for Canon Information
21 Systems Research Australia (CISRA)
23 1. Restore can now restore files with long file names
24 2. Save now saves directory information so that we can restore
25 directory creation times
26 3. tar now accepts both UNIX path names and DOS path names. I prefer
27 those lovely /'s to those UGLY \'s :-)
28 4. the files to exclude can be specified as a regular expression by adding
29 an r flag to the other tar flags. Eg:
31 -TcrX file.tar "*.(obj|exe)"
33 will skip all .obj and .exe files
38 #include "system/filesys.h"
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 */
52 struct timespec mtime_ts;
53 struct timespec atime_ts;
54 struct timespec ctime_ts;
55 char *name; /* This is dynamically allocated */
56 file_info2 *next, *prev; /* Used in the stack ... */
64 #define SEPARATORS " \t\n\r"
65 extern time_t newer_than;
66 extern struct cli_state *cli;
68 /* These defines are for the do_setrattr routine, to indicate
69 * setting and reseting of file attributes in the function call */
73 static uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
75 #ifndef CLIENT_TIMEOUT
76 #define CLIENT_TIMEOUT (30*1000)
79 static char *tarbuf, *buffer_p;
80 static int tp, ntarf, tbufsiz;
82 /* Incremental mode */
83 static bool tar_inc=False;
84 /* Reset archive bit */
85 static bool tar_reset=False;
86 /* Include / exclude mode (true=include, false=exclude) */
87 static bool tar_excl=True;
88 /* use regular expressions for search on file names */
89 static bool tar_re_search=False;
90 /* Do not dump anything, just calculate sizes */
91 static bool dry_run=False;
92 /* Dump files with System attribute */
93 static bool tar_system=True;
94 /* Dump files with Hidden attribute */
95 static bool tar_hidden=True;
96 /* Be noisy - make a catalogue */
97 static bool tar_noisy=True;
98 static bool tar_real_noisy=False; /* Don't want to be really noisy by default */
101 static char **cliplist=NULL;
103 static bool must_free_cliplist = False;
104 extern const char *cmd_ptr;
106 extern bool lowercase;
108 extern bool readbraw_supported;
110 extern int get_total_time_ms;
111 extern int get_total_size;
113 static int blocksize=20;
114 static int tarhandle;
116 static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime,
117 const char *amode, unsigned char ftype);
118 static NTSTATUS do_atar(const char *rname_in, char *lname,
119 struct file_info *finfo1);
120 static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
122 static void oct_it(uint64_t 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, const 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 Write a tar header to buffer
141 ****************************************************************************/
143 static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime,
144 const char *amode, unsigned char ftype)
150 DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
152 memset(hb.dummy, 0, sizeof(hb.dummy));
155 /* We will be prepending a '.' in fixtarheader so use +2 to
156 * take care of the . and terminating zero. JRA.
159 /* write a GNU tar style long header */
161 b = (char *)SMB_MALLOC(l+TBLOCK+100);
163 DEBUG(0,("out of memory\n"));
166 writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
167 memset(b, 0, l+TBLOCK+100);
168 fixtarname(b, aname, l+2);
170 DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
171 dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
175 fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2);
178 strlower_m(hb.dbuf.name);
180 /* write out a "standard" tar format header */
182 hb.dbuf.name[NAMSIZ-1]='\0';
183 strlcpy(hb.dbuf.mode, amode ? amode : "", sizeof(hb.dbuf.mode));
184 oct_it((uint64_t)0, 8, hb.dbuf.uid);
185 oct_it((uint64_t)0, 8, hb.dbuf.gid);
186 oct_it((uint64_t) size, 13, hb.dbuf.size);
187 if (size > (uint64_t)077777777777LL) {
188 /* This is a non-POSIX compatible extention to store files
191 memset(hb.dbuf.size, 0, 4);
193 for (i = 8, jp=(char*)&size; i; i--)
194 hb.dbuf.size[i+3] = *(jp++);
196 oct_it((uint64_t) mtime, 13, hb.dbuf.mtime);
197 memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
198 memset(hb.dbuf.linkname, 0, NAMSIZ);
199 hb.dbuf.linkflag=ftype;
201 for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;)
204 oct_it((uint64_t) chk, 8, hb.dbuf.chksum);
205 hb.dbuf.chksum[6] = '\0';
207 (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
210 /****************************************************************************
211 Read a tar header into a hblock structure, and validate
212 ***************************************************************************/
214 static long readtarheader(union hblock *hb, file_info2 *finfo, const char *prefix)
221 * read in a "standard" tar format header - we're not that interested
222 * in that many fields, though
225 /* check the checksum */
226 for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;)
232 /* compensate for blanks in chksum header */
233 for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
236 chk += ' ' * sizeof(hb->dbuf.chksum);
238 fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
240 DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
241 chk, fchk, hb->dbuf.chksum));
244 DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
245 dump_data(5, (uint8 *)hb - TBLOCK, TBLOCK *3);
249 if ((finfo->name = SMB_MALLOC(strlen(prefix) + strlen(hb -> dbuf.name) + 4)) == NULL) {
250 DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
254 strlcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 4);
256 /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
257 unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
258 strlen(hb->dbuf.name) + 1, True);
260 /* can't handle some links at present */
261 if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
262 if (hb->dbuf.linkflag == 0) {
263 DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
266 if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
267 /* Do nothing here at the moment. do_tarput will handle this
268 as long as the longlink gets back to it, as it has to advance
269 the buffer pointer, etc */
271 DEBUG(0, ("this tar file appears to contain some kind \
272 of link other than a GNUtar Longlink - ignoring\n"));
278 if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
279 (*(finfo->name+strlen(finfo->name)-1) == '\\')) {
280 finfo->mode=FILE_ATTRIBUTE_DIRECTORY;
282 finfo->mode=0; /* we don't care about mode at the moment, we'll
283 * just make it a regular file */
287 * Bug fix by richard@sj.co.uk
289 * REC: restore times correctly (as does tar)
290 * We only get the modification time of the file; set the creation time
291 * from the mod. time, and the access time to current time
293 finfo->mtime_ts = finfo->ctime_ts =
294 convert_time_t_to_timespec((time_t)strtol(hb->dbuf.mtime, NULL, 8));
295 finfo->atime_ts = convert_time_t_to_timespec(time(NULL));
296 finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
301 /****************************************************************************
302 Write out the tar buffer to tape or wherever
303 ****************************************************************************/
305 static int dotarbuf(int f, char *b, int n)
312 /* This routine and the next one should be the only ones that do write()s */
313 if (tp + n >= tbufsiz) {
317 memcpy(tarbuf + tp, b, diff);
318 fail=fail && (1+sys_write(f, tarbuf, tbufsiz));
323 while (n >= tbufsiz) {
324 fail=fail && (1 + sys_write(f, b, tbufsiz));
331 memcpy(tarbuf+tp, b, n);
335 return(fail ? writ : 0);
338 /****************************************************************************
339 Write zeros to buffer / tape
340 ****************************************************************************/
342 static void dozerobuf(int f, int n)
344 /* short routine just to write out n zeros to buffer -
345 * used to round files to nearest block
346 * and to do tar EOFs */
351 if (n+tp >= tbufsiz) {
352 memset(tarbuf+tp, 0, tbufsiz-tp);
353 if (sys_write(f, tarbuf, tbufsiz) != tbufsiz) {
354 DEBUG(0, ("dozerobuf: sys_write fail\n"));
357 memset(tarbuf, 0, (tp+=n-tbufsiz));
359 memset(tarbuf+tp, 0, n);
364 /****************************************************************************
366 ****************************************************************************/
368 static void initarbuf(void)
370 /* initialize tar buffer */
371 tbufsiz=blocksize*TBLOCK;
372 tarbuf=(char *)SMB_MALLOC(tbufsiz); /* FIXME: We might not get the buffer */
374 /* reset tar buffer pointer and tar file counter and total dumped */
375 tp=0; ntarf=0; ttarf=0;
378 /****************************************************************************
379 Write two zero blocks at end of file
380 ****************************************************************************/
382 static void dotareof(int f)
384 SMB_STRUCT_STAT stbuf;
385 /* Two zero blocks at end of file, write out full buffer */
390 (void) dozerobuf(f, TBLOCK);
391 (void) dozerobuf(f, TBLOCK);
393 if (sys_fstat(f, &stbuf, false) == -1) {
394 DEBUG(0, ("Couldn't stat file handle\n"));
398 /* Could be a pipe, in which case S_ISREG should fail,
399 * and we should write out at full size */
401 size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz;
402 if (sys_write(f, tarbuf, towrite) != towrite) {
403 DEBUG(0,("dotareof: sys_write fail\n"));
408 /****************************************************************************
409 (Un)mangle DOS pathname, make nonabsolute
410 ****************************************************************************/
412 static void fixtarname(char *tptr, const char *fp, size_t l)
414 /* add a '.' to start of file name, convert from ugly dos \'s in path
415 * to lovely unix /'s :-} */
419 StrnCpy(tptr, fp, l-1);
420 string_replace(tptr, '\\', '/');
423 /****************************************************************************
424 Convert from decimal to octal string
425 ****************************************************************************/
427 static void oct_it (uint64_t value, int ndgs, char *p)
429 /* Converts long to octal string, pads with leading zeros */
431 /* skip final null, but do final space */
435 /* Loop does at least one digit */
437 p[--ndgs] = '0' + (char) (value & 7);
439 } while (ndgs > 0 && value != 0);
441 /* Do leading zeros */
446 /****************************************************************************
447 Convert from octal string to long
448 ***************************************************************************/
450 static long unoct(char *p, int ndgs)
453 /* Converts octal string to long, ignoring any non-digit */
456 if (isdigit((int)*p))
457 value = (value << 3) | (long) (*p - '0');
465 /****************************************************************************
466 Compare two strings in a slash insensitive way, allowing s1 to match s2
467 if s1 is an "initial" string (up to directory marker). Thus, if s2 is
468 a file in any subdirectory of s1, declare a match.
469 ***************************************************************************/
471 static int strslashcmp(char *s1, char *s2)
475 while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) ||
476 (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
480 /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
483 if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\'))
486 /* ignore trailing slash on s1 */
487 if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1))
490 /* check for s1 is an "initial" string of s2 */
491 if ((*s2 == '/' || *s2 == '\\') && !*s1)
497 /****************************************************************************
498 Ensure a remote path exists (make if necessary)
499 ***************************************************************************/
501 static bool ensurepath(const char *fname)
503 /* *must* be called with buffer ready malloc'ed */
504 /* ensures path exists */
506 char *partpath, *ffname;
507 size_t fnamelen = strlen(fname)+1;
512 DEBUG(5, ( "Ensurepath called with: %s\n", fname));
514 partpath = SMB_MALLOC(fnamelen);
515 ffname = SMB_MALLOC(fnamelen);
517 if ((partpath == NULL) || (ffname == NULL)){
518 DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
526 /* fname copied to ffname so can strtok_r */
528 strlcpy(ffname, fname, fnamelen);
530 /* do a `basename' on ffname, so don't try and make file name directory */
531 if ((basehack=strrchr_m(ffname, '\\')) == NULL) {
539 p=strtok_r(ffname, "\\", &saveptr);
542 strlcat(partpath, p, fnamelen);
544 if (!NT_STATUS_IS_OK(cli_chkpath(cli, partpath))) {
545 if (!NT_STATUS_IS_OK(cli_mkdir(cli, partpath))) {
548 DEBUG(0, ("Error mkdir %s\n", cli_errstr(cli)));
551 DEBUG(3, ("mkdirhiering %s\n", partpath));
555 strlcat(partpath, "\\", fnamelen);
556 p = strtok_r(NULL, "/\\", &saveptr);
564 static int padit(char *buf, uint64_t bufsize, uint64_t padsize)
569 DEBUG(5, ("Padding with %0.f zeros\n", (double)padsize));
570 memset(buf, 0, (size_t)bufsize);
571 while( !berr && padsize > 0 ) {
572 bytestowrite= (int)MIN(bufsize, padsize);
573 berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
574 padsize -= bytestowrite;
580 static void do_setrattr(char *name, uint16 attr, int set)
584 if (!NT_STATUS_IS_OK(cli_getatr(cli, name, &oldattr, NULL, NULL))) {
588 if (set == ATTRSET) {
591 attr = oldattr & ~attr;
594 if (!NT_STATUS_IS_OK(cli_setatr(cli, name, attr, 0))) {
595 DEBUG(1,("setatr failed: %s\n", cli_errstr(cli)));
599 /****************************************************************************
600 append one remote file to the tar file
601 ***************************************************************************/
603 static NTSTATUS do_atar(const char *rname_in, char *lname,
604 struct file_info *finfo1)
606 uint16_t fnum = (uint16_t)-1;
610 bool shallitime=True;
612 int read_size = 65520;
615 TALLOC_CTX *ctx = talloc_stackframe();
616 NTSTATUS status = NT_STATUS_OK;
617 struct timespec tp_start;
619 clock_gettime_mono(&tp_start);
621 data = SMB_MALLOC_ARRAY(char, read_size);
623 DEBUG(0,("do_atar: out of memory.\n"));
624 status = NT_STATUS_NO_MEMORY;
628 ftype = '0'; /* An ordinary file ... */
632 finfo.size = finfo1 -> size;
633 finfo.mode = finfo1 -> mode;
634 finfo.uid = finfo1 -> uid;
635 finfo.gid = finfo1 -> gid;
636 finfo.mtime_ts = finfo1 -> mtime_ts;
637 finfo.atime_ts = finfo1 -> atime_ts;
638 finfo.ctime_ts = finfo1 -> ctime_ts;
641 DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo1->name,
642 (double)finfo.size));
644 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
649 rname = clean_name(ctx, rname_in);
651 status = NT_STATUS_NO_MEMORY;
655 status = cli_open(cli, rname, O_RDONLY, DENY_NONE, &fnum);
656 if (!NT_STATUS_IS_OK(status)) {
657 DEBUG(0,("%s opening remote file %s (%s)\n",
658 cli_errstr(cli),rname, client_get_cur_dir()));
662 finfo.name = smb_xstrdup(rname);
663 if (finfo.name == NULL) {
664 DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
665 status = NT_STATUS_NO_MEMORY;
669 DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
671 if (tar_inc && !(finfo.mode & FILE_ATTRIBUTE_ARCHIVE)) {
672 DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
674 } else if (!tar_system && (finfo.mode & FILE_ATTRIBUTE_SYSTEM)) {
675 DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
677 } else if (!tar_hidden && (finfo.mode & FILE_ATTRIBUTE_HIDDEN)) {
678 DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
681 bool wrote_tar_header = False;
683 DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
684 finfo.name, (double)finfo.size, lname));
688 DEBUG(3,("nread=%.0f\n",(double)nread));
690 datalen = cli_read(cli, fnum, data, nread, read_size);
693 DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
694 status = cli_nt_error(cli);
700 /* Only if the first read succeeds, write out the tar header. */
701 if (!wrote_tar_header) {
702 /* write a tar header, don't bother with mode - just set to 100644 */
703 writetarheader(tarhandle, rname, finfo.size,
704 finfo.mtime_ts.tv_sec, "100644 \0", ftype);
705 wrote_tar_header = True;
708 /* if file size has increased since we made file size query, truncate
709 read so tar header for this file will be correct.
712 if (nread > finfo.size) {
713 datalen -= nread - finfo.size;
714 DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
715 finfo.name, (double)finfo.size));
718 /* add received bits of file to buffer - dotarbuf will
719 * write out in 512 byte intervals */
721 if (dotarbuf(tarhandle,data,datalen) != datalen) {
722 DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
723 status = map_nt_error_from_unix(errno);
727 if ( (datalen == 0) && (finfo.size != 0) ) {
728 status = NT_STATUS_UNSUCCESSFUL;
729 DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
734 } while ( nread < finfo.size );
736 if (wrote_tar_header) {
737 /* pad tar file with zero's if we couldn't get entire file */
738 if (nread < finfo.size) {
739 DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
740 (double)finfo.size, (int)nread));
741 if (padit(data, (uint64_t)sizeof(data), finfo.size - nread)) {
742 status = map_nt_error_from_unix(errno);
743 DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
747 /* round tar file to nearest block */
748 if (finfo.size % TBLOCK)
749 dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
751 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
754 DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name));
756 status = NT_STATUS_UNSUCCESSFUL;
760 cli_close(cli, fnum);
764 struct timespec tp_end;
767 /* if shallitime is true then we didn't skip */
768 if (tar_reset && !dry_run)
769 (void) do_setrattr(finfo.name, FILE_ATTRIBUTE_ARCHIVE, ATTRRESET);
771 clock_gettime_mono(&tp_end);
772 this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_nsec - tp_start.tv_nsec)/1000000;
773 get_total_time_ms += this_time;
774 get_total_size += finfo.size;
777 DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
778 (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
782 /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
783 DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
784 finfo.size / MAX(0.001, (1.024*this_time)),
785 get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
790 if (fnum != (uint16_t)-1) {
791 cli_close(cli, fnum);
799 /****************************************************************************
800 Append single file to tar file (or not)
801 ***************************************************************************/
803 static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
806 TALLOC_CTX *ctx = talloc_stackframe();
807 NTSTATUS status = NT_STATUS_OK;
809 if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
812 /* Is it on the exclude list ? */
813 if (!tar_excl && clipn) {
816 DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(client_get_cur_dir())));
818 exclaim = talloc_asprintf(ctx,
820 client_get_cur_dir(),
823 return NT_STATUS_NO_MEMORY;
826 DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
828 if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
829 (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
830 DEBUG(3,("Skipping file %s\n", exclaim));
831 TALLOC_FREE(exclaim);
834 TALLOC_FREE(exclaim);
837 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
838 char *saved_curdir = NULL;
840 char *mtar_mask = NULL;
842 saved_curdir = talloc_strdup(ctx, client_get_cur_dir());
844 return NT_STATUS_NO_MEMORY;
847 DEBUG(5, ("strlen(cur_dir)=%d, \
848 strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
849 (int)strlen(saved_curdir),
850 (int)strlen(finfo->name), finfo->name, saved_curdir));
852 new_cd = talloc_asprintf(ctx,
854 client_get_cur_dir(),
857 return NT_STATUS_NO_MEMORY;
859 client_set_cur_dir(new_cd);
861 DEBUG(5, ("Writing a dir, Name = %s\n", client_get_cur_dir()));
863 /* write a tar directory, don't bother with mode - just
865 writetarheader(tarhandle, client_get_cur_dir(), 0,
866 finfo->mtime_ts.tv_sec, "040755 \0", '5');
868 DEBUG(0,(" directory %s\n",
869 client_get_cur_dir()));
871 ntarf++; /* Make sure we have a file on there */
872 mtar_mask = talloc_asprintf(ctx,
874 client_get_cur_dir());
876 return NT_STATUS_NO_MEMORY;
878 DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
879 status = do_list(mtar_mask, attribute, do_tar, False, True);
880 client_set_cur_dir(saved_curdir);
881 TALLOC_FREE(saved_curdir);
883 TALLOC_FREE(mtar_mask);
885 char *rname = talloc_asprintf(ctx,
887 client_get_cur_dir(),
890 return NT_STATUS_NO_MEMORY;
892 status = do_atar(rname,finfo->name,finfo);
898 /****************************************************************************
899 Convert from UNIX to DOS file names
900 ***************************************************************************/
902 static void unfixtarname(char *tptr, char *fp, int l, bool first)
904 /* remove '.' from start of file name, convert from unix /'s to
905 * dos \'s in path. Kill any absolute path names. But only if first!
908 DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l));
915 if (*fp == '\\' || *fp == '/') {
924 strlcpy(tptr, fp, l);
925 string_replace(tptr, '/', '\\');
928 /****************************************************************************
929 Move to the next block in the buffer, which may mean read in another set of
930 blocks. FIXME, we should allow more than one block to be skipped.
931 ****************************************************************************/
933 static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
935 int bufread, total = 0;
937 DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
941 if (*bufferp >= (ltarbuf + bufsiz)) {
943 DEBUG(5, ("Reading more data into ltarbuf ...\n"));
946 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
947 * Fixes bug where read can return short if coming from
951 bufread = read(tarhandle, ltarbuf, bufsiz);
954 while (total < bufsiz) {
955 if (bufread < 0) { /* An error, return false */
956 return (total > 0 ? -2 : bufread);
964 bufread = read(tarhandle, <arbuf[total], bufsiz - total);
968 DEBUG(5, ("Total bytes read ... %i\n", total));
976 /* Skip a file, even if it includes a long file name? */
977 static int skip_file(int skipsize)
979 int dsize = skipsize;
981 DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
983 /* FIXME, we should skip more than one block at a time */
986 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
987 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
996 /*************************************************************
997 Get a file from the tar file and store it.
998 When this is called, tarbuf already contains the first
999 file block. This is a bit broken & needs fixing.
1000 **************************************************************/
1002 static int get_file(file_info2 finfo)
1004 uint16_t fnum = (uint16_t) -1;
1005 int pos = 0, dsize = 0, bpos = 0;
1009 DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
1011 if (!ensurepath(finfo.name)) {
1012 DEBUG(0, ("abandoning restore\n"));
1016 status = cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnum);
1017 if (!NT_STATUS_IS_OK(status)) {
1018 DEBUG(0, ("abandoning restore\n"));
1022 /* read the blocks from the tar file and write to the remote file */
1024 rsize = finfo.size; /* This is how much to write */
1028 /* We can only write up to the end of the buffer */
1029 dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
1030 dsize = MIN(dsize, rsize); /* Should be only what is left */
1031 DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
1033 status = cli_writeall(cli, fnum, 0,
1034 (uint8_t *)(buffer_p + bpos), pos,
1036 if (!NT_STATUS_IS_OK(status)) {
1037 DEBUG(0, ("Error writing remote file: %s\n",
1038 nt_errstr(status)));
1045 /* Now figure out how much to move in the buffer */
1047 /* FIXME, we should skip more than one block at a time */
1049 /* First, skip any initial part of the part written that is left over */
1050 /* from the end of the first TBLOCK */
1052 if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
1053 dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */
1056 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */
1057 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
1063 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
1064 * If the file being extracted is an exact multiple of
1065 * TBLOCK bytes then we don't want to extract the next
1066 * block from the tarfile here, as it will be done in
1067 * the caller of get_file().
1070 while (((rsize != 0) && (dsize >= TBLOCK)) ||
1071 ((rsize == 0) && (dsize > TBLOCK))) {
1073 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
1074 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
1083 /* Now close the file ... */
1085 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
1086 DEBUG(0, ("Error %s closing remote file\n",
1091 /* Now we update the creation date ... */
1092 DEBUG(5, ("Updating creation date on %s\n", finfo.name));
1094 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec))) {
1095 if (tar_real_noisy) {
1096 DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
1097 /*return(False); */ /* Ignore, as Win95 does not allow changes */
1102 DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
1106 /* Create a directory. We just ensure that the path exists and return as there
1107 is no file associated with a directory
1109 static int get_dir(file_info2 finfo)
1111 DEBUG(0, ("restore directory %s\n", finfo.name));
1113 if (!ensurepath(finfo.name)) {
1114 DEBUG(0, ("Problems creating directory\n"));
1121 /* Get a file with a long file name ... first file has file name, next file
1122 has the data. We only want the long file name, as the loop in do_tarput
1123 will deal with the rest.
1125 static char *get_longfilename(file_info2 finfo)
1127 /* finfo.size here is the length of the filename as written by the "/./@LongLink" name
1129 int namesize = finfo.size + strlen(client_get_cur_dir()) + 2;
1130 char *longname = (char *)SMB_MALLOC(namesize);
1131 int offset = 0, left = finfo.size;
1134 DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
1135 DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
1137 if (longname == NULL) {
1138 DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize));
1142 /* First, add cur_dir to the long file name */
1144 if (strlen(client_get_cur_dir()) > 0) {
1145 strncpy(longname, client_get_cur_dir(), namesize);
1146 offset = strlen(client_get_cur_dir());
1149 /* Loop through the blocks picking up the name */
1152 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
1153 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
1154 SAFE_FREE(longname);
1158 unfixtarname(longname + offset, buffer_p,
1159 namesize - offset, first--);
1160 DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
1169 static void do_tarput(void)
1172 struct timespec tp_start;
1173 char *longfilename = NULL, linkflag;
1178 clock_gettime_mono(&tp_start);
1179 DEBUG(5, ("RJS do_tarput called ...\n"));
1181 buffer_p = tarbuf + tbufsiz; /* init this to force first read */
1183 /* Now read through those files ... */
1185 /* Get us to the next block, or the first block first time around */
1186 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
1187 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
1188 SAFE_FREE(longfilename);
1192 DEBUG(5, ("Reading the next header ...\n"));
1194 switch (readtarheader((union hblock *) buffer_p,
1195 &finfo, client_get_cur_dir())) {
1196 case -2: /* Hmm, not good, but not fatal */
1197 DEBUG(0, ("Skipping %s...\n", finfo.name));
1198 if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) {
1199 DEBUG(0, ("Short file, bailing out...\n"));
1200 SAFE_FREE(longfilename);
1206 DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
1207 SAFE_FREE(longfilename);
1210 case 0: /* chksum is zero - looks like an EOF */
1211 DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
1212 SAFE_FREE(longfilename);
1213 return; /* Hmmm, bad here ... */
1220 /* Now, do we have a long file name? */
1221 if (longfilename != NULL) {
1222 SAFE_FREE(finfo.name); /* Free the space already allocated */
1223 finfo.name = longfilename;
1224 longfilename = NULL;
1227 /* Well, now we have a header, process the file ... */
1228 /* Should we skip the file? We have the long name as well here */
1229 skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) ||
1230 (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True)));
1232 DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
1234 skip_file(finfo.size);
1238 /* We only get this far if we should process the file */
1239 linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
1241 case '0': /* Should use symbolic names--FIXME */
1243 * Skip to the next block first, so we can get the file, FIXME, should
1244 * be in get_file ...
1245 * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
1246 * Fixes bug where file size in tarfile is zero.
1248 if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
1249 DEBUG(0, ("Short file, bailing out...\n"));
1252 if (!get_file(finfo)) {
1253 DEBUG(0, ("Abandoning restore\n"));
1258 if (!get_dir(finfo)) {
1259 DEBUG(0, ("Abandoning restore \n"));
1264 SAFE_FREE(longfilename);
1265 longfilename = get_longfilename(finfo);
1266 if (!longfilename) {
1267 DEBUG(0, ("abandoning restore\n"));
1270 DEBUG(5, ("Long file name: %s\n", longfilename));
1274 skip_file(finfo.size); /* Don't handle these yet */
1281 * samba interactive commands
1284 /****************************************************************************
1286 ***************************************************************************/
1290 TALLOC_CTX *ctx = talloc_tos();
1294 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
1295 DEBUG(0, ("blocksize <n>\n"));
1300 if (block < 0 || block > 65535) {
1301 DEBUG(0, ("blocksize out of range"));
1306 DEBUG(2,("blocksize is now %d\n", blocksize));
1310 /****************************************************************************
1311 command to set incremental / reset mode
1312 ***************************************************************************/
1314 int cmd_tarmode(void)
1316 TALLOC_CTX *ctx = talloc_tos();
1319 while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
1320 if (strequal(buf, "full"))
1322 else if (strequal(buf, "inc"))
1324 else if (strequal(buf, "reset"))
1326 else if (strequal(buf, "noreset"))
1328 else if (strequal(buf, "system"))
1330 else if (strequal(buf, "nosystem"))
1332 else if (strequal(buf, "hidden"))
1334 else if (strequal(buf, "nohidden"))
1336 else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
1338 else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
1341 DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
1345 DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
1346 tar_inc ? "incremental" : "full",
1347 tar_system ? "system" : "nosystem",
1348 tar_hidden ? "hidden" : "nohidden",
1349 tar_reset ? "reset" : "noreset",
1350 tar_noisy ? "verbose" : "quiet"));
1354 /****************************************************************************
1355 Feeble attrib command
1356 ***************************************************************************/
1358 int cmd_setmode(void)
1360 TALLOC_CTX *ctx = talloc_tos();
1367 attra[0] = attra[1] = 0;
1369 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
1370 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1374 fname = talloc_asprintf(ctx,
1376 client_get_cur_dir(),
1382 while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
1394 attra[direct]|=FILE_ATTRIBUTE_READONLY;
1397 attra[direct]|=FILE_ATTRIBUTE_HIDDEN;
1400 attra[direct]|=FILE_ATTRIBUTE_SYSTEM;
1403 attra[direct]|=FILE_ATTRIBUTE_ARCHIVE;
1406 DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
1412 if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) {
1413 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
1417 DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
1418 do_setrattr(fname, attra[ATTRSET], ATTRSET);
1419 do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
1424 Convert list of tokens to array; dependent on above routine.
1425 Uses the global cmd_ptr from above - bit of a hack.
1428 static char **toktocliplist(int *ctok, const char *sep)
1430 char *s=(char *)cmd_ptr;
1437 while(*s && strchr_m(sep,*s))
1446 while(*s && (!strchr_m(sep,*s)))
1448 while(*s && strchr_m(sep,*s))
1455 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
1472 /****************************************************************************
1473 Principal command for creating / extracting
1474 ***************************************************************************/
1478 TALLOC_CTX *ctx = talloc_tos();
1484 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
1485 DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
1489 argl=toktocliplist(&argcl, NULL);
1490 if (!tar_parseargs(argcl, argl, buf, 0)) {
1495 ret = process_tar();
1500 /****************************************************************************
1501 Command line (option) version
1502 ***************************************************************************/
1504 int process_tar(void)
1506 TALLOC_CTX *ctx = talloc_tos();
1522 if (clipn && tar_excl) {
1524 char *tarmac = NULL;
1526 for (i=0; i<clipn; i++) {
1527 DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
1529 if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
1530 *(cliplist[i]+strlen(cliplist[i])-1)='\0';
1533 if (strrchr_m(cliplist[i], '\\')) {
1536 char *saved_dir = talloc_strdup(ctx,
1537 client_get_cur_dir());
1542 if (*cliplist[i]=='\\') {
1543 tarmac = talloc_strdup(ctx,
1546 tarmac = talloc_asprintf(ctx,
1548 client_get_cur_dir(),
1555 * Strip off the last \\xxx
1556 * xxx element of tarmac to set
1557 * it as current directory.
1559 p = strrchr_m(tarmac, '\\');
1566 client_set_cur_dir(tarmac);
1569 * Restore the character we
1576 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
1577 do_list(tarmac,attribute,do_tar, False, True);
1579 client_set_cur_dir(saved_dir);
1581 TALLOC_FREE(saved_dir);
1582 TALLOC_FREE(tarmac);
1584 tarmac = talloc_asprintf(ctx,
1586 client_get_cur_dir(),
1591 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
1592 do_list(tarmac,attribute,do_tar, False, True);
1593 TALLOC_FREE(tarmac);
1597 char *mask = talloc_asprintf(ctx,
1599 client_get_cur_dir());
1603 DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
1604 do_list(mask,attribute,do_tar,False, True);
1609 dotareof(tarhandle);
1614 DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
1615 DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
1619 if (must_free_cliplist) {
1621 for (i = 0; i < clipn; ++i) {
1622 SAFE_FREE(cliplist[i]);
1624 SAFE_FREE(cliplist);
1627 must_free_cliplist = False;
1632 /****************************************************************************
1633 Find a token (filename) in a clip list
1634 ***************************************************************************/
1636 static int clipfind(char **aret, int ret, char *tok)
1641 /* ignore leading slashes or dots in token */
1642 while(strchr_m("/\\.", *tok))
1648 /* ignore leading slashes or dots in list */
1649 while(strchr_m("/\\.", *pkey))
1652 if (!strslashcmp(pkey, tok))
1658 /****************************************************************************
1659 Read list of files to include from the file and initialize cliplist
1661 ***************************************************************************/
1663 static int read_inclusion_file(char *filename)
1665 XFILE *inclusion = NULL;
1666 char buf[PATH_MAX + 1];
1667 char *inclusion_buffer = NULL;
1668 int inclusion_buffer_size = 0;
1669 int inclusion_buffer_sofar = 0;
1676 buf[PATH_MAX] = '\0'; /* guarantee null-termination */
1677 if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
1678 /* XXX It would be better to include a reason for failure, but without
1679 * autoconf, it's hard to use strerror, sys_errlist, etc.
1681 DEBUG(0,("Unable to open inclusion file %s\n", filename));
1685 while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
1686 if (inclusion_buffer == NULL) {
1687 inclusion_buffer_size = 1024;
1688 if ((inclusion_buffer = (char *)SMB_MALLOC(inclusion_buffer_size)) == NULL) {
1689 DEBUG(0,("failure allocating buffer to read inclusion file\n"));
1695 if (buf[strlen(buf)-1] == '\n') {
1696 buf[strlen(buf)-1] = '\0';
1699 if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
1700 inclusion_buffer_size *= 2;
1701 inclusion_buffer = (char *)SMB_REALLOC(inclusion_buffer,inclusion_buffer_size);
1702 if (!inclusion_buffer) {
1703 DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
1704 inclusion_buffer_size));
1710 strlcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
1711 inclusion_buffer_sofar += strlen(buf) + 1;
1714 x_fclose(inclusion);
1717 /* Allocate an array of clipn + 1 char*'s for cliplist */
1718 cliplist = SMB_MALLOC_ARRAY(char *, clipn + 1);
1719 if (cliplist == NULL) {
1720 DEBUG(0,("failure allocating memory for cliplist\n"));
1723 cliplist[clipn] = NULL;
1724 p = inclusion_buffer;
1725 for (i = 0; (! error) && (i < clipn); i++) {
1726 /* set current item to NULL so array will be null-terminated even if
1727 * malloc fails below. */
1729 if ((tmpstr = (char *)SMB_MALLOC(strlen(p)+1)) == NULL) {
1730 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
1733 unfixtarname(tmpstr, p, strlen(p) + 1, True);
1734 cliplist[i] = tmpstr;
1735 if ((p = strchr_m(p, '\000')) == NULL) {
1736 DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
1742 must_free_cliplist = True;
1746 SAFE_FREE(inclusion_buffer);
1750 /* We know cliplist is always null-terminated */
1751 for (pp = cliplist; *pp; ++pp) {
1754 SAFE_FREE(cliplist);
1756 must_free_cliplist = False;
1761 /* cliplist and its elements are freed at the end of process_tar. */
1765 /****************************************************************************
1766 Parse tar arguments. Sets tar_type, tar_excl, etc.
1767 ***************************************************************************/
1769 int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
1771 int newOptind = Optind;
1772 char tar_clipfl='\0';
1774 /* Reset back to defaults - could be from interactive version
1775 * reset mode and archive mode left as they are though
1787 if (tar_type=='c') {
1788 printf("Tar must be followed by only one of c or x.\n");
1794 if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
1795 DEBUG(0,("Option b must be followed by valid blocksize\n"));
1807 DEBUG(0,("Option N must be followed by valid file name\n"));
1810 SMB_STRUCT_STAT stbuf;
1812 if (sys_stat(argv[Optind], &stbuf,
1814 newer_than = convert_timespec_to_time_t(
1816 DEBUG(1,("Getting files newer than %s",
1817 time_to_asc(newer_than)));
1821 DEBUG(0,("Error setting newer-than time\n"));
1834 DEBUG(0,("Only one of I,X,F must be specified\n"));
1841 DEBUG(0,("Only one of I,X,F must be specified\n"));
1848 DEBUG(0,("Only one of I,X,F must be specified\n"));
1854 DEBUG(0, ("tar_re_search set\n"));
1855 tar_re_search = True;
1858 if (tar_type == 'c') {
1859 DEBUG(0, ("dry_run set\n"));
1862 DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
1867 DEBUG(0,("Unknown tar option\n"));
1873 printf("Option T must be followed by one of c or x.\n");
1877 /* tar_excl is true if cliplist lists files to be included.
1878 * Both 'I' and 'F' mean include. */
1879 tar_excl=tar_clipfl!='X';
1881 if (tar_clipfl=='F') {
1882 if (argc-Optind-1 != 1) {
1883 DEBUG(0,("Option F must be followed by exactly one filename.\n"));
1887 /* Optind points at the tar output file, Optind+1 at the inclusion file. */
1888 if (! read_inclusion_file(argv[Optind+1])) {
1891 } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
1896 cliplist=argv+Optind+1;
1897 clipn=argc-Optind-1;
1900 if ((tmplist=SMB_MALLOC_ARRAY(char *,clipn)) == NULL) {
1901 DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));
1905 for (clipcount = 0; clipcount < clipn; clipcount++) {
1907 DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
1909 if ((tmpstr = (char *)SMB_MALLOC(strlen(cliplist[clipcount])+1)) == NULL) {
1910 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));
1915 unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
1916 tmplist[clipcount] = tmpstr;
1917 DEBUG(5, ("Processed an item, %s\n", tmpstr));
1919 DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
1923 must_free_cliplist = True;
1928 if (Optind+1<argc && tar_re_search && tar_clipfl != 'F') {
1929 /* Doing regular expression seaches not from an inclusion file. */
1930 clipn=argc-Optind-1;
1931 cliplist=argv+Optind+1;
1935 if (Optind>=argc || !strcmp(argv[Optind], "-")) {
1936 /* Sets tar handle to either 0 or 1, as appropriate */
1937 tarhandle=(tar_type=='c');
1939 * Make sure that dbf points to stderr if we are using stdout for
1942 if (tarhandle == 1) {
1943 setup_logging("smbclient", DEBUG_STDERR);
1945 if (!argv[Optind]) {
1946 DEBUG(0,("Must specify tar filename\n"));
1949 if (!strcmp(argv[Optind], "-")) {
1954 if (tar_type=='c' && dry_run) {
1956 } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
1957 || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {
1958 DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno)));