]> git.sur5r.net Git - bacula/bacula/commitdiff
- Apply patch from Christopher Hull
authorKern Sibbald <kern@sibbald.com>
Wed, 19 Apr 2006 17:14:19 +0000 (17:14 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 19 Apr 2006 17:14:19 +0000 (17:14 +0000)
  - Allow multiple connections to database with different
    parameters.
  - Invalidate the scheduler when doing a reload. Fixes seg
    fault, but still 60 second window.
  - Additional info in Reschedule message.
  - Use set_jcr_job_status() everywhere to prevent loss of
    cancel, error.
  - Display peer IP in FD if error from connecting DIR.
  - Don't increment file count for DIRBEGIN.
  - Replace illegal characters in Win32 filename by _.
  - Add SE_CREATE_PERMANENT_NAME privilege in Win32.
  - Hash hard link filenames rather than linked list.
  - Fix for security failure in chdir on Win32.
  - Add CreateDirectoryA/W win32 API entry points.
- Add /silent option to Win32 FD for Install/Remove service.
- Always print Heap statistics in FD.

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

33 files changed:
bacula/kes-1.39
bacula/src/cats/mysql.c
bacula/src/cats/postgresql.c
bacula/src/cats/sql.c
bacula/src/cats/sqlite.c
bacula/src/dird/authenticate.c
bacula/src/dird/dird.c
bacula/src/dird/jobq.c
bacula/src/dird/migrate.c
bacula/src/dird/scheduler.c
bacula/src/dird/ua_run.c
bacula/src/dird/ua_server.c
bacula/src/filed/authenticate.c
bacula/src/filed/backup.c
bacula/src/filed/estimate.c
bacula/src/filed/status.c
bacula/src/filed/win32/winmain.cpp
bacula/src/filed/win32/winservice.cpp
bacula/src/filed/win32/winservice.h
bacula/src/findlib/create_file.c
bacula/src/findlib/enable_priv.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c
bacula/src/findlib/makepath.c
bacula/src/lib/bnet.c
bacula/src/lib/bsock.h
bacula/src/lib/bsys.c
bacula/src/lib/jcr.c
bacula/src/lib/protos.h
bacula/src/lib/winapi.c
bacula/src/lib/winapi.h
bacula/src/stored/askdir.c
bacula/src/version.h

index 4a23fde8ca2c4a6fbb8e55437816709fcb1c3a07..b379c2c425e5f40ed42dfcb7ed6cf9cfe0e377ce 100644 (file)
@@ -2,6 +2,24 @@
                         Kern Sibbald
 
 General:
+19Apr06
+- Apply patch from Christopher Hull
+  - Allow multiple connections to database with different
+    parameters.
+  - Invalidate the scheduler when doing a reload. Fixes seg
+    fault, but still 60 second window.
+  - Additional info in Reschedule message.
+  - Use set_jcr_job_status() everywhere to prevent loss of
+    cancel, error.
+  - Display peer IP in FD if error from connecting DIR.
+  - Don't increment file count for DIRBEGIN.
+  - Replace illegal characters in Win32 filename by _.
+  - Add SE_CREATE_PERMANENT_NAME privilege in Win32.
+  - Hash hard link filenames rather than linked list.
+  - Fix for security failure in chdir on Win32.
+  - Add CreateDirectoryA/W win32 API entry points.
+- Add /silent option to Win32 FD for Install/Remove service.
+- Always print Heap statistics in FD.
 18Apr06
 - Remove the -f option from the chown in Makefile.in for more
   portability.
index 0ff62087f8684bcc066e7223f9db1043e8f82437..ad0be7a6ca86b3957d15320464636f42ccec9129 100644 (file)
@@ -64,7 +64,9 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
    /* Look to see if DB already open */
    if (!mult_db_connections) {
       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
-         if (strcmp(mdb->db_name, db_name) == 0) {
+         if (bstrcmp(mdb->db_name, db_name) &&
+             bstrcmp(mdb->db_address, db_address) &&
+             mdb->db_port == db_port) {
             Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
             mdb->ref_count++;
             V(mutex);
index ddcd2cda32de439128e2689306a077f5fe679bb7..4b0e151dc72a33c7bbbcf0c345f7a4abb43ed95f 100644 (file)
@@ -66,7 +66,9 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
    if (!mult_db_connections) {
       /* Look to see if DB already open */
       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
-         if (strcmp(mdb->db_name, db_name) == 0) {
+         if (bstrcmp(mdb->db_name, db_name) &&
+             bstrcmp(mdb->db_address, db_address) &&
+             mdb->db_port == db_port) {
             Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
             mdb->ref_count++;
             V(mutex);
index 7446ed9fd0abbe27e2f34ffadceed941a2af664c..933c96663a7219c4a9b0b162e2494a22f0bec0ed 100644 (file)
@@ -77,7 +77,10 @@ int check_tables_version(JCR *jcr, B_DB *mdb)
    const char *query = "SELECT VersionId FROM Version";
 
    bacula_db_version = 0;
-   db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version);
+   if (!db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version)) {
+      Mmsg(mdb->errmsg, "Database not created or server not running.\n");
+      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+   }
    if (bacula_db_version != BDB_VERSION) {
       Mmsg(mdb->errmsg, "Version error for database \"%s\". Wanted %d, got %d\n",
           mdb->db_name, BDB_VERSION, bacula_db_version);
index 67332ff2d5c01d8ca8ed3be3c4ef1ec341da4c48..f2b9f769636f599d545f05dc12618aec86a317f3 100644 (file)
@@ -5,28 +5,23 @@
  *
  *    Version $Id$
  */
-
 /*
-   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 as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
 
+
 /* The following is necessary so that we do not include
  * the dummy external definition of DB.
  */
@@ -69,7 +64,9 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
    /* Look to see if DB already open */
    if (!mult_db_connections) {
       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
-         if (strcmp(mdb->db_name, db_name) == 0) {
+         if (bstrcmp(mdb->db_name, db_name) &&
+             bstrcmp(mdb->db_address, db_address) &&
+             mdb->db_port == db_port) {
             Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
             mdb->ref_count++;
             V(mutex);
index 2b92fb2dc3b6d3cebc0efa8ff16648c0200d9957..93d33ce29f3717fff8f727388b592df6a906e948 100644 (file)
@@ -11,7 +11,7 @@
  *
  */
 /*
-   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
index 617400c8a208b42f247feda2433861f2b62099fb..a6e45638490fec3eb4cb02e001a3ec6f9dc019e9 100644 (file)
@@ -29,8 +29,8 @@ static void terminate_dird(int sig);
 static int check_resources();
 
 /* Exported subroutines */
-
 extern "C" void reload_config(int sig);
+extern void invalidate_schedules();
 
 
 /* Imported subroutines */
@@ -291,7 +291,7 @@ struct RELOAD_TABLE {
    RES **res_table;
 };
 
-static const int max_reloads = 10;
+static const int max_reloads = 32;
 static RELOAD_TABLE reload_table[max_reloads];
 
 static void init_reload(void)
@@ -422,6 +422,7 @@ void reload_config(int sig)
       }
       table = rtable;                 /* release new, bad, saved table below */
    } else {
+      invalidate_schedules();
       /*
        * Hook all active jobs so that they release this table
        */
@@ -680,8 +681,8 @@ static int check_resources()
                          catalog->db_port, catalog->db_socket,
                          catalog->mult_db_connections);
       if (!db || !db_open_database(NULL, db)) {
-         Jmsg(NULL, M_FATAL, 0, _("Could not open database \"%s\".\n"),
-              catalog->db_name);
+         Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
+              catalog->hdr.name, catalog->db_name);
          if (db) {
             Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
          }
index 4d79e77a3d2d67d271afda8394233aeb8009b7b7..18e9cd1f06e559a67ed6a5d9c47f297bc067149c 100755 (executable)
@@ -467,25 +467,28 @@ void *jobq_server(void *arg)
              jcr->job->RescheduleTimes > 0 &&
              jcr->JobType == JT_BACKUP &&
              jcr->reschedule_count < jcr->job->RescheduleTimes) {
-             char dt[50];
+             char dt[50], dt2[50];
 
              /*
               * Reschedule this job by cleaning it up, but
               *  reuse the same JobId if possible.
               */
+            time_t now = time(NULL);
             jcr->reschedule_count++;
-            jcr->sched_time = time(NULL) + jcr->job->RescheduleInterval;
-            Dmsg2(2300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
-               (int)jcr->job->RescheduleInterval);
-            bstrftime(dt, sizeof(dt), time(NULL));
-            Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
-               jcr->Job, dt, (int)jcr->job->RescheduleInterval);
+            jcr->sched_time = now + jcr->job->RescheduleInterval;
+            bstrftime(dt, sizeof(dt), now);
+            bstrftime(dt2, sizeof(dt2), jcr->sched_time);
+            Dmsg4(2300, "Rescheduled Job %s to re-run in %d seconds.(now=%u,then=%u)\n", jcr->Job,
+                  (int)jcr->job->RescheduleInterval, now, jcr->sched_time);
+            Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds (%s).\n"),
+                 jcr->Job, dt, (int)jcr->job->RescheduleInterval, dt2);
             dird_free_jcr_pointers(jcr);     /* partial cleanup old stuff */
-            jcr->JobStatus = JS_WaitStartTime;
+            jcr->JobStatus = -1;
+            set_jcr_job_status(jcr, JS_WaitStartTime);
             jcr->SDJobStatus = 0;
             if (jcr->JobBytes == 0) {
                Dmsg2(2300, "Requeue job=%d use=%d\n", jcr->JobId, jcr->use_count());
-               jcr->JobStatus = JS_WaitStartTime;
+               set_jcr_job_status(jcr, JS_WaitStartTime);
                V(jq->mutex);
                jobq_add(jq, jcr);     /* queue the job to run again */
                P(jq->mutex);
@@ -503,7 +506,8 @@ void *jobq_server(void *arg)
             set_jcr_defaults(njcr, jcr->job);
             njcr->reschedule_count = jcr->reschedule_count;
             njcr->JobLevel = jcr->JobLevel;
-            njcr->JobStatus = jcr->JobStatus;
+            njcr->JobStatus = -1;
+            set_jcr_job_status(njcr, jcr->JobStatus);
             copy_storage(njcr, jcr->storage);
             njcr->messages = jcr->messages;
             Dmsg0(2300, "Call to run new job\n");
index 207bf9f3600aa7f43e3d070c06bed69a728c02e8..ac8f8f0ac0b70821592fab6c69ca0f42d3572549 100644 (file)
@@ -127,7 +127,7 @@ bool do_migration(JCR *jcr)
    JCR *prev_jcr;
 
    if (jcr->previous_jr.JobId == 0) {
-      jcr->JobStatus = JS_Terminated;
+      set_jcr_job_status(jcr, JS_Terminated);
       migration_cleanup(jcr, jcr->JobStatus);
       return true;                    /* no work */
    }
@@ -287,7 +287,7 @@ bool do_migration(JCR *jcr)
    /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */
    wait_for_storage_daemon_termination(jcr);
 
-   jcr->JobStatus = jcr->SDJobStatus;
+   set_jcr_job_status(jcr, jcr->SDJobStatus);
    if (jcr->JobStatus == JS_Terminated) {
       migration_cleanup(jcr, jcr->JobStatus);
       return true;
index 80c72f7f0dda2b707bede0379f88c761697eb68c..8dc27249f3c3ef2d4c8887d46147db15ac91a8e9 100644 (file)
 #include "bacula.h"
 #include "dird.h"
 
-/* #define SCHED_DEBUG */
+#if 0
+#define SCHED_DEBUG
+#define DBGLVL 0
+#else
+#undef SCHED_DEBUG
+#define DBGLVL 200
+#endif
 
+const int dbglvl = DBGLVL;
 
 /* Local variables */
 struct job_item {
@@ -54,6 +61,19 @@ static void dump_job(job_item *ji, const char *msg);
 
 /* Imported variables */
 
+/**
+ * called by reload_config to tell us that the schedules
+ * we may have based our next jobs to run queues have been
+ * invalidated.  In fact the schedules may not have changed
+ * but the run object that we have recorded the last_run time
+ * on are new and no longer have a valid last_run time which
+ * causes us to double run schedules that get put into the list
+ * because run_nh = 1.
+ */   
+static bool schedules_invalidated = false;
+void invalidate_schedules(void) {
+    schedules_invalidated = true;
+}
 
 /*********************************************************************
  *
@@ -69,7 +89,7 @@ JCR *wait_for_next_job(char *one_shot_job_to_run)
    static bool first = true;
    job_item *next_job = NULL;
 
-   Dmsg0(200, "Enter wait_for_next_job\n");
+   Dmsg0(dbglvl, "Enter wait_for_next_job\n");
    if (first) {
       first = false;
       /* Create scheduled jobs list */
@@ -119,12 +139,24 @@ again:
    /* Now wait for the time to run the job */
    for (;;) {
       time_t twait;
+      if (schedules_invalidated) { /** discard scheduled queue and rebuild with new schedule objects. **/
+          dump_job(next_job, "Invalidated job");
+          free(next_job);
+          while (!jobs_to_run->empty()) {
+              next_job = (job_item *)jobs_to_run->first();
+              jobs_to_run->remove(next_job);
+              dump_job(next_job, "Invalidated job");
+              free(next_job);
+          }
+          schedules_invalidated = false;
+          goto again;
+      }
       now = time(NULL);
       twait = next_job->runtime - now;
       if (twait <= 0) {               /* time to run it */
          break;
       }
-      bmicrosleep(twait, 0);
+      bmicrosleep((NEXT_CHECK_SECS<twait)?NEXT_CHECK_SECS:twait, 0); /* recheck at least once per minute */      
    }
    run = next_job->run;               /* pick up needed values */
    job = next_job->job;
@@ -170,7 +202,7 @@ again:
    if (run->write_part_after_job_set) {
       jcr->write_part_after_job = run->write_part_after_job;
    }
-   Dmsg0(200, "Leave wait_for_next_job()\n");
+   Dmsg0(dbglvl, "Leave wait_for_next_job()\n");
    return jcr;
 }
 
@@ -205,7 +237,7 @@ static void find_runs()
    /* Items corresponding to above at the next hour */
    int nh_hour, nh_mday, nh_wday, nh_month, nh_wom, nh_woy, nh_year;
 
-   Dmsg0(1200, "enter find_runs()\n");
+   Dmsg0(dbglvl, "enter find_runs()\n");
 
 
    /* compute values for time now */
@@ -241,7 +273,7 @@ static void find_runs()
       if (sched == NULL || !job->enabled) { /* scheduled? or enabled? */
          continue;                    /* no, skip this job */
       }
-      Dmsg1(1200, "Got job: %s\n", job->hdr.name);
+      Dmsg1(dbglvl, "Got job: %s\n", job->hdr.name);
       for (run=sched->run; run; run=run->next) {
          bool run_now, run_nh;
          /*
@@ -284,7 +316,7 @@ static void find_runs()
             bit_is_set(nh_wom, run->wom) &&
             bit_is_set(nh_woy, run->woy);
 
-         Dmsg2(1200, "run_now=%d run_nh=%d\n", run_now, run_nh);
+         Dmsg3(dbglvl, "run@%p: run_now=%d run_nh=%d\n", run, run_now, run_nh);
 
          /* find time (time_t) job is to be run */
          localtime_r(&now, &tm);      /* reset tm structure */
@@ -307,7 +339,7 @@ static void find_runs()
       }
    }
    UnlockRes();
-   Dmsg0(1200, "Leave find_runs()\n");
+   Dmsg0(dbglvl, "Leave find_runs()\n");
 }
 
 static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
@@ -324,12 +356,16 @@ static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
       bstrftime_nc(dt, sizeof(dt), runtime);
       bstrftime_nc(dt1, sizeof(dt1), run->last_run);
       bstrftime_nc(dt2, sizeof(dt2), now);
-      Dmsg4(000, "Drop: Job=\"%s\" run=%s. last_run=%s. now=%s\n", job->hdr.name,
-            dt, dt1, dt2);
+      Dmsg7(000, "Drop: Job=\"%s\" run=%s(%x). last_run=%s(%x). now=%s(%x)\n", job->hdr.name, 
+            dt, runtime, dt1, run->last_run, dt2, now);
       fflush(stdout);
 #endif
       return;
    }
+#ifdef SCHED_DEBUG
+   Dmsg4(000, "Add: Job=\"%s\" run=%x last_run=%x now=%x\n", job->hdr.name, 
+            runtime, run->last_run, now);
+#endif
    /* accept to run this job */
    job_item *je = (job_item *)malloc(sizeof(job_item));
    je->run = run;
@@ -369,12 +405,11 @@ static void dump_job(job_item *ji, const char *msg)
 #ifdef SCHED_DEBUG
    char dt[MAX_TIME_LENGTH];
    int save_debug = debug_level;
-   debug_level = 200;
-   if (debug_level < 200) {
+   if (debug_level < dbglvl) {
       return;
    }
    bstrftime_nc(dt, sizeof(dt), ji->runtime);
-   Dmsg4(200, "%s: Job=%s priority=%d run %s\n", msg, ji->job->hdr.name,
+   Dmsg4(dbglvl, "%s: Job=%s priority=%d run %s\n", msg, ji->job->hdr.name, 
       ji->Priority, dt);
    fflush(stdout);
    debug_level = save_debug;
index b4f4172979d7ce85087ab8a155bcbd237fa53007..38c0cf6e9085f7400fd77474fe1b00e5857601f2 100644 (file)
@@ -931,6 +931,12 @@ try_again:
       Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
 start_job:
       JobId = run_job(jcr);
+#if 0  
+      bsendmsg(ua, "<job director=\"console\" time=\"%u\" status=\"%c\" type=\"%c\" "
+              "jobid=\"%u\" job=\"%s\" level=\"%c\" finished=\"false\" priority=\"%u\"/>\n",
+               time(NULL), jcr->JobStatus, jcr->JobType, jcr->JobId,
+              jcr->Job, jcr->JobLevel, jcr->JobPriority);
+#endif
       free_jcr(jcr);                  /* release jcr */
       if (JobId == 0) {
          bsendmsg(ua, _("Job failed.\n"));
index 0ec2f11d3fce42a60624e349b622c91ca9bb9991..6add1905a9c10fe348351fdf049441acf1acb4c8 100644 (file)
@@ -96,7 +96,7 @@ JCR *new_control_jcr(const char *base_name, int job_type)
    jcr->sched_time = jcr->start_time;
    jcr->JobType = job_type;
    jcr->JobLevel = L_NONE;
-   jcr->JobStatus = JS_Running;
+   set_jcr_job_status(jcr, JS_Running);
    jcr->JobId = 0;
    return jcr;
 }
index 7609d108eb66f621c23ef9a83bb05ef7246ebfe7..c1165a3d1b4800f2b7328244562dfd11eb21d1ae 100644 (file)
@@ -48,20 +48,24 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    if (bs->msglen < 25 || bs->msglen > 200) {
       Dmsg2(50, "Bad Hello command from Director at %s. Len=%d.\n",
             bs->who, bs->msglen);
+       char addr[64];
+       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
       Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s. Len=%d.\n"),
-            bs->who, bs->msglen);
+            who, bs->msglen);
       return 0;
    }
    dirname = get_pool_memory(PM_MESSAGE);
    dirname = check_pool_memory_size(dirname, bs->msglen);
 
    if (sscanf(bs->msg, "Hello Director %s calling\n", dirname) != 1) {
+       char addr[64];
+       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
       free_pool_memory(dirname);
       bs->msg[100] = 0;
       Dmsg2(50, "Bad Hello command from Director at %s: %s\n",
             bs->who, bs->msg);
       Emsg2(M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"),
-            bs->who, bs->msg);
+           who, bs->msg);
       return 0;
    }
    unbash_spaces(dirname);
@@ -72,11 +76,10 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    }
    UnlockRes();
    if (!director) {
-      Dmsg2(50, "Connection from unknown Director %s at %s rejected.\n",
-            dirname, bs->who);
-      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"
-       "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
-            dirname, bs->who);
+       char addr[64];
+       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
+      Emsg2(M_FATAL, 0, _("Connection from unknown Director %s at %s rejected.\n"), 
+           dirname, who);
       free_pool_memory(dirname);
       return 0;
    }
@@ -97,21 +100,24 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
    }
 
    btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT);
