Fix all warnings in source3 with gcc4.3.
[ira/wip.git] / source3 / client / clitar.c
index 14ebffb60ffd58d0b9417846bbfd78be35583ce8..18edf037e26613eced1e46783dd730e638dd02e7 100644 (file)
@@ -1,28 +1,27 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Tar Extensions
    Copyright (C) Ricky Poulten 1995-1998
    Copyright (C) Richard Sharpe 1998
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /* The following changes developed by Richard Sharpe for Canon Information
    Systems Research Australia (CISRA)
 
    1. Restore can now restore files with long file names
-   2. Save now saves directory information so that we can restore 
+   2. Save now saves directory information so that we can restore
       directory creation times
    3. tar now accepts both UNIX path names and DOS path names. I prefer
       those lovely /'s to those UGLY \'s :-)
@@ -44,16 +43,15 @@ static int clipfind(char **aret, int ret, char *tok);
 typedef struct file_info_struct file_info2;
 
 struct file_info_struct {
-       SMB_BIG_UINT size;
+       SMB_OFF_T size;
        uint16 mode;
        uid_t uid;
        gid_t gid;
        /* These times are normally kept in GMT */
-       time_t mtime;
-       time_t atime;
-       time_t ctime;
-       char *name;     /* This is dynamically allocate */
-
+       struct timespec mtime_ts;
+       struct timespec atime_ts;
+       struct timespec ctime_ts;
+       char *name;     /* This is dynamically allocated */
        file_info2 *next, *prev;  /* Used in the stack ... */
 };
 
@@ -63,6 +61,7 @@ typedef struct {
 } stack;
 
 #define SEPARATORS " \t\n\r"
+extern time_t newer_than;
 extern struct cli_state *cli;
 
 /* These defines are for the do_setrattr routine, to indicate
@@ -80,45 +79,44 @@ static char *tarbuf, *buffer_p;
 static int tp, ntarf, tbufsiz;
 static double ttarf;
 /* Incremental mode */
-static BOOL tar_inc=False;
+static bool tar_inc=False;
 /* Reset archive bit */
-static BOOL tar_reset=False;
+static bool tar_reset=False;
 /* Include / exclude mode (true=include, false=exclude) */
-static BOOL tar_excl=True;
+static bool tar_excl=True;
 /* use regular expressions for search on file names */
-static BOOL tar_re_search=False;
+static bool tar_re_search=False;
 /* Do not dump anything, just calculate sizes */
-static BOOL dry_run=False;
+static bool dry_run=False;
 /* Dump files with System attribute */
-static BOOL tar_system=True;
+static bool tar_system=True;
 /* Dump files with Hidden attribute */
-static BOOL tar_hidden=True;
+static bool tar_hidden=True;
 /* Be noisy - make a catalogue */
-static BOOL tar_noisy=True;
-static BOOL tar_real_noisy=False;  /* Don't want to be really noisy by default */
+static bool tar_noisy=True;
+static bool tar_real_noisy=False;  /* Don't want to be really noisy by default */
 
 char tar_type='\0';
 static char **cliplist=NULL;
 static int clipn=0;
-static BOOL must_free_cliplist = False;
+static bool must_free_cliplist = False;
+extern const char *cmd_ptr;
 
-extern file_info def_finfo;
-extern BOOL lowercase;
+extern bool lowercase;
 extern uint16 cnum;
-extern BOOL readbraw_supported;
+extern bool readbraw_supported;
 extern int max_xmit;
-extern pstring cur_dir;
 extern int get_total_time_ms;
 extern int get_total_size;
 
 static int blocksize=20;
 static int tarhandle;
 
-static void writetarheader(int f,  const char *aname, SMB_BIG_UINT size, time_t mtime,
+static void writetarheader(int f,  const char *aname, uint64_t size, time_t mtime,
                           const char *amode, unsigned char ftype);
-static void do_atar(char *rname,char *lname,file_info *finfo1);
-static void do_tar(file_info *finfo);
-static void oct_it(SMB_BIG_UINT value, int ndgs, char *p);
+static void do_atar(const char *rname_in,char *lname,file_info *finfo1);
+static void do_tar(file_info *finfo, const char *dir);
+static void oct_it(uint64_t value, int ndgs, char *p);
 static void fixtarname(char *tptr, const char *fp, size_t l);
 static int dotarbuf(int f, char *b, int n);
 static void dozerobuf(int f, int n);
@@ -126,10 +124,10 @@ static void dotareof(int f);
 static void initarbuf(void);
 
 /* restore functions */
-static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix);
+static long readtarheader(union hblock *hb, file_info2 *finfo, const char *prefix);
 static long unoct(char *p, int ndgs);
 static void do_tarput(void);
-static void unfixtarname(char *tptr, char *fp, int l, BOOL first);
+static void unfixtarname(char *tptr, char *fp, int l, bool first);
 
 /*
  * tar specific utitlities
@@ -156,7 +154,7 @@ static char *string_create_s(int size)
 Write a tar header to buffer
 ****************************************************************************/
 
