]> git.sur5r.net Git - bacula/bacula/commitdiff
17Mar06
authorKern Sibbald <kern@sibbald.com>
Fri, 17 Mar 2006 17:42:42 +0000 (17:42 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 17 Mar 2006 17:42:42 +0000 (17:42 +0000)
- Implement regex test program in tools directory.
- Attempt to fix time problem with bsmtp with foreign langs.
- Add strip_trailing_newline() submitted by user.
- Implement regex matching in migrate.c
16Mar06
- Fix bug #537 to allow arbitrary time to mount a volume for
  restore, if polling is turned on.
- If dir_user or dir-group is specified in ./configure apply it to
  the working-dir. Fixes bug #533.
- If rescheduling a job cancel the previous incarnation with the SD.
  Fixes bugs #566 and 557.
- Fix bug #567 do_message() definition type conflict.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2836 91ce42f0-d328-0410-95d8-f526ca767f89

23 files changed:
bacula/Makefile.in
bacula/ReleaseNotes
bacula/kes-1.38
bacula/kes-1.39
bacula/src/dird/inc_conf.c
bacula/src/dird/migrate.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/recycle.c
bacula/src/dird/ua.h
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_prune.c
bacula/src/lib/dlist.c
bacula/src/lib/dlist.h
bacula/src/lib/protos.h
bacula/src/lib/scan.c
bacula/src/lib/tree.c
bacula/src/lib/tree.h
bacula/src/stored/acquire.c
bacula/src/tools/Makefile.in
bacula/src/tools/bsmtp.c
bacula/src/tools/regex.c [new file with mode: 0644]
bacula/src/version.h

index 64042e8390ab841cdf3f66e9c1500883d7627919..f6cd26a08a142e702a805bc2aff55581d4af298f 100755 (executable)
@@ -4,6 +4,8 @@
 @MCOMMON@
 
 working_dir=@working_dir@
+dir_group=@dir_group@
+dir_user=@dir_user@
 
 srcdir =       @srcdir@
 VPATH =        @srcdir@
@@ -88,6 +90,10 @@ installdirs:
        $(MKDIR) $(DESTDIR)$(sysconfdir)
        $(MKDIR) $(DESTDIR)$(scriptdir)
        $(MKDIR) $(DESTDIR)$(working_dir)
+       if test "x$(dir_user)" != "x" ; then \
+          chown -f $(dir_user) $(DESTDIR)$(working_dir); fi
+       if test "x$(dir_group)" != "x" ; then \
+          chown -f :$(dir_group) $(DESTDIR)$(working_dir); fi
 #      $(MKDIR) $(DESTDIR)$(mandir)
 
 gnomedirs:
index 53f9bbb104eeb2d60df5be36e096f9852ed2892f..1b9402964e303135cfbcfa401bf3e5cca66a308e 100644 (file)
@@ -1,5 +1,5 @@
 
-          Release Notes for Bacula 1.38.6-beta5
+          Release Notes for Bacula 1.38.6-beta6
 
   Bacula code: Total files = 419 Total lines = 137,078 (*.h *.c *.in)
       20,440 additional lines of code since version 1.36.3
@@ -49,6 +49,18 @@ Major bug fixes:
 Minor bug fixes:
 - See below:
 
+Release 1.38.6 beta6 16Mar06
+- Fix bug #537 to allow arbitrary time to mount a volume for
+  restore, if polling is turned on.     
+- Disallow multiple storage specifications for a job. Should fix Arno's
+  problem.
+- Add back a missing store of poolid in jr.poolid.    
+- If dir_user or dir-group is specified in ./configure apply it to
+  the working-dir. Fixes bug #533.
+- If rescheduling a job cancel the previous incarnation with the SD.
+  Fixes bugs #566 and 557.
+- Fix bug #567 do_message() definition type conflict.
+
 Release 1.38.6 beta5 14Mar06
 - Add more jcr methods and make mutex and use_count private.
 - Create lock/unlock methods for jcr.
index 4f2221c8f5276045bcab75171e8ecd6c45724269..548e218a386625dd5b3f70c983a025c84628c5d4 100644 (file)
@@ -2,6 +2,19 @@
                         Kern Sibbald
 
 General:
+16Mar06
+- Fix bug #537 to allow arbitrary time to mount a volume for
+  restore, if polling is turned on.     
+- Disallow multiple storage specifications for a job. Should fix Arno's
+  problem.
+- Add back a missing store of poolid in jr.poolid.    
+- If dir_user or dir-group is specified in ./configure apply it to
+  the working-dir. Fixes bug #533.
+- If rescheduling a job cancel the previous incarnation with the SD.
+  Fixes bugs #566 and 557.
+- Fix bug #567 do_message() definition type conflict.
+
+
 14Mar06
 - Add more jcr methods and make mutex and use_count private.
 - Create lock/unlock methods for jcr.
index 8ba0f81523da5a8a1c6e51c4f2fa893de5f571ad..ee005f41c63a329c504b1448fa329fa8bd414618 100644 (file)
@@ -2,6 +2,20 @@
                         Kern Sibbald
 
 General:
+17Mar06
+- Implement regex test program in tools directory.
+- Attempt to fix time problem with bsmtp with foreign langs.
+- Add strip_trailing_newline() submitted by user.
+- Implement regex matching in migrate.c
+16Mar06
+- Fix bug #537 to allow arbitrary time to mount a volume for
+  restore, if polling is turned on.     
+- If dir_user or dir-group is specified in ./configure apply it to
+  the working-dir. Fixes bug #533.
+- If rescheduling a job cancel the previous incarnation with the SD.
+  Fixes bugs #566 and 557.
+- Fix bug #567 do_message() definition type conflict.
+
 14Mar06
 - Add more jcr methods and make mutex and use_count private.
 - Create lock/unlock methods for jcr.
index 67ebde2ac8dcbe1c1ac8167898f0646dd700853f..38adb0b838eba656f05ddb86e172584327d3c3f9 100644 (file)
@@ -7,7 +7,7 @@
  *     Version $Id$
  */
 /*
-   Copyright (C) 2003-2005 Kern Sibbald
+   Copyright (C) 2003-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
index 4f94b3bb64d1346fd49ed576555450405fac0a40..1efd2441644b20d20bff3ad74f130a8dcf731b19 100644 (file)
@@ -32,6 +32,7 @@
 #include "bacula.h"
 #include "dird.h"
 #include "ua.h"
+#include <regex.h>
 
 static char OKbootstrap[] = "3000 OK bootstrap\n";
 static bool get_job_to_migrate(JCR *jcr);
@@ -217,7 +218,7 @@ bool do_migration(JCR *jcr)
         edit_uint64(jcr->JobId, ed1), jcr->Job);
 
    set_jcr_job_status(jcr, JS_Running);
-   set_jcr_job_status(jcr, JS_Running);
+   set_jcr_job_status(tjcr, JS_Running);
    Dmsg2(100, "JobId=%d JobLevel=%c\n", jcr->jr.JobId, jcr->jr.JobLevel);
    if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
       Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
@@ -262,7 +263,6 @@ bool do_migration(JCR *jcr)
       return false;
    }
 
-
    /*
     * Now start a Storage daemon message thread
     */
@@ -303,6 +303,38 @@ static int jobid_handler(void *ctx, int num_fields, char **row)
    return 0;
 }
 