-   auth_success = cram_md5_auth(bs, director->password, tls_local_need);
+   auth_success = cram_md5_auth(bs, director->password, tls_local_need);  
    if (auth_success) {
       auth_success = cram_md5_get_auth(bs, director->password, &tls_remote_need);
       if (!auth_success) {
-         Dmsg1(50, "cram_get_auth failed for %s\n", bs->who);
+         char addr[64];
+         char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
+         Dmsg1(50, "cram_get_auth failed for %s\n", who);
       }
    } else {
-      Dmsg1(50, "cram_auth failed for %s\n", bs->who);
+       char addr[64];
+       char *who = bnet_get_peer(bs, addr, sizeof(addr)) ? bs->who : addr;
+       Dmsg1(50, "cram_auth failed for %s\n", who);
    }
    if (!auth_success) {
-      Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"
-       "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"),
-            bs->who);
-      director = NULL;
-      goto auth_fatal;
+       Emsg1(M_FATAL, 0, _("Incorrect password given by Director at %s.\n"),
+            bs->who);
+       director = NULL;
+       goto auth_fatal;
    }
 
    /* Verify that the remote host is willing to meet our TLS requirements */
index 32c1e8535bbafd4a958ade0682e886e5b982b39c..ebf3d2c57f547fe26038fabd292009c722cfee84 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-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
@@ -182,14 +182,13 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
 #else
    crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
 #endif