-static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
+static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime,
                           const char *amode, unsigned char ftype)
 {
        union hblock hb;
@@ -166,7 +164,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
        DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
 
        memset(hb.dummy, 0, sizeof(hb.dummy));
-  
+
        l=strlen(aname);
        /* We will be prepending a '.' in fixtarheader so use +2 to
         * take care of the . and terminating zero. JRA.
@@ -197,11 +195,10 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
 
        hb.dbuf.name[NAMSIZ-1]='\0';
        safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
-       oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
-       oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
-       oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
-       if (size > (SMB_BIG_UINT)077777777777LL) {    
-
+       oct_it((uint64_t)0, 8, hb.dbuf.uid);
+       oct_it((uint64_t)0, 8, hb.dbuf.gid);
+       oct_it((uint64_t) size, 13, hb.dbuf.size);
+       if (size > (uint64_t)077777777777LL) {
                /* This is a non-POSIX compatible extention to store files
                        greater than 8GB. */
 
@@ -210,15 +207,15 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
                for (i = 8, jp=(char*)&size; i; i--)
                        hb.dbuf.size[i+3] = *(jp++);
        }
-       oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
+       oct_it((uint64_t) mtime, 13, hb.dbuf.mtime);
        memcpy(hb.dbuf.chksum, "        ", sizeof(hb.dbuf.chksum));
        memset(hb.dbuf.linkname, 0, NAMSIZ);
        hb.dbuf.linkflag=ftype;
-  
+
        for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;)
                chk+=(0xFF & *jp++);
 
