]> git.sur5r.net Git - bacula/bacula/commitdiff
1.20 update -- kes18May02
authorKern Sibbald <kern@sibbald.com>
Sat, 18 May 2002 08:48:40 +0000 (08:48 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 18 May 2002 08:48:40 +0000 (08:48 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@24 91ce42f0-d328-0410-95d8-f526ca767f89

39 files changed:
bacula/src/bc_types.h
bacula/src/cats/sql_update.c
bacula/src/console.glade
bacula/src/console/console.c
bacula/src/dird/backup.c
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/dird.c
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/job.c
bacula/src/dird/protos.h
bacula/src/dird/restore.c
bacula/src/dird/run_conf.c
bacula/src/dird/ua_prune.c
bacula/src/dird/ua_purge.c
bacula/src/dird/ua_select.c
bacula/src/dird/verify.c
bacula/src/filed/filed.c
bacula/src/filed/filed_conf.c
bacula/src/filed/filed_conf.h
bacula/src/filed/win32/winmain.cpp
bacula/src/jcr.h
bacula/src/lib/mem_pool.c
bacula/src/lib/mem_pool.h
bacula/src/lib/message.c
bacula/src/lib/protos.h
bacula/src/lib/signal.c
bacula/src/lib/smartall.c
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/record.c
bacula/src/stored/stored.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/version.h

index 52af67ddc6b187e3d99e5feebd7232a37be86f52..640463f4f37f995686a312f990222681d8971fcb 100644 (file)
@@ -40,6 +40,8 @@
 /* ****FIXME***** implement 64 bit file addresses ! */
 #define faddr_t long 
 
+#define POOLMEM char
+
 /* Types */
 
 /* If sys/types.h does not supply intXX_t, supply them ourselves */
index eef77585c8ca3853f1fab81cbfe2b844757203fa..af77ff3408bb60faff81ea54f41b73784623f136 100644 (file)
@@ -192,7 +192,7 @@ db_update_media_record(B_DB *mdb, MEDIA_DBR *mr)
    localtime_r(&ttime, &tm);
    strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm);
 
-   Dmsg1(000, "update_media: FirstWritte=%d\n", mr->FirstWritten);
+   Dmsg1(100, "update_media: FirstWritten=%d\n", mr->FirstWritten);
    P(mdb->mutex);
    if (mr->VolMounts == 1) {
       Mmsg(&mdb->cmd, "UPDATE Media SET FirstWritten=\"%s\"\
index 5a7fa1c3ec3dd7c820a85b63860d14f6e4e2cf13..cf1622a78321472018d70b2b1156f6950eff6030 100644 (file)
       <widget>
        <class>GtkHBox</class>
        <name>hbox19</name>
+       <height>22</height>
        <homogeneous>False</homogeneous>
        <spacing>0</spacing>
        <child>
          <padding>0</padding>
          <expand>False</expand>
-         <fill>True</fill>
+         <fill>False</fill>
        </child>
 
        <widget>
index 24c6e7a8aa4da6b683451b1a1a00e5cb1f3da43b..bbe0e3fd8c134102faac4c83c7110313c5333cec 100644 (file)
@@ -142,16 +142,9 @@ int main(int argc, char *argv[])
 
    init_stack_dump();
    my_name_is(argc, argv, "console");
+   init_msg(NULL, NULL);
    working_directory = "/tmp";
 
-   /*
-    * Ensure that every message is always printed
-    */
-   for (i=1; i<=M_MAX; i++) {
-      add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
-   }
-
-
    while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) {
       switch (ch) {
          case 'c':                    /* configuration file */
index 92c1f6e200e415b48acb7429a83b06ae539cb045..631a971c5db00808c9263870dd3e2324a0781366 100644 (file)
@@ -68,34 +68,14 @@ int do_backup(JCR *jcr)
    int stat;
    BSOCK   *fd;
    POOL_DBR pr;
-#ifdef needed
-   MEDIA_DBR mr;
-#endif
-   CLIENT_DBR cr;
    FILESET_DBR fsr;
 
    since[0] = 0;
-   /*
-    * Get or Create client record
-    */
-   memset(&cr, 0, sizeof(cr));
-   strcpy(cr.Name, jcr->client->hdr.name);
-   cr.AutoPrune = jcr->client->AutoPrune;
-   cr.FileRetention = jcr->client->FileRetention;
-   cr.JobRetention = jcr->client->JobRetention;
-   if (jcr->client_name) {
-      free(jcr->client_name);
-   }
-   jcr->client_name = bstrdup(jcr->client->hdr.name);
-   if (!db_create_client_record(jcr->db, &cr)) {
-      Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), 
-        db_strerror(jcr->db));
+
+   if (!get_or_create_client_record(jcr)) {
       backup_cleanup(jcr, JS_ErrorTerminated, since);
-      return 0;
    }
-   jcr->jr.ClientId = cr.ClientId;
-   Dmsg2(9, "Created Client %s record %d\n", jcr->client->hdr.name, 
-      jcr->jr.ClientId);
+
 
    /*
     * Get or Create FileSet record
@@ -354,22 +334,12 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since)
    int msg_type;
    MEDIA_DBR mr;
 
-   memset(&mr, 0, sizeof(mr));
    Dmsg0(100, "Enter backup_cleanup()\n");
-   if (jcr->jr.EndTime == 0) {
-      jcr->jr.EndTime = time(NULL);
-   }
-   jcr->end_time = jcr->jr.EndTime;
-   jcr->jr.JobId = jcr->JobId;
-   jcr->jr.JobStatus = jcr->JobStatus = TermCode;
-   jcr->jr.JobFiles = jcr->JobFiles;
-   jcr->jr.JobBytes = jcr->JobBytes;
-   jcr->jr.VolSessionId = jcr->VolSessionId;
-   jcr->jr.VolSessionTime = jcr->VolSessionTime;
-   if (!db_update_job_end_record(jcr->db, &jcr->jr)) {
-      Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), 
-        db_strerror(jcr->db));
-   }
+   memset(&mr, 0, sizeof(mr));
+   jcr->JobStatus = TermCode;
+
+   update_job_end_record(jcr);       /* update database */
+   
    if (!db_get_job_record(jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_WARNING, 0, _("Error getting job record for stats: %s"), 
         db_strerror(jcr->db));
index 3087e87fe90523dcfd8b5e562d0b2c5b5ab54c8a..8b266fd914a90b59fb992bb315da4418c68c99b6 100644 (file)
@@ -21,6 +21,7 @@ Director {                            # define myself
   SubSysDirectory = "@subsysdir@"
   Maximum Concurrent Jobs = 1
   Password = "@dir_password@"         # Console password
+  Messages = Standard
 }
 
 # Define the backup Job
@@ -124,7 +125,7 @@ Messages {
   Name = Standard
   mailcommand = "@sbindir@/smtp -h @smtp_host@ -f \"Bacula <%r>\" -s \"Bacula: %t %e of %c %l\" %r"
   operatorcommand = "@sbindir@/smtp -h @smtp_host@ -f \"Bacula <%r>\" -s \"Bacula: Intervention needed for %j\" %r"
-  mail = @job_email@ = all, !skipped, !terminate
+  mail = @job_email@ = all, !skipped            
   operator = @job_email@ = mount
   console = all, !skipped, !saved
 }
index a9a49da782712b1c51e04b03884b6ab3c0010ec5..cc93770be07d7fa4714ae402ff7d0a5abea5ae0e 100644 (file)
@@ -89,6 +89,7 @@ int main (int argc, char *argv[])
 
    init_stack_dump();
    my_name_is(argc, argv, "bacula-dir");
+   init_msg(NULL, NULL);             /* initialize message handler */
    daemon_start_time = time(NULL);
    memset(&last_job, 0, sizeof(last_job));
 
@@ -160,29 +161,29 @@ int main (int argc, char *argv[])
       configfile = bstrdup(CONFIG_FILE);
    }
 
-   init_msg(NULL, NULL);             /* initialize message handler */
    parse_config(configfile);
 
    if (!check_resources()) {
       Emsg1(M_ABORT, 0, "Please correct configuration file: %s\n", configfile);
    }
 
-   my_name_is(0, (char **)NULL, director->hdr.name);   /* set user defined name */
-
-   FDConnectTimeout = director->FDConnectTimeout;
-   SDConnectTimeout = director->SDConnectTimeout;
-
-
    if (test_config) {
       terminate_dird(0);
-      exit(0);
    }
 
+   my_name_is(0, NULL, director->hdr.name);    /* set user defined name */
+
+   FDConnectTimeout = director->FDConnectTimeout;
+   SDConnectTimeout = director->SDConnectTimeout;
+
    if (background) {
       daemon_start();
       init_stack_dump();             /* grab new pid */
    }
 
+   /* Create pid must come after we are a daemon -- so we have our final pid */
+   create_pid_file(director->pid_directory, "bacula-dir", director->DIRport);
+
    signal(SIGHUP, reload_config);
 
    init_console_msg(working_directory);
@@ -203,7 +204,6 @@ int main (int argc, char *argv[])
    }
 
    terminate_dird(0);
-   exit(0);                          /* for compiler */
 }
 
 /* Cleanup and then exit */
@@ -215,6 +215,8 @@ static void terminate_dird(int sig)
       exit(1);
    }
    already_here = TRUE;
+   delete_pid_file(director->pid_directory, "bacula-dir",  
+                  director->DIRport);
    stop_watchdog();
    signal(SIGCHLD, SIG_IGN);          /* don't worry about children now */
    term_scheduler();
@@ -229,10 +231,10 @@ static void terminate_dird(int sig)
    }
    free_config_resources();
    term_ua_server();
-   close_memory_pool();              /* free memory in pool */
    term_msg();                       /* terminate message handler */
+   close_memory_pool();              /* release free memory in pool */
    sm_dump(False);
-   exit(0);
+   exit(sig != 0);
 }
 
 /*
@@ -291,39 +293,48 @@ static int check_resources()
    job = (JOB *)GetNextRes(R_JOB, NULL);
    director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
    if (!director) {
-      Emsg1(M_WARNING, 0, _("No Director resource defined in %s\n\
+      Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n\
 Without that I don't know who I am :-(\n"), configfile);
       OK = FALSE;
+   } else {
+      if (!director->working_directory) {
+         Emsg0(M_FATAL, 0, _("No working directory specified. Cannot continue.\n"));
+        OK = FALSE;
+      }       
+      working_directory = director->working_directory;
+      if (!director->messages) {       /* If message resource not specified */
+        director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
+        if (!director->messages) {
+            Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
+           OK = FALSE;
+        }
+      }
+      if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
+         Emsg1(M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
+           configfile);
+        OK = FALSE;
+      } 
    }
