Merge tag 'upstream/3.3.2'
[debian/amanda] / common-src / util.c
index 9ca0b4db604d249ffdbd737e614b49c60cc706df..eed9d981bca4bc5283453f532e281412de548788 100644 (file)
@@ -438,52 +438,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 +960,7 @@ expand_braced_alternates(
     char * source)
 {
     GPtrArray *rval = g_ptr_array_new();
+    gpointer *pdata;
 
     g_ptr_array_add(rval, g_strdup(""));
 
@@ -894,6 +972,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 +990,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;
     }
@@ -1027,7 +1111,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 +1146,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 +1180,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 +1620,73 @@ 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");
+
+    output_string = agets(out);
+    if (!output_string)
+       output_string = agets(err);
+
+    fclose(out);
+    fclose(err);
+
+    waitpid(pid, NULL, 0);
+
+    return output_string;
+}
+