-       oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
+       oct_it((uint64_t) chk, 8, hb.dbuf.chksum);
        hb.dbuf.chksum[6] = '\0';
 
        (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
@@ -228,7 +225,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
 Read a tar header into a hblock structure, and validate
 ***************************************************************************/
 
-static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
+static long readtarheader(union hblock *hb, file_info2 *finfo, const char *prefix)
 {
        long chk, fchk;
        int i;
@@ -259,7 +256,7 @@ static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
 
        if (fchk != chk) {
                DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
-               dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
+               dump_data(5, (uint8 *)hb - TBLOCK, TBLOCK *3);
                return -1;
        }
 
@@ -279,7 +276,7 @@ static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
                if (hb->dbuf.linkflag == 0) {
                        DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
                                finfo->name));
-               } else { 
+               } else {
                        if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
                                /* Do nothing here at the moment. do_tarput will handle this
                                        as long as the longlink gets back to it, as it has to advance 
@@ -291,7 +288,7 @@ of link other than a GNUtar Longlink - ignoring\n"));
                        }
                }
        }
-    
+
        if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
                                (*(finfo->name+strlen(finfo->name)-1) == '\\')) {
                finfo->mode=aDIR;
@@ -307,8 +304,9 @@ of link other than a GNUtar Longlink - ignoring\n"));
         * We only get the modification time of the file; set the creation time
         * from the mod. time, and the access time to current time
         */
-       finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
-       finfo->atime = time(NULL);
+       finfo->mtime_ts = finfo->ctime_ts =
+               convert_time_t_to_timespec((time_t)strtol(hb->dbuf.mtime, NULL, 8));
+       finfo->atime_ts = convert_time_t_to_timespec(time(NULL));
        finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
 
        return True;
@@ -331,13 +329,13 @@ static int dotarbuf(int f, char *b, int n)
 
                diff=tbufsiz-tp;
                memcpy(tarbuf + tp, b, diff);
-               fail=fail && (1+write(f, tarbuf, tbufsiz));
+               fail=fail && (1+sys_write(f, tarbuf, tbufsiz));
                n-=diff;
                b+=diff;
                tp=0;
 
                while (n >= tbufsiz) {
-                       fail=fail && (1 + write(f, b, tbufsiz));
+                       fail=fail && (1 + sys_write(f, b, tbufsiz));
                        n-=tbufsiz;
                        b+=tbufsiz;
                }
@@ -363,10 +361,13 @@ static void dozerobuf(int f, int n)
 
        if (dry_run)
                return;
-  
+
        if (n+tp >= tbufsiz) {
                memset(tarbuf+tp, 0, tbufsiz-tp);
-               write(f, tarbuf, tbufsiz);
+               if (sys_write(f, tarbuf, tbufsiz) != tbufsiz) {
+                       DEBUG(0, ("dozerobuf: sys_write fail\n"));
+                       return;
+               }
                memset(tarbuf, 0, (tp+=n-tbufsiz));
        } else {
                memset(tarbuf+tp, 0, n);
@@ -382,7 +383,7 @@ static void initarbuf(void)
 {
        /* initialize tar buffer */
        tbufsiz=blocksize*TBLOCK;
-       tarbuf=SMB_MALLOC(tbufsiz);      /* FIXME: We might not get the buffer */
+       tarbuf=(char *)SMB_MALLOC(tbufsiz);      /* FIXME: We might not get the buffer */
 
        /* reset tar buffer pointer and tar file counter and total dumped */
        tp=0; ntarf=0; ttarf=0;
@@ -410,8 +411,12 @@ static void dotareof(int f)
 
        /* Could be a pipe, in which case S_ISREG should fail,
                * and we should write out at full size */
-       if (tp > 0)
-               write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
+       if (tp > 0) {
+               size_t towrite = S_ISREG(stbuf.st_mode) ? tp : tbufsiz;
+               if (sys_write(f, tarbuf, towrite) != towrite) {
+                       DEBUG(0,("dotareof: sys_write fail\n"));
+               }
+       }
 }
 
 /****************************************************************************
@@ -433,20 +438,20 @@ static void fixtarname(char *tptr, const char *fp, size_t l)
 Convert from decimal to octal string
 ****************************************************************************/
 
-static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
+static void oct_it (uint64_t value, int ndgs, char *p)
 {
        /* Converts long to octal string, pads with leading zeros */
 
        /* skip final null, but do final space */
        --ndgs;
        p[--ndgs] = ' ';
+
        /* Loop does at least one digit */
        do {
                p[--ndgs] = '0' + (char) (value & 7);
                value >>= 3;
        } while (ndgs > 0 && value != 0);
+
        /* Do leading zeros */
        while (ndgs > 0)
                p[--ndgs] = '0';
@@ -472,8 +477,8 @@ static long unoct(char *p, int ndgs)
 }
 
 /****************************************************************************
-Compare two strings in a slash insensitive way, allowing s1 to match s2 
-if s1 is an "initial" string (up to directory marker).  Thus, if s2 is 
+Compare two strings in a slash insensitive way, allowing s1 to match s2
+if s1 is an "initial" string (up to directory marker).  Thus, if s2 is
 a file in any subdirectory of s1, declare a match.
 ***************************************************************************/
 
@@ -481,7 +486,7 @@ static int strslashcmp(char *s1, char *s2)
 {
        char *s1_0=s1;
 
-       while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) ||
+       while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) ||
                                (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
                s1++; s2++;
        }
@@ -507,13 +512,15 @@ static int strslashcmp(char *s1, char *s2)
 Ensure a remote path exists (make if necessary)
 ***************************************************************************/
 
-static BOOL ensurepath(char *fname)
+static bool ensurepath(const char *fname)
 {
        /* *must* be called with buffer ready malloc'ed */
        /* ensures path exists */
 
        char *partpath, *ffname;
-       char *p=fname, *basehack;
+       const char *p=fname;
+       char *basehack;
+       char *saveptr;
 
        DEBUG(5, ( "Ensurepath called with: %s\n", fname));
 
@@ -522,29 +529,36 @@ static BOOL ensurepath(char *fname)
 
        if ((partpath == NULL) || (ffname == NULL)){
                DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
+               SAFE_FREE(partpath);
+               SAFE_FREE(ffname);
                return(False);
        }
 
        *partpath = 0;
 
-       /* fname copied to ffname so can strtok */
+       /* fname copied to ffname so can strtok_r */
 
        safe_strcpy(ffname, fname, strlen(fname));
 
        /* do a `basename' on ffname, so don't try and make file name directory */
-       if ((basehack=strrchr_m(ffname, '\\')) == NULL)
+       if ((basehack=strrchr_m(ffname, '\\')) == NULL) {
+               SAFE_FREE(partpath);
+               SAFE_FREE(ffname);
                return True;
-       else
+       } else {
                *basehack='\0';
+       }
 
-       p=strtok(ffname, "\\");
+       p=strtok_r(ffname, "\\", &saveptr);
 
        while (p) {
                safe_strcat(partpath, p, strlen(fname) + 1);
 
                if (!cli_chkpath(cli, partpath)) {
                        if (!cli_mkdir(cli, partpath)) {
-                               DEBUG(0, ("Error mkdirhiering\n"));
+                               SAFE_FREE(partpath);
+                               SAFE_FREE(ffname);
+                               DEBUG(0, ("Error mkdir %s\n", cli_errstr(cli)));
                                return False;
                        } else {
                                DEBUG(3, ("mkdirhiering %s\n", partpath));
@@ -552,25 +566,27 @@ static BOOL ensurepath(char *fname)
                }
 
                safe_strcat(partpath, "\\", strlen(fname) + 1);
-               p = strtok(NULL,"/\\");
+               p = strtok_r(NULL, "/\\", &saveptr);
        }
 
+       SAFE_FREE(partpath);
+       SAFE_FREE(ffname);
        return True;
 }
 
-static int padit(char *buf, int bufsize, int padsize)
+static int padit(char *buf, uint64_t bufsize, uint64_t padsize)
 {
        int berr= 0;
        int bytestowrite;
-  
-       DEBUG(5, ("Padding with %d zeros\n", padsize));
-       memset(buf, 0, bufsize);
+
+       DEBUG(5, ("Padding with %0.f zeros\n", (double)padsize));
+       memset(buf, 0, (size_t)bufsize);
        while( !berr && padsize > 0 ) {
-               bytestowrite= MIN(bufsize, padsize);
+               bytestowrite= (int)MIN(bufsize, padsize);
                berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
                padsize -= bytestowrite;
        }
-  
+
        return berr;
 }
 
@@ -595,77 +611,70 @@ static void do_setrattr(char *name, uint16 attr, int set)
 append one remote file to the tar file
 ***************************************************************************/
 
-static void do_atar(char *rname,char *lname,file_info *finfo1)
+static void do_atar(const char *rname_in,char *lname,file_info *finfo1)
 {
-       int fnum;
-       SMB_BIG_UINT nread=0;
+       int fnum = -1;
+       uint64_t nread=0;
        char ftype;
        file_info2 finfo;
-       BOOL close_done = False;
-       BOOL shallitime=True;
-       char data[65520];
+       bool shallitime=True;
+       char *data = NULL;
        int read_size = 65520;
        int datalen=0;
+       char *rname = NULL;
+       TALLOC_CTX *ctx = talloc_stackframe();
 
        struct timeval tp_start;
 
        GetTimeOfDay(&tp_start);
 
+       data = SMB_MALLOC_ARRAY(char, read_size);
+       if (!data) {
+               DEBUG(0,("do_atar: out of memory.\n"));
+               goto cleanup;
+       }
+
        ftype = '0'; /* An ordinary file ... */
 
-       if (finfo1) {
-               finfo.size  = finfo1 -> size;
-               finfo.mode  = finfo1 -> mode;
-               finfo.uid   = finfo1 -> uid;
-               finfo.gid   = finfo1 -> gid;
-               finfo.mtime = finfo1 -> mtime;
-               finfo.atime = finfo1 -> atime;
-               finfo.ctime = finfo1 -> ctime;
-               finfo.name  = finfo1 -> name;
-       } else {
-               finfo.size  = def_finfo.size;
-               finfo.mode  = def_finfo.mode;
-               finfo.uid   = def_finfo.uid;
-               finfo.gid   = def_finfo.gid;
-               finfo.mtime = def_finfo.mtime;
-               finfo.atime = def_finfo.atime;
-               finfo.ctime = def_finfo.ctime;
-               finfo.name  = def_finfo.name;
-       }
+       ZERO_STRUCT(finfo);
+
+       finfo.size  = finfo1 -> size;
+       finfo.mode  = finfo1 -> mode;
+       finfo.uid   = finfo1 -> uid;
+       finfo.gid   = finfo1 -> gid;
+       finfo.mtime_ts = finfo1 -> mtime_ts;
+       finfo.atime_ts = finfo1 -> atime_ts;
+       finfo.ctime_ts = finfo1 -> ctime_ts;
 
        if (dry_run) {
-               DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name,
+               DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo1->name,
                                (double)finfo.size));
                shallitime=0;
                ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
                ntarf++;
-               return;
+               goto cleanup;
        }
 
-       fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
+       rname = clean_name(ctx, rname_in);
+       if (!rname) {
+               goto cleanup;
+       }
 
-       dos_clean_name(rname);
+       fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
 
        if (fnum == -1) {
                DEBUG(0,("%s opening remote file %s (%s)\n",
-                               cli_errstr(cli),rname, cur_dir));
-               return;
+                               cli_errstr(cli),rname, client_get_cur_dir()));
+               goto cleanup;
        }
 
        finfo.name = string_create_s(strlen(rname));
        if (finfo.name == NULL) {
                DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
-               return;
+               goto cleanup;
        }
 
        safe_strcpy(finfo.name,rname, strlen(rname));