+
+struct uitem {
+   dlink link;   
+   char *item;
+};
+
+static int item_compare(void *item1, void *item2)
+{
+   uitem *i1 = (uitem *)item1;
+   uitem *i2 = (uitem *)item2;
+   return strcmp(i1->item, i2->item);
+}
+
+static int unique_name_handler(void *ctx, int num_fields, char **row)
+{
+   dlist *list = (dlist *)ctx;
+
+   uitem *new_item = (uitem *)malloc(sizeof(uitem));
+   uitem *item;
+   
+   memset(new_item, 0, sizeof(uitem));
+   new_item->item = bstrdup(row[0]);
+
+   item = (uitem *)list->binary_insert((void *)new_item, item_compare);
+   if (item != new_item) {            /* already in list */
+      free(new_item->item);
+      free((char *)new_item);
+      return 0;
+   }
+   return 0;
+}
+
 const char *sql_smallest_vol = 
    "SELECT MediaId FROM Media,Pool WHERE"
    " VolStatus in ('Full','Used','Error') AND"
@@ -338,16 +370,14 @@ const char *sql_client =
    " Job.PoolId=Media.PoolId";
 
 const char *sql_job =
-   "SELECT DISTINCT Job.Name from Client,Pool,Media,Job,JobMedia "
+   "SELECT DISTINCT Job.Name from Pool,Media,Job,JobMedia "
    " WHERE Media.PoolId=Pool.PoolId AND Pool.Name='%s' AND"
-   " JobMedia.JobId=Job.JobId AND Job.ClientId=Client.ClientId AND"
-   " Job.PoolId=Media.PoolId";
+   " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId";
 
 const char *sql_ujobid =
    "SELECT DISTINCT Job.Job from Client,Pool,Media,Job,JobMedia "
    " WHERE Media.PoolId=Pool.PoolId AND Pool.Name='%s' AND"
-   " JobMedia.JobId=Job.JobId AND Job.ClientId=Client.ClientId AND"
-   " Job.PoolId=Media.PoolId";
+   " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId";
 
 const char *sql_vol = 
    "SELECT DISTINCT VolumeName FROM Media,Pool WHERE"
@@ -355,7 +385,6 @@ const char *sql_vol =
    " Media.PoolId=Pool.PoolId AND Pool.Name='%s'";
 
 
