r16230: Fix Klocwork #861 and others. localtime and asctime
[kai/samba.git] / source3 / client / clitar.c
index f38d6fe91a5a728f2e28c99c6a9c8e799597025b..14c28acfc5a712302c8fe8f26c940bee9c9bd958 100644 (file)
 
 #include "includes.h"
 #include "clitar.h"
-#include "../client/client_proto.h"
+#include "client/client_proto.h"
 
 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;
@@ -63,6 +63,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
@@ -87,9 +88,6 @@ static BOOL tar_reset=False;
 static BOOL tar_excl=True;
 /* use regular expressions for search on file names */
 static BOOL tar_re_search=False;
-#ifdef HAVE_REGEX_H
-regex_t *preg;
-#endif
 /* Do not dump anything, just calculate sizes */
 static BOOL dry_run=False;
 /* Dump files with System attribute */
@@ -146,7 +144,7 @@ static char *string_create_s(int size)
 {
        char *tmp;
 
-       tmp = (char *)malloc(size+1);
+       tmp = (char *)SMB_MALLOC(size+1);
 
        if (tmp == NULL) {
                DEBUG(0, ("Out of memory in string_create_s\n"));
@@ -177,7 +175,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t m
        if (l+2 >= NAMSIZ) {
                /* write a GNU tar style long header */
                char *b;
-               b = (char *)malloc(l+TBLOCK+100);
+               b = (char *)SMB_MALLOC(l+TBLOCK+100);
                if (!b) {
                        DEBUG(0,("out of memory\n"));
                        exit(1);
@@ -385,7 +383,7 @@ static void initarbuf(void)
 {
        /* initialize tar buffer */
        tbufsiz=blocksize*TBLOCK;
-       tarbuf=malloc(tbufsiz);      /* FIXME: We might not get the buffer */
+       tarbuf=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;
@@ -484,7 +482,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++;
        }
@@ -525,6 +523,8 @@ 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);
        }
 
@@ -561,15 +561,15 @@ static BOOL ensurepath(char *fname)
        return True;
 }
 
-static int padit(char *buf, int bufsize, int padsize)
+static int padit(char *buf, SMB_BIG_UINT bufsize, SMB_BIG_UINT 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;
        }
@@ -682,12 +682,11 @@ 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) {
              
                        DEBUG(3,("nread=%.0f\n",(double)nread));
@@ -701,6 +700,13 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
              
                        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, "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.
                        */
@@ -727,20 +733,25 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
                        datalen=0;
                }
 
-               /* 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)));
-               }
+               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, (SMB_BIG_UINT)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);
@@ -797,11 +808,7 @@ static void do_tar(file_info *finfo)
                DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
 
                if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
-#ifdef HAVE_REGEX_H
-                               (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) {
-#else
-                               (tar_re_search && mask_match(exclaim, cliplist[0], True))) {
-#endif
+                               (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
                        DEBUG(3,("Skipping file %s\n", exclaim));
                        return;
                }
@@ -1059,7 +1066,7 @@ 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 = malloc(namesize);
+       char *longname = SMB_MALLOC(namesize);
        int offset = 0, left = finfo.size;
        BOOL first = True;
 
@@ -1083,6 +1090,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);
                }
 
@@ -1103,6 +1111,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"));
 
@@ -1113,6 +1123,7 @@ 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;
                }
 
@@ -1150,11 +1161,7 @@ static void do_tarput(void)
                /* Well, now we have a header, process the file ...            */
                /* Should we skip the file? We have the long name as well here */
                skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) ||
-#ifdef HAVE_REGEX_H
-                                       (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
-#else
-                                       (tar_re_search && mask_match(finfo.name, cliplist[0], True)));
-#endif
+                                       (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True)));
 
                DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
                if (skip) {
@@ -1188,6 +1195,7 @@ static void do_tarput(void)
                                }
                                break;
                        case 'L':
+                               SAFE_FREE(longfilename);
                                longfilename = get_longfilename(finfo);
                                if (!longfilename) {
                                        DEBUG(0, ("abandoning restore\n"));
@@ -1345,8 +1353,9 @@ Principal command for creating / extracting
 int cmd_tar(void)
 {
        fstring buf;
-       char **argl;
-       int argcl;
+       char **argl = NULL;
+       int argcl = 0;
+       int ret;
 
        if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
                DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
@@ -1357,9 +1366,9 @@ int cmd_tar(void)
        if (!tar_parseargs(argcl, argl, buf, 0))
                return 1;
 
-       process_tar();
+       ret = process_tar();
        SAFE_FREE(argl);
-       return 0;
+       return ret;
 }
 
 /****************************************************************************
@@ -1368,6 +1377,7 @@ Command line (option) version
 
 int process_tar(void)
 {
+       int rc = 0;
        initarbuf();
        switch(tar_type) {
                case 'x':
@@ -1445,7 +1455,7 @@ int process_tar(void)
                clipn = 0;
                must_free_cliplist = False;
        }
-       return(0);
+       return rc;
 }
 
 /****************************************************************************
@@ -1504,7 +1514,7 @@ 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 = malloc(inclusion_buffer_size)) == NULL) {
+                       if ((inclusion_buffer = SMB_MALLOC(inclusion_buffer_size)) == NULL) {
                                DEBUG(0,("failure allocating buffer to read inclusion file\n"));
                                error = 1;
                                break;
@@ -1516,16 +1526,13 @@ static int read_inclusion_file(char *filename)
                }
     
                if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
-                       char *ib;
                        inclusion_buffer_size *= 2;
-                       ib = Realloc(inclusion_buffer,inclusion_buffer_size);
-                       if (! ib) {
+                       inclusion_buffer = 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;
                        }
                }
     
@@ -1537,7 +1544,7 @@ static int read_inclusion_file(char *filename)
 
        if (! error) {
                /* Allocate an array of clipn + 1 char*'s for cliplist */
-               cliplist = malloc((clipn + 1) * sizeof(char *));
+               cliplist = SMB_MALLOC_ARRAY(char *, clipn + 1);
                if (cliplist == NULL) {
                        DEBUG(0,("failure allocating memory for cliplist\n"));
                        error = 1;
@@ -1548,7 +1555,7 @@ static int read_inclusion_file(char *filename)
                                /* set current item to NULL so array will be null-terminated even if
                                                * malloc fails below. */
                                cliplist[i] = NULL;
-                               if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) {
+                               if ((tmpstr = (char *)SMB_MALLOC(strlen(p)+1)) == NULL) {
                                        DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
                                        error = 1;
                                } else {
@@ -1630,12 +1637,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 {
@@ -1705,8 +1711,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 */
@@ -1718,7 +1724,7 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                clipn=argc-Optind-1;
                clipcount = clipn;
 
-               if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) {
+               if ((tmplist=SMB_MALLOC_ARRAY(char *,clipn)) == NULL) {
                        DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));
                        return 0;
                }
@@ -1727,8 +1733,9 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
 
                        DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
 
-                       if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) {
+                       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;
                        }
 
@@ -1745,26 +1752,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 */
-#ifdef HAVE_REGEX_H
-               int errcode;
-
-               if ((preg = (regex_t *)malloc(65536)) == NULL) {
-
-                       DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
-                       return;
-               }
-
-               if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) {
-                       char errstr[1024];
-                       size_t errlen;
-
-                       errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1);
-                       DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr));
-                       return;
-               }
-#endif
-
+       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;
@@ -1789,11 +1778,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)) {