From e18da82dec310aa4144c6fa2bed2449590d7f38a Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 19 Apr 2006 17:14:19 +0000 Subject: [PATCH] - 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. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2943 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kes-1.39 | 18 ++++++++ bacula/src/cats/mysql.c | 4 +- bacula/src/cats/postgresql.c | 4 +- bacula/src/cats/sql.c | 5 ++- bacula/src/cats/sqlite.c | 23 +++++----- bacula/src/dird/authenticate.c | 2 +- bacula/src/dird/dird.c | 9 ++-- bacula/src/dird/jobq.c | 24 ++++++----- bacula/src/dird/migrate.c | 4 +- bacula/src/dird/scheduler.c | 61 +++++++++++++++++++++------ bacula/src/dird/ua_run.c | 6 +++ bacula/src/dird/ua_server.c | 2 +- bacula/src/filed/authenticate.c | 36 +++++++++------- bacula/src/filed/backup.c | 6 +-- bacula/src/filed/estimate.c | 2 +- bacula/src/filed/status.c | 20 ++++----- bacula/src/filed/win32/winmain.cpp | 31 ++++++-------- bacula/src/filed/win32/winservice.cpp | 24 +++++++---- bacula/src/filed/win32/winservice.h | 10 ++--- bacula/src/findlib/create_file.c | 23 ++++++++++ bacula/src/findlib/enable_priv.c | 38 +++++++++-------- bacula/src/findlib/find.h | 2 +- bacula/src/findlib/find_one.c | 45 +++++++++++++++++--- bacula/src/findlib/makepath.c | 9 +++- bacula/src/lib/bnet.c | 16 +++++++ bacula/src/lib/bsock.h | 1 + bacula/src/lib/bsys.c | 12 +++++- bacula/src/lib/jcr.c | 2 +- bacula/src/lib/protos.h | 2 + bacula/src/lib/winapi.c | 9 +++- bacula/src/lib/winapi.h | 40 ++++++++++++------ bacula/src/stored/askdir.c | 4 +- bacula/src/version.h | 4 +- 33 files changed, 343 insertions(+), 155 deletions(-) diff --git a/bacula/kes-1.39 b/bacula/kes-1.39 index 4a23fde8ca..b379c2c425 100644 --- a/bacula/kes-1.39 +++ b/bacula/kes-1.39 @@ -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. diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index 0ff62087f8..ad0be7a6ca 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -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); diff --git a/bacula/src/cats/postgresql.c b/bacula/src/cats/postgresql.c index ddcd2cda32..4b0e151dc7 100644 --- a/bacula/src/cats/postgresql.c +++ b/bacula/src/cats/postgresql.c @@ -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); diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index 7446ed9fd0..933c96663a 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -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); diff --git a/bacula/src/cats/sqlite.c b/bacula/src/cats/sqlite.c index 67332ff2d5..f2b9f76963 100644 --- a/bacula/src/cats/sqlite.c +++ b/bacula/src/cats/sqlite.c @@ -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); diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 2b92fb2dc3..93d33ce29f 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -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 diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 617400c8a2..a6e4563849 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -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)); } diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index 4d79e77a3d..18e9cd1f06 100755 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -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"); diff --git a/bacula/src/dird/migrate.c b/bacula/src/dird/migrate.c index 207bf9f360..ac8f8f0ac0 100644 --- a/bacula/src/dird/migrate.c +++ b/bacula/src/dird/migrate.c @@ -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; diff --git a/bacula/src/dird/scheduler.c b/bacula/src/dird/scheduler.c index 80c72f7f0d..8dc27249f3 100644 --- a/bacula/src/dird/scheduler.c +++ b/bacula/src/dird/scheduler.c @@ -27,8 +27,15 @@ #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_SECSrun; /* 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; diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index b4f4172979..38c0cf6e90 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -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, "\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")); diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index 0ec2f11d3f..6add1905a9 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -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; } diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index 7609d108eb..c1165a3d1b 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -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 */ diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 32c1e8535b..ebf3d2c57f 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -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"), diff --git a/bacula/src/filed/estimate.c b/bacula/src/filed/estimate.c index 24a70034ad..1651f2d457 100644 --- a/bacula/src/filed/estimate.c +++ b/bacula/src/filed/estimate.c @@ -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); diff --git a/bacula/src/filed/status.c b/bacula/src/filed/status.c index 4962da52e5..4c342c8a41 100755 --- a/bacula/src/filed/status.c +++ b/bacula/src/filed/status.c @@ -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); diff --git a/bacula/src/filed/win32/winmain.cpp b/bacula/src/filed/win32/winmain.cpp index ffb62a8482..a12030481a 100755 --- a/bacula/src/filed/win32/winmain.cpp +++ b/bacula/src/filed/win32/winmain.cpp @@ -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; } diff --git a/bacula/src/filed/win32/winservice.cpp b/bacula/src/filed/win32/winservice.cpp index 186d0a73ef..4d803e9ae0 100755 --- a/bacula/src/filed/win32/winservice.cpp +++ b/bacula/src/filed/win32/winservice.cpp @@ -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); } diff --git a/bacula/src/filed/win32/winservice.h b/bacula/src/filed/win32/winservice.h index 2195b58fca..06622ca994 100755 --- a/bacula/src/filed/win32/winservice.h +++ b/bacula/src/filed/win32/winservice.h @@ -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 diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 56b2df9298..1ebae9a644 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -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; diff --git a/bacula/src/findlib/enable_priv.c b/bacula/src/findlib/enable_priv.c index 38b69462e5..8fd78fbd9c 100755 --- a/bacula/src/findlib/enable_priv.c +++ b/bacula/src/findlib/enable_priv.c @@ -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 */ diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index f71c573eb9..1f4f25c5b3 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -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 */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 1f497687c0..75d3e855e9 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -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<>= 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; } diff --git a/bacula/src/findlib/makepath.c b/bacula/src/findlib/makepath.c index 452c45bcfd..11eb9f804e 100644 --- a/bacula/src/findlib/makepath.c +++ b/bacula/src/findlib/makepath.c @@ -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. */ diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index d94112490a..eb58d956b4 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -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 diff --git a/bacula/src/lib/bsock.h b/bacula/src/lib/bsock.h index 22ed040f26..b04af0ffaf 100644 --- a/bacula/src/lib/bsock.h +++ b/bacula/src/lib/bsock.h @@ -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() */ diff --git a/bacula/src/lib/bsys.c b/bacula/src/lib/bsys.c index 3f6afaa3ca..c620740a5a 100644 --- a/bacula/src/lib/bsys.c +++ b/bacula/src/lib/bsys.c @@ -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 * diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 8c2c241ba9..d49ee3c0ee 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -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); diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 7cdd8eeb1a..048872ab0d 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -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); diff --git a/bacula/src/lib/winapi.c b/bacula/src/lib/winapi.c index c23d25f4cd..d8f8bbc420 100644 --- a/bacula/src/lib/winapi.c +++ b/bacula/src/lib/winapi.c @@ -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"); diff --git a/bacula/src/lib/winapi.h b/bacula/src/lib/winapi.h index 42db9f3fcb..e068b0019c 100644 --- a/bacula/src/lib/winapi.h +++ b/bacula/src/lib/winapi.h @@ -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; diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index b7fc61a113..8b7f8a5301 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -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 */ diff --git a/bacula/src/version.h b/bacula/src/version.h index 00f6740a6a..9e934c1366 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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 -- 2.39.5