-   if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
-      Emsg1(M_WARNING, 0, _("Only one Director resource permitted in %s\n"),
-        configfile);
-      OK = FALSE;
-   } 
-   if (!director->working_directory) {
-      Emsg0(M_WARNING, 0, _("No working directory specified. Cannot continue.\n"));
-      OK = FALSE;
-   }      
-   working_directory = director->working_directory;
+
    if (!job) {
-      Emsg1(M_WARNING, 0, _("No Job records defined in %s\n"), configfile);
+      Emsg1(M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
       OK = FALSE;
    }
    for (job=NULL; (job = (JOB *)GetNextRes(R_JOB, (RES *)job)); ) {
       if (!job->client) {
-         Emsg1(M_WARNING, 0, _("No Client record defined for job %s\n"), job->hdr.name);
+         Emsg1(M_FATAL, 0, _("No Client record defined for job %s\n"), job->hdr.name);
         OK = FALSE;
       }
       if (!job->fs) {
-         Emsg1(M_WARNING, 0, _("No FileSet record defined for job %s\n"), job->hdr.name);
+         Emsg1(M_FATAL, 0, _("No FileSet record defined for job %s\n"), job->hdr.name);
         OK = FALSE;
       }
       if (!job->storage && job->JobType != JT_VERIFY) {
-         Emsg1(M_WARNING, 0, _("No Storage resource defined for job %s\n"), job->hdr.name);
+         Emsg1(M_FATAL, 0, _("No Storage resource defined for job %s\n"), job->hdr.name);
         OK = FALSE;
       }
       if (!job->pool) {
-         Emsg1(M_WARNING, 0, _("No Pool resource defined for job %s\n"), job->hdr.name);
+         Emsg1(M_FATAL, 0, _("No Pool resource defined for job %s\n"), job->hdr.name);
         OK = FALSE;
       }
       if (job->client->catalog) {
@@ -337,16 +348,20 @@ Without that I don't know who I am :-(\n"), configfile);
         db = db_init_database(catalog->db_name, catalog->db_user,
                            catalog->db_password);
         if (!db_open_database(db)) {
-            Emsg1(M_WARNING,  0, "%s", db_strerror(db));
+            Emsg1(M_FATAL,  0, "%s", db_strerror(db));
         }
         db_close_database(db);
       } else {
-         Emsg1(M_WARNING, 0, _("No Catalog resource defined for client %s\n"), 
+         Emsg1(M_FATAL, 0, _("No Catalog resource defined for client %s\n"), 
               job->client->hdr.name);
         OK = FALSE;
       }
    }
 
    UnlockRes();
+   if (OK) {
+      close_msg(NULL);               /* close temp message handler */
+      init_msg(NULL, director->messages); /* open daemon message handler */
+   }
    return OK;
 }
index 7d327814e2d7d4df3cabbdf812739fff171c9379..9043edcab06208dfe28ec962d727fcca40cf863e 100644 (file)
@@ -19,7 +19,7 @@
  *
  *     Kern Sibbald, January MM
  *
- *     $Id:
+ *     $Id$
  */
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
@@ -61,6 +61,8 @@ extern void store_run(LEX *lc, struct res_items *item, int index, int pass);
 static void store_inc(LEX *lc, struct res_items *item, int index, int pass);
 static void store_backup(LEX *lc, struct res_items *item, int index, int pass);
 static void store_restore(LEX *lc, struct res_items *item, int index, int pass);
+static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
+static void store_level(LEX *lc, struct res_items *item, int index, int pass);
 
 
 /* We build the current resource here as we are
@@ -155,16 +157,20 @@ static struct res_items cat_items[] = {
  *   name         handler     value                 code flags    default_value
  */
 static struct res_items job_items[] = {
-   {"name",     store_name,   ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0},
-   {"description", store_str, ITEM(res_job.hdr.desc), 0, 0, 0},
-   {"backup",   store_backup, ITEM(res_job),          JT_BACKUP, 0, 0},
-   {"verify",   store_backup, ITEM(res_job),          JT_VERIFY, 0, 0},
-   {"restore",  store_restore, ITEM(res_job),         JT_RESTORE, 0, 0},
-   {"schedule", store_res,    ITEM(res_job.schedule), R_SCHEDULE, 0, 0},
-   {"messages", store_res,    ITEM(res_job.messages), R_MSGS, 0, 0},
-   {"storage",  store_res,    ITEM(res_job.storage),  R_STORAGE, 0, 0},
-   {"pool",     store_res,    ITEM(res_job.pool),     R_POOL, 0, 0},
-   {"maxruntime", store_time, ITEM(res_job.MaxRunTime), 0, 0, 0},
+   {"name",     store_name,    ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0},
+   {"description", store_str,  ITEM(res_job.hdr.desc), 0, 0, 0},
+   {"backup",   store_backup,  ITEM(res_job),          JT_BACKUP, 0, 0},
+   {"verify",   store_backup,  ITEM(res_job),          JT_VERIFY, 0, 0},
+   {"restore",  store_restore, ITEM(res_job),          JT_RESTORE, 0, 0},
+   {"schedule", store_res,     ITEM(res_job.schedule), R_SCHEDULE, 0, 0},
+   {"type",     store_jobtype, ITEM(res_job),          0, 0, 0},
+   {"level",    store_level,   ITEM(res_job),          0, 0, 0},
+   {"messages", store_res,     ITEM(res_job.messages), R_MSGS, 0, 0},
+   {"storage",  store_res,     ITEM(res_job.storage),  R_STORAGE, 0, 0},
+   {"pool",     store_res,     ITEM(res_job.pool),     R_POOL, 0, 0},
+   {"client",   store_res,     ITEM(res_job.client),   R_CLIENT, 0, 0},
+   {"fileset",  store_res,     ITEM(res_job.fs),       R_FILESET, 0, 0},
+   {"maxruntime", store_time,  ITEM(res_job.MaxRunTime), 0, 0, 0},
    {"maxstartdelay", store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
@@ -249,7 +255,7 @@ struct s_res resources[] = {
 
 /* Keywords (RHS) permitted in Job Level records   
  *
- *   level_name      level             level_class
+ *   level_name      level             job_type
  */
 struct s_jl joblevels[] = {
    {"Full",          L_FULL,            JT_BACKUP},
@@ -264,6 +270,18 @@ struct s_jl joblevels[] = {
    {NULL,           0}
 };
 
+/* Keywords (RHS) permitted in Job type records   
+ *
+ *   type_name      job_type
+ */
+struct s_jt jobtypes[] = {
+   {"backup",        JT_BACKUP},
+   {"verify",        JT_VERIFY},
+   {"restore",       JT_RESTORE},
+   {NULL,           0}
+};
+
+
 /* Keywords (RHS) permitted in Backup and Verify records */
 static struct s_kw BakVerFields[] = {
    {"client",        'C'},
@@ -586,6 +604,8 @@ void free_resource(int type)
            free(res->res_msgs.mail_cmd);
         if (res->res_msgs.operator_cmd)
            free(res->res_msgs.operator_cmd);
+        free_msgs_res((MSGS *)res);  /* free message resource */
+        res = NULL;
         break;
       case R_GROUP:
         break;
@@ -593,13 +613,17 @@ void free_resource(int type)
          printf("Unknown resource type %d\n", type);
    }
    /* Common stuff again -- free the resource, recurse to next one */
-   free(res);
+   if (res) {
+      free(res);
+   }
    resources[rindex].res_head = nres;
-   if (nres)
+   if (nres) {
       free_resource(type);
+   }
 }
 
-/* Save the new resource by chaining it into the head list for
+/*
+ * Save the new resource by chaining it into the head list for
  * the resource. If this is pass 2, we update any resource
  * pointers (currently only in the Job resource).
  */
@@ -660,6 +684,23 @@ void save_resource(int type, struct res_items *items, int pass)
            res->res_job.fs       = res_all.res_job.fs;
            res->res_job.storage  = res_all.res_job.storage;
            res->res_job.pool     = res_all.res_job.pool;
+           if (res->res_job.JobType == 0) {
+               Emsg1(M_ABORT, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name);
+           }
+           if (res->res_job.level != 0) {
+              int i;
+              for (i=0; joblevels[i].level_name; i++) {
+                 if (joblevels[i].level == res->res_job.level &&
+                     joblevels[i].job_type == res->res_job.JobType) {
+                    i = 0;
+                    break;
+                 }
+              }
+              if (i != 0) {
+                  Emsg1(M_ABORT, 0, "Inappropriate level specified in Job resource %s\n", 
+                    res_all.res_dir.hdr.name);
+              }
+           }
            break;
         case R_CLIENT:
            if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) {
@@ -679,6 +720,10 @@ void save_resource(int type, struct res_items *items, int pass)
         free(res_all.res_dir.hdr.name);
         res_all.res_dir.hdr.name = NULL;
       }
+      if (res_all.res_dir.hdr.desc) {
+        free(res_all.res_dir.hdr.desc);
+        res_all.res_dir.hdr.desc = NULL;
+      }
       return;
    }
 
@@ -730,6 +775,64 @@ void save_resource(int type, struct res_items *items, int pass)
 
 }
 
+/* 
+ * Store JobType (backup, verify, restore)
+ *
+ */
+static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token, i;   
+
+   token = lex_get_token(lc);
+   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
+   } else {
+      /* Store the type both pass 1 and pass 2 */
+      for (i=0; jobtypes[i].type_name; i++) {
+        if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
+           ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
+           i = 0;
+           break;
+        }
+      }
+      if (i != 0) {
+         scan_err1(lc, "Expected a Job Type keyword, got: %s", lc->str);
+      }
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
+}
+
+/* 
+ * Store Job Level (Full, Incremental, ...)
+ *
+ */
+static void store_level(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token, i;
+
+   token = lex_get_token(lc);
+   if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
+      scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
+   } else {
+      /* Store the level pass 2 so that type is defined */
+      for (i=0; joblevels[i].level_name; i++) {
+        if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
+           ((JOB *)(item->value))->level = joblevels[i].level;
+           i = 0;
+           break;
+        }
+      }
+      if (i != 0) {
+         scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+      }
+   }
+   scan_to_eol(lc);
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
+
 /* 
  * Store backup/verify info for Job record 
  *
@@ -753,7 +856,6 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass)
       if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
          scan_err1(lc, "Expected a backup/verify keyword, got: %s", lc->str);
       } else {
-        lcase(lc->str);
          Dmsg1(190, "Got keyword: %s\n", lc->str);
         found = FALSE;
         for (i=0; BakVerFields[i].name; i++) {
@@ -792,9 +894,8 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass)
                     break;
                   case 'L':
                     /* Get level */