-   BSOCK *sd;
    JCR *jcr = (JCR *)vjcr;
+   BSOCK *sd = jcr->store_bsock;
 
    if (job_canceled(jcr)) {
       return 0;
    }
 
-   sd = jcr->store_bsock;
    jcr->num_files_examined++;         /* bump total file count */
 
    switch (ff_pkt->type) {
@@ -206,6 +205,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
       Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
       break;
    case FT_DIRBEGIN:
+      jcr->num_files_examined--;      /* correct file count */
       return 1;                       /* not used */
    case FT_NORECURSE:
      Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend into %s\n"),
index 24a70034adbd35b7185ba053bf178e2dc29c5cbb..1651f2d457669f934e030344205219d596a117b0 100644 (file)
@@ -39,7 +39,7 @@ int make_estimate(JCR *jcr)
 {
    int stat;
 
-   jcr->JobStatus = JS_Running;
+   set_jcr_job_status(jcr, JS_Running);
 
    set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
    stat = find_files(jcr, (FF_PKT *)jcr->ff, tally_file, (void *)jcr);
index 4962da52e5aad003bd66e4ada2e4a8fed08d8aaf..4c342c8a4148ed365e3c3e2fdb1923d5e23596db 100755 (executable)
@@ -117,17 +117,15 @@ static void do_status(void sendit(const char *msg, int len, void *sarg), void *a
      sendit(msg, len, arg);
    }
 #endif
-   if (debug_level > 0) {
-      len = Mmsg(msg, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
-            edit_uint64_with_commas(sm_bytes, b1),
-            edit_uint64_with_commas(sm_max_bytes, b2),
-            edit_uint64_with_commas(sm_buffers, b3),
-            edit_uint64_with_commas(sm_max_buffers, b4));
-      sendit(msg, len, arg);
-      len = Mmsg(msg, _(" Sizeof: off_t=%d size_t=%d debug=%d trace=%d\n"),
-            sizeof(off_t), sizeof(size_t), debug_level, get_trace());
-      sendit(msg, len, arg);
-   }
+   len = Mmsg(msg, _(" Heap: bytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
+         edit_uint64_with_commas(sm_bytes, b1),
+         edit_uint64_with_commas(sm_max_bytes, b2),
+         edit_uint64_with_commas(sm_buffers, b3),
+         edit_uint64_with_commas(sm_max_buffers, b4));
+   sendit(msg, len, arg);
+   len = Mmsg(msg, _(" Sizeof: off_t=%d size_t=%d debug=%d trace=%d\n"),
+         sizeof(off_t), sizeof(size_t), debug_level, get_trace());
+   sendit(msg, len, arg);
 
    list_terminated_jobs(sendit, arg);
 
index ffb62a8482f0fbd16e9ba5158cab88fe6be1d558..a12030481a4d509f0b9c160981932b37b27cc2b6 100755 (executable)
@@ -1,20 +1,15 @@
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-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 as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
    This file is patterned after the VNC Win32 code by ATT
   
@@ -66,6 +61,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    char *szCmdLine = CmdLine;
    char *wordPtr, *tempPtr;
    int i, quote;
+   bool silent = false;
 
    /* Save the application instance and main thread id */
    hAppInstance = hInstance;
@@ -167,11 +163,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 
       /* Now check for command-line arguments */
 
-      /* /service helper - probably only needed on win9x */
-      if (strncmp(&szCmdLine[i], BaculaRunServiceHelper, strlen(BaculaRunServiceHelper)) == 0
-          && g_platform_id == VER_PLATFORM_WIN32_NT) {
-         /* exit with result "okay" */
-         return 0;          
+      /* /silent install quietly -- no prompts */
+      if (strncmp(&szCmdLine[i], "/silent", strlen("/silent")) == 0) {
+         silent = true;
+         i += strlen("/silent");
       }
 
       /* /service start service */
@@ -187,14 +182,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       /* /install */
       if (strncmp(&szCmdLine[i], BaculaInstallService, strlen(BaculaInstallService)) == 0) {
          /* Install Bacula as a service */
-         bacService::InstallService();
+         bacService::InstallService(silent);
          i += strlen(BaculaInstallService);
          continue;
       }
       /* /remove */
       if (strncmp(&szCmdLine[i], BaculaRemoveService, strlen(BaculaRemoveService)) == 0) {
          /* Remove the Bacula service */
-         bacService::RemoveService();
+         bacService::RemoveService(silent);
          i += strlen(BaculaRemoveService);
          continue;
       }
index 186d0a73efc142c01f034609a6f70d374776c7c9..4d803e9ae0d367336d0aca49c998fe0c3fdc63e3 100755 (executable)
@@ -25,7 +25,7 @@
 // by Kern E. Sibbald.  Many thanks to ATT and James Weatherall,
 // the original author, for providing an excellent template.
 //
-// Copyright (2000-2003) Kern E. Sibbald
+// Copyright (C) 2000-2006 Kern E. Sibbald
 //
 
 
@@ -343,7 +343,7 @@ void ServiceStop()
 
 // SERVICE INSTALL ROUTINE
 int
-bacService::InstallService()
+bacService::InstallService(bool silent)
 {
    const int pathlength = 2048;
    char path[pathlength];
@@ -402,13 +402,15 @@ bacService::InstallService()
       RegCloseKey(runservices);
 
       // We have successfully installed the service!
-      MessageBox(NULL,
+      if (!silent) {
+         MessageBox(NULL,
               _("The Bacula File service was successfully installed.\n"
               "The service may be started by double clicking on the\n"
               "Bacula \"Start\" icon and will be automatically\n"
               "be run the next time this machine is rebooted. "),
               szAppName,
               MB_ICONINFORMATION | MB_OK);
+      }
       break;
 
    // Windows NT, Win2K, WinXP
@@ -458,12 +460,14 @@ _("Provides file backup and restore services. Bacula -- the network backup solut
       CloseServiceHandle(hservice);
 
       // Everything went fine
-      MessageBox(NULL,
+      if (!silent) {
+         MessageBox(NULL,
               _("The Bacula File service was successfully installed.\n"
               "The service may be started from the Control Panel and will\n"
               "automatically be run the next time this machine is rebooted."),
               szAppName,
               MB_ICONINFORMATION | MB_OK);
+      }
       break;
    default:
       log_error_message("Unknown Windows System version"); 
@@ -480,7 +484,7 @@ _("Provides file backup and restore services. Bacula -- the network backup solut
 
 // SERVICE REMOVE ROUTINE
 int
-bacService::RemoveService()
+bacService::RemoveService(bool silent)
 {
    // How to remove the Bacula service depends upon the OS
    switch (g_platform_id) {
@@ -514,7 +518,9 @@ bacService::RemoveService()
       }
 
       // We have successfully removed the service!
-      MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK);
+      if (!silent) {
+         MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK);
+      }
       break;
 
    // Windows NT, Win2K, WinXP
@@ -549,8 +555,10 @@ bacService::RemoveService()
             }
 
             // Now remove the service from the SCM
-            if(DeleteService(hservice)) {
-               MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK);
+            if (DeleteService(hservice)) {
+               if (!silent) {
+                  MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK);
+               }
             } else {
                MessageBox(NULL, _("The Bacula service could not be removed"), szAppName, MB_ICONEXCLAMATION | MB_OK);
             }
index 2195b58fca16110d244f4e301bb19be46258c86c..06622ca994c76f0365b1364cc410a1f1d16596f7 100755 (executable)
@@ -25,7 +25,7 @@
 // by Kern E. Sibbald.  Many thanks to ATT and James Weatherall,
 // the original author, for providing an excellent template.
 //
-// Copyright (2000) Kern E. Sibbald
+// Copyright (C) 2000-2006 Kern E. Sibbald
 //
 
 
@@ -46,19 +46,19 @@ class bacService;
 class bacService
 {
 public:
-       bacService();
+        bacService();
 
    // SERVICE INSTALL & START FUNCTIONS
 
    // Routine called by WinMain to cause Bacula to be installed
    // as a service.
-   static int BaculaServiceMain();
+   int BaculaServiceMain();
 
    // Routine to install the Apcupsd service on the local machine
-   static int InstallService();
+   int InstallService(bool silent);
 
    // Routine to remove the Apcupsd service from the local machine
-   static int RemoveService();
+   int RemoveService(bool silent);
 
    // SERVICE SUPPORT FUNCTIONS
 
index 56b2df9298947e38e654e24872156ba5ca7fc6e2..1ebae9a6447417db409f80262631104ea2eedf56 100644 (file)
@@ -77,6 +77,29 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
    gid = attr->statp.st_gid;
    uid = attr->statp.st_uid;
 
+#ifdef HAVE_WIN32
+   if (!bfd->use_backup_api) {
+      // eliminate invalid windows filename characters from foreign filenames
+      char *ch = (char *)attr->ofname;
+      if (ch[0] != 0 && ch[1] != 0) {
+         ch+=2;
+         while (*ch) {
+            switch (*ch) {
+            case ':':
+            case '<':
+            case '>':
+            case '*':
+            case '?':
+            case '|':
+               *ch = '_';
+                break;
+            }
+            ch++;
+         }
+      }
+   }
+#endif
+
    Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
    if (lstat(attr->ofname, &mstatp) == 0) {
       exists = true;
index 38b69462e516c040286d591643384435322aefad..8fd78fbd9c7eeaad307e60e594cb3c3c150e2b5b 100755 (executable)
@@ -32,9 +32,9 @@
 
 
 /*=============================================================*/
-/*                                                            */
-/*                * * *  U n i x * * * *                      */
-/*                                                            */
+/*                                                             */
+/*                 * * *  U n i x * * * *                      */
+/*                                                             */
 /*=============================================================*/
 
 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
@@ -48,9 +48,9 @@ int enable_backup_privileges(JCR *jcr, int ignore_errors)
 
 
 /*=============================================================*/
-/*                                                            */
-/*                * * *  W i n 3 2 * * * *                    */
-/*                                                            */
+/*                                                             */
+/*                 * * *  W i n 3 2 * * * *                    */
+/*                                                             */
 /*=============================================================*/
 
 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
@@ -64,14 +64,13 @@ enable_priv(JCR *jcr, HANDLE hToken, char *name, int ignore_errors)
     DWORD lerror;
 
     if (!(p_LookupPrivilegeValue && p_AdjustTokenPrivileges)) {
-       return 0;                     /* not avail on this OS */
+       return 0;                      /* not avail on this OS */
     }
 
     // Get the LUID for the security privilege.
     if (!p_LookupPrivilegeValue(NULL, name,  &tkp.Privileges[0].Luid)) {
-       if (!ignore_errors) {
-         win_error(jcr, "LookupPrivilegeValue", GetLastError());
-       }
+       win_error(jcr, "LookupPrivilegeValue", GetLastError());
+       return 0;
     }
 
     /* Set the security privilege for this process. */
@@ -81,10 +80,10 @@ enable_priv(JCR *jcr, HANDLE hToken, char *name, int ignore_errors)
     lerror = GetLastError();
     if (lerror != ERROR_SUCCESS) {
        if (!ignore_errors) {
-         char buf[200];
-         strcpy(buf, _("AdjustTokenPrivileges set "));
-         bstrncat(buf, name, sizeof(buf));
-         win_error(jcr, buf, lerror);
+          char buf[200];
+          strcpy(buf, _("AdjustTokenPrivileges set "));
+          bstrncat(buf, name, sizeof(buf));
+          win_error(jcr, buf, lerror);
        }
        return 0;
     }
@@ -102,16 +101,16 @@ int enable_backup_privileges(JCR *jcr, int ignore_errors)
     int stat = 0;
 
     if (!p_OpenProcessToken) {
-       return 0;                     /* No avail on this OS */
+       return 0;                      /* No avail on this OS */
     }
 
     hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
 
     // Get a token for this process.
     if (!p_OpenProcessToken(hProcess,
-           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
+            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        if (!ignore_errors) {
-         win_error(jcr, "OpenProcessToken", GetLastError());
+          win_error(jcr, "OpenProcessToken", GetLastError());
        }
        /* Forge on anyway */
     }
@@ -144,6 +143,9 @@ int enable_backup_privileges(JCR *jcr, int ignore_errors)
     if (enable_priv(jcr, hToken, SE_TCB_NAME, ignore_errors)) {
        stat |= 1<<8;
     }
+    if (enable_priv(jcr, hToken, SE_CREATE_PERMANENT_NAME, ignore_errors)) {
+       stat |= 1<<10;
+    }
     if (stat) {
        stat |= 1<<9;
     }
@@ -153,4 +155,4 @@ int enable_backup_privileges(JCR *jcr, int ignore_errors)
     return stat;
 }
 
-#endif /* HAVE_CYGWIN */
+#endif  /* HAVE_CYGWIN */
index f71c573eb925541c37b76dcd2e36af2fea573a7b..1f4f25c5b39830b4a7cf440a368e92f6d56f0d1a 100755 (executable)
@@ -201,7 +201,7 @@ struct FF_PKT {
    alist fstypes;                     /* allowed file system types */
 
    /* List of all hard linked files found */
-   struct f_link *linklist;           /* hard linked files */
+   struct f_link **linkhash;          /* hard linked files */
 
    /* Darwin specific things.
     * To avoid clutter, we always include rsrc_bfd and volhas_attrlist */
index 1f497687c02a43bcb4dd0482fa8681325ee98212..75d3e855e9f0d7886ed9f89f330e87934d795dcd 100755 (executable)
@@ -53,6 +53,25 @@ struct f_link {
     char name[1];                     /* The name */
 };
 
+typedef struct f_link link_t;
+#define LINK_HASHTABLE_BITS 16
+#define LINK_HASHTABLE_SIZE (1<<LINK_HASHTABLE_BITS)
+#define LINK_HASHTABLE_MASK (LINK_HASHTABLE_SIZE-1)
+
+static inline int LINKHASH(const struct stat &info)
+{
+    int hash = info.st_dev;
+    unsigned long long i = info.st_ino;
+    hash ^= i;
+    i >>= 16;
+    hash ^= i;
+    i >>= 16;
+    hash ^= i;
+    i >>= 16;
+    hash ^= i;
+    return hash & LINK_HASHTABLE_MASK;
+}
+
 static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
 {
    free(dir_ff_pkt->fname);
@@ -231,9 +250,14 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
            || S_ISSOCK(ff_pkt->statp.st_mode))) {
 
        struct f_link *lp;
+       if (ff_pkt->linkhash == NULL) {
+          ff_pkt->linkhash = (link_t **)bmalloc(LINK_HASHTABLE_SIZE * sizeof(link_t *));
+          memset(ff_pkt->linkhash, 0, LINK_HASHTABLE_SIZE * sizeof(link_t *));
+       }
+       const int linkhash = LINKHASH(ff_pkt->statp);
 
       /* Search link list of hard linked files */
-      for (lp = ff_pkt->linklist; lp; lp = lp->next)
+       for (lp = ff_pkt->linkhash[linkhash]; lp; lp = lp->next)
          if (lp->ino == (ino_t)ff_pkt->statp.st_ino &&
              lp->dev == (dev_t)ff_pkt->statp.st_dev) {
              /* If we have already backed up the hard linked file don't do it again */
@@ -252,8 +276,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
       lp->ino = ff_pkt->statp.st_ino;
       lp->dev = ff_pkt->statp.st_dev;
       bstrncpy(lp->name, fname, len);
-      lp->next = ff_pkt->linklist;
-      ff_pkt->linklist = lp;
+       lp->next = ff_pkt->linkhash[linkhash];
+       ff_pkt->linkhash[linkhash] = lp;
       ff_pkt->linked = lp;            /* mark saved link */
    } else {
       ff_pkt->linked = NULL;
@@ -392,7 +416,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
       dir_ff_pkt->included_files_list = NULL;
       dir_ff_pkt->excluded_files_list = NULL;
       dir_ff_pkt->excluded_paths_list = NULL;
-      dir_ff_pkt->linklist = NULL;
+      dir_ff_pkt->linkhash = NULL;
 
       /*
        * Do not descend into subdirectories (recurse) if the
@@ -551,9 +575,15 @@ int term_find_one(FF_PKT *ff)
 {
    struct f_link *lp, *lc;
    int count = 0;
+   int i;
 
+   
+   if (ff->linkhash == NULL) return 0;
+
+   for (i =0 ; i < LINK_HASHTABLE_SIZE; i ++) {
    /* Free up list of hard linked files */
-   for (lp = ff->linklist; lp;) {
+       lp = ff->linkhash[i];
+       while (lp) {
       lc = lp;
       lp = lp->next;
       if (lc) {
@@ -561,6 +591,9 @@ int term_find_one(FF_PKT *ff)
          count++;
       }
    }
-   ff->linklist = NULL;
+       ff->linkhash[i] = NULL;
+   }
+   free(ff->linkhash);
+   ff->linkhash = NULL;
    return count;
 }
index 452c45bcfd7d3b7f68e1bec0b140b8d935a2554d..11eb9f804e1689105db6b1a4b85e1348c2cc71df 100644 (file)
@@ -217,12 +217,17 @@ make_path(
       /* Because of silly Win32 security, we allow everything */
       tmp_mode = S_IRWXUGO;
       re_protect = 0;
-#endif
 
+#endif
+#if defined(HAVE_WIN32)
+      // chdir can fail if permissions are sufficiently restricted since I don't think
+      // backup/restore security rights affect ChangeWorkingDirectory
+      cwd.do_chdir = 0;
+#else
       /* If we can record the current working directory, we may be able
         to do the chdir optimization.  */
       cwd.do_chdir = !save_cwd(&cwd);
-
+#endif
       /* If we've saved the cwd and DIRPATH is an absolute pathname,
         we must chdir to `/' in order to enable the chdir optimization.
         So if chdir ("/") fails, turn off the optimization.  */
index d94112490a7754ef77c4b38dc67570516166b8b9..eb58d956b418d48ec679437c2b60e6971d1ead23 100644 (file)
@@ -909,6 +909,21 @@ bool bnet_fsend(BSOCK * bs, const char *fmt, ...)
    return bnet_send(bs);
 }
 
+int bnet_get_peer(BSOCK *bs, char *buf, socklen_t buflen) {
+#if !defined(HAVE_WIN32)
+    if (bs->peer_addr.sin_family == 0) {
+       socklen_t salen = sizeof(bs->peer_addr);
+       int rval = (getpeername)(bs->fd, (struct sockaddr *)&bs->peer_addr, &salen);
+       if (rval < 0) return rval;
+    }
+    if (!inet_ntop(bs->peer_addr.sin_family, &bs->peer_addr.sin_addr, buf, buflen))
+       return -1;
+
+    return 0;
+#else
+    return -1;
+#endif
+}
 /*
  * Set the network buffer size, suggested size is in size.
  *  Actual size obtained is returned in bs->msglen
@@ -1137,6 +1152,7 @@ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int
    bsock->who = bstrdup(who);
    bsock->host = bstrdup(host);
    bsock->port = port;
+   memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
    memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
    /*
     * ****FIXME**** reduce this to a few hours once
index 22ed040f2698a02a1b5c69d68dcf31ae7106e409..b04af0ffaf4d4605f1bae151bd21f9354501171a 100644 (file)
@@ -53,6 +53,7 @@ struct BSOCK {
    FILE *spool_fd;                    /* spooling file */
    JCR *jcr;                          /* jcr or NULL for error msgs */
    struct sockaddr client_addr;    /* client's IP address */
+   struct sockaddr_in peer_addr;    /* peer's IP address */
 };
 
 /* Signal definitions for use in bnet_sig() */
index 3f6afaa3caf67c14a43d4c1b642da7be5469c67e..c620740a5a59d6881affb1e786d3a1f85957e4dc 100644 (file)
@@ -8,7 +8,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-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
@@ -113,6 +113,16 @@ char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
    return dest;
 }
 
+/*
+ * Allows one or both pointers to be NULL
+ */
+bool bstrcmp(const char *s1, const char *s2)
+{
+   if (s1 == s2) return true;
+   if (s1 == NULL || s2 == NULL) return false;
+   return strcmp(s1, s2) == 0;
+}
+
 /*
  * Get character length of UTF-8 string
  *
index 8c2c241ba982b8e65b8011acba6a1cceb2482fbb..d49ee3c0ee7feb14ca52019bab6839efad84cf25 100755 (executable)
@@ -231,7 +231,7 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
    jcr->daemon_free_jcr = daemon_free_jcr;    /* plug daemon free routine */
    jcr->init_mutex();
    jcr->inc_use_count();   
-   jcr->JobStatus = JS_Created;       /* ready to run */
+   set_jcr_job_status(jcr, JS_Created);       /* ready to run */
    jcr->VolumeName = get_pool_memory(PM_FNAME);
    jcr->VolumeName[0] = 0;
    jcr->errmsg = get_pool_memory(PM_MESSAGE);
index 7cdd8eeb1ae729ed627e8e4d1c4207bfd55900de..048872ab0d84ca05c0fb81cbe516e71bde5d8630 100644 (file)
@@ -38,6 +38,7 @@ char     *bstrncpy               (char *dest, const char *src, int maxlen);
 char     *bstrncpy               (char *dest, POOL_MEM &src, int maxlen);
 char     *bstrncat               (char *dest, const char *src, int maxlen);
 char     *bstrncat               (char *dest, POOL_MEM &src, int maxlen);
+bool      bstrcmp                (const char *s1, const char *s2);
 int       cstrlen                (const char *str);
 void     *b_malloc               (const char *file, int line, size_t size);
 #ifndef DEBUG
@@ -75,6 +76,7 @@ BSOCK *    bnet_connect          (JCR *jcr, int retry_interval,
 void       bnet_close            (BSOCK *bsock);
 BSOCK *    init_bsock            (JCR *jcr, int sockfd, const char *who, const char *ip,
                                   int port, struct sockaddr *client_addr);
+int       bnet_get_peer           (BSOCK *bs, char *buf, socklen_t buflen);
 BSOCK *    dup_bsock             (BSOCK *bsock);
 void       term_bsock            (BSOCK *bsock);
 const char *bnet_strerror         (BSOCK *bsock);
index c23d25f4cdf61026e59e17401e8ca58db2f881ea..d8f8bbc420ded1a272394a07fb709f2467e74e11 100644 (file)
@@ -6,7 +6,7 @@
  *     Kern Sibbald MMIII
  */
 /*
-   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
@@ -48,6 +48,8 @@ t_SetProcessShutdownParameters p_SetProcessShutdownParameters = NULL;
 
 t_CreateFileA   p_CreateFileA = NULL;
 t_CreateFileW   p_CreateFileW = NULL;
+t_CreateDirectoryA   p_CreateDirectoryA;
+t_CreateDirectoryW   p_CreateDirectoryW;
 
 t_wunlink p_wunlink = NULL;
 t_wmkdir p_wmkdir = NULL;
@@ -101,6 +103,11 @@ InitWinAPIWrapper()
       p_CreateFileW = (t_CreateFileW)
           GetProcAddress(hLib, "CreateFileW");      
 
+      p_CreateDirectoryA = (t_CreateDirectoryA)
+          GetProcAddress(hLib, "CreateDirectoryA");
+      p_CreateDirectoryW = (t_CreateDirectoryW)
+          GetProcAddress(hLib, "CreateDirectoryW");      
+
       /* attribute calls */
       p_GetFileAttributesA = (t_GetFileAttributesA)
           GetProcAddress(hLib, "GetFileAttributesA");
index 42db9f3fcba95f087a641ec9bb28794cd3cf9d38..e068b0019cca713f91888862f348a27241edd35f 100644 (file)
@@ -6,22 +6,17 @@
  *     Kern Sibbald MMIII
  */
 /*
-   Copyright (C) 2000-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 as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   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 GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -47,11 +42,23 @@ typedef char POOLMEM;
 #endif
 
 // unicode enabling of win 32 needs some defines and functions
-#define MAX_PATH_UTF8    MAX_PATH*3
+
+// using an average of 3 bytes per character is probably fine in
+// practice but I believe that Windows actually uses UTF-16 encoding
+// as opposed to UCS2 which means characters 0x10000-0x10ffff are
+// valid and result in 4 byte UTF-8 encodings.
+#define MAX_PATH_UTF8    MAX_PATH*4  // strict upper bound on UTF-16 to UTF-8 conversion
+// from
+// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getfileattributesex.asp
+// In the ANSI version of this function, the name is limited to
+// MAX_PATH characters. To extend this limit to 32,767 wide
+// characters, call the Unicode version of the function and prepend
+// "\\?\" to the path. For more information, see Naming a File.
+#define MAX_PATH_W 32767
 
 int wchar_2_UTF8(char *pszUTF, const WCHAR *pszUCS, int cchChar = MAX_PATH_UTF8);
 int UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF);
-int make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL* pBIsRawPath = NULL);
+
 
 /* In ADVAPI32.DLL */
 
@@ -89,6 +96,9 @@ typedef HANDLE (WINAPI * t_CreateFileA) (LPCSTR, DWORD ,DWORD, LPSECURITY_ATTRIB
 typedef HANDLE (WINAPI * t_CreateFileW) (LPCWSTR, DWORD ,DWORD, LPSECURITY_ATTRIBUTES,
         DWORD , DWORD, HANDLE);
 
+typedef BOOL (WINAPI * t_CreateDirectoryA) (LPCSTR, LPSECURITY_ATTRIBUTES);
+typedef BOOL (WINAPI * t_CreateDirectoryW) (LPCWSTR, LPSECURITY_ATTRIBUTES);
+
 typedef BOOL (WINAPI * t_SetProcessShutdownParameters)(DWORD, DWORD);
 typedef BOOL (WINAPI * t_BackupRead)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*);
 typedef BOOL (WINAPI * t_BackupWrite)(HANDLE,LPBYTE,DWORD,LPDWORD,BOOL,BOOL,LPVOID*);
@@ -123,6 +133,10 @@ extern t_SetFileAttributesW   p_SetFileAttributesW;
 
 extern t_CreateFileA   p_CreateFileA;
 extern t_CreateFileW   p_CreateFileW;
+
+extern t_CreateDirectoryA   p_CreateDirectoryA;
+extern t_CreateDirectoryW   p_CreateDirectoryW;
+
 extern t_SetProcessShutdownParameters p_SetProcessShutdownParameters;
 extern t_BackupRead         p_BackupRead;
 extern t_BackupWrite        p_BackupWrite;
index b7fc61a113be361a6e6e8c51acc577005b50e0a5..8b7f8a5301772fe36c4a64ce16e23c65aef0f683 100644 (file)
@@ -451,7 +451,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
          }
       }
 
-      jcr->JobStatus = JS_WaitMedia;
+      set_jcr_job_status(jcr, JS_WaitMedia);
       dir_send_job_status(jcr);
 
       stat = wait_for_sysop(dcr);
@@ -532,7 +532,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
                dcr->VolumeName, dev->print_name(), jcr->Job);
       }
 
-      jcr->JobStatus = JS_WaitMount;
+      set_jcr_job_status(jcr, JS_WaitMount);
       dir_send_job_status(jcr);
 
       stat = wait_for_sysop(dcr);          /* wait on device */
index 00f6740a6a424c75e6241c422a50c310cf625c92..9e934c13660cac8bdb19b2b1d813c510455139d5 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "1.39.9"
-#define BDATE   "18 April 2006"
-#define LSMDATE "18Apr06"
+#define BDATE   "19 April 2006"
+#define LSMDATE "19Apr06"
 
 /* Debug flags */
 #undef  DEBUG