-       if (!finfo1) {
-               if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
-                       DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
-                       return;
-               }
-               finfo.ctime = finfo.mtime;
-       }
 
        DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
 
@@ -679,25 +688,32 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
                shallitime=0;
        } else {
+               bool wrote_tar_header = False;
+
                DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
                        finfo.name, (double)finfo.size, lname));
-      
-               /* write a tar header, don't bother with mode - just set to 100644 */
-               writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
 
-               while (nread < finfo.size && !close_done) {
-             
+               do {
+
                        DEBUG(3,("nread=%.0f\n",(double)nread));
-             
+
                        datalen = cli_read(cli, fnum, data, nread, read_size);
-             
+
                        if (datalen == -1) {
                                DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
                                break;
                        }
-             
+
                        nread += datalen;
 
+                       /* Only if the first read succeeds, write out the tar header. */
+                       if (!wrote_tar_header) {
+                               /* write a tar header, don't bother with mode - just set to 100644 */
+                               writetarheader(tarhandle, rname, finfo.size,
+                                       finfo.mtime_ts.tv_sec, "100644 \0", ftype);
+                               wrote_tar_header = True;
+                       }
+
                        /* if file size has increased since we made file size query, truncate
                                read so tar header for this file will be correct.
                        */
@@ -715,32 +731,38 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                                DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
                                break;
                        }
-             
-                       if (datalen == 0) {
+
+                       if ( (datalen == 0) && (finfo.size != 0) ) {
                                DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
                                break;
                        }
 
                        datalen=0;
-               }
+               } while ( nread < finfo.size );
+
+               if (wrote_tar_header) {
+                       /* pad tar file with zero's if we couldn't get entire file */
+                       if (nread < finfo.size) {
+                               DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
+                                                       (double)finfo.size, (int)nread));
+                               if (padit(data, (uint64_t)sizeof(data), finfo.size - nread))
+                                       DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+                       }
 
