X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=common-src%2Ffile.c;h=a03197e2793cae42613368103f79bf9485a98cfa;hb=refs%2Ftags%2Fupstream%2F2.5.1;hp=ce4d28bd6695362e4426fd9acc5e9c32663dbfd6;hpb=94c03cae686e4196a345d72452fda2a5203768ce;p=debian%2Famanda diff --git a/common-src/file.c b/common-src/file.c index ce4d28b..a03197e 100644 --- a/common-src/file.c +++ b/common-src/file.c @@ -23,7 +23,7 @@ * Author: AMANDA core development group. */ /* - * $Id: file.c,v 1.35 2006/03/09 16:51:41 martinea Exp $ + * $Id: file.c,v 1.40 2006/07/19 17:41:15 martinea Exp $ * * file and directory bashing routines */ @@ -31,7 +31,9 @@ #include "amanda.h" #include "util.h" -static int mk1dir P((const char *, int, uid_t, gid_t)); +void amanda_setup(int argc, char **argv, int setup_flags); +static int mk1dir(const char *, mode_t, uid_t, gid_t); +static void areads_getbuf(const char *s, int l, int fd); uid_t client_uid = (uid_t) -1; gid_t client_gid = (gid_t) -1; @@ -42,24 +44,25 @@ gid_t client_gid = (gid_t) -1; ** it will do nothing - only root is permitted to change the owner ** of a file. */ -static int mk1dir(dir, mode, uid, gid) -const char *dir; /* directory to create */ -int mode; /* mode for new directory */ -uid_t uid; /* uid for new directory */ -gid_t gid; /* gid for new directory */ +static int +mk1dir( + const char *dir, /* directory to create */ + mode_t mode, /* mode for new directory */ + uid_t uid, /* uid for new directory */ + gid_t gid) /* gid for new directory */ { int rc; /* return code */ - rc = 0; /* assume the best */ - - if(mkdir(dir, mode) == 0) { - chmod(dir, mode); /* mkdir() is affected by the umask */ - chown(dir, uid, gid); /* XXX - no-op on most systems? */ + if((rc = mkdir(dir, mode)) == 0) { + if ((rc = chmod(dir, mode)) == 0) { /* mkdir() affected by the umask */ + rc = chown(dir, uid, gid); + } } else { /* maybe someone beat us to it */ int serrno; serrno = errno; - if(access(dir, F_OK) != 0) rc = -1; + if(access(dir, F_OK) != 0) + rc = -1; errno = serrno; /* pass back the real error */ } @@ -73,19 +76,20 @@ gid_t gid; /* gid for new directory */ * the last element, but not the last element. So a (potential) file name * may be passed to mkpdir and all the parents of that file will be created. */ -int mkpdir(file, mode, uid, gid) -char *file; /* file to create parent directories for */ -int mode; /* mode for new directories */ -uid_t uid; /* uid for new directories */ -gid_t gid; /* gid for new directories */ +int +mkpdir( + char * file, /* file to create parent directories for */ + mode_t mode, /* mode for new directories */ + uid_t uid, /* uid for new directories */ + gid_t gid) /* gid for new directories */ { - char *dir = NULL, *p; + char *dir; + char *p; int rc; /* return code */ rc = 0; dir = stralloc(file); /* make a copy we can play with */ - p = strrchr(dir, '/'); if(p != dir && p != NULL) { /* got a '/' or a simple name */ *p = '\0'; @@ -107,12 +111,13 @@ gid_t gid; /* gid for new directories */ ** - stops deleting before topdir, ie: topdir will not be removed ** - if file is not under topdir this routine will not notice */ -int rmpdir(file, topdir) -char *file; /* directory hierarchy to remove */ -char *topdir; /* where to stop removing */ +int +rmpdir( + char * file, /* directory hierarchy to remove */ + char * topdir) /* where to stop removing */ { int rc; - char *p, *dir = NULL; + char *p, *dir; if(strcmp(file, topdir) == 0) return 0; /* all done */ @@ -138,10 +143,10 @@ char *topdir; /* where to stop removing */ dir = stralloc(file); p = strrchr(dir, '/'); - if(p == dir) rc = 0; /* no /'s */ - else { + if (p == NULL || p == dir) { + rc = 0; + } else { *p = '\0'; - rc = rmpdir(dir, topdir); } @@ -163,11 +168,14 @@ char *topdir; /* where to stop removing */ */ void -amanda_setup (argc, argv, setup_flags) - int argc; - char **argv; - int setup_flags; +amanda_setup ( + int argc, + char ** argv, + int setup_flags) { + (void)argc; /* Quiet unused parameter warning */ + (void)argv; /* Quiet unused parameter warning */ + (void)setup_flags; /* Quiet unused parameter warning */ } /* @@ -197,7 +205,7 @@ amanda_setup (argc, argv, setup_flags) */ void -safe_cd() +safe_cd(void) { int cd_ok = 0; struct stat sbuf; @@ -215,11 +223,11 @@ safe_cd() if (client_uid != (uid_t) -1) { #if defined(AMANDA_DBGDIR) d = stralloc2(AMANDA_DBGDIR, "/."); - (void) mkpdir(d, 02700, client_uid, client_gid); + (void) mkpdir(d, (mode_t)02700, client_uid, client_gid); amfree(d); #endif d = stralloc2(AMANDA_TMPDIR, "/."); - (void) mkpdir(d, 02700, client_uid, client_gid); + (void) mkpdir(d, (mode_t)02700, client_uid, client_gid); amfree(d); } @@ -241,7 +249,9 @@ safe_cd() if(cd_ok) { save_core(); /* save any old core file */ } else { - (void) chdir("/"); /* assume this works */ + if ((cd_ok = chdir("/")) == -1) { + (void)cd_ok; /* Quiet compiler warning if DEBUG disabled */ + } } } @@ -263,9 +273,9 @@ safe_cd() */ void -safe_fd(fd_start, fd_count) - int fd_start; - int fd_count; +safe_fd( + int fd_start, + int fd_count) { int fd; @@ -299,7 +309,6 @@ safe_fd(fd_start, fd_count) } } } - } /* @@ -324,7 +333,7 @@ safe_fd(fd_start, fd_count) */ void -save_core() +save_core(void) { struct stat sbuf; @@ -360,46 +369,32 @@ save_core() /* ** Sanitise a file name. ** -** Convert all funny characters to '_' so that we can use, +** Convert all '/' characters to '_' so that we can use, ** for example, disk names as part of file names. ** Notes: ** - there is a many-to-one mapping between input and output -** XXX - We only look for '/' and ' ' at the moment. May -** XXX - be we should also do all unprintables. +** - Only / and '\0' are disallowed in filenames by POSIX... */ -char *sanitise_filename(inp) -char *inp; +char * +sanitise_filename( + char * inp) { char *buf; - int buf_size; + size_t buf_size; char *s, *d; int ch; - buf_size = 2 * strlen(inp) + 1; /* worst case */ + buf_size = strlen(inp) + 1; /* worst case */ buf = alloc(buf_size); d = buf; s = inp; while((ch = *s++) != '\0') { - if(ch == '_') { - if(d >= buf + buf_size) { - amfree(buf); - return NULL; /* cannot happen */ - } - *d++ = '_'; /* convert _ to __ to try */ - /* and ensure unique output */ - } else if(ch == '/' || isspace(ch)) { + if(ch == '/') { ch = '_'; /* convert "bad" to "_" */ } - if(d >= buf + buf_size) { - amfree(buf); - return NULL; /* cannot happen */ - } - *d++ = ch; - } - if(d >= buf + buf_size) { - amfree(buf); - return NULL; /* cannot happen */ + *d++ = (char)ch; } + assert(d < buf + buf_size); *d = '\0'; return buf; @@ -409,84 +404,98 @@ char *inp; *===================================================================== * Get the next line of input from a stdio file. * - * char *agets (FILE *f) + * char *agets (FILE *stream) * - * entry: f = stdio stream to read - * exit: returns a pointer to an alloc'd string or NULL at EOF - * or error (errno will be zero on EOF). + * entry: stream - stream to read + * exit: returns a pointer to an alloc'd string or NULL + * at EOF or error. The functions ferror(stream) and + * feof(stream) should be checked by caller to determine + * stream status. * - * Notes: the newline, if read, is removed from the string + * Notes: the newline at the end of a line, if read, is removed from + * the string. Quoted newlines are left intact. * the caller is responsible for free'ing the string + * *===================================================================== */ +#define AGETS_LINE_INCR 128 + char * -debug_agets(s, l, file) - const char *s; - int l; - FILE *file; +debug_agets( + const char *sourcefile, + int lineno, + FILE * stream) { - char *line = NULL, *line_ptr; - size_t line_size, size_save; - int line_free, line_len; - char *cp; - char *f; - - malloc_enter(dbmalloc_caller_loc(s, l)); + int ch; + char *line = alloc(AGETS_LINE_INCR); + size_t line_size = 0; + size_t loffset = 0; + int inquote = 0; + int escape = 0; + + (void)sourcefile; /* Quiet unused parameter warning if not debugging */ + (void)lineno; /* Quiet unused parameter warning if not debugging */ + + while ((ch = fgetc(stream)) != EOF) { + if (ch == '\n') { + if (!inquote) { + if (escape) { + escape = 0; + loffset--; /* Consume escape in buffer */ + continue; + } + /* Reached end of line so exit without passing on LF */ + break; + } + } -#define AGETS_LINE_INCR 128 + if (ch == '\\') { + escape = 1; + } else { + if (ch == '"') { + if (!escape) + inquote = !inquote; + } + escape = 0; + } - line_size = AGETS_LINE_INCR; - line = debug_alloc (s, l, line_size); - line_free = line_size; - line_ptr = line; - line_len = 0; + if ((loffset + 1) >= line_size) { + char *tmpline; - while ((f = fgets(line_ptr, line_free, file)) != NULL) { - /* - * Note that we only have to search what we just read, not - * the whole buffer. - */ - if ((cp = strchr (line_ptr, '\n')) != NULL) { - line_len += cp - line_ptr; - *cp = '\0'; /* zap the newline */ - break; /* got to end of line */ - } - line_len += line_free - 1; /* bytes read minus '\0' */ - size_save = line_size; - if (line_size < 256 * AGETS_LINE_INCR) { - line_size *= 2; - } else { - line_size += 256 * AGETS_LINE_INCR; + /* + * Reallocate input line. + * alloc() never return NULL pointer. + */ + tmpline = alloc(line_size + AGETS_LINE_INCR); + memcpy(tmpline, line, line_size); + amfree(line); + line = tmpline; + line_size = line_size + AGETS_LINE_INCR; } - cp = debug_alloc (s, l, line_size); /* get more space */ - memcpy (cp, line, size_save); /* copy old to new */ - free (line); /* and release the old */ - line = cp; - line_ptr = line + size_save - 1; /* start at the null byte */ - line_free = line_size - line_len; /* and we get to use it */ + line[loffset++] = (char)ch; } + + if ((ch == EOF) && (loffset == 0)) { + amfree(line); /* amfree zeros line... */ + } else { + line[loffset] = '\0'; + } + /* - * Return what we got even if there was not a newline. Only - * report done (NULL) when no data was processed. + * Return what we got even if there was not a newline. + * Only report done (NULL) when no data was processed. */ - if (f == NULL && line_len == 0) { - amfree (line); - line = NULL; /* redundant, but clear */ - if(!ferror(file)) { - errno = 0; /* flag EOF vs error */ - } - } - malloc_leave(dbmalloc_caller_loc(s, l)); return line; } + /* *===================================================================== * Find/create a buffer for a particular file descriptor for use with * areads(). * - * void areads_getbuf (const char *file, int line, int fd) + * void areads_getbuf (const char *file, size_t line, int fd) * * entry: file, line = caller source location * fd = file descriptor to look up @@ -497,27 +506,27 @@ debug_agets(s, l, file) static struct areads_buffer { char *buffer; char *endptr; - ssize_t bufsize; + size_t bufsize; } *areads_buffer = NULL; static int areads_bufcount = 0; -static ssize_t areads_bufsize = BUFSIZ; /* for the test program */ +static size_t areads_bufsize = BUFSIZ; /* for the test program */ static void -areads_getbuf(s, l, fd) - const char *s; - int l; - int fd; +areads_getbuf( + const char *s, + int l, + int fd) { struct areads_buffer *new; - ssize_t size; + size_t size; assert(fd >= 0); if(fd >= areads_bufcount) { - size = (fd + 1) * sizeof(*areads_buffer); + size = (size_t)(fd + 1) * SIZEOF(*areads_buffer); new = (struct areads_buffer *) debug_alloc(s, l, size); memset((char *)new, 0, size); if(areads_buffer) { - size = areads_bufcount * sizeof(*areads_buffer); + size = areads_bufcount * SIZEOF(*areads_buffer); memcpy(new, areads_buffer, size); } amfree(areads_buffer); @@ -545,8 +554,8 @@ areads_getbuf(s, l, fd) */ ssize_t -areads_dataready(fd) - int fd; +areads_dataready( + int fd) { ssize_t r = 0; @@ -568,8 +577,8 @@ areads_dataready(fd) */ void -areads_relbuf(fd) - int fd; +areads_relbuf( + int fd) { if(fd >= 0 && fd < areads_bufcount) { amfree(areads_buffer[fd].buffer); @@ -594,18 +603,18 @@ areads_relbuf(fd) */ char * -debug_areads (s, l, fd) - const char *s; - int l; - int fd; +debug_areads ( + const char *s, + int l, + int fd) { char *nl; char *line; char *buffer; char *endptr; char *newbuf; - ssize_t buflen; - ssize_t size; + size_t buflen; + size_t size; ssize_t r; malloc_enter(dbmalloc_caller_loc(s, l)); @@ -617,7 +626,7 @@ debug_areads (s, l, fd) areads_getbuf(s, l, fd); buffer = areads_buffer[fd].buffer; endptr = areads_buffer[fd].endptr; - buflen = areads_buffer[fd].bufsize - (endptr - buffer); + buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer); while((nl = strchr(buffer, '\n')) == NULL) { /* * No newline yet, so get more data. @@ -631,13 +640,12 @@ debug_areads (s, l, fd) newbuf = debug_alloc(s, l, size + 1); memcpy (newbuf, buffer, areads_buffer[fd].bufsize + 1); amfree(areads_buffer[fd].buffer); - buffer = NULL; areads_buffer[fd].buffer = newbuf; areads_buffer[fd].endptr = newbuf + areads_buffer[fd].bufsize; areads_buffer[fd].bufsize = size; buffer = areads_buffer[fd].buffer; endptr = areads_buffer[fd].endptr; - buflen = areads_buffer[fd].bufsize - (endptr - buffer); + buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer); } if ((r = read(fd, endptr, buflen)) <= 0) { if(r == 0) { @@ -652,7 +660,7 @@ debug_areads (s, l, fd) } *nl++ = '\0'; line = stralloc(buffer); - size = endptr - nl; /* data still left in buffer */ + size = (size_t)(endptr - nl); /* data still left in buffer */ memmove(buffer, nl, size); areads_buffer[fd].endptr = buffer + size; areads_buffer[fd].endptr[0] = '\0'; @@ -662,9 +670,10 @@ debug_areads (s, l, fd) #ifdef TEST -int main(argc, argv) - int argc; - char **argv; +int +main( + int argc, + char ** argv) { int rc; int fd; @@ -677,6 +686,8 @@ int main(argc, argv) set_pname("file test"); + dbopen(NULL); + /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); @@ -694,7 +705,7 @@ int main(argc, argv) } fprintf(stderr, "Create parent directories of %s ...", name); - rc = mkpdir(name, 02777, (uid_t)-1, (gid_t)-1); + rc = mkpdir(name, (mode_t)02777, (uid_t)-1, (gid_t)-1); if (rc == 0) fprintf(stderr, " done\n"); else {