]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix new FileSet exclusion
authorKern Sibbald <kern@sibbald.com>
Thu, 5 Aug 2004 11:51:54 +0000 (11:51 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 5 Aug 2004 11:51:54 +0000 (11:51 +0000)
Implement update all Volumes from pool
File update volume from pool
Implement Alert command in SD
Add eliminate orphaned Client records to dbcheck

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

26 files changed:
bacula/kernstodo
bacula/src/cats/bdb_update.c
bacula/src/cats/protos.h
bacula/src/cats/sql_update.c
bacula/src/console/authenticate.c
bacula/src/dird/authenticate.c
bacula/src/dird/protos.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/filed/authenticate.c
bacula/src/findlib/bfile.c
bacula/src/findlib/bfile.h
bacula/src/findlib/find.c
bacula/src/gnome2-console/authenticate.c
bacula/src/stored/acquire.c
bacula/src/stored/authenticate.c
bacula/src/stored/bextract.c
bacula/src/stored/btape.c
bacula/src/stored/dircmd.c
bacula/src/stored/protos.h
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/tools/dbcheck.c
bacula/src/version.h
bacula/src/wx-console/authenticate.c

index fedae668e36e699c4ea5c107a30477c5f87979de..ade42c86c4d44f8c2ec1aad6ef8ab1ee0dc5fbcd 100644 (file)
@@ -1,5 +1,5 @@
                  Kern's ToDo List
-                   03 August 2004
+                   05 August 2004
 
 Major development:      
 Project                     Developer
@@ -12,35 +12,31 @@ Version 1.35                Kern (see below)
 
 1.35 Items to do for release:
 - Knoppix CDROM
-- Add bscan to four-concurrent-jobs regression.
-- Doc new IPv6 syntax
-- Add IPv6 to regression
-- Do tape alerts -- see tapealert.txt
-- Document a get out of jail procedure if everything breaks if 
-  you lost/broke the Catalog -- do the same for "I know my
-  file is there how do I get it back?".
-- When passwords do not match, print message that points the
-  user to the doc.
 - Make Verify jobs require exclusive use of Volume as Restore 
   jobs do.
 - Perhaps add read/write programs and/or plugins to FileSets.
-- Look at adding Client run command that will use the
-  port opened by the client.
-- Fix find_device in stored/dircmd.c:462
-- Add new DCR calling sequences everywhere in SD.
-  This will permit simultaneous use of multiple 
-  devices by a single job.
-- bscan does not put first of two volumes back with all info in
-  bscan-test.
+- Add new DCR calling sequences everywhere in SD. This will permit 
+  simultaneous use of multiple devices by a single job.
 - Fix restore ++++ that get intermingled with "Building directory tree"
 - Solve the termcap.h problem on Solaris configure.
-- Fix ./configure to handle installed SQLite
-- Test Win32 errno handling.
-
 
+- Test Win32 errno handling.
+- Add bscan to four-concurrent-jobs regression.
+- Doc new IPv6 syntax
+- Add IPv6 to regression
+- Alternative to static linking "ldd prog" save all binaries listed,
+  restore them and point LD_LIBRARY_PATH to them.
+- Document a get out of jail procedure if everything breaks if 
+  you lost/broke the Catalog -- do the same for "I know my
+  file is there how do I get it back?".
+- Test Tape Alerts
+- Doc update AllFromVol
+- Doc dbcheck eliminate orphaned clients.
+   
 
 Documentation to do: (any release a little bit at a time)
 - Document query file format.
+- Add more documentation for bsr files.
 - Document problems with Verify and pruning.
 - Document how to use multiple databases.
 - VXA drives have a "cleaning required"
@@ -64,18 +60,20 @@ Documentation to do: (any release a little bit at a time)
 - Document doing table repair
           
 Testing to do: (painful)
-- Test drive polling!
-- blocksize recognition code.
-- Test if rewind at end of tape waits for tape to rewind.
-- Test cancel at EOM.       
+
 
 For 1.37 Testing/Documentation:
+- Fix find_device in stored/dircmd.c:462 (see code) 
 - Add db check test to regression. Test each function like delete,
   purge, ...
 - If you use restore replace=never, the directory attributes for
   non-existent directories will not be restored properly.
 
 Wish list:  
+- Look at adding Client run command that will use the
+  port opened by the client.
+- bscan does not put first of two volumes back with all info in
+  bscan-test.
 - Implement the FreeBSD nodump flag in chflags.
 - Figure out how to make named console messages go only to that
   console and to the non-restricted console (new console class?).
@@ -1165,3 +1163,7 @@ Block Position: 0
 - Add better error codes to run_program (10000+)
 - Revisit and revise Disaster Recovery (fix SCSI and RAID 
   disk detection)
+- When passwords do not match, print message that points the
+  user to the doc.
+- Do tape alerts -- see tapealert.txt
+
index 4d60965d647cb785d10c0a0a087b00f4d73193c5..d3e594558df4c155379d92478361d8e74172b30f 100755 (executable)
@@ -217,5 +217,10 @@ int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
    return 0;
 }
 
+int db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) 
+{
+   return 1;
+}
+
 
 #endif /* HAVE_BACULA_DB */