-               /* pad tar file with zero's if we couldn't get entire file */
-               if (nread < finfo.size) {
-                       DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
-                                               (double)finfo.size, (int)nread));
-                       if (padit(data, sizeof(data), finfo.size - nread))
-                               DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
-               }
+                       /* round tar file to nearest block */
+                       if (finfo.size % TBLOCK)
+                               dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
 
-               /* round tar file to nearest block */
-               if (finfo.size % TBLOCK)
-                       dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
-      
-               ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
-               ntarf++;
+                       ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+                       ntarf++;
+               } else {
+                       DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name));
+                       shallitime=0;
+               }
        }
-  
+
        cli_close(cli, fnum);
+       fnum = -1;
 
        if (shallitime) {
                struct timeval tp_end;
@@ -749,7 +771,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                /* if shallitime is true then we didn't skip */
                if (tar_reset && !dry_run)
                        (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
-      
+
                GetTimeOfDay(&tp_end);
                this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000;
                get_total_time_ms += this_time;
@@ -766,72 +788,110 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                                finfo.size / MAX(0.001, (1.024*this_time)),
                                get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
        }
+
+  cleanup:
+
+       if (fnum != -1) {
+               cli_close(cli, fnum);
+               fnum = -1;
+       }
+       TALLOC_FREE(ctx);
+       SAFE_FREE(data);
 }
 
 /****************************************************************************
 Append single file to tar file (or not)
 ***************************************************************************/
 
-static void do_tar(file_info *finfo)
+static void do_tar(file_info *finfo, const char *dir)
 {
-       pstring rname;
+       TALLOC_CTX *ctx = talloc_stackframe();
 
        if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
                return;
 
        /* Is it on the exclude list ? */
        if (!tar_excl && clipn) {
-               pstring exclaim;
+               char *exclaim;
 
-               DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
+               DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(client_get_cur_dir())));
 
-               pstrcpy(exclaim, cur_dir);
-               *(exclaim+strlen(exclaim)-1)='\0';
-
-               pstrcat(exclaim, "\\");
-               pstrcat(exclaim, finfo->name);
+               exclaim = talloc_asprintf(ctx,
+                               "%s\\%s",
+                               client_get_cur_dir(),
+                               finfo->name);
+               if (!exclaim) {
+                       return;
+               }
 
                DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
 
                if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
                                (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
                        DEBUG(3,("Skipping file %s\n", exclaim));
+                       TALLOC_FREE(exclaim);
                        return;
                }
+               TALLOC_FREE(exclaim);
        }
 
        if (finfo->mode & aDIR) {
-               pstring saved_curdir;
-               pstring mtar_mask;
+               char *saved_curdir = NULL;
+               char *new_cd = NULL;
+               char *mtar_mask = NULL;
 
-               pstrcpy(saved_curdir, cur_dir);
+               saved_curdir = talloc_strdup(ctx, client_get_cur_dir());
+               if (!saved_curdir) {
+                       return;
+               }
 
-               DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \
+               DEBUG(5, ("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));
-
-               pstrcat(cur_dir,finfo->name);
-               pstrcat(cur_dir,"\\");
+                       (int)strlen(saved_curdir),
+                       (int)strlen(finfo->name), finfo->name, saved_curdir));
+
+               new_cd = talloc_asprintf(ctx,
+                               "%s%s\\",
+                               client_get_cur_dir(),
+                               finfo->name);
+               if (!new_cd) {
+                       return;
+               }
+               client_set_cur_dir(new_cd);
 
-               DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
+               DEBUG(5, ("Writing a dir, Name = %s\n", client_get_cur_dir()));
 
-               /* write a tar directory, don't bother with mode - just set it to
-                       * 40755 */
-               writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
+               /* write a tar directory, don't bother with mode - just
+                * set it to 40755 */
+               writetarheader(tarhandle, client_get_cur_dir(), 0,
+                               finfo->mtime_ts.tv_sec, "040755 \0", '5');
                if (tar_noisy) {
-                       DEBUG(0,("                directory %s\n", cur_dir));
+                       DEBUG(0,("                directory %s\n",
+                               client_get_cur_dir()));
                }
                ntarf++;  /* Make sure we have a file on there */
-               pstrcpy(mtar_mask,cur_dir);
-               pstrcat(mtar_mask,"*");
+               mtar_mask = talloc_asprintf(ctx,
+                               "%s*",
+                               client_get_cur_dir());
+               if (!mtar_mask) {
+                       return;
+               }
                DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
                do_list(mtar_mask, attribute, do_tar, False, True);
-               pstrcpy(cur_dir,saved_curdir);
+               client_set_cur_dir(saved_curdir);
+               TALLOC_FREE(saved_curdir);
+               TALLOC_FREE(new_cd);
+               TALLOC_FREE(mtar_mask);
        } else {
-               pstrcpy(rname,cur_dir);
-               pstrcat(rname,finfo->name);
+               char *rname = talloc_asprintf(ctx,
+                                       "%s%s",
+                                       client_get_cur_dir(),
+                                       finfo->name);
+               if (!rname) {
+                       return;
+               }
                do_atar(rname,finfo->name,finfo);
+               TALLOC_FREE(rname);
        }
 }
 