-                    lcase(lc->str);
                     for (i=0; joblevels[i].level_name; i++) {
-                       if (joblevels[i].job_class == item->code && 
+                       if (joblevels[i].job_type == item->code && 
                             strcasecmp(lc->str, joblevels[i].level_name) == 0) {
                           ((JOB *)(item->value))->level = joblevels[i].level;
                           i = 0;
@@ -841,11 +942,10 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
       if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
          scan_err1(lc, "Expected a Restore keyword, got: %s", lc->str);
       } else {
-        lcase(lc->str);
         found = FALSE;
         for (i=0; RestoreFields[i].name; i++) {
             Dmsg1(190, "Restore kw=%s\n", lc->str);
-           if (strcmp(lc->str, RestoreFields[i].name) == 0) {
+           if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
               found = TRUE;
               if (lex_get_token(lc) != T_EQUALS) {
                   scan_err1(lc, "Expected an equals, got: %s", lc->str);
@@ -901,10 +1001,9 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass)
                     if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
                         scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
                     }
-                    lcase(lc->str);
                     /* Fix to scan Replacement options */
                     for (i=0; ReplaceOptions[i].name; i++) {
-                       if (strcmp(lc->str, ReplaceOptions[i].name) == 0) {
+                       if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
                            ((JOB *)(item->value))->RestoreOptions = ReplaceOptions[i].token;
                           i = 0;
                           break;
@@ -945,7 +1044,6 @@ static char *scan_fs_options(LEX *lc, int keyword)
       if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
          scan_err1(lc, "expected a FileSet option, got: %s", lc->str);
       }
-      lcase(lc->str);
       if (keyword == FS_KW_VERIFY) { /* special case */
         /* ***FIXME**** ensure these are in permitted set */
          strcpy(option, "V");         /* indicate Verify */
@@ -953,7 +1051,7 @@ static char *scan_fs_options(LEX *lc, int keyword)
          strcat(option, ":");         /* terminate it */
       } else {
         for (i=0; FS_options[i].name; i++) {
-           if (strcmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
+           if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
               option[0] = FS_options[i].option;
               i = 0;
               break;
@@ -995,9 +1093,8 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass)
          scan_err1(lc, "expected a FileSet option keyword, got: %s", lc->str);
       } else {
         keyword = FS_KW_NONE;
-        lcase(lc->str);
         for (i=0; FS_option_kw[i].name; i++) {
-           if (strcmp(lc->str, FS_option_kw[i].name) == 0) {
+           if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) {
               keyword = FS_option_kw[i].token;
               break;
            }
index f70441d5268a6b2c860cbd45005723bcb043056f..07ca5c20c8a0df1ec7d7d2a7eca5af13695cd618 100644 (file)
@@ -61,11 +61,16 @@ struct s_kw {
 
 /* Job Level keyword structure */
 struct s_jl {
-   char *level_name;
-   int  level;
-   int  job_class;
+   char *level_name;                  /* level keyword */
+   int  level;                        /* level */
+   int  job_type;                     /* JobType permitting this level */
 };
 
+/* Job Type keyword structure */
+struct s_jt {
+   char *type_name;
+   int job_type;
+};
 
 /* Definition of the contents of each Resource */
 
@@ -81,7 +86,7 @@ struct s_res_dir {
    char *working_directory;           /* WorkingDirectory */
    char *pid_directory;               /* PidDirectory */
    char *subsys_directory;            /* SubsysDirectory */
-   struct s_res_msgs *messages;
+   struct s_res_msgs *messages;       /* Daemon message handler */
    int   MaxConcurrentJobs;
    btime_t FDConnectTimeout;          /* timeout for connect in seconds */
    btime_t SDConnectTimeout;          /* timeout in seconds */
@@ -244,7 +249,7 @@ typedef union u_res URES;
 struct s_run {
    struct s_run *next;                /* points to next run record */
    int level;
-   int job_class;  
+   int job_type;  
    char *since;
    int level_no;
    int minute;                        /* minute to run job */
index 539b73cae0ccc75bf22a8f99fbd1fda3e17fd773..ea2dbd22d9cae99b6eecba02ad50081fbbdc9d66 100644 (file)
@@ -59,7 +59,8 @@ void init_job_server(int max_workers)
 }
 
 /*
- * Run a job
+ * Run a job -- typically called by the scheduler, but may also
+ *             be called by the UA (Console program).
  *
  */
 void run_job(JCR *jcr)
@@ -124,7 +125,11 @@ void run_job(JCR *jcr)
    Dmsg0(200, "Done run_job()\n");
 }
 
-/* This is the engine called by workq_add() */
+/* 
+ * This is the engine called by workq_add() when we were pulled               
+ *  from the work queue.
+ *  At this point, we are running in our own thread 
+ */
 static void job_thread(void *arg)
 {
    time_t now;
@@ -137,29 +142,85 @@ static void job_thread(void *arg)
    if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
        (btime_t)(jcr->start_time - jcr->sched_time)) {
       Jmsg(jcr, M_FATAL, 0, _("Job cancelled because max delay time exceeded.\n"));
-      free_jcr(jcr);
-   }
-   jcr->JobStatus = JS_Running;
+      jcr->JobStatus = JS_ErrorTerminated;
+      update_job_end_record(jcr);
+   } else {
 
-   switch (jcr->JobType) {
-      case JT_BACKUP:
-        do_backup(jcr);
-        break;
-      case JT_VERIFY:
-        do_verify(jcr);
-        break;
-      case JT_RESTORE:
-        do_restore(jcr);
-        break;
-      default:
-         Dmsg1(0, "Unimplemented job type: %d\n", jcr->JobType);
-        break;
+      /* Run Job */
+      jcr->JobStatus = JS_Running;
+
+      switch (jcr->JobType) {
+        case JT_BACKUP:
+           do_backup(jcr);
+           break;
+        case JT_VERIFY:
+           do_verify(jcr);
+           break;
+        case JT_RESTORE:
+           do_restore(jcr);
+           break;
+        case JT_ADMIN:
+           /* No actual job */
+           break;
+        default:
+            Dmsg1(0, "Unimplemented job type: %d\n", jcr->JobType);
+           break;
+        }
    }
    Dmsg0(50, "Before free jcr\n");
    free_jcr(jcr);
    Dmsg0(50, "======== End Job ==========\n");
 }
 
+/*
+ * Get or create a Client record for this Job
+ */
+int get_or_create_client_record(JCR *jcr)
+{
+   CLIENT_DBR cr;
+
+   memset(&cr, 0, sizeof(cr));
+   strcpy(cr.Name, jcr->client->hdr.name);
+   cr.AutoPrune = jcr->client->AutoPrune;
+   cr.FileRetention = jcr->client->FileRetention;
+   cr.JobRetention = jcr->client->JobRetention;
+   if (jcr->client_name) {
+      free(jcr->client_name);
+   }
+   jcr->client_name = bstrdup(jcr->client->hdr.name);
+   if (!db_create_client_record(jcr->db, &cr)) {
+      Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), 
+        db_strerror(jcr->db));
+      return 0;
+   }
+   jcr->jr.ClientId = cr.ClientId;
+   Dmsg2(9, "Created Client %s record %d\n", jcr->client->hdr.name, 
+      jcr->jr.ClientId);
+   return 1;
+}
+
+
+/*
+ * Write status and such in DB
+ */
+void update_job_end_record(JCR *jcr)
+{
+   if (jcr->jr.EndTime == 0) {
+      jcr->jr.EndTime = time(NULL);
+   }
+   jcr->end_time = jcr->jr.EndTime;
+   jcr->jr.JobId = jcr->JobId;
+   jcr->jr.JobStatus = jcr->JobStatus;
+   jcr->jr.JobFiles = jcr->JobFiles;
+   jcr->jr.JobBytes = jcr->JobBytes;
+   jcr->jr.VolSessionId = jcr->VolSessionId;
+   jcr->jr.VolSessionTime = jcr->VolSessionTime;
+   if (!db_update_job_end_record(jcr->db, &jcr->jr)) {
+      Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), 
+        db_strerror(jcr->db));
+   }
+}
+
 /*
  * Takes base_name and appends (unique) current
  *   date and time to form unique job name.
index 8cd2a22ba539d1f848fe07465cb81eb155f004ab..7f09c081a6eddc6bb56e05db1df3c5acf0a7f871 100644 (file)
@@ -49,6 +49,8 @@ extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
 extern void free_jcr(JCR *jcr);
 extern void set_jcr_defaults(JCR *jcr, JOB *job);
 extern void create_unique_job_name(JCR *jcr, char *base_name);
+extern void update_job_end_record(JCR *jcr);
+extern int get_or_create_client_record(JCR *jcr);
 
 /* mountreq.c */
 extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
index 51581b34a65c6cc25a14d919aa5111bc67cac62f..a63c47eb1fbf5dc2964b4b6fbeeb19b6bccc11da 100644 (file)
@@ -68,27 +68,12 @@ int do_restore(JCR *jcr)
    char dt[MAX_TIME_LENGTH];
    BSOCK   *fd;
    JOB_DBR rjr;                      /* restore job record */
-   CLIENT_DBR cr;
 
-   /*
-    * Get or Create a client record
-    */
-   memset(&cr, 0, sizeof(cr));
-   strcpy(cr.Name, jcr->client->hdr.name);
-   cr.AutoPrune = jcr->client->AutoPrune;
-   cr.FileRetention = jcr->client->FileRetention;
-   cr.JobRetention = jcr->client->JobRetention;
-   if (jcr->client_name) {
-      free(jcr->client_name);
-   }
-   jcr->client_name = bstrdup(jcr->client->hdr.name);
-   if (!db_create_client_record(jcr->db, &cr)) {
-      Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), 
-        db_strerror(jcr->db));
+
+   if (!get_or_create_client_record(jcr)) {
       restore_cleanup(jcr, JS_ErrorTerminated);
       return 0;
    }
-   jcr->jr.ClientId = cr.ClientId;
 
    memset(&rjr, 0, sizeof(rjr));
    jcr->jr.Level = 'F';            /* Full restore */
@@ -258,14 +243,9 @@ static void restore_cleanup(JCR *jcr, int status)
    char dt[MAX_TIME_LENGTH];
 
    Dmsg0(20, "In restore_cleanup\n");
-   if (jcr->jr.EndTime == 0) {
-      jcr->jr.EndTime = time(NULL);
-   }
-   jcr->jr.JobStatus = jcr->JobStatus = status;
-   if (!db_update_job_end_record(jcr->db, &jcr->jr)) {
-      Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), 
-        db_strerror(jcr->db));
-   }
+   jcr->JobStatus = status;
+
+   update_job_end_record(jcr);
 
    bstrftime(dt, sizeof(dt), jcr->jr.EndTime);
    Jmsg(jcr, M_INFO, 0, _("%s End Restore Job %s.\n"),
index 21b69f894496a9d7ff4fab881f1c52bbb5fb2235..3fe299354a5768e0f23c0b1f36b6d132142cdc5c 100644 (file)
@@ -174,11 +174,16 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass)
    if (token != T_STRING) {
       scan_err1(lc, _("Expected a Job level identifier, got: %s"), lc->str);
    } else {
-      lcase(lc->str);
+      if (strcasecmp(lc->str, "level")) {
+        if (lex_get_token(lc) != T_EQUALS) {
+            scan_err1(lc, "Expected an equals, got: %s", lc->str);
+        }
+        token = lex_get_token(lc);
+      }
       for (i=0; joblevels[i].level_name; i++) {
         if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
            lrun.level = joblevels[i].level;
-           lrun.job_class = joblevels[i].job_class;
+           lrun.job_type = joblevels[i].job_type;
            i = 0;
            break;
         }
index d790e78c8285335a20fde4db65214e64e4458c2a..2111d09e99561053f735dfba8ac85db600c971a6 100644 (file)
@@ -5,7 +5,7 @@
  *
  *     Kern Sibbald, February MMII
  *
- *     $Id:
+ *     $Id$
  */
 
 /*
@@ -134,7 +134,7 @@ static int count_handler(void *ctx, int num_fields, char **row)
 
 
 /*
- * Called here to count entries to be deleted 
+ * Called here to count the number of Jobs to be pruned
  */
 static int file_count_handler(void *ctx, int num_fields, char **row)
 {
@@ -276,7 +276,7 @@ int prune_files(UAContext *ua, CLIENT *client)
    int i;
    btime_t now, period;
    CLIENT_DBR cr;
-   char ed1[50];
+   char ed1[50], ed2[50];
 
    memset(&cr, 0, sizeof(cr));
    memset(&del, 0, sizeof(del));
@@ -320,7 +320,12 @@ int prune_files(UAContext *ua, CLIENT *client)
    db_sql_query(ua->db, query, file_delete_handler, (void *)&del);
 
    for (i=0; i < del.num_ids; i++) {
+      struct s_count_ctx cnt;
       Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]);
+      Mmsg(&query, "SELECT count(*) FROM File WHERE JobId=%d", del.JobId[i]);
+      cnt.count = 0;
+      db_sql_query(ua->db, query, count_handler, (void *)&cnt);
+      del.tot_ids += cnt.count;
       Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]);
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       /* 
@@ -333,8 +338,10 @@ int prune_files(UAContext *ua, CLIENT *client)
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Dmsg1(050, "Del sql=%s\n", query);
    }
-   bsendmsg(ua, _("Pruned %d Files for client %s from %s catalog.\n"), del.num_ids,
-      client->hdr.name, client->catalog->hdr.name);
+   edit_uint64_with_commas(del.tot_ids, ed1);
+   edit_uint64_with_commas(del.num_ids, ed2);
+   bsendmsg(ua, _("Pruned %s Files from %s Jobs for client %s from %s catalog.\n"), 
+      ed1, ed2, client->hdr.name, client->catalog->hdr.name);
    
 bail_out:
    if (del.JobId) {
index 552d8d90963b12f0daf8648325d13ba6d45e90e9..b2c4a502151f05ea1f0937872653a6e95c068a31 100644 (file)
@@ -8,7 +8,7 @@
  *
  *     Kern Sibbald, February MMII
  *
- *     $Id:
+ *     $Id$
  */
 
 /*
index f0329268a600b81227fa44a92608b07676775ec0..5992c63f4957283b699943b58e9d8fcfd4cb3d26 100644 (file)
@@ -4,7 +4,7 @@
  *
  *     Kern Sibbald, October MMI
  *
- *     $Id:
+ *     $Id$
  */
 
 /*
index 8c3c63d9b9fec51eecdd229f8c4b573080ef1a9e..ea1b9583f874715648b8e1ec95ed7c7a2195a87f 100644 (file)
@@ -54,7 +54,7 @@ static char OKverify[]   = "2000 OK verify\n";
 static char OKlevel[]    = "2000 OK level\n";
 
 /* Forward referenced functions */
-static void verify_cleanup(JCR *jcr);
+static void verify_cleanup(JCR *jcr, int TermCode);
 static void prt_fname(JCR *jcr);
 static int missing_handler(void *ctx, int num_fields, char **row);
 
@@ -70,25 +70,11 @@ int do_verify(JCR *jcr)
    BSOCK   *fd;
    JOB_DBR jr;
    int last_full_id;
