lintian doesn't like orphan packages with uploaders...
[debian/amanda] / common-src / util.c
index 9ca0b4db604d249ffdbd737e614b49c60cc706df..9d5ffca74d6eb824ecb623944c4f1886821d38a3 100644 (file)
@@ -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;
+    }
+}