Merge tag 'upstream/3.3.3'
[debian/amanda] / common-src / util.c
index c6368a2b3546b22227039ddfdbe38103579c7936..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
@@ -960,6 +961,7 @@ expand_braced_alternates(
     char * source)
 {
     GPtrArray *rval = g_ptr_array_new();
+    gpointer *pdata;
 
     g_ptr_array_add(rval, g_strdup(""));
 
@@ -971,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;
        }
@@ -987,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;
     }
@@ -1052,7 +1060,7 @@ int copy_file(
 {
     int     infd, outfd;
     int     save_errno;
-    size_t nb;
+    ssize_t nb;
     char    buf[32768];
     char   *quoted;
 
@@ -1076,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"),
@@ -1139,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
@@ -1168,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) {
@@ -1605,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;
+    }
+}