X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Futil.c;h=9d5ffca74d6eb824ecb623944c4f1886821d38a3;hb=691567b16c13087b31ee4c2b6d038e57872fae82;hp=9ca0b4db604d249ffdbd737e614b49c60cc706df;hpb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;p=debian%2Famanda diff --git a/common-src/util.c b/common-src/util.c index 9ca0b4d..9d5ffca 100644 --- a/common-src/util.c +++ b/common-src/util.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1999 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -438,52 +439,129 @@ quote_string_maybe( if ((str == NULL) || (*str == '\0')) { ret = stralloc("\"\""); - } else if (!always && (match("[:\'\\\"[:space:][:cntrl:]]", str)) == 0) { - /* - * String does not need to be quoted since it contains - * neither whitespace, control or quote characters. - */ - ret = stralloc(str); } else { - /* - * Allocate maximum possible string length. - * (a string of all quotes plus room for leading ", trailing " and NULL) - */ - ret = s = alloc((strlen(str) * 2) + 2 + 1); - *(s++) = '"'; - while (*str != '\0') { - if (*str == '\t') { - *(s++) = '\\'; - *(s++) = 't'; - str++; - continue; - } else if (*str == '\n') { - *(s++) = '\\'; - *(s++) = 'n'; - str++; - continue; - } else if (*str == '\r') { - *(s++) = '\\'; - *(s++) = 'r'; - str++; - continue; - } else if (*str == '\f') { - *(s++) = '\\'; - *(s++) = 'f'; - str++; - continue; - } else if (*str == '\\') { - *(s++) = '\\'; - *(s++) = '\\'; - str++; - continue; - } - if (*str == '"') - *(s++) = '\\'; - *(s++) = *(str++); + const char *r; + for (r = str; *r; r++) { + if (*r == ':' || *r == '\'' || *r == '\\' || *r == '\"' || + *r <= ' ' || *r == 0x7F ) + always = 1; + } + if (!always) { + /* + * String does not need to be quoted since it contains + * neither whitespace, control or quote characters. + */ + ret = stralloc(str); + } else { + /* + * Allocate maximum possible string length. + * (a string of all quotes plus room for leading ", trailing " and + * NULL) + */ + ret = s = alloc((strlen(str) * 2) + 2 + 1); + *(s++) = '"'; + while (*str != '\0') { + if (*str == '\t') { + *(s++) = '\\'; + *(s++) = 't'; + str++; + continue; + } else if (*str == '\n') { + *(s++) = '\\'; + *(s++) = 'n'; + str++; + continue; + } else if (*str == '\r') { + *(s++) = '\\'; + *(s++) = 'r'; + str++; + continue; + } else if (*str == '\f') { + *(s++) = '\\'; + *(s++) = 'f'; + str++; + continue; + } else if (*str == '\\') { + *(s++) = '\\'; + *(s++) = '\\'; + str++; + continue; + } + if (*str == '"') + *(s++) = '\\'; + *(s++) = *(str++); + } + *(s++) = '"'; + *s = '\0'; } - *(s++) = '"'; - *s = '\0'; + } + return (ret); +} + + +int +len_quote_string_maybe( + const char *str, + gboolean always) +{ + int ret; + + if ((str == NULL) || (*str == '\0')) { + ret = 0; + } else { + const char *r; + for (r = str; *r; r++) { + if (*r == ':' || *r == '\'' || *r == '\\' || *r == '\"' || + *r <= ' ' || *r == 0x7F ) + always = 1; + } + if (!always) { + /* + * String does not need to be quoted since it contains + * neither whitespace, control or quote characters. + */ + ret = strlen(str); + } else { + /* + * Allocate maximum possible string length. + * (a string of all quotes plus room for leading ", trailing " and + * NULL) + */ + ret = 1; + while (*str != '\0') { + if (*str == '\t') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\n') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\r') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\f') { + ret++; + ret++; + str++; + continue; + } else if (*str == '\\') { + ret++; + ret++; + str++; + continue; + } + if (*str == '"') + ret++; + ret++; + str++; + } + ret++; + } } return (ret); } @@ -883,6 +961,7 @@ expand_braced_alternates( char * source) { GPtrArray *rval = g_ptr_array_new(); + gpointer *pdata; g_ptr_array_add(rval, g_strdup("")); @@ -894,6 +973,8 @@ expand_braced_alternates( new_components = parse_braced_component(&source); if (!new_components) { /* parse error */ + for (i = 0, pdata = rval->pdata; i < rval->len; i++) + g_free(*pdata++); g_ptr_array_free(rval, TRUE); return NULL; } @@ -910,7 +991,11 @@ expand_braced_alternates( } } + for (i = 0, pdata = rval->pdata; i < rval->len; i++) + g_free(*pdata++); g_ptr_array_free(rval, TRUE); + for (i = 0, pdata = new_components->pdata; i < new_components->len; i++) + g_free(*pdata++); g_ptr_array_free(new_components, TRUE); rval = new_rval; } @@ -975,7 +1060,7 @@ int copy_file( { int infd, outfd; int save_errno; - size_t nb; + ssize_t nb; char buf[32768]; char *quoted; @@ -999,7 +1084,7 @@ int copy_file( } while((nb=read(infd, &buf, SIZEOF(buf))) > 0) { - if(full_write(outfd,&buf,nb) < nb) { + if(full_write(outfd,&buf,nb) < (size_t)nb) { save_errno = errno; quoted = quote_string(dst); *errmsg = vstrallocf(_("Error writing to '%s': %s"), @@ -1027,7 +1112,7 @@ int copy_file( return 0; } -#ifndef HAVE_READLINE +#ifndef HAVE_LIBREADLINE /* * simple readline() replacements, used when we don't have readline * support from the system. @@ -1062,6 +1147,11 @@ add_history( # error No readdir() or readdir64() available! #endif +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + char * portable_readdir(DIR* handle) { #ifdef USE_DIRENT64 @@ -1091,6 +1181,9 @@ char * portable_readdir(DIR* handle) { sure what to do about that case. */ return strdup(entry_p->d_name); } +#if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 31)) +# pragma GCC diagnostic pop +#endif int search_directory(DIR * handle, const char * regex, SearchDirectoryFunctor functor, gpointer user_data) { @@ -1528,3 +1621,102 @@ debug_executing( amfree(cmdline); } +char * +get_first_line( + GPtrArray *argv_ptr) +{ + char *output_string = NULL; + int inpipe[2], outpipe[2], errpipe[2]; + int pid; + FILE *out, *err; + + assert(argv_ptr != NULL); + assert(argv_ptr->pdata != NULL); + assert(argv_ptr->len >= 1); + + if (pipe(inpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + if (pipe(outpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + if (pipe(errpipe) == -1) { + error(_("error [open pipe: %s]"), strerror(errno)); + /*NOTREACHED*/ + } + + fflush(stdout); + switch(pid = fork()) { + case -1: + error(_("error [fork: %s]"), strerror(errno)); + /*NOTREACHED*/ + + default: /* parent process */ + aclose(inpipe[0]); + aclose(outpipe[1]); + aclose(errpipe[1]); + break; + + case 0: /* child process */ + aclose(inpipe[1]); + aclose(outpipe[0]); + aclose(errpipe[0]); + + dup2(inpipe[0], 0); + dup2(outpipe[1], 1); + dup2(errpipe[1], 2); + + debug_executing(argv_ptr); + g_fprintf(stdout, "unknown\n"); + execv((char *)*argv_ptr->pdata, (char **)argv_ptr->pdata); + error(_("error [exec %s: %s]"), (char *)*argv_ptr->pdata, strerror(errno)); + } + + aclose(inpipe[1]); + + out = fdopen(outpipe[0],"r"); + err = fdopen(errpipe[0],"r"); + + if (out) { + output_string = agets(out); + fclose(out); + } + + if (err) { + if (!output_string) + output_string = agets(err); + fclose(err); + } + + waitpid(pid, NULL, 0); + + return output_string; +} + +gboolean +make_amanda_tmpdir(void) +{ + struct stat stat_buf; + + if (stat(AMANDA_TMPDIR, &stat_buf) != 0) { + if (errno != ENOENT) { + g_debug("Error doing a stat of AMANDA_TMPDIR (%s): %s", AMANDA_TMPDIR, strerror(errno)); + return FALSE; + } + /* create it */ + if (mkdir(AMANDA_TMPDIR,0700) != 0) { + g_debug("Error mkdir of AMANDA_TMPDIR (%s): %s", AMANDA_TMPDIR, strerror(errno)); + return FALSE; + } + if (chown(AMANDA_TMPDIR, (int)get_client_uid(), (int)get_client_gid()) < 0) { + g_debug("Error chown of AMANDA_TMPDIR (%s): %s", AMANDA_TMPDIR, strerror(errno)); + return FALSE; + } + return TRUE; + } else { + /* check permission */ + return TRUE; + } +}