index ef5d6ade115f9ac4d9f4f712c99b482bd84b5a65..c5c41879ebe716b2ce62c66c4660d711d57af01f 100644 (file)
@@ -34,7 +34,7 @@
 
 /* sql.c */
 B_DB *db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password, 
-                       const char *db_address, int db_port, const char *db_socket);
+                      const char *db_address, int db_port, const char *db_socket);
 int  db_open_database(JCR *jcr, B_DB *db);
 void db_close_database(JCR *jcr, B_DB *db);
 void db_escape_string(char *snew, char *old, int len);
@@ -51,7 +51,7 @@ int db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
 int db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr);
 int db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr);
 int db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr);
-int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);          
+int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr);         
 int db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jr);
 int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
 
@@ -102,6 +102,7 @@ int  db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
 int  db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
 int  db_update_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pr);
 int  db_update_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *mr);
+int  db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
 int  db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
 int  db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type);  
 int  db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId);
index c0af9184cc90e3ce246457485f25978947ca9fb9..fed8d82c20a29669f61c0ccc0cbb24a4d1d6ee1e 100644 (file)
@@ -333,6 +333,51 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
    return stat;
 }
 
+/* 
+ * Update the Media Record Default values from Pool
+ *
+ * Returns: 0 on failure
+ *         numrows on success
+ */
+int
+db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) 
+{
+   int stat;
+   char ed1[30], ed2[30], ed3[30];
+       
+
+   db_lock(mdb);
+   if (mr->VolumeName[0]) {
+      Mmsg(&mdb->cmd, "UPDATE Media SET "
+           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+           " WHERE VolumeName='%s'",
+          mr->Recycle,edit_uint64(mr->VolRetention, ed1), 
+          edit_uint64(mr->VolUseDuration, ed2),
+          mr->MaxVolJobs, mr->MaxVolFiles,
+          edit_uint64(mr->VolBytes, ed3),
+          mr->VolumeName);
+   } else {
+      Mmsg(&mdb->cmd, "UPDATE Media SET "
+           "Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
+           "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s"
+           " WHERE PoolId=%u",
+          mr->Recycle,edit_uint64(mr->VolRetention, ed1), 
+          edit_uint64(mr->VolUseDuration, ed2),
+          mr->MaxVolJobs, mr->MaxVolFiles,
+          edit_uint64(mr->VolBytes, ed3),
+          mr->PoolId);
+   }
+
+   Dmsg1(400, "%s\n", mdb->cmd);
+
+   stat = UPDATE_DB(jcr, mdb, mdb->cmd);
+
+   db_unlock(mdb);
+   return stat;
+}
+
+
 /* 
  * If we have a non-zero InChanger, ensure that no other Media
  *  record has InChanger set on the same Slot.
index 23fb727b679a1436e38d324b854f8fd67d130276..fe242c256b332af2c63ed57bb76750407d618e6d 100644 (file)
@@ -74,7 +74,8 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
        !cram_md5_auth(dir, password, ssl_need)) {
       stop_bsock_timer(tid);
       sendit( _("Director authorization problem.\n"
-            "Most likely the passwords do not agree.\n"));  
+            "Most likely the passwords do not agree.\n"     
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
       return 0;
    }
 
index c2522be1facaf1ffad21c7ded04779861dacfb95..00c793f3d3e4346a26ccaa264c8826a19e320127 100644 (file)
@@ -73,7 +73,8 @@ int authenticate_storage_daemon(JCR *jcr)
    if (!cram_md5_get_auth(sd, jcr->store->password, ssl_need) || 
        !cram_md5_auth(sd, jcr->store->password, ssl_need)) {
       stop_bsock_timer(tid);
-      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n"));
+      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
       return 0;
    }
    Dmsg1(116, ">stored: %s", sd->msg);
@@ -116,7 +117,8 @@ int authenticate_file_daemon(JCR *jcr)
    if (!cram_md5_get_auth(fd, jcr->client->password, ssl_need) || 
        !cram_md5_auth(fd, jcr->client->password, ssl_need)) {
       stop_bsock_timer(tid);
-      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
       return 0;
    }
    Dmsg1(116, ">filed: %s", fd->msg);
index ac61ca9935738b0b25a8221466a9c807f3a3f0ee..45101b08e346d34dd9c4a51d8801a3b94e24ef05 100644 (file)
@@ -62,7 +62,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp);
 
 /* fd_cmds.c */
 extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
-                                 int max_retry_time, int verbose);
+                                  int max_retry_time, int verbose);
 extern int send_include_list(JCR *jcr);
 extern int send_exclude_list(JCR *jcr);
 extern int send_bootstrap_file(JCR *jcr);
@@ -70,7 +70,7 @@ extern int send_level_command(JCR *jcr);
 extern int get_attributes_and_put_in_catalog(JCR *jcr);
 extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
 extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, 
-                         char *link, char *attr, int stream);
+                          char *link, char *attr, int stream);
 extern void get_level_since_time(JCR *jcr, char *since, int since_len);
 extern int send_run_before_and_after_commands(JCR *jcr);
 
@@ -96,7 +96,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
 
 /* msgchan.c */
 extern int connect_to_storage_daemon(JCR *jcr, int retry_interval,    
-                             int max_retry_time, int verbose);
+                              int max_retry_time, int verbose);
 extern int start_storage_daemon_job(JCR *jcr);
 extern int start_storage_daemon_message_thread(JCR *jcr);
 extern int bget_dirmsg(BSOCK *bs);