-
 /*
  * Returns: false on error
  *          true  if OK and jcr->previous_jr filled in
@@ -366,8 +395,12 @@ static bool get_job_to_migrate(JCR *jcr)
    POOL_MEM query(PM_MESSAGE);
    POOLMEM *JobIds = get_pool_memory(PM_MESSAGE);
    JobId_t JobId;
-   int stat;
+   int stat, rc;
    char *p;
+   dlist *item_chain;
+   uitem *item; 
+   char prbuf[500];
+   regex_t preg;
 
    if (jcr->MigrateJobId != 0) {
       jcr->previous_jr.JobId = jcr->MigrateJobId;
@@ -386,6 +419,7 @@ static bool get_job_to_migrate(JCR *jcr)
             Jmsg(jcr, M_INFO, 0, _("No Volumes found to migrate.\n"));
             goto ok_out;
          }
+         /* ***FIXME*** must loop over JobIds */
          Mmsg(query, sql_jobids_from_mediaid, JobIds);
          JobIds[0] = 0;
          if (!db_sql_query(jcr->db, query.c_str(), jobid_handler, (void *)JobIds)) {
@@ -405,7 +439,7 @@ static bool get_job_to_migrate(JCR *jcr)
             goto bail_out;
          }
          if (JobIds[0] == 0) {
-            Jmsg(jcr, M_INFO, 0, _("No jobs found to migrate.\n"));
+            Jmsg(jcr, M_INFO, 0, _("No Volume found to migrate.\n"));
             goto ok_out;
          }
          Mmsg(query, sql_jobids_from_mediaid, JobIds);
@@ -434,10 +468,103 @@ static bool get_job_to_migrate(JCR *jcr)
       case MT_POOL_TIME:
          break;
       case MT_CLIENT:
+         if (!jcr->job->selection_pattern) {
+            Jmsg(jcr, M_FATAL, 0, _("No selection pattern specified.\n"));
+            goto bail_out;
+         }
+         rc = regcomp(&preg, jcr->job->selection_pattern, REG_EXTENDED);
+         if (rc != 0) {
+            regerror(rc, &preg, prbuf, sizeof(prbuf));
+            Jmsg(jcr, M_FATAL, 0, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
+                 jcr->job->selection_pattern, prbuf);
+         }
+         item_chain = New(dlist(item, &item->link));
+         Mmsg(query, sql_client, jcr->pool->hdr.name);
+         Dmsg1(100, "query=%s\n", query.c_str());
+         if (!db_sql_query(jcr->db, query.c_str(), unique_name_handler, 
+              (void *)item_chain)) {
+            Jmsg(jcr, M_FATAL, 0,
+                 _("SQL to get Client failed. ERR=%s\n"), db_strerror(jcr->db));
+            goto bail_out;
+         }
+         /* Now apply the regex and create the jobs */
+         foreach_dlist(item, item_chain) {
+            const int nmatch = 30;
+            regmatch_t pmatch[nmatch];
+            rc = regexec(&preg, item->item, nmatch, pmatch,  0);
+            if (rc == 0) {
+               Dmsg1(000, "Do Client=%s\n", item->item);
+            }
+            free(item->item);
+         }
+         regfree(&preg);
+         delete item_chain;
          break;
       case MT_VOLUME:
+         if (!jcr->job->selection_pattern) {
+            Jmsg(jcr, M_FATAL, 0, _("No selection pattern specified.\n"));
+            goto bail_out;
+         }
+         rc = regcomp(&preg, jcr->job->selection_pattern, REG_EXTENDED);
+         if (rc != 0) {
+            regerror(rc, &preg, prbuf, sizeof(prbuf));
+            Jmsg(jcr, M_FATAL, 0, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
+                 jcr->job->selection_pattern, prbuf);
+         }
+         item_chain = New(dlist(item, &item->link));
+         Mmsg(query, sql_vol, jcr->pool->hdr.name);
+         Dmsg1(100, "query=%s\n", query.c_str());
+         if (!db_sql_query(jcr->db, query.c_str(), unique_name_handler, 
+              (void *)item_chain)) {
+            Jmsg(jcr, M_FATAL, 0,
+                 _("SQL to get Job failed. ERR=%s\n"), db_strerror(jcr->db));
+            goto bail_out;
+         }
+         /* Now apply the regex and create the jobs */
+         foreach_dlist(item, item_chain) {
+            const int nmatch = 30;
+            regmatch_t pmatch[nmatch];
+            rc = regexec(&preg, item->item, nmatch, pmatch,  0);
+            if (rc == 0) {
+               Dmsg1(000, "Do Vol=%s\n", item->item);
+            }
+            free(item->item);
+         }
+         regfree(&preg);
+         delete item_chain;
          break;
       case MT_JOB:
+         if (!jcr->job->selection_pattern) {
+            Jmsg(jcr, M_FATAL, 0, _("No selection pattern specified.\n"));
+            goto bail_out;
+         }
+         rc = regcomp(&preg, jcr->job->selection_pattern, REG_EXTENDED);
+         if (rc != 0) {
+            regerror(rc, &preg, prbuf, sizeof(prbuf));
+            Jmsg(jcr, M_FATAL, 0, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
+                 jcr->job->selection_pattern, prbuf);
+         }
+         item_chain = New(dlist(item, &item->link));
+         Mmsg(query, sql_job, jcr->pool->hdr.name);
+         Dmsg1(100, "query=%s\n", query.c_str());
+         if (!db_sql_query(jcr->db, query.c_str(), unique_name_handler, 
+              (void *)item_chain)) {
+            Jmsg(jcr, M_FATAL, 0,
+                 _("SQL to get Job failed. ERR=%s\n"), db_strerror(jcr->db));
+            goto bail_out;
+         }
+         /* Now apply the regex and create the jobs */
+         foreach_dlist(item, item_chain) {
+            const int nmatch = 30;
+            regmatch_t pmatch[nmatch];
+            rc = regexec(&preg, item->item, nmatch, pmatch,  0);
+            if (rc == 0) {
+               Dmsg1(000, "Do Job=%s\n", item->item);
+            }
+            free(item->item);
+         }
+         regfree(&preg);
+         delete item_chain;
          break;
       case MT_SQLQUERY:
          JobIds[0] = 0;