-   CLIENT_DBR cr;
-
-   memset(&cr, 0, sizeof(cr));
-   cr.AutoPrune = jcr->client->AutoPrune;
-   cr.FileRetention = jcr->client->FileRetention;
-   cr.JobRetention = jcr->client->JobRetention;
-   strcpy(cr.Name, jcr->client->hdr.name);
-   if (jcr->client_name) {
-      free(jcr->client_name);
-   }
-   jcr->client_name = bstrdup(jcr->client->hdr.name);
-   if (!db_create_client_record(jcr->db, &cr)) {
-      Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), 
-        db_strerror(jcr->db));
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);                   
+
+   if (!get_or_create_client_record(jcr)) {
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
-   jcr->jr.ClientId = cr.ClientId;
 
    Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
 
@@ -101,8 +87,7 @@ int do_verify(JCR *jcr)
       if (!db_find_last_full_verify(jcr->db, &jr)) {
          Jmsg(jcr, M_FATAL, 0, _("Unable to find last full verify. %s"),
            db_strerror(jcr->db));
-        jcr->JobStatus = JS_ErrorTerminated;
-        verify_cleanup(jcr);
+        verify_cleanup(jcr, JS_ErrorTerminated);                    
         return 0;
       }
       last_full_id = jr.JobId;
@@ -114,8 +99,7 @@ int do_verify(JCR *jcr)
    jcr->jr.Level = jcr->level;
    if (!db_update_job_start_record(jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
@@ -134,8 +118,7 @@ int do_verify(JCR *jcr)
       jr.JobId = last_full_id;
       if (!db_get_job_record(jcr->db, &jr)) {
          Jmsg(jcr, M_ERROR, 0, _("Could not get job record. %s"), db_strerror(jcr->db));
-        jcr->JobStatus = JS_ErrorTerminated;
-        verify_cleanup(jcr);
+        verify_cleanup(jcr, JS_ErrorTerminated);                    
         return 0;
       }
       Jmsg(jcr, M_INFO, 0, _("Verifying against Init JobId %d run %s\n"),
@@ -148,8 +131,7 @@ int do_verify(JCR *jcr)
     */
    jcr->sd_auth_key = bstrdup("dummy");    /* dummy Storage daemon key */
    if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) {
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
@@ -157,15 +139,13 @@ int do_verify(JCR *jcr)
 
    Dmsg0(30, ">filed: Send include list\n");
    if (!send_include_list(jcr)) {
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
    Dmsg0(30, ">filed: Send exclude list\n");
    if (!send_exclude_list(jcr)) {
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
@@ -188,15 +168,13 @@ int do_verify(JCR *jcr)
         break;
       default:
          Emsg1(M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->level);
-        jcr->JobStatus = JS_ErrorTerminated;
-        verify_cleanup(jcr);
+        verify_cleanup(jcr, JS_ErrorTerminated);                    
         return 0;
    }
    Dmsg1(20, ">filed: %s", fd->msg);
    bnet_fsend(fd, levelcmd, level, " ");
    if (!response(fd, OKlevel, "Level")) {
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
@@ -205,8 +183,7 @@ int do_verify(JCR *jcr)
     */
    bnet_fsend(fd, verifycmd);
    if (!response(fd, OKverify, "Verify")) {
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
@@ -227,12 +204,11 @@ int do_verify(JCR *jcr)
 
    } else {
       Emsg1(M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->level);
-      jcr->JobStatus = JS_ErrorTerminated;
-      verify_cleanup(jcr);
+      verify_cleanup(jcr, JS_ErrorTerminated);                   
       return 0;
    }
 
-   verify_cleanup(jcr);
+   verify_cleanup(jcr, JS_Terminated);
    return 1;
 }
 
@@ -240,40 +216,28 @@ int do_verify(JCR *jcr)
  * Release resources allocated during backup.
  *
  */
-static void verify_cleanup(JCR *jcr)
+static void verify_cleanup(JCR *jcr, int TermCode)
 {
    char sdt[50], edt[50];
    char ec1[30];
    char term_code[100];
    char *term_msg;
    int msg_type;
-   int TermCode;
    int last_full_id;
 
    Dmsg0(100, "Enter verify_cleanup()\n");
 
    last_full_id = jcr->jr.JobId;
+   jcr->JobStatus = TermCode;
 
-
-   if (jcr->jr.EndTime == 0) {
-      jcr->jr.EndTime = time(NULL);
-   }
-   jcr->end_time = jcr->jr.EndTime;
-   jcr->jr.JobId = jcr->JobId;
-   jcr->jr.JobStatus = jcr->JobStatus;
-   TermCode = jcr->JobStatus;
-
-   if (!db_update_job_end_record(jcr->db, &jcr->jr)) {
-      Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), 
-        db_strerror(jcr->db));
-   }
+   update_job_end_record(jcr);
 
    msg_type = M_INFO;                /* by default INFO message */
    switch (TermCode) {
       case JS_Terminated:
          term_msg = _("Verify OK");
         break;
-      case JS_Errored:
+      case JS_ErrorTerminated:
          term_msg = _("*** Verify Error ***"); 
         msg_type = M_ERROR;          /* Generate error message */
         break;
index 5a40ade9fb3b070c587ec66ccda239745347c2ff..83dc02ed44dbae5ed8e698e2a6ec18af588e34e6 100644 (file)
@@ -48,6 +48,7 @@ int win32_client = 0;
 static char *configfile = NULL;
 static int foreground = 0;
 static workq_t dir_workq;            /* queue of work from Director */
+static CLIENT *me;                   /* my resource */
 
 static void usage()
 {
@@ -78,11 +79,11 @@ int main (int argc, char *argv[])
    int ch;
    int no_signals = FALSE;
    int test_config = FALSE;
-   CLIENT *me;                       /* my resource */
    DIRRES *director;
 
    init_stack_dump();
    my_name_is(argc, argv, "filed");
+   init_msg(NULL, NULL);
    daemon_start_time = time(NULL);
 
    memset(&last_job, 0, sizeof(last_job));
@@ -143,8 +144,6 @@ int main (int argc, char *argv[])
       configfile = bstrdup(CONFIG_FILE);
    }
 
-
-   init_msg(NULL, NULL);
    parse_config(configfile);
 
    LockRes();
@@ -162,7 +161,17 @@ int main (int argc, char *argv[])
       Emsg1(M_ABORT, 0, _("No File daemon resource defined in %s\n\
 Without that I don't know who I am :-(\n"), configfile);
    } else {
-      my_name_is(0, (char **)NULL, me->hdr.name);
+      my_name_is(0, NULL, me->hdr.name);
+      if (!me->messages) {
+        LockRes();
+        me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
+        UnlockRes();
+        if (!me->messages) {
+             Emsg1(M_ABORT, 0, _("No Messages resource defined in %s\n"), configfile);
+        }
+      }
+      close_msg(NULL);               /* close temp message handler */
+      init_msg(NULL, me->messages);   /* open user specified message handler */
    }
    working_directory = me->working_directory;
 
@@ -175,6 +184,8 @@ Without that I don't know who I am :-(\n"), configfile);
       init_stack_dump();             /* set new pid */
    }
 
+   create_pid_file(me->pid_directory, "bacula-fd", me->FDport);
+
 #ifdef BOMB
    me += 1000000;
 #endif
@@ -198,9 +209,10 @@ void terminate_filed(int sig)
    if (debug_level > 5) {
       print_memory_pool_stats(); 
    }
+   delete_pid_file(me->pid_directory, "bacula-fd", me->FDport);
    free_config_resources();
-   close_memory_pool();              /* free memory in pool */
    term_msg();
+   close_memory_pool();              /* release free memory in pool */
    sm_dump(False);                   /* dump orphaned buffers */
    exit(1);
 }
index 708fafbd2b28202c791949d54614f4c7eecbb91f..21a756765e1f90aad350e0d3ed19f614fd5c1632 100644 (file)
@@ -72,9 +72,10 @@ static struct res_items cli_items[] = {
    {"name",     store_name,     ITEM(res_client.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,   ITEM(res_client.hdr.desc), 0, 0, 0},
    {"fdport",   store_pint,     ITEM(res_client.FDport),  0, ITEM_REQUIRED, 0},
-   {"workingdirectory",  store_dir,  ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, 
-   {"piddirectory",  store_dir,  ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, 
+   {"workingdirectory",  store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, 
+   {"piddirectory",  store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, 
    {"subsysdirectory",  store_dir,  ITEM(res_client.subsys_directory), 0, ITEM_REQUIRED, 0}, 
+   {"messages",      store_res, ITEM(res_client.messages), R_MSGS, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
@@ -128,6 +129,10 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
         break;
       case R_MSGS:
          sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
+        if (res->res_msgs.mail_cmd) 
+            sendit(sock, "      mailcmd=%s\n", res->res_msgs.mail_cmd);
+        if (res->res_msgs.operator_cmd) 
+            sendit(sock, "      opcmd=%s\n", res->res_msgs.operator_cmd);
         break;
       default:
          sendit(sock, "Unknown resource type %d\n", type);
@@ -182,12 +187,16 @@ void free_resource(int type)
            free(res->res_msgs.mail_cmd);
         if (res->res_msgs.operator_cmd)
            free(res->res_msgs.operator_cmd);
+        free_msgs_res((MSGS *)res);  /* free message resource */
+        res = NULL;
         break;
       default:
          printf("Unknown resource type %d\n", type);
    }
    /* Common stuff again -- free the resource, recurse to next one */
-   free(res);
+   if (res) {
+      free(res);
+   }
    resources[rindex].res_head = nres;
    if (nres) {
       free_resource(type);
@@ -227,9 +236,15 @@ void save_resource(int type, struct res_items *items, int pass)
         /* Resources not containing a resource */
         case R_MSGS:
         case R_DIRECTOR:
-        case R_CLIENT:
            break;
 
+        /* Resources containing another resource */
+        case R_CLIENT:
+           if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) {
+               Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name);
+           }
+           res->res_client.messages = res_all.res_client.messages;
+           break;
         default:
             Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
            error = 1;
@@ -266,7 +281,7 @@ void save_resource(int type, struct res_items *items, int pass)
    }
    /* Common */
    if (!error) {
-      res = (URES *) malloc(size);
+      res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       res->res_dir.hdr.next = resources[rindex].res_head;
       resources[rindex].res_head = (RES *)res;
index 3edffcc3f6f1bbe1a46d1a6c060888f912eb9a51..c2547a99eb6062f02829c54b9d1687586ddb5fef 100644 (file)
 /*
  * Resource codes -- they must be sequential for indexing   
  */
-#define R_FIRST                      1001
+#define R_FIRST                       1001
 
-#define R_DIRECTOR                   1001
-#define R_CLIENT                     1002
-#define R_MSGS                       1003
+#define R_DIRECTOR                    1001
+#define R_CLIENT                      1002
+#define R_MSGS                        1003
 
-#define R_LAST                       R_MSGS
+#define R_LAST                        R_MSGS
 
 /*
  * Some resource attributes
  */
-#define R_NAME                       1020
-#define R_ADDRESS                    1021
-#define R_PASSWORD                   1022
-#define R_TYPE                       1023
+#define R_NAME                        1020
+#define R_ADDRESS                     1021
+#define R_PASSWORD                    1022
+#define R_TYPE                        1023
 
 
 /* Definition of the contents of each Resource */
 struct s_res_dir {
-   RES  hdr;
-   char *password;                   /* Director password */
-   char *address;                    /* Director address or zero */
+   RES   hdr;
+   char *password;                    /* Director password */
+   char *address;                     /* Director address or zero */
 };
 typedef struct s_res_dir DIRRES;
 
 struct s_res_client {
-   RES  hdr;
-   int  FDport;                      /* where we listen for Directors */ 
+   RES   hdr;
+   int   FDport;                      /* where we listen for Directors */ 
    char *working_directory;
    char *pid_directory;
    char *subsys_directory;
+   struct s_res_msgs *messages;       /* daemon message handler */
 };
 typedef struct s_res_client CLIENT;
 
@@ -66,9 +67,9 @@ typedef struct s_res_client CLIENT;
  * resource structure definitions.
  */
 union u_res {
-   struct s_res_dir    res_dir;
-   struct s_res_client res_client;
-   struct s_res_msgs   res_msgs;
+   struct s_res_dir     res_dir;
+   struct s_res_client  res_client;
+   struct s_res_msgs    res_msgs;
    RES hdr;
 };
 
index 7c54033d46acc994304f57b70421c0aacde1037f..938aba1d633cf9199e35cc01971f32ca41b07be3 100755 (executable)
@@ -264,7 +264,7 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam)
    }
 
 
-   // Now enter the message handling loop until told to quit!
+   // Now enter the Windows message handling loop until told to quit!
    MSG msg;
    while (GetMessage(&msg, NULL, 0,0) ) {
       TranslateMessage(&msg);
@@ -281,7 +281,7 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam)
       // Tell the service manager that we've stopped.
       ReportStatus(SERVICE_STOPPED, g_error, 0);
    }   
-   kill(main_pid, SIGTERM);
+   kill(main_pid, SIGTERM);           /* ask main thread to terminate */
    _exit(0);
 }
  
index e25ed3ab8613107625e81c4145d49658719e233b..48b0eae69949de41a05ce496e36d77cab85f3638 100644 (file)
@@ -46,6 +46,8 @@
 #define JT_VERIFY                'V'
 #define JT_RESTORE               'R'
 #define JT_CONSOLE               'C'  /* console program */
+#define JT_ADMIN                 'D'  /* admin job */
+#define JT_ARCHIVE               'A'
 
 /* Job Status */
 #define JS_Created               'C'
@@ -95,12 +97,10 @@ struct s_jcr {
    time_t start_time;                 /* when job actually started */
    time_t run_time;                   /* used for computing speed */
    time_t end_time;                   /* job end time */
-   char *VolumeName;                  /* Volume name desired -- pool_memory */
+   POOLMEM *VolumeName;               /* Volume name desired -- pool_memory */
    char *client_name;                 /* client name */
    char *sd_auth_key;                 /* SD auth key */
    MSGS *msgs;                        /* Message resource */
-   DEST *dest_chain;                  /* Job message destination chain */
-   char send_msg[nbytes_for_bits(M_MAX+1)]; /* message bit mask */
 
    /* Daemon specific part of JCR */
    /* This should be empty in the library */
index 251d5dcc103b477c206f350383470a2504f2a0a0..1762cea4bc9a6af885a0aac67f23fdee09a55502 100644 (file)
@@ -69,9 +69,9 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
 
-extern void *sm_malloc(char *fname, int lineno, int nbytes);
+extern POOLMEM *sm_malloc(char *fname, int lineno, int nbytes);
 
-void *sm_get_pool_memory(char *fname, int lineno, int pool)
+POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool)
 {
    struct abufhead *buf;
 
@@ -90,7 +90,7 @@ void *sm_get_pool_memory(char *fname, int lineno, int pool)
       V(mutex);
       Dmsg3(150, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno);
       sm_new_owner(fname, lineno, (char *)buf);
-      return (void *)((char *)buf+HEAD_SIZE);
+      return (POOLMEM *)((char *)buf+HEAD_SIZE);
    }
       
    if ((buf = (struct abufhead *) sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
@@ -105,11 +105,11 @@ void *sm_get_pool_memory(char *fname, int lineno, int pool)
    }
    V(mutex);
    Dmsg3(150, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno);
-   return (void *)((char *)buf+HEAD_SIZE);
+   return (POOLMEM *)((char *)buf+HEAD_SIZE);
 }
 
 /* Get nonpool memory of size requested */
-void *sm_get_memory(char *fname, int lineno, size_t size)
+POOLMEM *sm_get_memory(char *fname, int lineno, size_t size)
 {
    struct abufhead *buf;
    int pool = 0;
@@ -124,12 +124,12 @@ void *sm_get_memory(char *fname, int lineno, size_t size)
    pool_ctl[pool].in_use++;
    if (pool_ctl[pool].in_use > pool_ctl[pool].max_used)
       pool_ctl[pool].max_used = pool_ctl[pool].in_use;
-   return (void *)(((char *)buf)+HEAD_SIZE);
+   return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 
 #else
 
-void *get_pool_memory(int pool)
+POOLMEM *get_pool_memory(int pool)
 {
    struct abufhead *buf;
 
@@ -138,7 +138,7 @@ void *get_pool_memory(int pool)
       buf = pool_ctl[pool].free_buf;
       pool_ctl[pool].free_buf = buf->next;
       V(mutex);
-      return (void *)((char *)buf+HEAD_SIZE);
+      return (POOLMEM *)((char *)buf+HEAD_SIZE);
    }
       
    if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
@@ -153,11 +153,11 @@ void *get_pool_memory(int pool)
       pool_ctl[pool].max_used = pool_ctl[pool].in_use;
    }
    V(mutex);
-   return (void *)(((char *)buf)+HEAD_SIZE);
+   return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 
 /* Get nonpool memory of size requested */
-void *get_memory(size_t size)
+POOLMEM *get_memory(size_t size)
 {
    struct abufhead *buf;
    int pool = 0;
@@ -172,14 +172,14 @@ void *get_memory(size_t size)
    if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
       pool_ctl[pool].max_used = pool_ctl[pool].in_use;
    }
-   return (void *)(((char *)buf)+HEAD_SIZE);
+   return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 #endif /* SMARTALLOC */
 
 
 
 /* Free a memory buffer */
-void free_pool_memory(void *obuf)
+void free_pool_memory(POOLMEM *obuf)
 {
    struct abufhead *buf;
    int pool;
@@ -202,7 +202,7 @@ void free_pool_memory(void *obuf)
 
 
 /* Return the size of a memory buffer */
-size_t sizeof_pool_memory(void *obuf)
+size_t sizeof_pool_memory(POOLMEM *obuf)
 {
    char *cp = (char *)obuf;
 
@@ -213,7 +213,7 @@ size_t sizeof_pool_memory(void *obuf)
 }
 
 /* Realloc pool memory buffer */
-void *realloc_pool_memory(void *obuf, size_t size)
+POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size)
 {
    char *cp = (char *)obuf;
    void *buf;
@@ -235,10 +235,10 @@ void *realloc_pool_memory(void *obuf, size_t size)
    }
    V(mutex);
    sm_check(__FILE__, __LINE__, False);
-   return (void *)(((char *)buf)+HEAD_SIZE);
+   return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
 }
 
-void *check_pool_memory_size(void *obuf, size_t size)
+POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size)
 {
    sm_check(__FILE__, __LINE__, False);
    ASSERT(obuf);
@@ -263,6 +263,7 @@ void close_memory_pool()
         free((char *)buf);
         buf = next;
       }
+      pool_ctl[i].free_buf = NULL;
    }
    V(mutex);
 }