@@ -148,28 +148,28 @@ JCR *new_control_jcr(const char *base_name, int job_type);
 void free_ua_context(UAContext *ua);
 
 /* ua_select.c */
-STORE  *select_storage_resource(UAContext *ua);
-JOB    *select_job_resource(UAContext *ua);
-JOB    *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE   *select_storage_resource(UAContext *ua);
+JOB     *select_job_resource(UAContext *ua);
+JOB     *select_restore_job_resource(UAContext *ua);
+CLIENT  *select_client_resource(UAContext *ua);
 FILESET *select_fileset_resource(UAContext *ua);
-int    select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int    select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-int    select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int    select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void   start_prompt(UAContext *ua, const char *msg);
-void   add_prompt(UAContext *ua, const char *prompt);
-int    do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
-CAT    *get_catalog_resource(UAContext *ua);          
+int     select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int     select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+bool    select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int     select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void    start_prompt(UAContext *ua, const char *msg);
+void    add_prompt(UAContext *ua, const char *prompt);
+int     do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
+CAT    *get_catalog_resource(UAContext *ua);           
 STORE  *get_storage_resource(UAContext *ua, int use_default);
-int    get_media_type(UAContext *ua, char *MediaType, int max_media);
-int    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int    get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int     get_media_type(UAContext *ua, char *MediaType, int max_media);
+bool    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int     get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
 POOL   *get_pool_resource(UAContext *ua);
 POOL   *select_pool_resource(UAContext *ua);
 CLIENT *get_client_resource(UAContext *ua);
-int    get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int     get_job_dbr(UAContext *ua, JOB_DBR *jr);
 
 int find_arg_keyword(UAContext *ua, const char **list);
 int find_arg(UAContext *ua, const char *keyword);
index 8aa7ecccc1d8d4cfe81738f10b80147702f6430e..173ba60490e5126f48759861312a88fe8f7790dc 100644 (file)
@@ -847,23 +847,44 @@ static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *o
 static void update_volfrompool(UAContext *ua, MEDIA_DBR *mr)
 {
    POOL_DBR pr;
-   char VolStatus[50];
 
    memset(&pr, 0, sizeof(pr));
    pr.PoolId = mr->PoolId;
    if (!get_pool_dbr(ua, &pr)) {
       return;
    }
-   bstrncpy(VolStatus, mr->VolStatus, sizeof(VolStatus));
    set_pool_dbr_defaults_in_media_dbr(mr, &pr);
-   bstrncpy(mr->VolStatus, VolStatus, sizeof(mr->VolStatus));
-   if (!db_update_media_record(ua->jcr, ua->db, mr)) {
+   if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
       bsendmsg(ua, _("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
    } else {
       bsendmsg(ua, _("Volume defaults updated from Pool record.\n"));
    }
 }
 
+/*
+ * Refresh the Volume information from the Pool record
+ *   for all Volumes
+ */
+static void update_all_vols_from_pool(UAContext *ua)
+{
+   POOL_DBR pr;
+   MEDIA_DBR mr;
+
+   memset(&pr, 0, sizeof(pr));
+   if (!get_pool_dbr(ua, &pr)) {
+      return;
+   }
+   memset(&mr, 0, sizeof(mr));
+   set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
+   mr.PoolId = pr.PoolId;
+   if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
+      bsendmsg(ua, _("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
+   } else {
+      bsendmsg(ua, _("All Volume defaults updated from Pool record.\n"));
+   }
+}
+
+
 /*
  * Update a media record -- allows you to change the
  *  Volume status. E.g. if you want Bacula to stop
@@ -887,13 +908,14 @@ static int update_volume(UAContext *ua)
       N_("Recycle"),                  /* 6 */
       N_("Pool"),                     /* 7 */
       N_("FromPool"),                 /* 8 */
+      N_("AllFromPool"),              /* 9 */
       NULL };
 
    for (int i=0; kw[i]; i++) {
       int j;
       POOL_DBR pr;
       if ((j=find_arg_with_value(ua, kw[i])) > 0) {
-        if (!select_media_dbr(ua, &mr)) {
+        if (i != 9 && !select_media_dbr(ua, &mr)) {
            return 0;
         }
         switch (i) {
@@ -930,6 +952,8 @@ static int update_volume(UAContext *ua)
         case 8:
            update_volfrompool(ua, &mr);
            break;
+        case 9:
+           update_all_vols_from_pool(ua);
         }
         done = true;
       }
index 2b3c95cdd521f8658077a2381d851e702f2739e5..16d2e28cbc54ddaf1c0bf5759f9dd14c1a89bc05 100644 (file)
@@ -248,16 +248,15 @@ int update_slots(UAContext *ua)
    }
    memset(&mr, 0, sizeof(mr));
    mr.InChanger = 1;
+   db_lock(ua->db);
    for (int i=1; i<max_slots; i++) {
       if (slot_list[i]) {
         mr.Slot = i;
         /* Set InChanger to zero for this Slot */
-        db_lock(ua->db);
         db_make_inchanger_unique(ua->jcr, ua->db, &mr);
-        db_unlock(ua->db);
-         bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), i);
       }
    }
+   db_unlock(ua->db);
       
 bail_out:
 
index f0d3b2588c6812772388792bfbf81b7bf443bd5b..2330de57845306ebd13d87c4b6642c4762c66607 100644 (file)
@@ -405,28 +405,28 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
  *  if error or not found, put up a list of pool DBRs
  *  to choose from.
  *
- *   returns: 0 on error
- *           1 on success and fills in POOL_DBR
+ *   returns: false on error
+ *           true  on success and fills in POOL_DBR
  */
-int get_pool_dbr(UAContext *ua, POOL_DBR *pr)
+bool get_pool_dbr(UAContext *ua, POOL_DBR *pr)
 {
    if (pr->Name[0]) {                /* If name already supplied */
       if (db_get_pool_record(ua->jcr, ua->db, pr) &&
          acl_access_ok(ua, Pool_ACL, pr->Name)) { 
-        return pr->PoolId;
+        return true;
       }
       bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db));
    }
    if (!select_pool_dbr(ua, pr)) {  /* try once more */
-      return 0;
+      return false;
    }