index 42dd9446e57d853cd982f621078a7ce720f7b8b4..524c2e520b52a2c25dd9882b7f18cb3280865958 100644 (file)
@@ -141,6 +141,16 @@ bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
    if (jcr->fileset->MD5[0] == 0) {
       bstrncpy(jcr->fileset->MD5, "**Dummy**", sizeof(jcr->fileset->MD5));
    }
+   /* If rescheduling, cancel the previous incarnation of this job
+    *  with the SD, which might be waiting on the FD connection.
+    *  If we do not cancel it the SD will not accept a new connection
+    *  for the same jobid.
+    */
+   if (jcr->reschedule_count) {
+      bnet_fsend(sd, "cancel Job=%s\n", jcr->Job);
+      while (bnet_recv(sd) >= 0)
+         { }
+   } 
    bnet_fsend(sd, jobcmd, jcr->JobId, jcr->Job, jcr->job->hdr.name,
               jcr->client->hdr.name, jcr->JobType, jcr->JobLevel,
               jcr->fileset->hdr.name, !jcr->pool->catalog_files,
index db1d32f6d296390a142bcb0e55b4663533057a10..03b4e4d45f14c88076925c167d699ff642bb6857 100644 (file)
@@ -34,9 +34,9 @@ extern int do_autoprune(JCR *jcr);
 extern int prune_volumes(JCR *jcr);
 
 /* autorecycle.c */
-extern int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
+extern bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
 extern int recycle_volume(JCR *jcr, MEDIA_DBR *mr);
-extern int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
+extern bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
 
 /* backup.c */
 extern int wait_for_job_termination(JCR *jcr);
index f034fae717526289488cb2149ae3a1d2b990f910..b8d0fc9d5615fa9776c3852e3135f591ad697427 100644 (file)
@@ -46,23 +46,23 @@ static int oldest_handler(void *ctx, int num_fields, char **row)
 
 /* Forward referenced functions */
 
-int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
+bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
 {
    bstrncpy(mr->VolStatus, "Recycle", sizeof(mr->VolStatus));
    if (db_find_next_volume(jcr, jcr->db, 1, InChanger, mr)) {
       jcr->MediaId = mr->MediaId;
       Dmsg1(20, "Find_next_vol MediaId=%u\n", jcr->MediaId);
       pm_strcpy(jcr->VolumeName, mr->VolumeName);
-      return 1;
+      return true;
    }
-   return 0;
+   return false;
 }
 
 
 /*
  *   Look for oldest Purged volume
  */
-int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
+bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
 {
    struct s_oldest_ctx oldest;
    char ed1[50];
@@ -88,7 +88,7 @@ int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
       Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
       Dmsg0(100, "return 0  recycle_oldest_purged_volume query\n");
       free_pool_memory(query);
-      return 0;
+      return false;
    }
    free_pool_memory(query);
    Dmsg1(100, "Oldest mediaid=%d\n", oldest.MediaId);
@@ -98,13 +98,13 @@ int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
          if (recycle_volume(jcr, mr)) {
             Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\"\n"), mr->VolumeName);
             Dmsg1(100, "return 1  recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName);
-            return 1;
+            return true;
          }
       }
       Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
    }
    Dmsg0(100, "return 0  recycle_oldest_purged_volume end\n");
-   return 0;
+   return false;
 }
 
 /*
index e88143095a48c3a2771fc557d0d66b6d0424eaa9..b06f62c7cb720c10e474698f9b755e36b5287fbc 100644 (file)
@@ -98,7 +98,7 @@ struct RESTORE_CTX {
    NAME_LIST name_list;
 };
 
-#define MAX_ID_LIST_LEN 1000000
+#define MAX_ID_LIST_LEN 2000000
 
 
 #endif
index 688ceb876469eda8606d67212a90a66aed49540d..60f9c62e090341d249a129d41b05b308cb450a34 100644 (file)
@@ -37,7 +37,7 @@ extern const char *client_backups;
 extern int console_msg_pending;
 
 /* Imported functions */
-extern int do_messages(UAContext *ua, const char *cmd);
+extern void do_messages(UAContext *ua, const char *cmd);
 extern int quit_cmd(UAContext *ua, const char *cmd);
 extern int qhelp_cmd(UAContext *ua, const char *cmd);
 extern int qstatus_cmd(UAContext *ua, const char *cmd);
index 7fdd575407b13a4011ddda7080a92a4399d75977..c6e8dd0d13be2caa5c4d600594719a0008a419d1 100644 (file)
@@ -30,7 +30,7 @@
 /* Forward referenced functions */
 
 
-#define MAX_DEL_LIST_LEN 1000000
+#define MAX_DEL_LIST_LEN 2000000
 
 /* Imported variables */
 extern char *select_job;
@@ -46,6 +46,7 @@ extern char *del_File;
 extern char *upd_Purged;
 extern char *cnt_DelCand;
 extern char *del_Job;
+extern char *del_MAC;
 extern char *del_JobMedia;
 extern char *cnt_JobMedia;
 extern char *sel_JobMedia;
@@ -556,6 +557,8 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr)
       db_sql_query(ua->db, query, NULL, (void *)NULL);
       Mmsg(query, del_JobMedia, ed1);
       db_sql_query(ua->db, query, NULL, (void *)NULL);
+      Mmsg(query, del_MAC, ed1);
+      db_sql_query(ua->db, query, NULL, (void *)NULL);
       Dmsg1(050, "Del sql=%s\n", query);
       del.num_del++;
    }
@@ -567,8 +570,18 @@ int prune_volume(UAContext *ua, MEDIA_DBR *mr)
          del.num_del == 1 ? "Job" : "Jobs", mr->VolumeName);
    }
 
-   /* If purged, mark it so */
-   if (del.num_ids == del.num_del) {
+   /*
+    * Find out how many Jobs remain on this Volume by
+    *  counting the JobMedia records.
+    */
+   cnt.count = 0;
+   Mmsg(query, cnt_JobMedia, edit_int64(mr->MediaId, ed1));
+   if (!db_sql_query(ua->db, query, count_handler, (void *)&cnt)) {
+      bsendmsg(ua, "%s", db_strerror(ua->db));
+      Dmsg0(050, "Count failed\n");
+      goto bail_out;
+   }
+   if (cnt.count == 0) {
       Dmsg0(200, "Volume is purged.\n");
       stat = mark_media_purged(ua, mr);
    }
index 9fff70c1730f3fefbb5de7da5ff6e846cb24289b..f3d59b1ce613fd1c17edeb530f7d6978ac8b0692 100644 (file)
@@ -2,7 +2,7 @@
  *  Bacula doubly linked list routines.
  *
  *    dlist is a doubly linked list with the links being in the
- *      list data item.
+ *       list data item.
  *
  *   Kern Sibbald, July MMIII
  *
@@ -10,7 +10,7 @@
  *
  */
 /*
-   Copyright (C) 2003-2005 Kern Sibbald
+   Copyright (C) 2003-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -41,8 +41,8 @@ void dlist::append(void *item)
       ((dlink *)(((char *)tail)+loffset))->next = item;
    }
    tail = item;
-   if (head == NULL) {               /* if empty list, */
-      head = item;                   /* item is head as well */
+   if (head == NULL) {                /* if empty list, */
+      head = item;                    /* item is head as well */
    }
    num_items++;
 }
@@ -58,8 +58,8 @@ void dlist::prepend(void *item)
       ((dlink *)(((char *)head)+loffset))->prev = item;
    }
    head = item;
-   if (tail == NULL) {               /* if empty list, */
-      tail = item;                   /* item is tail too */
+   if (tail == NULL) {                /* if empty list, */
+      tail = item;                    /* item is tail too */
    }
    num_items++;
 }
@@ -102,8 +102,8 @@ void dlist::insert_after(void *item, void *where)
  *  Insert an item in the list, but only if it is unique
  *  otherwise, the item is returned non inserted
  *
- * Returns: item        if item inserted
- *         other_item   if same value already exists (item not inserted)
+ * Returns: item         if item inserted
+ *          other_item   if same value already exists (item not inserted)
  */
 void *dlist::binary_insert(void *item, int compare(void *item1, void *item2))
 {
@@ -119,16 +119,16 @@ void *dlist::binary_insert(void *item, int compare(void *item1, void *item2))
    if (num_items == 1) {
       comp = compare(item, first());
       if (comp < 0) {
-        prepend(item);
+         prepend(item);
        //Dmsg0(000, "Insert before first.\n");
-        return item;
+         return item;
       } else if (comp > 0) {
-        insert_after(item, first());
+         insert_after(item, first());
        //Dmsg0(000, "Insert after first.\n");
-        return item;
+         return item;
       } else {
        //Dmsg0(000, "Same as first.\n");
-        return first();
+         return first();
       }
    }
    /* Check against last item */
@@ -164,25 +164,25 @@ void *dlist::binary_insert(void *item, int compare(void *item1, void *item2))
       int nxt;
       nxt = (low + high) / 2;
       while (nxt > cur) {
-        cur_item = next(cur_item);
-        cur++;
+         cur_item = next(cur_item);
+         cur++;
       }
       while (nxt < cur) {
-        cur_item = prev(cur_item);
-        cur--;
+         cur_item = prev(cur_item);
+         cur--;
       }
     //Dmsg1(000, "Compare item to %d\n", cur);
       comp = compare(item, cur_item);
     //Dmsg2(000, "Compare item to %d = %d\n", cur, comp);
       if (comp < 0) {
-        high = cur;
+         high = cur;
        //Dmsg2(000, "set high; low=%d high=%d\n", low, high);
       } else if (comp > 0) {
-        low = cur + 1;
+         low = cur + 1;
        //Dmsg2(000, "set low; low=%d high=%d\n", low, high);
       } else {
        //Dmsg1(000, "Same as item %d\n", cur);
-        return cur_item;
+         return cur_item;
       }
    }
    if (high == cur) {
@@ -225,9 +225,9 @@ void *dlist::binary_search(void *item, int compare(void *item1, void *item2))
    if (num_items == 1) {
       comp = compare(item, cur_item);
       if (comp == 0) {
-        return cur_item;
+         return cur_item;
       } else {
-        return NULL;
+         return NULL;
       }
    }
    low = 1;
@@ -239,35 +239,35 @@ void *dlist::binary_search(void *item, int compare(void *item1, void *item2))
       nxt = (low + high) / 2;
       /* Now get cur pointing to nxt */
       while (nxt > cur) {
-        cur_item = next(cur_item);
-        cur++;
+         cur_item = next(cur_item);
+         cur++;
       }
       while (nxt < cur) {
-        cur_item = prev(cur_item);
-        cur--;
+         cur_item = prev(cur_item);
+         cur--;
       }
       comp = compare(item, cur_item);
       //Dmsg2(000, "Compare item to %d = %d\n", cur, comp);
       if (comp < 0) {
-        high = cur;
+         high = cur;
          //Dmsg2(000, "set high; low=%d high=%d\n", low, high);
       } else if (comp > 0) {
-        low = cur + 1;
+         low = cur + 1;
          //Dmsg2(000, "set low; low=%d high=%d\n", low, high);
       } else {
-        return cur_item;
+         return cur_item;
       }
    }
    /*
     * low == high can only happen if low just 
-    *  got incremented from cur, and we have
-    *  not yet tested cur+1
+    *   got incremented from cur, and we have
+    *   not yet tested cur+1
     */
    if (low == high) {
       cur_item = next(cur_item);
       comp = compare(item, cur_item);
       if (comp == 0) {
-        return cur_item;
+         return cur_item;
       }
    }
    return NULL;
@@ -281,15 +281,15 @@ void dlist::remove(void *item)
    if (item == head) {
       head = ilink->next;
       if (head) {
-        ((dlink *)(((char *)head)+loffset))->prev = NULL;
+         ((dlink *)(((char *)head)+loffset))->prev = NULL;
       }
       if (item == tail) {
-        tail = ilink->prev;
+         tail = ilink->prev;
       }
    } else if (item == tail) {
       tail = ilink->prev;
       if (tail) {
-        ((dlink *)(((char *)tail)+loffset))->next = NULL;
+         ((dlink *)(((char *)tail)+loffset))->next = NULL;
       }
    } else {
       xitem = ilink->next;
@@ -371,7 +371,7 @@ int main()
       jcr->buf = bstrdup(buf);
       jcr_chain->prepend(jcr);
       if (i == 10) {
-        save_jcr = jcr;
+         save_jcr = jcr;
       }
    }
 
@@ -401,7 +401,7 @@ int main()
       jcr->buf = bstrdup(buf);
       jcr_chain->append(jcr);
       if (i == 10) {
-        save_jcr = jcr;
+         save_jcr = jcr;
       }
    }
 
@@ -432,21 +432,21 @@ int main()
    int count = 0;
    for (int i=0; i<CNT; i++) {
       for (int j=0; j<CNT; j++) {
-        for (int k=0; k<CNT; k++) {
-           count++;
-           if ((count & 0x3FF) == 0) {
+         for (int k=0; k<CNT; k++) {
+            count++;
+            if ((count & 0x3FF) == 0) {
                Dmsg1(000, "At %d\n", count);
-           }
-           jcr = (MYJCR *)malloc(sizeof(MYJCR));
-           jcr->buf = bstrdup(buf);
-           jcr1 = (MYJCR *)jcr_chain->binary_insert(jcr, my_compare);
-           if (jcr != jcr1) {
+            }
+            jcr = (MYJCR *)malloc(sizeof(MYJCR));
+            jcr->buf = bstrdup(buf);
+            jcr1 = (MYJCR *)jcr_chain->binary_insert(jcr, my_compare);
+            if (jcr != jcr1) {
                Dmsg2(000, "Insert of %s vs %s failed.\n", jcr->buf, jcr1->buf);
-           }
-           buf[1]--;
-        }
+            }
+            buf[1]--;
+         }
          buf[1] = 'Z';
-        buf[2]--;
+         buf[2]--;
       }
       buf[2] = 'Z';
       buf[0]--;
index ce975f486593d27e729eaac27bf435274228d289..40c54f013379ee396a81b902b6bd5c9afa2599d2 100644 (file)
@@ -2,7 +2,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2004-2005 Kern Sibbald
+   Copyright (C) 2004-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
index eedbc018cbc081881311cff0cd6291ccc91ff9e9..e24292a7c311ad7574597db4d7ab31a07d79e2fb 100644 (file)
@@ -235,6 +235,8 @@ void             init_stack_dump          (void);
 /* scan.c */
 void             strip_leading_space     (char *str);
 void             strip_trailing_junk     (char *str);
+void             strip_trailing_newline  (char *str);
+
 void             strip_trailing_slashes  (char *dir);
 bool             skip_spaces             (char **msg);
 bool             skip_nonspaces          (char **msg);
index cfb5751300de698e97bd015f0090bebdd4a42bf5..53c40242104bf875df494576396a809dad3f7ab2 100644 (file)
@@ -49,6 +49,16 @@ void strip_trailing_junk(char *cmd)
       *p-- = 0;
 }
 
+/* Strip any trailing newline characters from the string */
+void strip_trailing_newline(char *cmd)
+{
+   char *p;
+   p = cmd + strlen(cmd) - 1;
+
+   while ((p >= cmd) && (*p == '\n' || *p == '\r'))
+      *p-- = 0;
+}
+
 /* Strip any trailing slashes from a directory path */
 void strip_trailing_slashes(char *dir)
 {
index 6035e72f381233dcd49097eac570f95e1947299a..b223ef8a94f3d26e57c724b36dc0a00277892a08 100755 (executable)
@@ -5,7 +5,7 @@
  *
 */
 /*
-   Copyright (C) 2002-2005 Kern Sibbald
+   Copyright (C) 2002-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
index 3a696e235d835ac2c7c7ddfa0b7c93c4d339f1ae..c5faa14945dfa5461d250aec7e45d10fc4a9e961 100644 (file)
@@ -5,7 +5,7 @@
  *
 */
 /*
-   Copyright (C) 2002-2005 Kern Sibbald
+   Copyright (C) 2002-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
index 9528f786c562748af04b009f7421e88501bca29f..34b28609862e99a480acad067d92bee711086fbf 100644 (file)
@@ -47,6 +47,7 @@ bool acquire_device_for_read(DCR *dcr)
    bool try_autochanger = true;
    int i;
    int vol_label_status;
+   int retry = 0;
    
    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
    dev->block(BST_DOING_ACQUIRE);
@@ -156,7 +157,11 @@ bool acquire_device_for_read(DCR *dcr)
       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
    }
    
-   for (i=0; i<5; i++) {
+   for ( ;; ) {
+      /* If not polling limit retries */
+      if (!dev->poll && retry++ > 10) {
+         break;
+      }
       dev->clear_labeled();              /* force reread of label */
       if (job_canceled(jcr)) {
          Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
@@ -205,6 +210,12 @@ bool acquire_device_for_read(DCR *dcr)
             tape_initially_mounted = false;
             goto default_path;
          }
+         /* If polling and got a previous bad name, ignore it */
+         if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
+            goto default_path;
+         } else {
+             bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
+         }
          /* Fall through */
       default:
          Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
index 2debf389cb351c618d95e5e90348d8fdf5c3a380..d9614403923e6059924ed37c252815dff5a03644 100644 (file)
@@ -38,7 +38,7 @@ EXTRAOBJS = @OBJLIST@
 DIRCONFOBJS = ../dird/dird_conf.o ../dird/run_conf.o ../dird/inc_conf.o
 
 NODIRTOOLS = bsmtp
-DIRTOOLS = bsmtp dbcheck fstype testfind testls
+DIRTOOLS = bsmtp dbcheck fstype testfind testls regex
 TOOLS = $(@DIR_TOOLS@)
 
 INSNODIRTOOLS = bsmtp
@@ -75,6 +75,11 @@ testls: ../findlib/libfind.a ../lib/libbac.a testls.o
        $(CXX) -g $(LDFLAGS) -L. -L../lib -L../findlib -o $@ testls.o \
          $(DLIB) -lfind -lbac -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
 
+regex: ../findlib/libfind.a ../lib/libbac.a regex.o
+       $(CXX) -g $(LDFLAGS) -L. -L../lib -o $@ regex.o \
+         $(DLIB) -lbac -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
+
+
 Makefile: $(srcdir)/Makefile.in $(topdir)/config.status
        cd $(topdir) \
          && CONFIG_FILES=$(thisdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
index ab6883db736c914bb0fc37687b740159a84d315c..cb994bdf20545330d2aa89fe7c4cbff58234a403 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2001-2005 Kern Sibbald
+  Copyright (C) 2001-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -147,7 +147,7 @@ int main (int argc, char *argv[])
     time_t now = time(NULL);
     struct tm tm;
     
-   setlocale(LC_ALL, "");
+   setlocale(LC_ALL, "en_US");
    bindtextdomain("bacula", LOCALEDIR);
    textdomain("bacula");
 
@@ -313,35 +313,46 @@ hp:
     *  Send message header
     */
    fprintf(sfp, "From: %s\r\n", from_addr);
+   Dmsg1(10, "From: %s\r\n", from_addr);
    if (subject) {
       fprintf(sfp, "Subject: %s\r\n", subject);
+      Dmsg1(10, "Subject: %s\r\n", subject);
    }
    if (reply_addr) {
       fprintf(sfp, "Reply-To: %s\r\n", reply_addr);
+      Dmsg1(10, "Reply-To: %s\r\n", reply_addr);
    }
    if (err_addr) {
       fprintf(sfp, "Errors-To: %s\r\n", err_addr);
+      Dmsg1(10, "Errors-To: %s\r\n", err_addr);
    }
    if ((pwd = getpwuid(getuid())) == 0) {
       fprintf(sfp, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname);
+      Dmsg2(10, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname);
    } else {
       fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
+      Dmsg2(10, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
    }
 
    fprintf(sfp, "To: %s", argv[0]);
+   Dmsg1(10, "To: %s", argv[0]);
    for (i = 1; i < argc; i++) {
       fprintf(sfp, ",%s", argv[i]);
+      Dmsg1(10, ",%s", argv[i]);
    }
 
    fprintf(sfp, "\r\n");
+   Dmsg0(10, "\r\n");
    if (cc_addr) {
       fprintf(sfp, "Cc: %s\r\n", cc_addr);
+      Dmsg1(10, "Cc: %s\r\n", cc_addr);
    }
 
    /* Add RFC822 date */
    localtime_r(&now, &tm);
    strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", &tm);
    fprintf(sfp, "Date: %s\r\n", buf);
+   Dmsg1(10, "Date: %s\r\n", buf);
 
    fprintf(sfp, "\r\n");
 
diff --git a/bacula/src/tools/regex.c b/bacula/src/tools/regex.c
new file mode 100644 (file)
index 0000000..c2dcd58
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Test program for testing regular expressions.
+ */
+/*
+   Copyright (C) 2006 Kern Sibbald
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
+
+ */
+
+#include "bacula.h"
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
+
+
+static void usage()
+{
+   fprintf(stderr,
+"\n"
+"Usage: regex [-d debug_level] -f <data-file>\n"
+"       -f          specify file of data to be matched\n"
+"       -l          suppress line numbers\n"
+"       -n          print lines that do not match\n"
+"       -?          print this message.\n"
+"\n\n");
+
+   exit(1);
+}
+
+
+int main(int argc, char *const *argv)
+{
+#ifndef HAVE_REGEX_H
+   printf("The regex libraries don't seem to be available.\n");
+   exit(1);
+#else
+   regex_t preg;
+   char prbuf[500];
+   char *fname = NULL;
+   int rc, ch;
+   char data[1000];
+   char pat[500];
+   FILE *fd;
+   bool match_only = true;
+   int lineno;
+   bool no_linenos = false;
+   
+
+   setlocale(LC_ALL, "");
+   bindtextdomain("bacula", LOCALEDIR);
+   textdomain("bacula");
+
+   while ((ch = getopt(argc, argv, "d:f:n?")) != -1) {
+      switch (ch) {
+      case 'd':                       /* set debug level */
+         debug_level = atoi(optarg);
+         if (debug_level <= 0) {
+            debug_level = 1;
+         }
+         break;
+
+      case 'f':                       /* data */
+         fname = optarg;
+         break;
+
+      case 'l':
+         no_linenos = true;
+         break;
+
+      case 'n':
+         match_only = false;
+         break;
+
+      case '?':
+      default:
+         usage();
+
+      }
+   }
+   argc -= optind;
+   argv += optind;
+
+   if (!fname) {
+      printf("A data file must be specified.\n");
+      usage();
+   }
+
+   for ( ;; ) {
+      printf("Enter regex pattern: ");
+      if (fgets(pat, sizeof(pat)-1, stdin) == NULL) {
+         break;
+      }
+      strip_trailing_newline(pat);
+      if (pat[0] == 0) {
+         exit(0);
+      }
+      rc = regcomp(&preg, pat, REG_EXTENDED);
+      if (rc != 0) {
+         regerror(rc, &preg, prbuf, sizeof(prbuf));
+         printf("Regex compile error: %s\n", prbuf);
+         continue;
+      }
+      fd = fopen(fname, "r");
+      if (!fd) {
+         printf(_("Could not open data file: %s\n"), fname);
+         exit(1);
+      }
+      lineno = 0;
+      while (fgets(data, sizeof(data)-1, fd)) {
+         const int nmatch = 30;
+         regmatch_t pmatch[nmatch];
+         strip_trailing_newline(data);
+         lineno++;
+         rc = regexec(&preg, data, nmatch, pmatch,  0);
+         if ((match_only && rc == 0) || (!match_only && rc != 0)) {
+            if (no_linenos) {
+               printf("%s\n", data);
+            } else {
+               printf("%5d: %s\n", lineno, data);
+            }
+         }
+      }
+      fclose(fd);
+      regfree(&preg);
+   }
+   exit(0);
+#endif
+}
index e65726357cf5065a499c78e2c0693abc1ba2c113..575634919145814749fd4ef0442a4fc6822d3ea7 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "1.39.6"
-#define BDATE   "14 March 2006"
-#define LSMDATE "14Mar06"
+#define BDATE   "17 March 2006"
+#define LSMDATE "17Mar06"
 
 /* Debug flags */
 #undef  DEBUG