index 9bccd8b05873caa48e17f7f16865434d2a26d7bc..17f8d5671beecbe878814f162d2d5c03a39b274e 100644 (file)
 #ifdef SMARTALLOC
 
 #define get_pool_memory(pool) sm_get_pool_memory(__FILE__, __LINE__, pool)
-extern void *sm_get_pool_memory(char *file, int line, int pool);
+extern POOLMEM *sm_get_pool_memory(char *file, int line, int pool);
 #define get_memory(size) sm_get_memory(__FILE__, __LINE__, size)
-extern void *sm_get_memory(char *fname, int line, size_t size);
+extern POOLMEM *sm_get_memory(char *fname, int line, size_t size);
 
 #else
 
-extern void *get_pool_memory(int pool);
-extern void *get_memory(size_t size);
+extern POOLMEM *get_pool_memory(int pool);
+extern POOLMEM *get_memory(size_t size);
 
 #endif
  
 #define free_memory(x) free_pool_memory(x)
-extern void   free_pool_memory(void *buf);
-extern size_t sizeof_pool_memory(void *buf);
-extern void  *realloc_pool_memory(void *buf, size_t size);
-extern void  *check_pool_memory_size(void *buf, size_t size);
+extern void   free_pool_memory(POOLMEM *buf);
+extern size_t sizeof_pool_memory(POOLMEM *buf);
+extern POOLMEM  *realloc_pool_memory(POOLMEM *buf, size_t size);
+extern POOLMEM  *check_pool_memory_size(POOLMEM *buf, size_t size);
 extern void  close_memory_pool();
 extern void  print_memory_pool_stats();
 
index ec5cb380619f6b5a32a230531c812179668523f5..41e804e37de12dfcd4cf39457e93812491aaf695 100755 (executable)
@@ -46,7 +46,10 @@ FILE *con_fd = NULL;
 
 /* Imported functions */
 
-static MSGS daemon_msg;              /* global messages */
+
+/* Static storage */
+
+static MSGS *daemon_msgs;             /* global messages */
 
 /* 
  * Set daemon name. Also, find canonical execution
@@ -120,35 +123,64 @@ void my_name_is(int argc, char *argv[], char *name)
    }
 }
 
-/* Initialize message handler */
+/* 
+ * Initialize message handler for a daemon or a Job
+ * 
+ *   NULL for jcr -> initialize global messages for daemon
+ *   non-NULL    -> initialize jcr using Message resource
+ */
 void
 init_msg(void *vjcr, MSGS *msg)
 {
    DEST *d, *dnew, *temp_chain = NULL;
    JCR *jcr = (JCR *)vjcr;
 
-   if (!msg) {                       /* If nothing specified, use */
-      msg = &daemon_msg;             /*  daemon global message resource */
+   /*
+    * If msg is NULL, initialize global chain for STDOUT and syslog
+    */
+   if (msg == NULL) {
+      int i;
+      daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
+      memset(daemon_msgs, 0, sizeof(MSGS));
+      for (i=1; i<=M_MAX; i++) {
+        add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
+        add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL);
+      }
+      Dmsg1(050, "Create daemon global message resource 0x%x\n", daemon_msgs);
+      return;
    }
-   if (!jcr) { 
-      memset(msg, 0, sizeof(msg));           /* init daemon global message */
-   } else {                                  /* init for job */
-      /* Walk down the global chain duplicating it
-       * for the current Job.  No need to duplicate
-       * the attached strings.
-       */
-      for (d=daemon_msg.dest_chain; d; d=d->next) {
-        dnew = (DEST *) malloc(sizeof(DEST));
-        memcpy(dnew, d, sizeof(DEST));
-        dnew->next = temp_chain;
-        dnew->fd = NULL;
-        dnew->mail_filename = NULL;
-        temp_chain = dnew;
+
+   /*
+    * Walk down the message resource chain duplicating it
+    * for the current Job.
+    */
+   for (d=msg->dest_chain; d; d=d->next) {
+      dnew = (DEST *) malloc(sizeof(DEST));
+      memcpy(dnew, d, sizeof(DEST));
+      dnew->next = temp_chain;
+      dnew->fd = NULL;
+      dnew->mail_filename = NULL;
+      if (d->mail_cmd) {
+        dnew->mail_cmd = bstrdup(d->mail_cmd);
+      }
+      if (d->where) {
+        dnew->where = bstrdup(d->where);
       }
+      temp_chain = dnew;
+   }
 
-      jcr->dest_chain = temp_chain;
-      memcpy(jcr->send_msg, daemon_msg.send_msg, sizeof(daemon_msg.send_msg));
+   if (jcr) {
+      jcr->msgs = (MSGS *)malloc(sizeof(MSGS));
+      memset(jcr->msgs, 0, sizeof(MSGS));
+      jcr->msgs->dest_chain = temp_chain;
+      memcpy(jcr->msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
+   } else {
+      daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
+      memset(daemon_msgs, 0, sizeof(MSGS));
+      daemon_msgs->dest_chain = temp_chain;
+      memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
    }
+   Dmsg2(050, "Copy message resource 0x%x to 0x%x\n", msg, temp_chain);
 }
 
 /* Initialize so that the console (User Agent) can
@@ -187,27 +219,27 @@ void init_console_msg(char *wd)
 void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd)
 {
    DEST *d; 
-
-   /* First search the existing chain and see if we
+   /*
+    * First search the existing chain and see if we
     * can simply add this msg_type to an existing entry.
     */
-   for (d=daemon_msg.dest_chain; d; d=d->next) {
+   for (d=msg->dest_chain; d; d=d->next) {
       if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) ||
                     (strcmp(where, d->where) == 0))) {  
          Dmsg4(200, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n", 
             d, msg_type, dest_code, where);
         set_bit(msg_type, d->msg_types);
-        set_bit(msg_type, daemon_msg.send_msg);  /* set msg_type bit in our local */
+        set_bit(msg_type, msg->send_msg);  /* set msg_type bit in our local */
         return;
       }
    }
    /* Not found, create a new entry */
-   d = (DEST *) malloc(sizeof(DEST));
+   d = (DEST *)malloc(sizeof(DEST));
    memset(d, 0, sizeof(DEST));
-   d->next = daemon_msg.dest_chain;
+   d->next = msg->dest_chain;
    d->dest_code = dest_code;
    set_bit(msg_type, d->msg_types);     /* set type bit in structure */
-   set_bit(msg_type, daemon_msg.send_msg); /* set type bit in our local */
+   set_bit(msg_type, msg->send_msg);    /* set type bit in our local */
    if (where) {
       d->where = bstrdup(where);
    }
@@ -217,7 +249,7 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai
    Dmsg5(200, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n", 
           d, msg_type, dest_code, where?where:"(null)", 
           d->mail_cmd?d->mail_cmd:"(null)");
-   daemon_msg.dest_chain = d;
+   msg->dest_chain = d;
 }
 
 /* 
@@ -229,7 +261,7 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where)
 {
    DEST *d;
 
-   for (d=daemon_msg.dest_chain; d; d=d->next) {
+   for (d=msg->dest_chain; d; d=d->next) {
       Dmsg2(200, "Remove_msg_dest d=%x where=%s\n", d, d->where);
       if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) &&
          ((where == NULL && d->where == NULL) ||
@@ -457,36 +489,39 @@ static FILE *open_mail_pipe(JCR *jcr, char **cmd, DEST *d)
    Dmsg1(200, "mailcmd=%s\n", cmd);
    pfd = popen(*cmd, "w");
    if (!pfd) {
-      Emsg2(M_ERROR, 0, "popen %s failed: ERR=%s\n", cmd, strerror(errno));
-      if (jcr) {
-         Jmsg(jcr, M_ERROR, 0, "mail popen %s failed: ERR=%s\n", cmd, strerror(errno));
-      }
+      Jmsg(jcr, M_ERROR, 0, "mail popen %s failed: ERR=%s\n", cmd, strerror(errno));
    } 
    return pfd;
 }
 
 /* 
- * Close the messages for this job, which means to close
+ * Close the messages for this Messages resource, which means to close
  *  any open files, and dispatch any pending email messages.
- *     
- * This closes messages only for this job, other jobs can   
- *   still send messages.
- * 
- * Note, we free our local message destination chain, but
- * the global chain remains allowing other jobs to
- * start.
  */
 void close_msg(void *vjcr)
 {
-   DEST *d, *old;
+   MSGS *msgs;
+   JCR *jcr = (JCR *)vjcr;
+   DEST *d;
    FILE *pfd;
-   char *cmd, *line;
+   POOLMEM *cmd, *line;
    int len;
-   JCR *jcr = (JCR *)vjcr;
    
-   Dmsg0(200, "Close_msg\n");
-   cmd = (char *)get_pool_memory(PM_MESSAGE);
-   for (d=jcr->dest_chain; d; ) {
+   Dmsg1(050, "Close_msg jcr=0x%x\n", jcr);
+
+   if (jcr == NULL) {               /* NULL -> global chain */
+      msgs = daemon_msgs;
+      daemon_msgs = NULL;
+   } else {
+      msgs = jcr->msgs;
+      jcr->msgs = NULL;
+   }
+   if (msgs == NULL) {
+      return;
+   }
+   Dmsg1(050, "close msg resource at 0x%x\n", msgs);
+   cmd = get_pool_memory(PM_MESSAGE);
+   for (d=msgs->dest_chain; d; ) {
       if (d->fd) {
         switch (d->dest_code) {
         case MD_FILE:
@@ -500,7 +535,7 @@ void close_msg(void *vjcr)
            if (!d->fd) {
               break;
            }
-           if (d->dest_code == MD_MAIL_ON_ERROR && 
+           if (d->dest_code == MD_MAIL_ON_ERROR && jcr &&
                jcr->JobStatus == JS_Terminated) {
               goto rem_temp_file;
            }
@@ -510,7 +545,7 @@ void close_msg(void *vjcr)
               goto rem_temp_file;
            }
            len = d->max_len+10;
-           line = (char *)get_memory(len);
+           line = get_memory(len);
            rewind(d->fd);
            while (fgets(line, len, d->fd)) {
               fputs(line, pfd);
@@ -529,43 +564,48 @@ rem_temp_file:
         }
         d->fd = NULL;
       }
+      d = d->next;                   /* point to next buffer */
+   }
+   free_pool_memory(cmd);
+
+   free_msgs_res(msgs);
+}
+
+/*
+ * Free memory associated with Messages resource  
+ */
+void free_msgs_res(MSGS *msgs)
+{
+   DEST *d, *old;
+
+   for (d=msgs->dest_chain; d; ) {
+      if (d->where) {
+        free(d->where);
+      }
+      if (d->mail_cmd) {
+        free(d->mail_cmd);
+      }
       old = d;                       /* save pointer to release */
       d = d->next;                   /* point to next buffer */
       free(old);                     /* free the destination item */
    }
-   free_pool_memory(cmd);
-   jcr->dest_chain = NULL;
+   msgs->dest_chain = NULL;
+   free(msgs);
 }
 
 
 /* 
  * Terminate the message handler for good. 
  * Release the global destination chain.
+ * 
+ * Also, clean up a few other items (cons, exepath). Note,
+ *   these really should be done elsewhere.
  */
 void term_msg()
 {
-   DEST *d, *n;
-   
-   for (d=daemon_msg.dest_chain; d; d=n) {
-      if (d->fd) {
-        if (d->dest_code == MD_FILE || d->dest_code == MD_APPEND) {
-           fclose(d->fd);            /* close open file descriptor */
-           d->fd = NULL;
-        } else if (d->dest_code == MD_MAIL || d->dest_code == MD_MAIL_ON_ERROR) {
-           fclose(d->fd);
-           d->fd = NULL;
-           unlink(d->mail_filename);
-           free_pool_memory(d->mail_filename);
-           d->mail_filename = NULL;
-        }
-      }
-      n = d->next;
-      if (d->where)
-        free(d->where);              /* free destination address */
-      if (d->mail_cmd)
-        free(d->mail_cmd);
-      free(d);
-   }
+   Dmsg0(100, "Enter term_msg\n");
+   close_msg(NULL);                  /* close global chain */
+   daemon_msgs = NULL;
    if (con_fd) {
       fflush(con_fd);
       fclose(con_fd);
@@ -589,9 +629,11 @@ void term_msg()
 void dispatch_message(void *vjcr, int type, int level, char *buf)
 {
     DEST *d;   
-    char cmd[MAXSTRING], *mcmd;
+    char cmd[MAXSTRING];
+    POOLMEM *mcmd;
     JCR *jcr = (JCR *) vjcr;
     int len;
+    MSGS *msgs;
 
     Dmsg2(200, "Enter dispatch_msg type=%d msg=%s\n", type, buf);
 
@@ -600,12 +642,14 @@ void dispatch_message(void *vjcr, int type, int level, char *buf)
     }
 
     /* Now figure out where to send the message */
+    msgs = NULL;
     if (jcr) {
-       d = jcr->dest_chain;          /* use job message chain */
-    } else {
-       d = daemon_msg.dest_chain;     /* use global chain */
+       msgs = jcr->msgs;
+    } 
+    if (msgs == NULL) {
+       msgs = daemon_msgs;
     }
-    for ( ; d; d=d->next) {
+    for (d=msgs->dest_chain; d; d=d->next) {
        if (bit_is_set(type, d->msg_types)) {
          switch (d->dest_code) {
             case MD_CONSOLE:
@@ -639,7 +683,7 @@ void dispatch_message(void *vjcr, int type, int level, char *buf)
                break;
             case MD_OPERATOR:
                 Dmsg1(200, "OPERATOR for following err: %s\n", buf);
-               mcmd = (char *) get_pool_memory(PM_MESSAGE);
+               mcmd = get_pool_memory(PM_MESSAGE);
                d->fd = open_mail_pipe(jcr, &mcmd, d);
                free_pool_memory(mcmd);
                if (d->fd) {
@@ -771,7 +815,7 @@ d_msg(char *file, int line, int level, char *fmt,...)
 void 
 e_msg(char *file, int line, int type, int level, char *fmt,...)
 {
-    char     buf[1000];
+    char     buf[2000];
     va_list   arg_ptr;
     int i;
 
@@ -779,7 +823,8 @@ e_msg(char *file, int line, int type, int level, char *fmt,...)
      * Check if we have a message destination defined. 
      * We always report M_ABORT 
      */
-    if (type != M_ABORT && !bit_is_set(type, daemon_msg.send_msg))
+    if (!daemon_msgs || (type != M_ABORT && 
+                        !bit_is_set(type, daemon_msgs->send_msg)))
        return;                       /* no destination */
     switch (type) {
        case M_ABORT:
@@ -841,7 +886,7 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...)
      * Check if we have a message destination defined. 
      * We always report M_ABORT 
      */
-    if (type != M_ABORT && !bit_is_set(type, jcr->send_msg)) {
+    if (type != M_ABORT && jcr->msgs && !bit_is_set(type, jcr->msgs->send_msg)) {
        Dmsg1(200, "No bit set for type %d\n", type);
        return;                       /* no destination */
     }
index cc114032ecc03ed22df5d425c8934c73295ff0e7..470c2560d1e3c6cae6ce1b40413b880ad936acce 100644 (file)
  */
 
 /* base64.c */
-void      base64_init            __PROTO((void));
-int       to_base64              __PROTO((intmax_t value, char *where));
-int       from_base64            __PROTO((intmax_t *value, char *where));
-void      encode_stat            __PROTO((char *buf, struct stat *statp));
-void      decode_stat            __PROTO((char *buf, struct stat *statp));
-int       bin_to_base64          __PROTO((char *buf, char *bin, int len));
+void     base64_init            __PROTO((void));
+int      to_base64              __PROTO((intmax_t value, char *where));
+int      from_base64            __PROTO((intmax_t *value, char *where));
+void     encode_stat            __PROTO((char *buf, struct stat *statp));
+void     decode_stat            __PROTO((char *buf, struct stat *statp));
+int      bin_to_base64          __PROTO((char *buf, char *bin, int len));
 
 /* bmisc.c */
-void     *b_malloc               (char *file, int line, size_t size);
+void    *b_malloc               (char *file, int line, size_t size);
 #ifndef DEBUG
-void     *bmalloc                (size_t size);
+void    *bmalloc                (size_t size);
 #endif
-void     *brealloc               (void *buf, size_t size);
-void     *bcalloc                (size_t size1, size_t size2);
-int       bsnprintf              (char *str, size_t size, const  char  *format, ...);
-int       bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
-int       pool_sprintf           (char *pool_buf, char *fmt, ...);
-int       create_pid_file        (char *dir, char *progname, int port, char *errmsg);
-int       delete_pid_file        (char *dir, char *progname, int port);
+void    *brealloc               (void *buf, size_t size);
+void    *bcalloc                (size_t size1, size_t size2);
+int      bsnprintf              (char *str, size_t size, const  char  *format, ...);
+int      bvsnprintf             (char *str, size_t size, const char  *format, va_list ap);
+int      pool_sprintf           (char *pool_buf, char *fmt, ...);
+void     create_pid_file        (char *dir, char *progname, int port);
+int      delete_pid_file        (char *dir, char *progname, int port);
 
 /* bnet.c */
-int32_t    bnet_recv             __PROTO((BSOCK *bsock));
-int        bnet_send             __PROTO((BSOCK *bsock));
-int        bnet_fsend              (BSOCK *bs, char *fmt, ...);
-int        bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
-int        bnet_sig                (BSOCK *bs, int sig);
-BSOCK *    bnet_connect            (void *jcr, int retry_interval,
-               int max_retry_time, char *name, char *host, char *service, 
-               int port, int verbose);
-int        bnet_wait_data         (BSOCK *bsock, int sec);
-void       bnet_close            __PROTO((BSOCK *bsock));
-BSOCK *    init_bsock            __PROTO((int sockfd, char *who, char *ip, int port));
-BSOCK *    dup_bsock             __PROTO((BSOCK *bsock));
-void       term_bsock            __PROTO((BSOCK *bsock));
-char *     bnet_strerror         __PROTO((BSOCK *bsock));
-char *     bnet_sig_to_ascii     __PROTO((BSOCK *bsock));
-int        bnet_wait_data        __PROTO((BSOCK *bsock, int sec));
+int32_t    bnet_recv            __PROTO((BSOCK *bsock));
+int       bnet_send             __PROTO((BSOCK *bsock));
+int       bnet_fsend              (BSOCK *bs, char *fmt, ...);
+int       bnet_set_buffer_size    (BSOCK *bs, uint32_t size, int rw);
+int       bnet_sig                (BSOCK *bs, int sig);
+BSOCK *    bnet_connect           (void *jcr, int retry_interval,
+              int max_retry_time, char *name, char *host, char *service, 
+              int port, int verbose);
+int       bnet_wait_data         (BSOCK *bsock, int sec);
+void      bnet_close            __PROTO((BSOCK *bsock));
+BSOCK *    init_bsock           __PROTO((int sockfd, char *who, char *ip, int port));
+BSOCK *    dup_bsock            __PROTO((BSOCK *bsock));
+void      term_bsock            __PROTO((BSOCK *bsock));
+char *    bnet_strerror         __PROTO((BSOCK *bsock));
+char *    bnet_sig_to_ascii     __PROTO((BSOCK *bsock));
+int       bnet_wait_data        __PROTO((BSOCK *bsock, int sec));
 
 
 /* cram-md5.c */
 int cram_md5_get_auth(BSOCK *bs, char *password);
 int cram_md5_auth(BSOCK *bs, char *password);
 void hmac_md5(uint8_t* text, int text_len, uint8_t*  key,
-              int key_len, uint8_t *hmac);
+             int key_len, uint8_t *hmac);
 
 /* create_file.c */
 int create_file(void *jcr, char *fname, char *ofile, char *lname,
-                       int type, struct stat *statp, int *ofd);
+                      int type, struct stat *statp, int *ofd);
 int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type, 
-                       struct stat *statp);
+                      struct stat *statp);
 
 
 /* crc32.c */
 uint32_t bcrc32(uint8_t *buf, int len);
 
 /* daemon.c */
-void     daemon_start            __PROTO(());
+void    daemon_start            __PROTO(());
 
 /* lex.c */
-LEX *     lex_close_file         __PROTO((LEX *lf));
-LEX *     lex_open_file          __PROTO((LEX *lf, char *fname));
-int       lex_get_char           __PROTO((LEX *lf));
-void      lex_unget_char         __PROTO((LEX *lf));
-char *    lex_tok_to_str         __PROTO((int token));
-int       lex_get_token          __PROTO((LEX *lf));
+LEX *    lex_close_file         __PROTO((LEX *lf));
+LEX *    lex_open_file          __PROTO((LEX *lf, char *fname));
+int      lex_get_char           __PROTO((LEX *lf));
+void     lex_unget_char         __PROTO((LEX *lf));
+char *   lex_tok_to_str         __PROTO((int token));
+int      lex_get_token          __PROTO((LEX *lf));
 
 /* makepath.c */
 int make_path(
-           void *jcr,
-           const char *argpath,
-           int mode,
-           int parent_mode,
-           uid_t owner,
-           gid_t group,
-           int preserve_existing,
-           char *verbose_fmt_string);
+          void *jcr,
+          const char *argpath,
+          int mode,
+          int parent_mode,
+          uid_t owner,
+          gid_t group,
+          int preserve_existing,
+          char *verbose_fmt_string);
 
 
 /* message.c */
-void       my_name_is            __PROTO((int argc, char *argv[], char *name));
-void       init_msg              __PROTO((void *jcr, MSGS *msg));
-void       term_msg              __PROTO((void));
-void       close_msg             __PROTO((void *jcr));
-void       add_msg_dest          __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code));
-void       rem_msg_dest          __PROTO((MSGS *msg, int dest, int type, char *where));
-void       Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
-void       dispatch_message      __PROTO((void *jcr, int type, int level, char *buf));
-void       init_console_msg      __PROTO((char *wd));
+void      my_name_is            __PROTO((int argc, char *argv[], char *name));
+void      init_msg              __PROTO((void *jcr, MSGS *msg));
+void      term_msg              __PROTO((void));
+void      close_msg             __PROTO((void *jcr));
+void      add_msg_dest          __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code));
+void      rem_msg_dest          __PROTO((MSGS *msg, int dest, int type, char *where));
+void      Jmsg                  (void *jcr, int type, int level, char *fmt, ...);
+void      dispatch_message      __PROTO((void *jcr, int type, int level, char *buf));
+void      init_console_msg      __PROTO((char *wd));
+void      free_msgs_res(MSGS *msgs);
 
 
 /* bnet_server.c */
-void       bnet_thread_server(int port, int max_clients, workq_t *client_wq, 
-                   void handle_client_request(void *bsock));
-void             bnet_server             __PROTO((int port, void handle_client_request(BSOCK *bsock)));
-int              net_connect             __PROTO((int port));
-BSOCK *          bnet_bind               __PROTO((int port));
-BSOCK *          bnet_accept             __PROTO((BSOCK *bsock, char *who));
+void      bnet_thread_server(int port, int max_clients, workq_t *client_wq, 
+                  void handle_client_request(void *bsock));
+void            bnet_server             __PROTO((int port, void handle_client_request(BSOCK *bsock)));
+int             net_connect             __PROTO((int port));
+BSOCK *         bnet_bind               __PROTO((int port));
+BSOCK *         bnet_accept             __PROTO((BSOCK *bsock, char *who));
 
 /* signal.c */
-void             init_signals             __PROTO((void terminate(int sig)));
-void             init_stack_dump          (void);
+void            init_signals             __PROTO((void terminate(int sig)));
+void            init_stack_dump          (void);
 
 /* util.c */
-void             lcase                   __PROTO((char *str));
-void             bash_spaces             __PROTO((char *str));
-void             unbash_spaces           __PROTO((char *str));
-void             strip_trailing_junk     __PROTO((char *str));
-void             strip_trailing_slashes  __PROTO((char *dir));
-int              skip_spaces             __PROTO((char **msg));
-int              skip_nonspaces          __PROTO((char **msg));
-int              fstrsch                 __PROTO((char *a, char *b));
-char *           encode_time             __PROTO((time_t time, char *buf));
-char *           encode_mode             __PROTO((mode_t mode, char *buf));
-char *           edit_uint64_with_commas   __PROTO((uint64_t val, char *buf));
-char *           add_commas              __PROTO((char *val, char *buf));
-char *           edit_uint64             (uint64_t val, char *buf);
-int              do_shell_expansion      (char *name);
-int              is_a_number             (const char *num);
-int              string_to_btime(char *str, btime_t *value);
-char             *edit_btime(btime_t val, char *buf);
+void            lcase                   __PROTO((char *str));
+void            bash_spaces             __PROTO((char *str));
+void            unbash_spaces           __PROTO((char *str));
+void            strip_trailing_junk     __PROTO((char *str));
+void            strip_trailing_slashes  __PROTO((char *dir));
+int             skip_spaces             __PROTO((char **msg));
+int             skip_nonspaces          __PROTO((char **msg));
+int             fstrsch                 __PROTO((char *a, char *b));
+char *          encode_time             __PROTO((time_t time, char *buf));
+char *          encode_mode             __PROTO((mode_t mode, char *buf));
+char *          edit_uint64_with_commas   __PROTO((uint64_t val, char *buf));
+char *          add_commas              __PROTO((char *val, char *buf));
+char *          edit_uint64             (uint64_t val, char *buf);
+int             do_shell_expansion      (char *name);
+int             is_a_number             (const char *num);
+int             string_to_btime(char *str, btime_t *value);
+char            *edit_btime(btime_t val, char *buf);
 
 
 /*
- *void           print_ls_output         __PROTO((char *fname, char *lname, int type, struct stat *statp));
+ *void          print_ls_output         __PROTO((char *fname, char *lname, int type, struct stat *statp));
  */
 
 /* watchdog.c */
index de9fdfe6913c38e4324c3543e27da1eabeaaf3a4..5cb3c147be5c1daeafe44fb40fd42195cdad57cb 100644 (file)
@@ -64,7 +64,7 @@ static void signal_handler(int sig)
    if (already_dead) {
       _exit(1);
    }
-   already_dead = TRUE;
+   already_dead = sig;
    if (sig == SIGTERM) {
       Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name);
    } else {
@@ -78,7 +78,7 @@ static void signal_handler(int sig)
       static char btpath[400];
       pid_t pid;
 
-      Dmsg1(000, "Kaboom! Got signal %d. Attempting traceback\n", sig);
+      fprintf(stderr, "Kaboom! Got signal %d. Attempting traceback.\n", sig);
       if (strlen(exepath) + 12 > (int)sizeof(btpath)) {
          strcpy(btpath, "btraceback");
       } else {
@@ -97,6 +97,7 @@ static void signal_handler(int sig)
       Dmsg1(300, "exepath=%s\n", exepath);
       switch (pid = fork()) {
       case -1:                       /* error */
+         fprintf(stderr, "Fork error: ERR=%s\n", strerror(errno));
         break;
       case 0:                        /* child */
         argv[0] = btpath;            /* path to btraceback */
@@ -118,6 +119,7 @@ static void signal_handler(int sig)
       if (pid > 0) {
          Dmsg0(500, "Doing waitpid\n");
         waitpid(pid, NULL, 0);       /* wait for child to produce dump */
+         fprintf(stderr, "Traceback complete, attempting cleanup ...\n");
          Dmsg0(500, "Done waitpid\n");
         exit_handler(1);             /* clean up if possible */
          Dmsg0(500, "Done exit_handler\n");
@@ -125,6 +127,7 @@ static void signal_handler(int sig)
          Dmsg0(500, "Doing sleep\n");
         sleep(30);
       }
+      fprintf(stderr, "It looks like the traceback worked ...\n");
    }
 #endif
 
index cbde11df75d95b8b58cb0516affc613c5be7edcc..dfc822c4d61f597af0c08acd04562edfac754631 100644 (file)
@@ -42,8 +42,6 @@
 #undef malloc
 #undef free
       
-#define FULL_SM_CHECK 1
-
 /*LINTLIBRARY*/
 
 
@@ -104,9 +102,7 @@ static void *smalloc(char *fname, int lineno, unsigned int nbytes)
           buf[nbytes - 1] = (((long) buf) & 0xFF) ^ 0xC5;
           buf += HEAD_SIZE;  /* Increment to user data start */
        }
-#ifdef FULL_SM_CHECK
        sm_check(fname, lineno, True);
-#endif
         Dmsg4(1150, "smalloc %d at %x from %s:%d\n", nbytes, buf, fname, lineno);
        return (void *) buf;
 }
@@ -132,9 +128,7 @@ void sm_free(char *file, int line, void *fp)
        char *cp = (char *) fp;
        struct b_queue *qp;
 
-#ifdef FULL_SM_CHECK
        sm_check(__FILE__, __LINE__, True);
-#endif
        if (cp == NULL) {
            Emsg2(M_ABORT, 0, "Attempt to free NULL called from %s:%d\n", file, line);
        }
@@ -224,9 +218,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
        void *buf;
        char *cp = (char *) ptr;
 
-#ifdef FULL_SM_CHECK
        sm_check(fname, lineno, True);
-#endif
        if (size <= 0) {
            e_msg(fname, lineno, M_ABORT, 0, "sm_realloc size: %d\n", size);
        }
@@ -266,9 +258,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
           sm_free(__FILE__, __LINE__, ptr);
        }
         Dmsg4(150, "sm_realloc %d at %x from %s:%d\n", size, buf, fname, lineno);
-#ifdef FULL_SM_CHECK
        sm_check(fname, lineno, True);
-#endif
        return buf;
 }
 
@@ -311,8 +301,10 @@ void actuallyfree(void *cp)
 }
 
 /*  SM_DUMP  --  Print orphaned buffers (and dump them if BUFDUMP is
-                True). */
-
+ *              True).
+ *  N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...)
+ *    as they have all been shut down at this point.
+ */
 void sm_dump(Boolean bufdump)
 {
        struct abufhead *ap = (struct abufhead *) abqueue.qnext;
@@ -364,6 +356,7 @@ void sm_dump(Boolean bufdump)
        }
 }
 
+#undef sm_check
 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
 void sm_check(char *fname, int lineno, Boolean bufdump)
 {
@@ -373,6 +366,7 @@ void sm_check(char *fname, int lineno, Boolean bufdump)
        }
 }
 
+#undef sm_check_rtn
 /*  SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
 int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
 {
index a3c21f92f1773fa8d8200fa80bbece8f1da88574..0ef4c84b277ea15eb866cce0f26e27f765c5da4a 100644 (file)
@@ -4,6 +4,8 @@
  *
  *   Kern E. Sibbald
  *
+ *    $Id$
+ *
  */
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
@@ -58,11 +60,12 @@ static void my_free_jcr(JCR *jcr)
 
 int main (int argc, char *argv[])
 {
-   int ch, i;
+   int ch;   
    FILE *fd;
    char line[1000];
 
    my_name_is(argc, argv, "bextract");
+   init_msg(NULL, NULL);             /* setup message handler */
 
    memset(ff, 0, sizeof(FF_PKT));
    init_include_exclude_files(ff);
@@ -117,13 +120,6 @@ int main (int argc, char *argv[])
       usage();
    }
 
-   /*
-    * Ensure that every message is always printed
-    */
-   for (i=1; i<=M_MAX; i++) {
-      add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
-   }
-
    jcr = new_jcr(sizeof(JCR), my_free_jcr);
    jcr->VolSessionId = 1;
    jcr->VolSessionTime = (uint32_t)time(NULL);
index 012014edc2411327860c3c04f950b94f52c7507a..9b648a6a6f825aa4201c64b4441ebb0e1a8c92bb 100644 (file)
@@ -123,7 +123,7 @@ void free_block(DEV_BLOCK *block)
    Dmsg1(199, "free_block buffer %x\n", block->buf);
    free_memory(block->buf);
    Dmsg1(199, "free_block block %x\n", block);
-   free_memory(block);
+   free_memory((POOLMEM *)block);
 }
 
 /* Empty the block -- for writing */
index 5fa23b504acf5f382787e8ecf641a2cae030f3c1..fbbdb52a52e7651d94b6f3421f3ed64bc6f46793 100644 (file)
@@ -2,6 +2,7 @@
  *
  *  Dumb program to do an "ls" of a Bacula 1.0 mortal file.
  *
+ *   $Id$
  */
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
@@ -67,6 +68,7 @@ int main (int argc, char *argv[])
    char line[1000];
 
    my_name_is(argc, argv, "bls");
+   init_msg(NULL, NULL);             /* initialize message handler */
 
    memset(&ff, 0, sizeof(ff));
    init_include_exclude_files(&ff);
@@ -144,20 +146,12 @@ int main (int argc, char *argv[])
       add_fname_to_include_list(&ff, 0, "/");
    }
 
-   /*
-    * Ensure that every message is always printed
-    */
-   for (i=1; i<=M_MAX; i++) {
-      add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
-   }
-
    /* Try default device */
    if (default_tape) {
       do_ls(DEFAULT_TAPE_DRIVE);
       return 0;
    }
 
-
    for (i=0; i < argc; i++) {
       if (list_blocks) {
         do_blocks(argv[i]);
index 6738d866c8d2b74eaf6f7440a59439cbdb83dbbe..b3483fbe99221b92609a737a3acde9bccb60f135 100644 (file)
@@ -6,6 +6,8 @@
  *
  *   Kern E. Sibbald, December 2001
  *
+ *
+ *   $Id$
  */
 /*
    Copyright (C) 2001, 2002 Kern Sibbald and John Walker
@@ -56,9 +58,10 @@ static void my_free_jcr(JCR *jcr)
 
 int main (int argc, char *argv[])
 {
-   int ch, i;
+   int ch;
 
    my_name_is(argc, argv, "bscan");
+   init_msg(NULL, NULL);
 
 
    while ((ch = getopt(argc, argv, "d:?")) != -1) {
@@ -83,13 +86,6 @@ int main (int argc, char *argv[])
       usage();
    }
 
-   /*
-    * Ensure that every message is always printed
-    */
-   for (i=1; i<=M_MAX; i++) {
-      add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
-   }
-
    jcr = new_jcr(sizeof(JCR), my_free_jcr);
    jcr->VolSessionId = 1;
    jcr->VolSessionTime = (uint32_t)time(NULL);
index b6e606a2c9c4344ec119ddb4b0dadf5b371f45b3..9dcb553dd9e0fcf2b6e1095ed3f0075e837c7891 100644 (file)
@@ -10,6 +10,8 @@
  *   Note, this program reads stored.conf, and will only
  *     talk to devices that are configured.
  *
+ *   $Id$
+ *
  */
 /*
    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
@@ -98,7 +100,7 @@ int read_dev(DEVICE *dev, char *buf, size_t len)
  */
 int main(int argc, char *argv[])
 {
-   int ch, i;
+   int ch;
 
    /* Sanity checks */
    if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) {
@@ -147,6 +149,7 @@ int main(int argc, char *argv[])
 
 
    my_name_is(argc, argv, "btape");
+   init_msg(NULL, NULL);
    
    if (signals) {
       init_signals(terminate_btape);
@@ -160,13 +163,6 @@ int main(int argc, char *argv[])
 
    parse_config(configfile);
 
-   /*
-    * Ensure that every message is always printed
-    */
-   for (i=1; i<=M_MAX; i++) {
-      add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL);
-   }
-
 
    /* See if we can open a device */
    if (argc) {
index 5333f91b5a0cbff948d4655daa5c9e71e71d72f7..a5fa9399a1ebe5d26ea5ed37d7008890a54e8aa5 100644 (file)
@@ -1017,13 +1017,13 @@ term_dev(DEVICE *dev)
       dev->dev_name = NULL;
    }
    if (dev->errmsg) {
-      free_memory(dev->errmsg);
+      free_pool_memory(dev->errmsg);
       dev->errmsg = NULL;
    }
    pthread_mutex_destroy(&dev->mutex);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);
    if (dev->state & ST_MALLOC) {
-      free_memory(dev);
+      free_pool_memory((POOLMEM *)dev);
    }
 }
index 2b021fb2ec693d50dc70efd3a12a0c1fec74c651..92a8ea1536eaad6edaebe0ede3bc23c1e85c3a3c 100644 (file)
@@ -104,7 +104,7 @@ void free_record(DEV_RECORD *rec)
    Dmsg0(150, "Enter free_record.\n");
    free_pool_memory(rec->data);
    Dmsg0(150, "Data buf is freed.\n");
-   free_pool_memory(rec);
+   free_pool_memory((POOLMEM *)rec);
    Dmsg0(150, "Leave free_record.\n");
 } 
 
index cfe86abc7590dcdea0887cd441b00d038b27cd29..8164dd0491c73bada5dc93c988d361ead4f9a378 100644 (file)
@@ -93,6 +93,7 @@ int main (int argc, char *argv[])
 
    init_stack_dump();
    my_name_is(argc, argv, "stored");
+   init_msg(NULL, NULL);
    daemon_start_time = time(NULL);
    memset(&last_job, 0, sizeof(last_job));
 
@@ -162,7 +163,6 @@ int main (int argc, char *argv[])
       configfile = bstrdup(CONFIG_FILE);
    }
 
-   init_msg(NULL, NULL);
    parse_config(configfile);
    check_config();
 
@@ -176,6 +176,8 @@ int main (int argc, char *argv[])
       init_stack_dump();             /* pick up new pid */
    }
 
+   create_pid_file(me->pid_directory, "bacula-sd", me->SDport);
+
    /*  ****FIXME**** clean this up */
    /* Create and attach to shared memory. This is a
     * hold over from the days of child processes. 
@@ -318,6 +320,15 @@ static void check_config()
       Emsg1(M_ABORT, 0, _("No Device resource defined in %s. Cannot continue.\n"),
           configfile);
    }
+   if (!me->messages) {
+      me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
+      if (!me->messages) {
+         Emsg1(M_ABORT, 0, _("No Messages resource defined in %s. Cannot continue.\n"),
+           configfile);
+      }
+   }
+   close_msg(NULL);                  /* close temp message handler */
+   init_msg(NULL, me->messages);      /* open daemon message handler */
 
    UnlockRes();
 
@@ -347,6 +358,7 @@ void terminate_stored(int sig)
    }
    in_here = TRUE;
 
+   delete_pid_file(me->pid_directory, "bacula-sd", me->SDport);
    stop_watchdog();
 
    Dmsg0(200, "In terminate_stored()\n");
@@ -363,13 +375,15 @@ void terminate_stored(int sig)
    free(configfile);
    free_config_resources();
 
-   if (debug_level > 10)
+   if (debug_level > 10) {
       print_memory_pool_stats();
+   }
+   term_msg();
    close_memory_pool();
 
-   if (shm)
-   free(shm);
-   term_msg();
+   if (shm) {
+      free(shm);
+   }
 
    sm_dump(False);                   /* dump orphaned buffers */
    exit(1);
index 7781e8c1dd08c39c2140e65dbe35b6b23842ef01..1c97cff4bb5f82c1b90858f276a7501e42e925a0 100644 (file)
@@ -53,6 +53,7 @@ static struct res_items store_items[] = {
    {"name",                  store_name, ITEM(res_store.hdr.name),   0, ITEM_REQUIRED, 0},
    {"description",           store_str,  ITEM(res_dir.hdr.desc),     0, 0, 0},
    {"address",               store_str,  ITEM(res_store.address),    0, ITEM_REQUIRED, 0},
+   {"messages",              store_res,  ITEM(res_store.messages),   0, R_MSGS, 0},
    {"sdport",                store_int,  ITEM(res_store.SDport),     0, ITEM_REQUIRED, 0},
    {"sddport",               store_int,  ITEM(res_store.SDDport),    0, 0, 0}, /* depricated */
    {"workingdirectory",      store_dir,  ITEM(res_store.working_directory), 0, ITEM_REQUIRED, 0},
@@ -194,6 +195,10 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
         break;
       case R_MSGS:
          sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
+        if (res->res_msgs.mail_cmd) 
+            sendit(sock, "      mailcmd=%s\n", res->res_msgs.mail_cmd);
+        if (res->res_msgs.operator_cmd) 
+            sendit(sock, "      opcmd=%s\n", res->res_msgs.operator_cmd);
         break;
       default:
          sendit(sock, _("Warning: unknown resource type %d\n"), type);
@@ -253,16 +258,21 @@ void free_resource(int type)
            free(res->res_msgs.mail_cmd);
         if (res->res_msgs.operator_cmd)
            free(res->res_msgs.operator_cmd);
+        free_msgs_res((MSGS *)res);  /* free message resource */
+        res = NULL;
         break;
       default:
          Dmsg1(0, "Unknown resource type %d\n", type);
         break;
    }
    /* Common stuff again -- free the resource, recurse to next one */
-   free(res);
+   if (res) {
+      free(res);
+   }
    resources[rindex].res_head = (RES *)nres;
-   if (nres)
+   if (nres) {
       free_resource(type);
+   }
 }
 
 /* Save the new resource by chaining it into the head list for
@@ -299,16 +309,26 @@ void save_resource(int type, struct res_items *items, int pass)
     */
    if (pass == 2) {
       switch (type) {
+        /* Resources not containing a resource */
         case R_DIRECTOR:
-        case R_STORAGE:
         case R_DEVICE:
         case R_MSGS:
            break;
+
+        /* Resources containing a resource */
+        case R_STORAGE:
+           if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) {
+               Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name);
+           }
+           res->res_store.messages = res_all.res_store.messages;
+           break;
         default:
             printf("Unknown resource type %d\n", type);
            error = 1;
            break;
       }
+
+
       if (res_all.res_dir.hdr.name) {
         free(res_all.res_dir.hdr.name);
         res_all.res_dir.hdr.name = NULL;
index 7855a392b10b83f65d6313b161c94c9fb9f0e9d7..dcbc81339692983037da57d6c781eb765a7301a8 100644 (file)
 
  */
 
-#define R_FIRST                       3001
+#define R_FIRST                      3001
 
-#define R_DIRECTOR                    3001
-#define R_STORAGE                     3002
-#define R_DEVICE                      3003
-#define R_MSGS                        3004
+#define R_DIRECTOR                   3001
+#define R_STORAGE                    3002
+#define R_DEVICE                     3003
+#define R_MSGS                       3004
 
-#define R_LAST                        R_MSGS
+#define R_LAST                       R_MSGS
 
 
-#define R_NAME                        3020
-#define R_ADDRESS                     3021
-#define R_PASSWORD                    3022
-#define R_TYPE                        3023
-#define R_BACKUP                      3024
+#define R_NAME                       3020
+#define R_ADDRESS                    3021
+#define R_PASSWORD                   3022
+#define R_TYPE                       3023
+#define R_BACKUP                     3024
 
 #define STORAGE_DAEMON 1
 
 /* Definition of the contents of each Resource */
 struct s_res_dir {
-   RES   hdr;
+   RES  hdr;
 
-   char *password;                    /* Director password */
-   char *address;                     /* Director IP address or zero */
+   char *password;                   /* Director password */
+   char *address;                    /* Director IP address or zero */
 };
 typedef struct s_res_dir DIRRES;
 
 
 /* Storage daemon "global" definitions */
 struct s_res_store {
-   RES   hdr;
+   RES  hdr;
 
    char *address;
-   int   SDport;                      /* Where we listen for Directors */
+   int  SDport;                      /* Where we listen for Directors */
    int   SDDport;                     /* "Data" port where we listen for File daemons */
-   char *working_directory;           /* working directory for checkpoints */
+   char *working_directory;          /* working directory for checkpoints */
    char *pid_directory;
    char *subsys_directory;
    uint32_t max_concurrent_jobs;      /* maximum concurrent jobs to run */
+   struct s_res_msgs *messages;       /* Daemon message handler */
 };
 typedef struct s_res_store STORES;
 
 /* Device specific definitions */
 struct s_res_dev {
-   RES   hdr;
+   RES  hdr;
 
    char *media_type;
    char *device_name;
-   int  cap_bits;
-   uint32_t max_rewind_wait;          /* maximum secs to wait for rewind */
-   uint32_t min_block_size;           /* min block size */
-   uint32_t max_block_size;           /* max block size */
-   uint32_t max_volume_jobs;          /* max jobs to put on one volume */
-   int64_t max_volume_files;          /* max files to put on one volume */
-   int64_t max_volume_size;           /* max bytes to put on one volume */
-   int64_t max_file_size;             /* max file size in bytes */
-   int64_t volume_capacity;           /* advisory capacity */
+   int cap_bits;
+   uint32_t max_rewind_wait;         /* maximum secs to wait for rewind */
+   uint32_t min_block_size;          /* min block size */
+   uint32_t max_block_size;          /* max block size */
+   uint32_t max_volume_jobs;         /* max jobs to put on one volume */
+   int64_t max_volume_files;         /* max files to put on one volume */
+   int64_t max_volume_size;          /* max bytes to put on one volume */
+   int64_t max_file_size;            /* max file size in bytes */
+   int64_t volume_capacity;          /* advisory capacity */
    DEVICE *dev;
 };
 typedef struct s_res_dev DEVRES;
 
 union u_res {
-   struct s_res_dir     res_dir;
-   struct s_res_store   res_store;
-   struct s_res_dev     res_dev;
-   struct s_res_msgs    res_msgs;
+   struct s_res_dir    res_dir;
+   struct s_res_store  res_store;
+   struct s_res_dev    res_dev;
+   struct s_res_msgs   res_msgs;
    RES hdr;
 };
 typedef union u_res URES;
index ee81553dffe2cf90462f06b135f270eca9e5271b..a9e51fb515b4a81e58dc8b9c871785ae09a77f6a 100644 (file)
@@ -1,8 +1,8 @@
 /* */
-#define VERSION "1.19"
+#define VERSION "1.20"
 #define VSTRING "1"
-#define DATE    "10 May 2002"
-#define LSMDATE "10May02"
+#define DATE    "16 May 2002"
+#define LSMDATE "16May02"
 
 /* Debug flags */
 #define DEBUG 1