-   return 1;
+   return true;
 }
 
 /*
  * Select a Pool record from the catalog
  */
-int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
+bool select_pool_dbr(UAContext *ua, POOL_DBR *pr)
 {
    POOL_DBR opr;
    char name[MAX_NAME_LENGTH];
@@ -443,7 +443,7 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
            pr->PoolId = 0;
            break;
         }
-        return 1;
+        return true;
       }
    }
 
@@ -454,7 +454,7 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
    }
    if (num_pools <= 0) {
       bsendmsg(ua, _("No pools defined. Use the \"create\" command to create one.\n"));
-      return 0;
+      return false;
    }
      
    start_prompt(ua, _("Defined Pools:\n"));
@@ -468,17 +468,17 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
    }
    free(ids);
    if (do_prompt(ua, _("Pool"),  _("Select the Pool"), name, sizeof(name)) < 0) {
-      return 0;
+      return false;
    }
    memset(&opr, 0, sizeof(opr));
    bstrncpy(opr.Name, name, sizeof(opr.Name));
 
    if (!db_get_pool_record(ua->jcr, ua->db, &opr)) {
       bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), name, db_strerror(ua->db));
-      return 0;
+      return false;
    }
    memcpy(pr, &opr, sizeof(opr));
-   return 1;
+   return true;
 }
 
 /*
index e01870b121a0a3d793b49bbfc69c32d2c21181d4..ec3acb05e8ef4022d43e8556153fb6afdf4a6dcc 100644 (file)
@@ -69,7 +69,8 @@ static int authenticate(int rcode, BSOCK *bs)
    }
    UnlockRes();
    if (!director) {
-      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), 
+      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"), 
            dirname, bs->who);
       free_pool_memory(dirname);
       return 0;
@@ -77,7 +78,8 @@ static int authenticate(int rcode, BSOCK *bs)
    btimer_t *tid = start_bsock_timer(bs, 60 * 5);
    if (!cram_md5_auth(bs, director->password, ssl_need) ||
        !cram_md5_get_auth(bs, director->password, ssl_need)) {
-      Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
+      Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"  
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"), 
            bs->who);
       director = NULL;
    }
@@ -123,7 +125,8 @@ int authenticate_storagedaemon(JCR *jcr)
    stop_bsock_timer(tid);
    memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
    if (!stat) {
-      Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"));
+      Jmsg(jcr, M_FATAL, 0, _("Authorization key rejected by Storage daemon.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
    }
    return stat;
 }
index f2ff68dbaa9c7c1f52820cdab90fb92272c345b5..0197bd3c40b10a1b9db2cbb528907a6b140f3084 100644 (file)
@@ -255,6 +255,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    if (bfd->fh == INVALID_HANDLE_VALUE) {
       bfd->lerror = GetLastError();
       bfd->berrno = b_errno_win32;
+      errno = b_errno_win32;
       bfd->mode = BF_CLOSED;
    }
    bfd->errmsg = NULL;
@@ -287,6 +288,7 @@ int bclose(BFILE *bfd)
              1,                      /* Abort */
              1,                      /* ProcessSecurity */
              &bfd->lpContext)) {     /* Read context */
+        errno = b_errno_win32;
         stat = -1;
       } 
    } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
@@ -298,11 +300,13 @@ int bclose(BFILE *bfd)
              1,                      /* Abort */
              1,                      /* ProcessSecurity */
              &bfd->lpContext)) {     /* Write context */
+        errno = b_errno_win32;
         stat = -1;
       } 
    }
    if (!CloseHandle(bfd->fh)) {
       stat = -1;
+      errno = b_errno_win32;
    }
    bfd->mode = BF_CLOSED;
    bfd->lpContext = NULL;
@@ -312,7 +316,8 @@ int bclose(BFILE *bfd)
 /*
  * Generate error message 
  */
-char *berror(BFILE *bfd)
+/* DO NOT USE */
+char *xberror(BFILE *bfd)
 {
    LPTSTR msg;
 
@@ -351,6 +356,7 @@ ssize_t bread(BFILE *bfd, void *buf, size_t count)
           &bfd->lpContext)) {          /* Context */
         bfd->lerror = GetLastError();
         bfd->berrno = b_errno_win32;
+        errno = b_errno_win32;
         return -1;
       }
    } else {
@@ -361,6 +367,7 @@ ssize_t bread(BFILE *bfd, void *buf, size_t count)
           NULL)) {
         bfd->lerror = GetLastError();
         bfd->berrno = b_errno_win32;
+        errno = b_errno_win32;
         return -1;
       }
    }
@@ -382,6 +389,7 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
           &bfd->lpContext)) {          /* Context */
         bfd->lerror = GetLastError();
         bfd->berrno = b_errno_win32;
+        errno = b_errno_win32;
         return -1;
       }
    } else {
@@ -392,6 +400,7 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
           NULL)) {
         bfd->lerror = GetLastError();
         bfd->berrno = b_errno_win32;
+        errno = b_errno_win32;
         return -1;
       }
    }
@@ -405,7 +414,7 @@ int is_bopen(BFILE *bfd)
 
 off_t blseek(BFILE *bfd, off_t offset, int whence)
 {
-   /* ****FIXME**** this is needed if we want to read Win32 Archives */
+   /* ****FIXME**** this must be implemented if we want to read Win32 Archives */
    return -1;
 }
 
@@ -490,6 +499,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    bfd->fid = open(fname, flags, mode);
    bfd->berrno = errno;
    Dmsg1(400, "Open file %d\n", bfd->fid);
+   errno = bfd->berrno;
    return bfd->fid;
 }
 
@@ -536,7 +546,8 @@ off_t blseek(BFILE *bfd, off_t offset, int whence)
     return pos;
 }
 
-char *berror(BFILE *bfd)
+/* DO NOT USE */
+char *xberror(BFILE *bfd)
 {
     return strerror(bfd->berrno);
 }
index 2282010e81732906d614f83a68c721f287250798..d65e5867b568d6fd42891d98937df9f261754ad0 100644 (file)
 
 enum {
    BF_CLOSED,
-   BF_READ,                          /* BackupRead */
-   BF_WRITE                          /* BackupWrite */
+   BF_READ,                           /* BackupRead */
+   BF_WRITE                           /* BackupWrite */
 };
 
 /* In bfile.c */
 
 /* Basic low level I/O file packet */
 struct BFILE {
-   int use_backup_api;               /* set if using BackupRead/Write */
-   int mode;                         /* set if file is open */
-   HANDLE fh;                        /* Win32 file handle */
-   int fid;                          /* fd if doing Unix style */
-   LPVOID lpContext;                 /* BackupRead/Write context */
-   POOLMEM *errmsg;                  /* error message buffer */
-   DWORD rw_bytes;                   /* Bytes read or written */
-   DWORD lerror;                     /* Last error code */
-   int berrno;                       /* errno */
-};     
+   int use_backup_api;                /* set if using BackupRead/Write */
+   int mode;                          /* set if file is open */
+   HANDLE fh;                         /* Win32 file handle */
+   int fid;                           /* fd if doing Unix style */
+   LPVOID lpContext;                  /* BackupRead/Write context */
+   POOLMEM *errmsg;                   /* error message buffer */
+   DWORD rw_bytes;                    /* Bytes read or written */
+   DWORD lerror;                      /* Last error code */
+   int berrno;                        /* errno */
+};      
 
 HANDLE bget_handle(BFILE *bfd);
 
-#else  /* Linux/Unix systems */
+#else   /* Linux/Unix systems */
 
 /*  =======================================================
  *
@@ -73,26 +73,26 @@ HANDLE bget_handle(BFILE *bfd);
 
 /* Basic low level I/O file packet */
 struct BFILE {
-   int fid;                          /* file id on Unix */
+   int fid;                           /* file id on Unix */
    int berrno;
-};     
+};      
 
 #endif
 
-void   binit(BFILE *bfd);
-int    is_bopen(BFILE *bfd);
-int    set_win32_backup(BFILE *bfd);
-int    set_portable_backup(BFILE *bfd);
-int    have_win32_api();
-int    is_portable_backup(BFILE *bfd);
-int    is_stream_supported(int stream);
-int    is_win32_stream(int stream);
-char   *berror(BFILE *bfd);
-int    bopen(BFILE *bfd, const char *fname, int flags, mode_t mode);
-int    bclose(BFILE *bfd);
+void    binit(BFILE *bfd);
+int     is_bopen(BFILE *bfd);
+int     set_win32_backup(BFILE *bfd);
+int     set_portable_backup(BFILE *bfd);
+int     have_win32_api();
+int     is_portable_backup(BFILE *bfd);
+int     is_stream_supported(int stream);
+int     is_win32_stream(int stream);
+char   *xberror(BFILE *bfd);          /* DO NOT USE  -- use berrno class */
+int     bopen(BFILE *bfd, const char *fname, int flags, mode_t mode);
+int     bclose(BFILE *bfd);
 ssize_t bread(BFILE *bfd, void *buf, size_t count);
 ssize_t bwrite(BFILE *bfd, void *buf, size_t count);
-off_t  blseek(BFILE *bfd, off_t offset, int whence);
+off_t   blseek(BFILE *bfd, off_t offset, int whence);
 const char   *stream_to_ascii(int stream);
 
 #endif /* __BFILE_H */
index 0550e737867042422f919eec248b2939cff129e3..5efc6696558d0686504758bceb0231cf50970ad1 100644 (file)
@@ -218,7 +218,6 @@ static int our_callback(FF_PKT *ff, void *hpkt)
    case FT_NOFOLLOW:
    case FT_NOSTAT:
    case FT_NOCHG:
-   case FT_DIRNOCHG:
    case FT_ISARCH:
    case FT_NORECURSE:
    case FT_NOFSCHG:
@@ -235,6 +234,7 @@ static int our_callback(FF_PKT *ff, void *hpkt)
    case FT_RAW:
    case FT_FIFO:
    case FT_SPEC:
+   case FT_DIRNOCHG:
       if (accept_file(ff)) {
         return ff->callback(ff, hpkt);
       } else {
index f1c6febd746da12f039b0d88a06550ec45a854b4..8cebb7aca44e381c02cece3412c481da681c8dfb 100644 (file)
@@ -72,6 +72,9 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
       stop_bsock_timer(tid);
       printf(_("%s: Director authorization problem.\n"), my_name);
       set_text(_("Director authorization problem.\n"), -1);
+      set_text(_(
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"), 
+       -1);
       return 0;
    }
 
index 0a492a61f555aa432be44861acc17671f7613371..29b91e849e7ecdae48aa155df6ca729fed6bfaf1 100644 (file)
@@ -412,7 +412,31 @@ bool release_device(JCR *jcr)
            dev_name(dev), NPRT(jcr->VolumeName));
       Jmsg2(jcr, M_ERROR, 0, _("num_writers=%d state=%x\n"), dev->num_writers, dev->state);
    }
-// detach_jcr_from_device(dev, jcr);
+
+   /* Fire off Alert command and include any output */
+   if (jcr->device->alert_command) {
+      POOLMEM *alert;
+      int status;
+      BPIPE *bpipe;
+      char line[MAXSTRING];
+      alert = get_pool_memory(PM_FNAME);
+      alert = edit_device_codes(jcr, alert, jcr->device->alert_command, "");
+      bpipe = open_bpipe(alert, 0, "r");
+      free_pool_memory(alert);
+      while (fgets(line, sizeof(line), bpipe->rfd)) {
+         Jmsg(jcr, M_INFO, 0, _("Alert: %s"), line);
+      }
+      status = close_bpipe(bpipe);
+      if (status != 0) {
+        berrno be;
+        be.set_errno(status);
+         Jmsg(jcr, M_INFO, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
+             alert, be.strerror());
+      }
+
+      Dmsg1(400, "alert status=%d\n", status);
+      
+   }
    if (dev->prev && !dev_state(dev, ST_READ) && !dev->num_writers) {
       P(mutex);
       unlock_device(dev);
index 24c1383125ee24c3853a4fbefcfbc6e6ae7f2e55..2cd2110c5b00598139cddbe3cddf3e747a529ab9 100644 (file)
@@ -70,7 +70,8 @@ static int authenticate(int rcode, BSOCK *bs)
    }
    UnlockRes();
    if (!director) {
-      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), 
+      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"), 
            dirname, bs->who);
       free_pool_memory(dirname);
       return 0;
@@ -81,7 +82,8 @@ static int authenticate(int rcode, BSOCK *bs)
    if (!cram_md5_auth(bs, director->password, ssl_need) ||
        !cram_md5_get_auth(bs, director->password, ssl_need)) {
       stop_bsock_timer(tid);
-      Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"));
+      Emsg0(M_FATAL, 0, _("Incorrect password given by Director.\n"   
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"));
       free_pool_memory(dirname);
       return 0;
    }
@@ -128,7 +130,8 @@ int authenticate_filed(JCR *jcr)
    }
    stop_bsock_timer(tid);
    if (!jcr->authenticated) {
-      Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"), 
+      Jmsg(jcr, M_FATAL, 0, _("Incorrect authorization key from File daemon at %s rejected.\n"
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n"),
           fd->who);
    }
    return jcr->authenticated;
index daf491715cf51fece8beaeadaf4f35e5a64fbfd8..72439b49a3f1de518798171281fcf17139e67e35 100644 (file)
@@ -122,8 +122,9 @@ int main (int argc, char *argv[])
 
       case 'e':                    /* exclude list */
          if ((fd = fopen(optarg, "r")) == NULL) {
+           berrno be;
             Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
-              optarg, strerror(errno));
+              optarg, be.strerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
@@ -136,8 +137,9 @@ int main (int argc, char *argv[])
 
       case 'i':                    /* include list */
          if ((fd = fopen(optarg, "r")) == NULL) {
+           berrno be;
             Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
-              optarg, strerror(errno));
+              optarg, be.strerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
@@ -210,8 +212,9 @@ static void do_extract(char *devname)
 
    /* Make sure where directory exists and that it is a directory */
    if (stat(where, &statp) < 0) {
+      berrno be;
       Emsg2(M_ERROR_TERM, 0, "Cannot stat %s. It must exist. ERR=%s\n",
-        where, strerror(errno));
+        where, be.strerror());
    }
    if (!S_ISDIR(statp.st_mode)) {
       Emsg1(M_ERROR_TERM, 0, "%s must be a directory.\n", where);
@@ -329,8 +332,9 @@ static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            if (fileAddr != faddr) {
               fileAddr = faddr;
               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+                 berrno be;
                   Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"), 
-                    attr->ofname, strerror(errno));
+                    attr->ofname, be.strerror());
               }
            }
         } else {
@@ -340,8 +344,9 @@ static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
         total += wsize;
          Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
         if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
+           berrno be;
             Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"), 
-              attr->ofname, strerror(errno));
+              attr->ofname, be.strerror());
         }
         fileAddr += wsize;
       }
@@ -367,8 +372,9 @@ static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            if (fileAddr != faddr) {
               fileAddr = faddr;
               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+                 berrno be;
                   Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), 
-                    edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
+                    edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
                  extract = false;
                  return true;
               }
@@ -387,9 +393,10 @@ static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
          Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
         if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) {
+           berrno be;
             Pmsg0(0, "===Write error===\n");
             Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"), 
-              attr->ofname, strerror(errno));
+              attr->ofname, be.strerror());
            extract = false;
            return true;
         }
index e9a1dc548b1d9aaa91042aef7040e399ad5e0cf3..d588a400affc9df16dac3561d648bcc250247a85 100644 (file)
@@ -39,7 +39,6 @@
 
 /* External subroutines */
 extern void free_config_resources();
-extern char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
 
 /* Exported variables */
 int quit = 0;
index a68fa8cb7ad42594523a5614f1880bb2b16c000b..045add3b5afc5278ba2893602637b91681c4ae8d 100644 (file)
@@ -463,12 +463,12 @@ static int read_label(JCR *jcr, DEVICE *dev)
 
 static DEVICE *find_device(JCR *jcr, char *dname)
 {
-   DEVRES *device = NULL;
+   DEVRES *device;
    bool found = false;
 
    unbash_spaces(dname);
    LockRes();
-   while ((device=(DEVRES *)GetNextRes(R_DEVICE, (RES *)device))) {
+   foreach_res(device, R_DEVICE) {
       /* Find resource, and make sure we were able to open it */
       if (strcmp(device->hdr.name, dname) == 0 && device->dev) {
          Dmsg1(20, "Found device %s\n", device->hdr.name);
index 83471c1b83cf61c009989df845faf73f4c59db54..f003e87493ac3fc9c6180fe55e35c09664b66bf3 100644 (file)
@@ -176,6 +176,7 @@ void         mark_volume_in_error(JCR *jcr, DEVICE *dev);
 int     autoload_device(DCR *dcr, int writing, BSOCK *dir);
 bool    autochanger_list(DCR *dcr, BSOCK *dir);
 void    invalidate_slot_in_catalog(DCR *dcr);
+char   *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd);
 
 
 /* From parse_bsr.c */
index 9f2a4911efcb25b05d51eccfc42217ffcf8937c0..0e557ebcc30e461709cf6a1e4d250fa2daeed64e 100644 (file)
@@ -103,6 +103,7 @@ static RES_ITEM dev_items[] = {
    {"closeonpoll",           store_yesno,  ITEM(res_dev.cap_bits), CAP_CLOSEONPOLL, ITEM_DEFAULT, 0},
    {"changerdevice",         store_strname,ITEM(res_dev.changer_name), 0, 0, 0},
    {"changercommand",        store_strname,ITEM(res_dev.changer_command), 0, 0, 0},
+   {"alertcommand",          store_strname,ITEM(res_dev.alert_command), 0, 0, 0},
    {"maximumchangerwait",    store_pint,   ITEM(res_dev.max_changer_wait), 0, ITEM_DEFAULT, 5 * 60},
    {"maximumopenwait",       store_pint,   ITEM(res_dev.max_open_wait), 0, ITEM_DEFAULT, 5 * 60},
    {"maximumopenvolumes",    store_pint,   ITEM(res_dev.max_open_vols), 0, ITEM_DEFAULT, 1},
@@ -311,6 +312,9 @@ void free_resource(RES *sres, int type)
         if (res->res_dev.changer_command) {
            free(res->res_dev.changer_command);
         }
+        if (res->res_dev.alert_command) {
+           free(res->res_dev.alert_command);
+        }
         if (res->res_dev.spool_directory) {
            free(res->res_dev.spool_directory);
         }
index 17c7e6630f56a7aade53df578ff3e76a0c4d6fc9..d2bef94658f130c5dfe2242d2f00f628f200d629 100644 (file)
@@ -75,6 +75,7 @@ struct DEVRES {
    char *device_name;                /* Archive device name */
    char *changer_name;               /* Changer device name */
    char *changer_command;            /* Changer command  -- external program */
+   char *alert_command;              /* Alert command -- external program */
    char *spool_directory;            /* Spool file directory */
    uint32_t drive_index;             /* Autochanger drive index */
    uint32_t cap_bits;                /* Capabilities of this device */
index 54114787fe2061a330a7daea49890ca30c21795a..a692853dd9dd7559a97555c3a54b48dd32adb197 100644 (file)
@@ -58,7 +58,7 @@ static ID_LIST id_list;
 static NAME_LIST name_list;
 static char buf[2000];
 
-#define MAX_ID_LIST_LEN 1000000
+#define MAX_ID_LIST_LEN 10000000
 
 /* Forward referenced functions */
 static int make_id_list(const char *query, ID_LIST *id_list);
@@ -74,6 +74,7 @@ static void eliminate_orphaned_file_records();
 static void eliminate_orphaned_path_records();
 static void eliminate_orphaned_filename_records();
 static void eliminate_orphaned_fileset_records();
+static void eliminate_orphaned_client_records();
 static void repair_bad_paths();
 static void repair_bad_filenames();
 static void do_interactive_mode();
@@ -240,6 +241,7 @@ int main (int argc, char *argv[])
       eliminate_orphaned_path_records();
       eliminate_orphaned_filename_records();
       eliminate_orphaned_fileset_records();
+      eliminate_orphaned_client_records();
    } else {
       do_interactive_mode();
    }
@@ -274,8 +276,9 @@ Please select the fuction you want to perform.\n",
      9) Eliminate orphaned Path records\n\
     10) Eliminate orphaned Filename records\n\
     11) Eliminate orphaned FileSet records\n\
-    12) All (3-11)\n\
-    13) Quit\n"));
+    12) Eliminate orphaned Client records\n\
+    13) All (3-12)\n\
+    14) Quit\n"));
        } else {
          printf(_("\n\
      1) Toggle modify database flag\n\
@@ -289,8 +292,9 @@ Please select the fuction you want to perform.\n",
      9) Check for orphaned Path records\n\
     10) Check for orphaned Filename records\n\
     11) Check for orphaned FileSet records\n\
-    12) All (3-11)\n\
-    13) Quit\n"));
+    12) Check for orphaned FileSet records\n\
+    13) All (3-12)\n\
+    14) Quit\n"));
        }
 
       cmd = get_cmd(_("Select function number: "));
@@ -333,6 +337,9 @@ Please select the fuction you want to perform.\n",
            eliminate_orphaned_fileset_records();
            break;
         case 12:
+           eliminate_orphaned_client_records();
+           break;
+        case 13:
            repair_bad_filenames();
            repair_bad_paths();
            eliminate_duplicate_filenames();
@@ -342,8 +349,9 @@ Please select the fuction you want to perform.\n",
            eliminate_orphaned_path_records();
            eliminate_orphaned_filename_records();
            eliminate_orphaned_fileset_records();
+           eliminate_orphaned_client_records();
            break;
-        case 13:
+        case 14:
            quit = true;
            break;
         }
@@ -390,6 +398,14 @@ static int print_fileset_handler(void *ctx, int num_fields, char **row)
    return 0;
 }
 
+static int print_client_handler(void *ctx, int num_fields, char **row)
+{
+   printf(_("Orphaned ClientId=%s Name=\"%s\"\n"), 
+             NPRT(row[0]), NPRT(row[1]));
+   return 0;
+}
+
+
   
 /*
  * Called here with each id to be added to the list
@@ -762,6 +778,45 @@ static void eliminate_orphaned_fileset_records()
    }
 }
 
+static void eliminate_orphaned_client_records()
+{
+   const char *query;
+
+   printf("Checking for orphaned Client entries.\n");
+   /* In English:
+    *  Wiffle through Client for every Client
+    *  joining with the Job table including every Client even if
+    *  there is not a match in Job (left outer join), then
+    *  filter out only those where no Job points to a Client
+    *  i.e. Job.Client is NULL
+    */
+   query = "SELECT Client.ClientId,Client.Name FROM Client "
+           "LEFT OUTER JOIN Job ON (Client.ClientId=Job.ClientId) "
+           "WHERE Job.ClientId IS NULL";
+   if (verbose > 1) {
+      printf("%s\n", query);
+   }
+   if (!make_id_list(query, &id_list)) {
+      exit(1);
+   }
+   printf("Found %d orphaned Client records.\n", id_list.num_ids);
+   if (id_list.num_ids && verbose && yes_no("Print them? (yes/no): ")) {
+      for (int i=0; i < id_list.num_ids; i++) {
+         sprintf(buf, "SELECT ClientId,Name FROM Client "
+                      "WHERE ClientId=%u", id_list.Id[i]);
+        if (!db_sql_query(db, buf, print_client_handler, NULL)) {
+            printf("%s\n", db_strerror(db));
+        }
+      }
+   }
+   
+   if (fix && id_list.num_ids > 0) {
+      printf("Deleting %d orphaned Client records.\n", id_list.num_ids);
+      delete_id_list("DELETE FROM Client WHERE ClientId=%u", &id_list);
+   }
+}
+
+
 static void repair_bad_filenames()
 {
    const char *query;
index 67c7cfb2b5e76f57eff9b51c6abcff6b1965af7b..d0fd264694186b962806fb6972c6e8b942610f99 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
 #define VERSION "1.35.1"
-#define BDATE   "30 July 2004"
-#define LSMDATE "30Jul04"
+#define BDATE   "05 August 2004"
+#define LSMDATE "05Aug04"
 
 /* Debug flags */
 #undef  DEBUG
index 94dc6a9031058d23c1e62856d3eca5b64b89a0ab..1be70e7c757b4dfdd4a0bc94eaefc071448c4009 100644 (file)
@@ -74,6 +74,8 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
        !cram_md5_auth(dir, password, ssl_need)) {
       stop_bsock_timer(tid);
       csprint("Director authorization problem.\nMost likely the passwords do not agree.\n", CS_DATA);
+      csprint(
+       "Please see http://www.bacula.org/html-manual/faq.html#AuthorizationErrors for help.\n", CS_DATA);
       return 0;
    }