lintian doesn't like orphan packages with uploaders...
[debian/amanda] / amandad-src / amandad.c
index 5c15e0442efbae2afca8eeb3f762f25d442aa190..d864c3fa1bc7ca511ac93374fbccf9004a8d87f6 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
  * Copyright (c) 1991-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
@@ -81,7 +82,8 @@ typedef enum {
     SERVICE_SENDBACKUP,
     SERVICE_SELFCHECK,
     SERVICE_AMINDEXD,
-    SERVICE_AMIDXTAPED
+    SERVICE_AMIDXTAPED,
+    SERVICE_AMDUMPD
 } service_t;
 
 static struct services {
@@ -94,7 +96,8 @@ static struct services {
    { "sendbackup", 1, SERVICE_SENDBACKUP },
    { "selfcheck", 1, SERVICE_SELFCHECK },
    { "amindexd", 0, SERVICE_AMINDEXD },
-   { "amidxtaped", 0, SERVICE_AMIDXTAPED }
+   { "amidxtaped", 0, SERVICE_AMIDXTAPED },
+   { "amdumpd", 0, SERVICE_AMDUMPD }
 };
 #define        NSERVICES       (int)(sizeof(services) / sizeof(services[0]))
 
@@ -149,7 +152,7 @@ struct active_service {
  */
 GSList *serviceq = NULL;
 
-static int wait_30s = 1;
+static event_handle_t *exit_event;
 static int exit_on_qlength = 1;
 static char *auth = NULL;
 static kencrypt_type amandad_kencrypt = KENCRYPT_NONE;
@@ -242,6 +245,11 @@ main(
        /*NOTREACHED*/
     }
 
+    if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) {
+       printf("amandad-%s\n", VERSION);
+       return (0);
+    }
+
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
@@ -285,6 +293,14 @@ main(
                error(_("no driver for security type '%s'\n"), argv[i]);
                 /*NOTREACHED*/
            }
+           if (strcmp(auth, "local") == 0 ||
+               strcmp(auth, "rsh") == 0 ||
+               strcmp(auth, "ssh") == 0) {
+               int i;
+               for (i=0; i < NSERVICES; i++) {
+                   services[i].active = 1;
+               }
+           }
            continue;
        }
 
@@ -421,13 +437,13 @@ main(
     }
 
     /*
-     * If no security type specified, use BSD
+     * If no security type specified, use BSDTCP
      */
     if (secdrv == NULL) {
-       secdrv = security_getdriver("BSD");
-       auth = "bsd";
+       secdrv = security_getdriver("BSDTCP");
+       auth = "bsdtcp";
        if (secdrv == NULL) {
-           error(_("no driver for default security type 'BSD'\n"));
+           error(_("no driver for default security type 'BSDTCP'\n"));
            /*NOTREACHED*/
        }
     }
@@ -436,7 +452,6 @@ main(
        strcasecmp(auth, "ssh") == 0 ||
        strcasecmp(auth, "local") == 0 ||
        strcasecmp(auth, "bsdtcp") == 0) {
-       wait_30s = 0;
        exit_on_qlength = 1;
     }
 
@@ -489,8 +504,7 @@ main(
      * Schedule an event that will try to exit every 30 seconds if there
      * are no requests outstanding.
      */
-    if(wait_30s)
-       (void)event_register((event_id_t)30, EV_TIME, exit_check, &no_exit);
+    exit_event = event_register((event_id_t)30, EV_TIME, exit_check, &no_exit);
 
     /*
      * Call event_loop() with an arg of 0, telling it to block until all
@@ -529,6 +543,7 @@ exit_check(
     if (no_exit)
        return;
 
+    g_debug("timeout exit");
     dbclose();
     exit(0);
 }
@@ -549,13 +564,19 @@ protocol_accept(
     char *service_path = NULL;
     GSList *errlist = NULL;
     int i;
+    char *peer_name;
 
     pkt_out.body = NULL;
 
     /*
      * If handle is NULL, then the connection is closed.
      */
-    if(handle == NULL) {
+    if (handle == NULL) {
+       if (exit_on_qlength && exit_event) {
+           /* remove the timeout, we will exit once the service terminate */
+           event_release(exit_event);
+           exit_event = NULL;
+       }
        return;
     }
 
@@ -585,7 +606,9 @@ protocol_accept(
        return;
     }
 
-    g_debug("authenticated peer name is '%s'", security_get_authenticated_peer_name(handle));
+    peer_name = security_get_authenticated_peer_name(handle);
+    g_debug("authenticated peer name is '%s'", peer_name);
+    amfree(peer_name);
 
     /*
      * If pkt is NULL, then there was a problem with the new connection.
@@ -1463,9 +1486,7 @@ process_writenetfd(
        dbprintf(_("process_writenetfd: dh->fd_write <= 0\n"));
     } else if (size > 0) {
        full_write(dh->fd_write, buf, (size_t)size);
-       security_stream_read(dh->netfd, process_writenetfd, dh);
-    }
-    else {
+    } else {
        aclose(dh->fd_write);
     }
 }
@@ -1811,17 +1832,22 @@ service_delete(
     if (as->security_handle != NULL)
        security_close(as->security_handle);
 
+    /* try to kill the process; if this fails, then it's already dead and
+     * likely some of the other zombie cleanup ate its brains, so we don't
+     * bother to waitpid for it */
     assert(as->pid > 0);
-    kill(as->pid, SIGTERM);
     pid = waitpid(as->pid, NULL, WNOHANG);
-    count = 5;
-    while (pid != as->pid && count > 0) {
-       count--;
-       sleep(1);
+    if (pid != as->pid && kill(as->pid, SIGTERM) == 0) {
        pid = waitpid(as->pid, NULL, WNOHANG);
-    }
-    if (pid != as->pid) {
-       g_debug("Process %d failed to exit", (int)as->pid);
+       count = 5;
+       while (pid != as->pid && count > 0) {
+           count--;
+           sleep(1);
+           pid = waitpid(as->pid, NULL, WNOHANG);
+       }
+       if (pid != as->pid) {
+           g_debug("Process %d failed to exit", (int)as->pid);
+       }
     }
 
     serviceq = g_slist_remove(serviceq, (gpointer)as);