@@ -839,7 +899,7 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
 Convert from UNIX to DOS file names
 ***************************************************************************/
 
-static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
+static void unfixtarname(char *tptr, char *fp, int l, bool first)
 {
        /* remove '.' from start of file name, convert from unix /'s to
         * dos \'s in path. Kill any absolute path names. But only if first!
@@ -939,11 +999,11 @@ static int skip_file(int skipsize)
 static int get_file(file_info2 finfo)
 {
        int fnum = -1, pos = 0, dsize = 0, bpos = 0;
-       SMB_BIG_UINT rsize = 0;
+       uint64_t rsize = 0;
 
        DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
 
-       if (ensurepath(finfo.name) && 
+       if (ensurepath(finfo.name) &&
                        (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
                DEBUG(0, ("abandoning restore\n"));
                return(False);
@@ -1016,7 +1076,7 @@ static int get_file(file_info2 finfo)
        /* Now we update the creation date ... */
        DEBUG(5, ("Updating creation date on %s\n", finfo.name));
 
-       if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
+       if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec)) {
                if (tar_real_noisy) {
                        DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
                        /*return(False); */ /* Ignore, as Win95 does not allow changes */
@@ -1029,7 +1089,7 @@ static int get_file(file_info2 finfo)
 }
 
 /* Create a directory.  We just ensure that the path exists and return as there
-   is no file associated with a directory 
+   is no file associated with a directory
 */
 static int get_dir(file_info2 finfo)
 {
@@ -1051,10 +1111,10 @@ static char *get_longfilename(file_info2 finfo)
 {
        /* finfo.size here is the length of the filename as written by the "/./@LongLink" name
         * header call. */
-       int namesize = finfo.size + strlen(cur_dir) + 2;
-       char *longname = SMB_MALLOC(namesize);
+       int namesize = finfo.size + strlen(client_get_cur_dir()) + 2;
+       char *longname = (char *)SMB_MALLOC(namesize);
        int offset = 0, left = finfo.size;
-       BOOL first = True;
+       bool first = True;
 
        DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
        DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
@@ -1066,9 +1126,9 @@ static char *get_longfilename(file_info2 finfo)
 
        /* First, add cur_dir to the long file name */
 
-       if (strlen(cur_dir) > 0) {
-               strncpy(longname, cur_dir, namesize);
-               offset = strlen(cur_dir);
+       if (strlen(client_get_cur_dir()) > 0) {
+               strncpy(longname, client_get_cur_dir(), namesize);
+               offset = strlen(client_get_cur_dir());
        }
 
        /* Loop through the blocks picking up the name */
@@ -1076,6 +1136,7 @@ static char *get_longfilename(file_info2 finfo)
        while (left > 0) {
                if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
                        DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+                       SAFE_FREE(longname);
                        return(NULL);
                }
 
@@ -1096,6 +1157,8 @@ static void do_tarput(void)
        char *longfilename = NULL, linkflag;
        int skip = False;
 
+       ZERO_STRUCT(finfo);
+
        GetTimeOfDay(&tp_start);
        DEBUG(5, ("RJS do_tarput called ...\n"));
 
@@ -1106,12 +1169,14 @@ static void do_tarput(void)
                /* Get us to the next block, or the first block first time around */
                if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
                        DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+                       SAFE_FREE(longfilename);
                        return;
                }
 
                DEBUG(5, ("Reading the next header ...\n"));
 
-               switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
+               switch (readtarheader((union hblock *) buffer_p,
+                                       &finfo, client_get_cur_dir())) {
                        case -2:    /* Hmm, not good, but not fatal */
                                DEBUG(0, ("Skipping %s...\n", finfo.name));
                                if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) {
@@ -1155,7 +1220,7 @@ static void do_tarput(void)
                linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
                switch (linkflag) {
                        case '0':  /* Should use symbolic names--FIXME */
-                               /* 
+                               /*
                                 * Skip to the next block first, so we can get the file, FIXME, should
                                 * be in get_file ...
                                 * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
@@ -1177,6 +1242,7 @@ static void do_tarput(void)
                                }
                                break;
                        case 'L':
+                               SAFE_FREE(longfilename);
                                longfilename = get_longfilename(finfo);
                                if (!longfilename) {
                                        DEBUG(0, ("abandoning restore\n"));
@@ -1202,10 +1268,11 @@ Blocksize command
 
 int cmd_block(void)
 {
-       fstring buf;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *buf;
        int block;
 
-       if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+       if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                DEBUG(0, ("blocksize <n>\n"));
                return 1;
        }
@@ -1218,7 +1285,6 @@ int cmd_block(void)
 
        blocksize=block;
        DEBUG(2,("blocksize is now %d\n", blocksize));
-
        return 0;
 }
 
@@ -1228,9 +1294,10 @@ command to set incremental / reset mode
 
 int cmd_tarmode(void)
 {
-       fstring buf;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *buf;
 
-       while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+       while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                if (strequal(buf, "full"))
                        tar_inc=False;
                else if (strequal(buf, "inc"))
@@ -1253,6 +1320,7 @@ int cmd_tarmode(void)
                        tar_noisy=False;
                else
                        DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
+               TALLOC_FREE(buf);
        }
 
        DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
@@ -1270,23 +1338,29 @@ Feeble attrib command
 
 int cmd_setmode(void)
 {
+       TALLOC_CTX *ctx = talloc_tos();
        char *q;
-       fstring buf;
-       pstring fname;
+       char *buf;
+       char *fname = NULL;
        uint16 attra[2];
        int direct=1;
 
        attra[0] = attra[1] = 0;
 
-       if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+       if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
                return 1;
        }
 
-       pstrcpy(fname, cur_dir);
-       pstrcat(fname, buf);
+       fname = talloc_asprintf(ctx,
+                               "%s%s",
+                               client_get_cur_dir(),
+                               buf);
+       if (!fname) {
+               return 1;
+       }
 
-       while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+       while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                q=buf;
 
                while(*q) {
@@ -1327,25 +1401,77 @@ int cmd_setmode(void)
        return 0;
 }
 
+/**
+ Convert list of tokens to array; dependent on above routine.
+ Uses the global cmd_ptr from above - bit of a hack.
+**/
+
+static char **toktocliplist(int *ctok, const char *sep)
+{
+       char *s=(char *)cmd_ptr;
+       int ictok=0;
+       char **ret, **iret;
+
+       if (!sep)
+               sep = " \t\n\r";
+
+       while(*s && strchr_m(sep,*s))
+               s++;
+
+       /* nothing left? */
+       if (!*s)
+               return(NULL);
+
+       do {
+               ictok++;
+               while(*s && (!strchr_m(sep,*s)))
+                       s++;
+               while(*s && strchr_m(sep,*s))
+                       *s++=0;
+       } while(*s);
+
+       *ctok=ictok;
+       s=(char *)cmd_ptr;
+
+       if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
+               return NULL;
+
+       while(ictok--) {
+               *iret++=s;
+               if (ictok > 0) {
+                       while(*s++)
+                               ;
+                       while(!*s)
+                               s++;
+               }
+       }
+
+       ret[*ctok] = NULL;
+       return ret;
+}
+
 /****************************************************************************
 Principal command for creating / extracting
 ***************************************************************************/
 
 int cmd_tar(void)
 {
-       fstring buf;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *buf;
        char **argl = NULL;
        int argcl = 0;
        int ret;
 
-       if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+       if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
                DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
                return 1;
        }
 
        argl=toktocliplist(&argcl, NULL);
-       if (!tar_parseargs(argcl, argl, buf, 0))
+       if (!tar_parseargs(argcl, argl, buf, 0)) {
+               SAFE_FREE(argl);
                return 1;
+       }
 
        ret = process_tar();
        SAFE_FREE(argl);
@@ -1358,6 +1484,7 @@ Command line (option) version
 
 int process_tar(void)
 {
+       TALLOC_CTX *ctx = talloc_tos();
        int rc = 0;
        initarbuf();
        switch(tar_type) {
@@ -1375,7 +1502,7 @@ int process_tar(void)
                case 'c':
                        if (clipn && tar_excl) {
                                int i;
-                               pstring tarmac;
+                               char *tarmac = NULL;
 
                                for (i=0; i<clipn; i++) {
                                        DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
@@ -1383,44 +1510,72 @@ int process_tar(void)
                                        if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
                                                *(cliplist[i]+strlen(cliplist[i])-1)='\0';
                                        }
-       
+
                                        if (strrchr_m(cliplist[i], '\\')) {
-                                               pstring saved_dir;
-         
-                                               pstrcpy(saved_dir, cur_dir);
-         
+                                               char *p;
+                                               char *saved_dir = talloc_strdup(ctx,
+                                                                       client_get_cur_dir());
+                                               if (!saved_dir) {
+                                                       return 1;
+                                               }
+
                                                if (*cliplist[i]=='\\') {
-                                                       pstrcpy(tarmac, cliplist[i]);
+                                                       tarmac = talloc_strdup(ctx,
+                                                                       cliplist[i]);
                                                } else {
-                                                       pstrcpy(tarmac, cur_dir);
-                                                       pstrcat(tarmac, cliplist[i]);
+                                                       tarmac = talloc_asprintf(ctx,
+                                                                       "%s%s",
+                                                                       client_get_cur_dir(),
+                                                                       cliplist[i]);
+                                               }
+                                               if (!tarmac) {
+                                                       return 1;
                                                }
-                                               pstrcpy(cur_dir, tarmac);
-                                               *(strrchr_m(cur_dir, '\\')+1)='\0';
+                                               p = strrchr_m(tarmac, '\\');
+                                               if (!p) {
+                                                       return 1;
+                                               }
+                                               p[1] = '\0';
+                                               client_set_cur_dir(tarmac);
 
                                                DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
                                                do_list(tarmac,attribute,do_tar, False, True);
-                                               pstrcpy(cur_dir,saved_dir);
+
+                                               client_set_cur_dir(saved_dir);
+
+                                               TALLOC_FREE(saved_dir);
+                                               TALLOC_FREE(tarmac);
                                        } else {
-                                               pstrcpy(tarmac, cur_dir);
-                                               pstrcat(tarmac, cliplist[i]);
+                                               tarmac = talloc_asprintf(ctx,
+                                                               "%s%s",
+                                                               client_get_cur_dir(),
+                                                               cliplist[i]);
+                                               if (!tarmac) {
+                                                       return 1;
+                                               }
                                                DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
                                                do_list(tarmac,attribute,do_tar, False, True);
+                                               TALLOC_FREE(tarmac);
                                        }
                                }
                        } else {
-                               pstring mask;
-                               pstrcpy(mask,cur_dir);
+                               char *mask = talloc_asprintf(ctx,
+                                                       "%s\\*",
+                                                       client_get_cur_dir());
+                               if (!mask) {
+                                       return 1;
+                               }
                                DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
-                               pstrcat(mask,"\\*");
                                do_list(mask,attribute,do_tar,False, True);
+                               TALLOC_FREE(mask);
                        }
-    
-                       if (ntarf)
+
+                       if (ntarf) {
                                dotareof(tarhandle);
+                       }
                        close(tarhandle);
                        SAFE_FREE(tarbuf);
-    
+
                        DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
                        DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
                        break;
@@ -1495,31 +1650,28 @@ static int read_inclusion_file(char *filename)
        while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
                if (inclusion_buffer == NULL) {
                        inclusion_buffer_size = 1024;
-                       if ((inclusion_buffer = SMB_MALLOC(inclusion_buffer_size)) == NULL) {
+                       if ((inclusion_buffer = (char *)SMB_MALLOC(inclusion_buffer_size)) == NULL) {
                                DEBUG(0,("failure allocating buffer to read inclusion file\n"));
                                error = 1;
                                break;
                        }
                }
-    
+
                if (buf[strlen(buf)-1] == '\n') {
                        buf[strlen(buf)-1] = '\0';
                }
-    
+
                if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
-                       char *ib;
                        inclusion_buffer_size *= 2;
-                       ib = SMB_REALLOC(inclusion_buffer,inclusion_buffer_size);
-                       if (! ib) {
+                       inclusion_buffer = (char *)SMB_REALLOC(inclusion_buffer,inclusion_buffer_size);
+                       if (!inclusion_buffer) {
                                DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
                                                inclusion_buffer_size));
                                error = 1;
                                break;
-                       } else {
-                               inclusion_buffer = ib;
                        }
                }
-    
+
                safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
                inclusion_buffer_sofar += strlen(buf) + 1;
                clipn++;
@@ -1570,7 +1722,7 @@ static int read_inclusion_file(char *filename)
                }
                return 0;
        }
-  
+
        /* cliplist and its elements are freed at the end of process_tar. */
        return 1;
 }
@@ -1621,12 +1773,11 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                                        return 0;
                                } else {
                                        SMB_STRUCT_STAT stbuf;
-                                       extern time_t newer_than;
-       
+
                                        if (sys_stat(argv[Optind], &stbuf) == 0) {
                                                newer_than = stbuf.st_mtime;
                                                DEBUG(1,("Getting files newer than %s",
-                                                       asctime(LocalTime(&newer_than))));
+                                                       time_to_asc(newer_than)));
                                                newOptind++;
                                                Optind++;
                                        } else {
@@ -1696,8 +1847,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                        return 0;
                }
                newOptind++;
-               Optind++;
-               if (! read_inclusion_file(argv[Optind])) {
+               /* Optind points at the tar output file, Optind+1 at the inclusion file. */
+               if (! read_inclusion_file(argv[Optind+1])) {
                        return 0;
                }
        } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
@@ -1720,6 +1871,7 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
 
                        if ((tmpstr = (char *)SMB_MALLOC(strlen(cliplist[clipcount])+1)) == NULL) {
                                DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));
+                               SAFE_FREE(tmplist);
                                return 0;
                        }
 
@@ -1736,7 +1888,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                newOptind += clipn;
        }
 
-       if (Optind+1<argc && tar_re_search) {  /* Doing regular expression seaches */
+       if (Optind+1<argc && tar_re_search && tar_clipfl != 'F') {
+               /* Doing regular expression seaches not from an inclusion file. */
                clipn=argc-Optind-1;
                cliplist=argv+Optind+1;
                newOptind += clipn;
@@ -1761,11 +1914,7 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                }
 
        } else {
-               if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) {
-                       if (!dry_run) {
-                               DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
-                               dry_run = True;
-                       }
+               if (tar_type=='c' && dry_run) {
                        tarhandle=-1;
                } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
                                        || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {