From: Kern Sibbald Date: Fri, 30 Jan 2009 09:20:41 +0000 (+0000) Subject: kes Fix a text sizing problem in the tray-monitor reported in X-Git-Tag: Release-7.0.0~3418 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=14f98468584b359a7704e67d69e2c419b4a55c7d;p=bacula%2Fbacula kes Fix a text sizing problem in the tray-monitor reported in bug #1219, with patch included. + reorganize patches git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8414 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/AUTHORS b/bacula/AUTHORS index 0d6d9554f9..e6e181f278 100644 --- a/bacula/AUTHORS +++ b/bacula/AUTHORS @@ -99,6 +99,7 @@ Tim Oberfoell Tomas Cameron Tullio Andreatta Ulrich Leodolter +Vitaliy Kosharskiy Wolfgang Denk Yuri Timofeev Yves Orton diff --git a/bacula/patches/2.4.3-getmsg.patch b/bacula/patches/2.4.3-getmsg.patch deleted file mode 100644 index 926cbcdbb6..0000000000 --- a/bacula/patches/2.4.3-getmsg.patch +++ /dev/null @@ -1,135 +0,0 @@ - - This patch used the jcr stored in the BSOCK packet during callbacks - to the Director rather than looking them up in the JCR list. - - It can be applied to Bacula version 2.4.3 (or earlier) with: - - cd - patch -p0 <2.4.3-getmsg.patch - ./configure - make - ... - make install - - -Index: src/dird/getmsg.c -=================================================================== ---- src/dird/getmsg.c (revision 7970) -+++ src/dird/getmsg.c (working copy) -@@ -1,7 +1,7 @@ - /* - Bacula® - The Network Backup Solution - -- Copyright (C) 2000-2007 Free Software Foundation Europe e.V. -+ Copyright (C) 2000-2008 Free Software Foundation Europe e.V. - - The main author of Bacula is Kern Sibbald, with contributions from - many others, a complete list can be found in the file AUTHORS. -@@ -20,7 +20,7 @@ - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -- Bacula® is a registered trademark of John Walker. -+ Bacula® is a registered trademark of Kern Sibbald. - The licensor of Bacula is the Free Software Foundation Europe - (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, - Switzerland, email:ftf@fsfeurope.org. -@@ -102,12 +102,12 @@ - char Job[MAX_NAME_LENGTH]; - char MsgType[20]; - int type, level; -- JCR *jcr; -+ JCR *jcr = bs->jcr(); - char *msg; - - for (;;) { - n = bs->recv(); -- Dmsg2(100, "bget_dirmsg %d: %s", n, bs->msg); -+ Dmsg2(300, "bget_dirmsg %d: %s\n", n, bs->msg); - - if (is_bnet_stop(bs)) { - return n; /* error or terminate */ -@@ -142,7 +142,7 @@ - bs->fsend("btime %s\n", edit_uint64(get_current_btime(),ed1)); - break; - default: -- Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen); -+ Jmsg1(jcr, M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen); - return n; - } - continue; -@@ -160,21 +160,13 @@ - * Try to fulfill it. - */ - if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) { -- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); -+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); - continue; - } -- if (strcmp(Job, "*System*") == 0) { -- jcr = NULL; /* No jcr */ -- } else if (!(jcr=get_jcr_by_full_name(Job))) { -- Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg); -- continue; -- } -- Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr); - - /* Skip past "Jmsg Job=nnn" */ - if (!(msg=find_msg_start(bs->msg))) { -- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); -- free_jcr(jcr); -+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); - continue; - } - -@@ -185,8 +177,7 @@ - if (bs->msg[0] == 'J') { /* Job message */ - if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d", - Job, &type, &level) != 3) { -- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); -- free_jcr(jcr); -+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); - continue; - } - Dmsg1(900, "Got msg: %s\n", bs->msg); -@@ -199,7 +190,6 @@ - } - Dmsg1(900, "Dispatch msg: %s", msg); - dispatch_message(jcr, type, level, msg); -- free_jcr(jcr); - continue; - } - /* -@@ -209,21 +199,16 @@ - if (bs->msg[0] == 'C') { /* Catalog request */ - Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg); - catalog_request(jcr, bs); -- Dmsg1(900, "Calling freejcr 0x%x\n", jcr); -- free_jcr(jcr); - continue; - } - if (bs->msg[0] == 'U') { /* SD sending attributes */ - Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg); - catalog_update(jcr, bs); -- Dmsg1(900, "Calling freejcr 0x%x\n", jcr); -- free_jcr(jcr); - continue; - } - if (bs->msg[0] == 'M') { /* Mount request */ - Dmsg1(900, "Mount req: %s", bs->msg); - mount_request(jcr, bs, msg); -- free_jcr(jcr); - continue; - } - if (bs->msg[0] == 'S') { /* Status change */ -@@ -232,9 +217,8 @@ - if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) { - jcr->SDJobStatus = JobStatus; /* current status */ - } else { -- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); -+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); - } -- free_jcr(jcr); - continue; - } - #ifdef needed diff --git a/bacula/patches/2.4.3-jobs.patch b/bacula/patches/2.4.3-jobs.patch deleted file mode 100644 index 25d2d3cb45..0000000000 --- a/bacula/patches/2.4.3-jobs.patch +++ /dev/null @@ -1,127 +0,0 @@ - - This patch corrects two problems: - 1. If you start more than 60 jobs within a 1 minute period, the unique - jobname (critical for the daemons) can be duplicated leading to - authentication failures and orphaned jobs. - 2. FD jobs that fail SD authentication were not properly cleaned up. - - Apply it to Bacula 2.4.3 (possibly earlier versions) - with: - - cd - patch -p0 <2.4.3-jobs.patch - ./configure - make - ... - make install - - -Index: src/dird/job.c -=================================================================== ---- src/dird/job.c (revision 8011) -+++ src/dird/job.c (working copy) -@@ -758,17 +758,17 @@ - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - static time_t last_start_time = 0; - static int seq = 0; -- time_t now; -+ time_t now = time(NULL); - struct tm tm; - char dt[MAX_TIME_LENGTH]; - char name[MAX_NAME_LENGTH]; - char *p; -+ int len; - - /* Guarantee unique start time -- maximum one per second, and - * thus unique Job Name - */ - P(mutex); /* lock creation of jobs */ -- now = time(NULL); - seq++; - if (seq > 59) { /* wrap as if it is seconds */ - seq = 0; -@@ -783,9 +783,10 @@ - /* Form Unique JobName */ - (void)localtime_r(&now, &tm); - /* Use only characters that are permitted in Windows filenames */ -- strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M", &tm); -+ strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm); -+ len = strlen(dt) + 5; /* dt + .%02d EOS */ - bstrncpy(name, base_name, sizeof(name)); -- name[sizeof(name)-22] = 0; /* truncate if too long */ -+ name[sizeof(name)-len] = 0; /* truncate if too long */ - bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s.%02d", name, dt, seq); /* add date & time */ - /* Convert spaces into underscores */ - for (p=jcr->Job; *p; p++) { -@@ -793,6 +794,7 @@ - *p = '_'; - } - } -+ Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job); - } - - /* Called directly from job rescheduling */ -Index: src/stored/job.c -=================================================================== ---- src/stored/job.c (revision 8011) -+++ src/stored/job.c (working copy) -@@ -228,21 +228,25 @@ - if (!(jcr=get_jcr_by_full_name(job_name))) { - Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name); - Dmsg1(3, "**** Job \"%s\" not found\n", job_name); -+ fd->close(); - return; - } - -- jcr->file_bsock = fd; -- jcr->file_bsock->set_jcr(jcr); -- - Dmsg1(110, "Found Job %s\n", job_name); - - if (jcr->authenticated) { - Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), - (uint32_t)jcr->JobId, jcr->Job); -+ Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n", -+ (uint32_t)jcr->JobId, jcr->Job); -+ fd->close(); - free_jcr(jcr); - return; - } - -+ jcr->file_bsock = fd; -+ jcr->file_bsock->set_jcr(jcr); -+ - /* - * Authenticate the File daemon - */ -Index: src/lib/bnet_server.c -=================================================================== ---- src/lib/bnet_server.c (revision 8011) -+++ src/lib/bnet_server.c (working copy) -@@ -1,7 +1,7 @@ - /* - Bacula® - The Network Backup Solution - -- Copyright (C) 2000-2007 Free Software Foundation Europe e.V. -+ Copyright (C) 2000-2008 Free Software Foundation Europe e.V. - - The main author of Bacula is Kern Sibbald, with contributions from - many others, a complete list can be found in the file AUTHORS. -@@ -20,7 +20,7 @@ - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -- Bacula® is a registered trademark of John Walker. -+ Bacula® is a registered trademark of Kern Sibbald. - The licensor of Bacula is the Free Software Foundation Europe - (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, - Switzerland, email:ftf@fsfeurope.org. -@@ -137,7 +137,7 @@ - be.bstrerror()); - } - } -- listen(fd_ptr->fd, 5); /* tell system we are ready */ -+ listen(fd_ptr->fd, 20); /* tell system we are ready */ - sockfds.append(fd_ptr); - } - /* Start work queue thread */ diff --git a/bacula/patches/2.4.3-migrate-log.patch b/bacula/patches/2.4.3-migrate-log.patch deleted file mode 100644 index c593cc23ef..0000000000 --- a/bacula/patches/2.4.3-migrate-log.patch +++ /dev/null @@ -1,71 +0,0 @@ - - This patch should cause all Job Log records to be migrated when the - Job is migrated. It fixes the second issue reported in bug #1171. - - Apply it to Bacula 2.4.3 (possibly earlier versions) - with: - - cd - patch -p0 <2.4.3-migrate.patch - ./configure - make - ... - make install - -Index: src/dird/migrate.c -=================================================================== ---- src/dird/migrate.c (revision 7926) -+++ src/dird/migrate.c (working copy) -@@ -402,14 +402,6 @@ - } - - migration_cleanup(jcr, jcr->JobStatus); -- if (mig_jcr) { -- char jobid[50]; -- UAContext *ua = new_ua_context(jcr); -- edit_uint64(jcr->previous_jr.JobId, jobid); -- /* Purge all old file records, but leave Job record */ -- purge_files_from_jobs(ua, jobid); -- free_ua_context(ua); -- } - return true; - } - -@@ -1087,11 +1079,26 @@ - edit_uint64(mig_jcr->jr.JobId, ec2)); - db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); - -- /* Now mark the previous job as migrated if it terminated normally */ -- if (jcr->JobStatus == JS_Terminated) { -+ /* -+ * If we terminated a migration normally: -+ * - mark the previous job as migrated -+ * - move any Log records to the new JobId -+ * - Purge the File records from the previous job -+ */ -+ if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) { -+ char old_jobid[50], new_jobid[50]; - Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", -- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1)); -+ (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid)); - db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); -+ UAContext *ua = new_ua_context(jcr); -+ /* Move JobLog to new JobId */ -+ Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s", -+ new_jobid, -+ edit_uint64(jcr->previous_jr.JobId, old_jobid)); -+ db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); -+ /* Purge all old file records, but leave Job record */ -+ purge_files_from_jobs(ua, old_jobid); -+ free_ua_context(ua); - } - - if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { -@@ -1100,7 +1107,6 @@ - set_jcr_job_status(jcr, JS_ErrorTerminated); - } - -- - update_bootstrap_file(mig_jcr); - - if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) { diff --git a/bacula/patches/2.4.3-migrate.patch b/bacula/patches/2.4.3-migrate.patch deleted file mode 100644 index 138c09c9d1..0000000000 --- a/bacula/patches/2.4.3-migrate.patch +++ /dev/null @@ -1,53 +0,0 @@ - - This patch should prevent migration jobs from attempting to migrate - jobs that failed. Apply it to Bacula 2.4.3 (possibly earlier versions) - with: - - cd - patch -p0 <2.4.3-migrate.patch - ./configure - make - ... - make install - - -Index: src/dird/migrate.c -=================================================================== ---- src/dird/migrate.c (revision 7757) -+++ src/dird/migrate.c (working copy) -@@ -377,7 +377,7 @@ - * to avoid two threads from using the BSOCK structure at - * the same time. - */ -- if (!bnet_fsend(sd, "run")) { -+ if (!sd->fsend("run")) { - return false; - } - -@@ -520,6 +520,7 @@ - "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool,Client" - " WHERE Client.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId" - " AND Job.ClientId=Client.ClientId AND Job.Type='B'" -+ " AND Job.JobStatus = 'T'" - " ORDER by Job.StartTime"; - - /* Get Volume names in Pool */ -@@ -533,9 +534,9 @@ - "SELECT DISTINCT Job.JobId,Job.StartTime FROM Media,JobMedia,Job" - " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId" - " AND JobMedia.JobId=Job.JobId AND Job.Type='B'" -+ " AND Job.JobStatus = 'T' AND Media.Enabled=1" - " ORDER by Job.StartTime"; - -- - const char *sql_smallest_vol = - "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE" - " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND" -@@ -570,7 +571,6 @@ - const char *sql_job_bytes = - "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)"; - -- - /* Get Media Ids in Pool */ - const char *sql_mediaids = - "SELECT MediaId FROM Media,Pool WHERE" diff --git a/bacula/patches/2.4.3-migrate2.patch b/bacula/patches/2.4.3-migrate2.patch deleted file mode 100644 index 9d37e8c5b3..0000000000 --- a/bacula/patches/2.4.3-migrate2.patch +++ /dev/null @@ -1,85 +0,0 @@ - - This patch should fix two bugs: - - Bug #1206 -- sql error when there are no files to migrate. - - Bug #1171 -- Job catalog log is not migrated during migration. - - Apply it to a fully patched (requires two previous migration patches) - 2.4.3 version with: - - cd - patch -p0 <2.4.3-migrate2.patch - ./configure - make - ... - make install - - -Index: src/dird/migrate.c -=================================================================== ---- src/dird/migrate.c (revision 8152) -+++ src/dird/migrate.c (working copy) -@@ -122,6 +122,12 @@ - - Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source); - -+ if (!get_or_create_fileset_record(jcr)) { -+ Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); -+ Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n")); -+ return false; -+ } -+ - /* If we find a job or jobs to migrate it is previous_jr.JobId */ - count = get_job_to_migrate(jcr); - if (count < 0) { -@@ -139,12 +145,6 @@ - return true; /* no work */ - } - -- if (!get_or_create_fileset_record(jcr)) { -- Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); -- Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n")); -- return false; -- } -- - create_restore_bootstrap_file(jcr); - - if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) { -@@ -1062,6 +1062,11 @@ - * mig_jcr is jcr of the newly migrated job. - */ - if (mig_jcr) { -+ char old_jobid[50], new_jobid[50]; -+ -+ edit_uint64(jcr->previous_jr.JobId, old_jobid); -+ edit_uint64(mig_jcr->jr.JobId, new_jobid); -+ - mig_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles; - mig_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes; - mig_jcr->VolSessionId = jcr->VolSessionId; -@@ -1076,7 +1081,7 @@ - "JobTDate=%s WHERE JobId=%s", - jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, - edit_uint64(jcr->previous_jr.JobTDate, ec1), -- edit_uint64(mig_jcr->jr.JobId, ec2)); -+ new_jobid); - db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); - - /* -@@ -1086,15 +1091,13 @@ - * - Purge the File records from the previous job - */ - if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) { -- char old_jobid[50], new_jobid[50]; - Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", -- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid)); -+ (char)JT_MIGRATED_JOB, old_jobid); - db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); - UAContext *ua = new_ua_context(jcr); - /* Move JobLog to new JobId */ - Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s", -- new_jobid, -- edit_uint64(jcr->previous_jr.JobId, old_jobid)); -+ new_jobid, old_jobid); - db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); - /* Purge all old file records, but leave Job record */ - purge_files_from_jobs(ua, old_jobid); diff --git a/bacula/patches/2.4.3-orphaned-jobs.patch b/bacula/patches/2.4.3-orphaned-jobs.patch deleted file mode 100644 index 6162c9e95a..0000000000 --- a/bacula/patches/2.4.3-orphaned-jobs.patch +++ /dev/null @@ -1,24 +0,0 @@ - - This patch fixes a case of orphaned jobs (and possible deadlock) - during pruning. - Apply it to Bacula 2.4.3 (possibly earlier versions) with: - - cd - patch -p0 <2.4.3-orphaned-jobs.patch - ./configure - make - ... - make install - -Index: src/dird/ua_prune.c -=================================================================== ---- src/dird/ua_prune.c (revision 7949) -+++ src/dird/ua_prune.c (working copy) -@@ -468,6 +468,7 @@ - break; - } - } -+ endeach_jcr(jcr); - if (skip) { - continue; - } diff --git a/bacula/patches/2.4.3-prune.patch b/bacula/patches/2.4.3-prune.patch deleted file mode 100644 index 7af00a7bec..0000000000 --- a/bacula/patches/2.4.3-prune.patch +++ /dev/null @@ -1,57 +0,0 @@ - - This patch should fix the bug reported on the bacula-users list where - a retention period of 100 years does immediate prunning. - Apply it to 2.4.3 (or earlier versions) with: - - cd - patch -p0 <2.4.3-prune.patch - ./configure - make - ... - make install - -Index: src/dird/ua_prune.c -=================================================================== ---- src/dird/ua_prune.c (revision 7757) -+++ src/dird/ua_prune.c (working copy) -@@ -202,7 +202,7 @@ - now = (utime_t)time(NULL); - - /* Select Jobs -- for counting */ -- Mmsg(query, count_select_job, edit_uint64(now - period, ed1), -+ Mmsg(query, count_select_job, edit_int64(now - period, ed1), - edit_int64(cr.ClientId, ed2)); - Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, - (uint32_t)period, query.c_str()); -@@ -230,7 +230,7 @@ - del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); - - /* Now process same set but making a delete list */ -- Mmsg(query, select_job, edit_uint64(now - period, ed1), -+ Mmsg(query, select_job, edit_int64(now - period, ed1), - edit_int64(cr.ClientId, ed2)); - db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); - -@@ -318,7 +318,7 @@ - * Select all files that are older than the JobRetention period - * and stuff them into the "DeletionCandidates" table. - */ -- edit_uint64(now - period, ed1); -+ edit_int64(now - period, ed1); - Mmsg(query, insert_delcand, (char)JobType, ed1, - edit_int64(cr.ClientId, ed2)); - if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) { -@@ -443,10 +443,10 @@ - edit_int64(mr->MediaId, ed1); - period = mr->VolRetention; - now = (utime_t)time(NULL); -- edit_uint64(now-period, ed2); -+ edit_int64(now-period, ed2); - Mmsg(query, sel_JobMedia, ed1, ed2); -- Dmsg3(250, "Now=%d period=%d now-period=%d\n", (int)now, (int)period, -- (int)(now-period)); -+ Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period, -+ ed2); - - Dmsg1(050, "Query=%s\n", query.c_str()); - if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) { diff --git a/bacula/patches/2.4.3-purge-bug.patch b/bacula/patches/2.4.3-purge-bug.patch deleted file mode 100644 index 4682962e44..0000000000 --- a/bacula/patches/2.4.3-purge-bug.patch +++ /dev/null @@ -1,29 +0,0 @@ - - This patch corrects appears to fix bug #1188, where a Volume can - be purged while it is being written. - - Apply it to Bacula 2.4.3 (possibly earlier versions) - with: - - cd - patch -p0 <2.4.3-purge-bug.patch - ./configure - make - ... - make install - - -Index: src/dird/ua_purge.c -=================================================================== ---- src/dird/ua_purge.c (revision 8054) -+++ src/dird/ua_purge.c (working copy) -@@ -463,6 +463,9 @@ - bool purged = false; - char ed1[50]; - -+ if (mr->FirstWritten == 0 || mr->LastWritten == 0) { -+ goto bail_out; /* not written cannot purge */ -+ } - if (strcmp(mr->VolStatus, "Purged") == 0) { - purged = true; - goto bail_out; diff --git a/bacula/patches/2.4.3-win32-runscript-unicode-path.patch b/bacula/patches/2.4.3-win32-runscript-unicode-path.patch deleted file mode 100644 index b4b06747a7..0000000000 --- a/bacula/patches/2.4.3-win32-runscript-unicode-path.patch +++ /dev/null @@ -1,289 +0,0 @@ - - This patch fix #1110 about a problem when executing a program with - Unicode path. - - It can be applied to 2.4.3 (and previous versions) with: - - cd - patch -p0 <2.4.3-win32-runscript-unicode-path.patch - ./configure - make - ... - make install - - -Index: src/win32/compat/compat.cpp -=================================================================== ---- src/win32/compat/compat.cpp (révision 7772) -+++ src/win32/compat/compat.cpp (copie de travail) -@@ -1807,6 +1807,97 @@ - } - - /** -+ * Create the process with UTF8 API -+ */ -+static BOOL -+CreateChildProcessW(const char *comspec, const char *cmdLine, -+ PROCESS_INFORMATION *hProcInfo, -+ HANDLE in, HANDLE out, HANDLE err) -+{ -+ STARTUPINFOW siStartInfo; -+ BOOL bFuncRetn = FALSE; -+ -+ // Set up members of the STARTUPINFO structure. -+ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); -+ siStartInfo.cb = sizeof(siStartInfo); -+ // setup new process to use supplied handles for stdin,stdout,stderr -+ -+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; -+ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; -+ -+ siStartInfo.hStdInput = in; -+ siStartInfo.hStdOutput = out; -+ siStartInfo.hStdError = err; -+ -+ // Convert argument to WCHAR -+ POOLMEM *cmdLine_wchar = get_pool_memory(PM_FNAME); -+ POOLMEM *comspec_wchar = get_pool_memory(PM_FNAME); -+ -+ UTF8_2_wchar(&cmdLine_wchar, cmdLine); -+ UTF8_2_wchar(&comspec_wchar, comspec); -+ -+ // Create the child process. -+ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar); -+ -+ // try to execute program -+ bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar, -+ (WCHAR*)cmdLine_wchar,// command line -+ NULL, // process security attributes -+ NULL, // primary thread security attributes -+ TRUE, // handles are inherited -+ 0, // creation flags -+ NULL, // use parent's environment -+ NULL, // use parent's current directory -+ &siStartInfo, // STARTUPINFO pointer -+ hProcInfo); // receives PROCESS_INFORMATION -+ -+ free_pool_memory(cmdLine_wchar); -+ free_pool_memory(comspec_wchar); -+ -+ return bFuncRetn; -+} -+ -+ -+/** -+ * Create the process with ANSI API -+ */ -+static BOOL -+CreateChildProcessA(const char *comspec, char *cmdLine, -+ PROCESS_INFORMATION *hProcInfo, -+ HANDLE in, HANDLE out, HANDLE err) -+{ -+ STARTUPINFOA siStartInfo; -+ BOOL bFuncRetn = FALSE; -+ -+ // Set up members of the STARTUPINFO structure. -+ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); -+ siStartInfo.cb = sizeof(siStartInfo); -+ // setup new process to use supplied handles for stdin,stdout,stderr -+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; -+ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; -+ -+ siStartInfo.hStdInput = in; -+ siStartInfo.hStdOutput = out; -+ siStartInfo.hStdError = err; -+ -+ // Create the child process. -+ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); -+ -+ // try to execute program -+ bFuncRetn = p_CreateProcessA(comspec, -+ cmdLine, // command line -+ NULL, // process security attributes -+ NULL, // primary thread security attributes -+ TRUE, // handles are inherited -+ 0, // creation flags -+ NULL, // use parent's environment -+ NULL, // use parent's current directory -+ &siStartInfo,// STARTUPINFO pointer -+ hProcInfo);// receives PROCESS_INFORMATION -+ return bFuncRetn; -+} -+ -+/** - * OK, so it would seem CreateProcess only handles true executables: - * .com or .exe files. So grab $COMSPEC value and pass command line to it. - */ -@@ -1815,44 +1906,30 @@ - { - static const char *comspec = NULL; - PROCESS_INFORMATION piProcInfo; -- STARTUPINFOA siStartInfo; - BOOL bFuncRetn = FALSE; - -- if (comspec == NULL) { -+ if (!p_CreateProcessA || !p_CreateProcessW) -+ return INVALID_HANDLE_VALUE; -+ -+ if (comspec == NULL) - comspec = getenv("COMSPEC"); -- } - if (comspec == NULL) // should never happen - return INVALID_HANDLE_VALUE; - - // Set up members of the PROCESS_INFORMATION structure. - ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); - -- // Set up members of the STARTUPINFO structure. -- -- ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); -- siStartInfo.cb = sizeof(STARTUPINFO); -- // setup new process to use supplied handles for stdin,stdout,stderr - // if supplied handles are not used the send a copy of our STD_HANDLE - // as appropriate -- siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; -- siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; -+ if (in == INVALID_HANDLE_VALUE) -+ in = GetStdHandle(STD_INPUT_HANDLE); - -- if (in != INVALID_HANDLE_VALUE) -- siStartInfo.hStdInput = in; -- else -- siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); -+ if (out == INVALID_HANDLE_VALUE) -+ out = GetStdHandle(STD_OUTPUT_HANDLE); - -- if (out != INVALID_HANDLE_VALUE) -- siStartInfo.hStdOutput = out; -- else -- siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); -- if (err != INVALID_HANDLE_VALUE) -- siStartInfo.hStdError = err; -- else -- siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); -+ if (err == INVALID_HANDLE_VALUE) -+ err = GetStdHandle(STD_ERROR_HANDLE); - -- // Create the child process. -- - char *exeFile; - const char *argStart; - -@@ -1860,43 +1937,32 @@ - return INVALID_HANDLE_VALUE; - } - -- int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1; -+ POOL_MEM cmdLine(PM_FNAME); -+ Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart); - -- char *cmdLine = (char *)alloca(cmdLen); -- -- snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart); -- - free(exeFile); - -- Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); -+ if (p_CreateProcessW && p_MultiByteToWideChar) { -+ bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo, -+ in, out, err); -+ } else { -+ bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo, -+ in, out, err); -+ } - -- // try to execute program -- bFuncRetn = CreateProcessA(comspec, -- cmdLine, // command line -- NULL, // process security attributes -- NULL, // primary thread security attributes -- TRUE, // handles are inherited -- 0, // creation flags -- NULL, // use parent's environment -- NULL, // use parent's current directory -- &siStartInfo, // STARTUPINFO pointer -- &piProcInfo); // receives PROCESS_INFORMATION -- - if (bFuncRetn == 0) { - ErrorExit("CreateProcess failed\n"); - const char *err = errorString(); -- Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", comspec, cmdLine, err); -+ Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err); - LocalFree((void *)err); - return INVALID_HANDLE_VALUE; - } - // we don't need a handle on the process primary thread so we close - // this now. - CloseHandle(piProcInfo.hThread); -- - return piProcInfo.hProcess; - } - -- - void - ErrorExit (LPCSTR lpszMessage) - { -Index: src/win32/compat/winapi.c -=================================================================== ---- src/win32/compat/winapi.c (révision 7772) -+++ src/win32/compat/winapi.c (copie de travail) -@@ -88,6 +88,9 @@ - - t_SHGetFolderPath p_SHGetFolderPath = NULL; - -+t_CreateProcessA p_CreateProcessA = NULL; -+t_CreateProcessW p_CreateProcessW = NULL; -+ - void - InitWinAPIWrapper() - { -@@ -104,6 +107,12 @@ - - HMODULE hLib = LoadLibraryA("KERNEL32.DLL"); - if (hLib) { -+ /* create process calls */ -+ p_CreateProcessA = (t_CreateProcessA) -+ GetProcAddress(hLib, "CreateProcessA"); -+ p_CreateProcessW = (t_CreateProcessW) -+ GetProcAddress(hLib, "CreateProcessW"); -+ - /* create file calls */ - p_CreateFileA = (t_CreateFileA) - GetProcAddress(hLib, "CreateFileA"); -Index: src/win32/winapi.h -=================================================================== ---- src/win32/winapi.h (révision 7772) -+++ src/win32/winapi.h (copie de travail) -@@ -138,6 +138,32 @@ - - typedef BOOL (WINAPI * t_AttachConsole) (DWORD); - -+typedef BOOL (WINAPI *t_CreateProcessA) ( -+ LPCSTR, -+ LPSTR, -+ LPSECURITY_ATTRIBUTES, -+ LPSECURITY_ATTRIBUTES, -+ BOOL, -+ DWORD, -+ PVOID, -+ LPCSTR, -+ LPSTARTUPINFOA, -+ LPPROCESS_INFORMATION); -+typedef BOOL (WINAPI *t_CreateProcessW) ( -+ LPCWSTR, -+ LPWSTR, -+ LPSECURITY_ATTRIBUTES, -+ LPSECURITY_ATTRIBUTES, -+ BOOL, -+ DWORD, -+ PVOID, -+ LPCWSTR, -+ LPSTARTUPINFOW, -+ LPPROCESS_INFORMATION); -+ -+extern t_CreateProcessA DLL_IMP_EXP p_CreateProcessA; -+extern t_CreateProcessW DLL_IMP_EXP p_CreateProcessW; -+ - extern t_GetFileAttributesA DLL_IMP_EXP p_GetFileAttributesA; - extern t_GetFileAttributesW DLL_IMP_EXP p_GetFileAttributesW; - diff --git a/bacula/patches/2.4.4-reload.patch b/bacula/patches/2.4.4-reload.patch index 72a6867a3a..367a0d6dad 100644 --- a/bacula/patches/2.4.4-reload.patch +++ b/bacula/patches/2.4.4-reload.patch @@ -1,3 +1,16 @@ + + This patch fixes bug #1211 crash during reload with bad dird.conf file. + + Apply it to version 2.4.4 with: + + cd + patch -p0 <2.4.4-reload.patch + ./configure + make + ... + make install + + Index: src/lib/parse_conf.c =================================================================== --- src/lib/parse_conf.c (revision 8393) diff --git a/bacula/patches/2.4.4-tray-sizing.patch b/bacula/patches/2.4.4-tray-sizing.patch new file mode 100644 index 0000000000..abeffb7343 --- /dev/null +++ b/bacula/patches/2.4.4-tray-sizing.patch @@ -0,0 +1,59 @@ + + This patch fixes a text sizing problem in the tray-monitor. + It fixes bug #1219. + + Apply it to version 2.4.4 with: + + cd + patch -p0 <2.4.4-tray-sizing.patch + ./configure + make + ... + make install + + +Index: src/tray-monitor/tray-monitor.c +=================================================================== +--- src/tray-monitor/tray-monitor.c (revision 8393) ++++ src/tray-monitor/tray-monitor.c (working copy) +@@ -1,7 +1,7 @@ + /* + Bacula® - The Network Backup Solution + +- Copyright (C) 2004-2007 Free Software Foundation Europe e.V. ++ Copyright (C) 2004-2009 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. +@@ -97,6 +97,7 @@ + static GtkWidget *textview; + static GtkTextBuffer *buffer; + static GtkWidget *timeoutspinner; ++static GtkWidget *scrolledWindow; + char** xpm_generic_var; + static gboolean blinkstate = TRUE; + +@@ -409,9 +410,13 @@ + } + + gtk_box_pack_start(GTK_BOX(vbox), daemon_table, FALSE, FALSE, 0); +- ++ + textview = gtk_text_view_new(); + ++ scrolledWindow = gtk_scrolled_window_new(NULL, NULL); ++ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); ++ gtk_container_add(GTK_CONTAINER (scrolledWindow), textview); ++ + buffer = gtk_text_buffer_new(NULL); + + gtk_text_buffer_set_text(buffer, "", -1); +@@ -456,7 +461,7 @@ + + gtk_text_view_set_buffer(GTK_TEXT_VIEW(textview), buffer); + +- gtk_box_pack_start(GTK_BOX(vbox), textview, TRUE, TRUE, 0); ++ gtk_box_pack_start(GTK_BOX(vbox), scrolledWindow, TRUE, TRUE, 0); + + GtkWidget* hbox = gtk_hbox_new(FALSE, 10); + diff --git a/bacula/patches/2.4.x/2.4.3-getmsg.patch b/bacula/patches/2.4.x/2.4.3-getmsg.patch new file mode 100644 index 0000000000..926cbcdbb6 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-getmsg.patch @@ -0,0 +1,135 @@ + + This patch used the jcr stored in the BSOCK packet during callbacks + to the Director rather than looking them up in the JCR list. + + It can be applied to Bacula version 2.4.3 (or earlier) with: + + cd + patch -p0 <2.4.3-getmsg.patch + ./configure + make + ... + make install + + +Index: src/dird/getmsg.c +=================================================================== +--- src/dird/getmsg.c (revision 7970) ++++ src/dird/getmsg.c (working copy) +@@ -1,7 +1,7 @@ + /* + Bacula® - The Network Backup Solution + +- Copyright (C) 2000-2007 Free Software Foundation Europe e.V. ++ Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. +@@ -20,7 +20,7 @@ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +- Bacula® is a registered trademark of John Walker. ++ Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +@@ -102,12 +102,12 @@ + char Job[MAX_NAME_LENGTH]; + char MsgType[20]; + int type, level; +- JCR *jcr; ++ JCR *jcr = bs->jcr(); + char *msg; + + for (;;) { + n = bs->recv(); +- Dmsg2(100, "bget_dirmsg %d: %s", n, bs->msg); ++ Dmsg2(300, "bget_dirmsg %d: %s\n", n, bs->msg); + + if (is_bnet_stop(bs)) { + return n; /* error or terminate */ +@@ -142,7 +142,7 @@ + bs->fsend("btime %s\n", edit_uint64(get_current_btime(),ed1)); + break; + default: +- Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen); ++ Jmsg1(jcr, M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen); + return n; + } + continue; +@@ -160,21 +160,13 @@ + * Try to fulfill it. + */ + if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) { +- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); ++ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); + continue; + } +- if (strcmp(Job, "*System*") == 0) { +- jcr = NULL; /* No jcr */ +- } else if (!(jcr=get_jcr_by_full_name(Job))) { +- Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg); +- continue; +- } +- Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr); + + /* Skip past "Jmsg Job=nnn" */ + if (!(msg=find_msg_start(bs->msg))) { +- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); +- free_jcr(jcr); ++ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); + continue; + } + +@@ -185,8 +177,7 @@ + if (bs->msg[0] == 'J') { /* Job message */ + if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d", + Job, &type, &level) != 3) { +- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); +- free_jcr(jcr); ++ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); + continue; + } + Dmsg1(900, "Got msg: %s\n", bs->msg); +@@ -199,7 +190,6 @@ + } + Dmsg1(900, "Dispatch msg: %s", msg); + dispatch_message(jcr, type, level, msg); +- free_jcr(jcr); + continue; + } + /* +@@ -209,21 +199,16 @@ + if (bs->msg[0] == 'C') { /* Catalog request */ + Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg); + catalog_request(jcr, bs); +- Dmsg1(900, "Calling freejcr 0x%x\n", jcr); +- free_jcr(jcr); + continue; + } + if (bs->msg[0] == 'U') { /* SD sending attributes */ + Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg); + catalog_update(jcr, bs); +- Dmsg1(900, "Calling freejcr 0x%x\n", jcr); +- free_jcr(jcr); + continue; + } + if (bs->msg[0] == 'M') { /* Mount request */ + Dmsg1(900, "Mount req: %s", bs->msg); + mount_request(jcr, bs, msg); +- free_jcr(jcr); + continue; + } + if (bs->msg[0] == 'S') { /* Status change */ +@@ -232,9 +217,8 @@ + if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) { + jcr->SDJobStatus = JobStatus; /* current status */ + } else { +- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); ++ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg); + } +- free_jcr(jcr); + continue; + } + #ifdef needed diff --git a/bacula/patches/2.4.x/2.4.3-jobs.patch b/bacula/patches/2.4.x/2.4.3-jobs.patch new file mode 100644 index 0000000000..25d2d3cb45 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-jobs.patch @@ -0,0 +1,127 @@ + + This patch corrects two problems: + 1. If you start more than 60 jobs within a 1 minute period, the unique + jobname (critical for the daemons) can be duplicated leading to + authentication failures and orphaned jobs. + 2. FD jobs that fail SD authentication were not properly cleaned up. + + Apply it to Bacula 2.4.3 (possibly earlier versions) + with: + + cd + patch -p0 <2.4.3-jobs.patch + ./configure + make + ... + make install + + +Index: src/dird/job.c +=================================================================== +--- src/dird/job.c (revision 8011) ++++ src/dird/job.c (working copy) +@@ -758,17 +758,17 @@ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + static time_t last_start_time = 0; + static int seq = 0; +- time_t now; ++ time_t now = time(NULL); + struct tm tm; + char dt[MAX_TIME_LENGTH]; + char name[MAX_NAME_LENGTH]; + char *p; ++ int len; + + /* Guarantee unique start time -- maximum one per second, and + * thus unique Job Name + */ + P(mutex); /* lock creation of jobs */ +- now = time(NULL); + seq++; + if (seq > 59) { /* wrap as if it is seconds */ + seq = 0; +@@ -783,9 +783,10 @@ + /* Form Unique JobName */ + (void)localtime_r(&now, &tm); + /* Use only characters that are permitted in Windows filenames */ +- strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M", &tm); ++ strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm); ++ len = strlen(dt) + 5; /* dt + .%02d EOS */ + bstrncpy(name, base_name, sizeof(name)); +- name[sizeof(name)-22] = 0; /* truncate if too long */ ++ name[sizeof(name)-len] = 0; /* truncate if too long */ + bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s.%02d", name, dt, seq); /* add date & time */ + /* Convert spaces into underscores */ + for (p=jcr->Job; *p; p++) { +@@ -793,6 +794,7 @@ + *p = '_'; + } + } ++ Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job); + } + + /* Called directly from job rescheduling */ +Index: src/stored/job.c +=================================================================== +--- src/stored/job.c (revision 8011) ++++ src/stored/job.c (working copy) +@@ -228,21 +228,25 @@ + if (!(jcr=get_jcr_by_full_name(job_name))) { + Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name); + Dmsg1(3, "**** Job \"%s\" not found\n", job_name); ++ fd->close(); + return; + } + +- jcr->file_bsock = fd; +- jcr->file_bsock->set_jcr(jcr); +- + Dmsg1(110, "Found Job %s\n", job_name); + + if (jcr->authenticated) { + Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), + (uint32_t)jcr->JobId, jcr->Job); ++ Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n", ++ (uint32_t)jcr->JobId, jcr->Job); ++ fd->close(); + free_jcr(jcr); + return; + } + ++ jcr->file_bsock = fd; ++ jcr->file_bsock->set_jcr(jcr); ++ + /* + * Authenticate the File daemon + */ +Index: src/lib/bnet_server.c +=================================================================== +--- src/lib/bnet_server.c (revision 8011) ++++ src/lib/bnet_server.c (working copy) +@@ -1,7 +1,7 @@ + /* + Bacula® - The Network Backup Solution + +- Copyright (C) 2000-2007 Free Software Foundation Europe e.V. ++ Copyright (C) 2000-2008 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. +@@ -20,7 +20,7 @@ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + +- Bacula® is a registered trademark of John Walker. ++ Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +@@ -137,7 +137,7 @@ + be.bstrerror()); + } + } +- listen(fd_ptr->fd, 5); /* tell system we are ready */ ++ listen(fd_ptr->fd, 20); /* tell system we are ready */ + sockfds.append(fd_ptr); + } + /* Start work queue thread */ diff --git a/bacula/patches/2.4.x/2.4.3-migrate-log.patch b/bacula/patches/2.4.x/2.4.3-migrate-log.patch new file mode 100644 index 0000000000..c593cc23ef --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-migrate-log.patch @@ -0,0 +1,71 @@ + + This patch should cause all Job Log records to be migrated when the + Job is migrated. It fixes the second issue reported in bug #1171. + + Apply it to Bacula 2.4.3 (possibly earlier versions) + with: + + cd + patch -p0 <2.4.3-migrate.patch + ./configure + make + ... + make install + +Index: src/dird/migrate.c +=================================================================== +--- src/dird/migrate.c (revision 7926) ++++ src/dird/migrate.c (working copy) +@@ -402,14 +402,6 @@ + } + + migration_cleanup(jcr, jcr->JobStatus); +- if (mig_jcr) { +- char jobid[50]; +- UAContext *ua = new_ua_context(jcr); +- edit_uint64(jcr->previous_jr.JobId, jobid); +- /* Purge all old file records, but leave Job record */ +- purge_files_from_jobs(ua, jobid); +- free_ua_context(ua); +- } + return true; + } + +@@ -1087,11 +1079,26 @@ + edit_uint64(mig_jcr->jr.JobId, ec2)); + db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); + +- /* Now mark the previous job as migrated if it terminated normally */ +- if (jcr->JobStatus == JS_Terminated) { ++ /* ++ * If we terminated a migration normally: ++ * - mark the previous job as migrated ++ * - move any Log records to the new JobId ++ * - Purge the File records from the previous job ++ */ ++ if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) { ++ char old_jobid[50], new_jobid[50]; + Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", +- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1)); ++ (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid)); + db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); ++ UAContext *ua = new_ua_context(jcr); ++ /* Move JobLog to new JobId */ ++ Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s", ++ new_jobid, ++ edit_uint64(jcr->previous_jr.JobId, old_jobid)); ++ db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); ++ /* Purge all old file records, but leave Job record */ ++ purge_files_from_jobs(ua, old_jobid); ++ free_ua_context(ua); + } + + if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) { +@@ -1100,7 +1107,6 @@ + set_jcr_job_status(jcr, JS_ErrorTerminated); + } + +- + update_bootstrap_file(mig_jcr); + + if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) { diff --git a/bacula/patches/2.4.x/2.4.3-migrate.patch b/bacula/patches/2.4.x/2.4.3-migrate.patch new file mode 100644 index 0000000000..138c09c9d1 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-migrate.patch @@ -0,0 +1,53 @@ + + This patch should prevent migration jobs from attempting to migrate + jobs that failed. Apply it to Bacula 2.4.3 (possibly earlier versions) + with: + + cd + patch -p0 <2.4.3-migrate.patch + ./configure + make + ... + make install + + +Index: src/dird/migrate.c +=================================================================== +--- src/dird/migrate.c (revision 7757) ++++ src/dird/migrate.c (working copy) +@@ -377,7 +377,7 @@ + * to avoid two threads from using the BSOCK structure at + * the same time. + */ +- if (!bnet_fsend(sd, "run")) { ++ if (!sd->fsend("run")) { + return false; + } + +@@ -520,6 +520,7 @@ + "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool,Client" + " WHERE Client.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId" + " AND Job.ClientId=Client.ClientId AND Job.Type='B'" ++ " AND Job.JobStatus = 'T'" + " ORDER by Job.StartTime"; + + /* Get Volume names in Pool */ +@@ -533,9 +534,9 @@ + "SELECT DISTINCT Job.JobId,Job.StartTime FROM Media,JobMedia,Job" + " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId" + " AND JobMedia.JobId=Job.JobId AND Job.Type='B'" ++ " AND Job.JobStatus = 'T' AND Media.Enabled=1" + " ORDER by Job.StartTime"; + +- + const char *sql_smallest_vol = + "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE" + " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND" +@@ -570,7 +571,6 @@ + const char *sql_job_bytes = + "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)"; + +- + /* Get Media Ids in Pool */ + const char *sql_mediaids = + "SELECT MediaId FROM Media,Pool WHERE" diff --git a/bacula/patches/2.4.x/2.4.3-migrate2.patch b/bacula/patches/2.4.x/2.4.3-migrate2.patch new file mode 100644 index 0000000000..9d37e8c5b3 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-migrate2.patch @@ -0,0 +1,85 @@ + + This patch should fix two bugs: + - Bug #1206 -- sql error when there are no files to migrate. + - Bug #1171 -- Job catalog log is not migrated during migration. + + Apply it to a fully patched (requires two previous migration patches) + 2.4.3 version with: + + cd + patch -p0 <2.4.3-migrate2.patch + ./configure + make + ... + make install + + +Index: src/dird/migrate.c +=================================================================== +--- src/dird/migrate.c (revision 8152) ++++ src/dird/migrate.c (working copy) +@@ -122,6 +122,12 @@ + + Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source); + ++ if (!get_or_create_fileset_record(jcr)) { ++ Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); ++ Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n")); ++ return false; ++ } ++ + /* If we find a job or jobs to migrate it is previous_jr.JobId */ + count = get_job_to_migrate(jcr); + if (count < 0) { +@@ -139,12 +145,6 @@ + return true; /* no work */ + } + +- if (!get_or_create_fileset_record(jcr)) { +- Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); +- Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n")); +- return false; +- } +- + create_restore_bootstrap_file(jcr); + + if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) { +@@ -1062,6 +1062,11 @@ + * mig_jcr is jcr of the newly migrated job. + */ + if (mig_jcr) { ++ char old_jobid[50], new_jobid[50]; ++ ++ edit_uint64(jcr->previous_jr.JobId, old_jobid); ++ edit_uint64(mig_jcr->jr.JobId, new_jobid); ++ + mig_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles; + mig_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes; + mig_jcr->VolSessionId = jcr->VolSessionId; +@@ -1076,7 +1081,7 @@ + "JobTDate=%s WHERE JobId=%s", + jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime, + edit_uint64(jcr->previous_jr.JobTDate, ec1), +- edit_uint64(mig_jcr->jr.JobId, ec2)); ++ new_jobid); + db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); + + /* +@@ -1086,15 +1091,13 @@ + * - Purge the File records from the previous job + */ + if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) { +- char old_jobid[50], new_jobid[50]; + Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s", +- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid)); ++ (char)JT_MIGRATED_JOB, old_jobid); + db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); + UAContext *ua = new_ua_context(jcr); + /* Move JobLog to new JobId */ + Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s", +- new_jobid, +- edit_uint64(jcr->previous_jr.JobId, old_jobid)); ++ new_jobid, old_jobid); + db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL); + /* Purge all old file records, but leave Job record */ + purge_files_from_jobs(ua, old_jobid); diff --git a/bacula/patches/2.4.x/2.4.3-orphaned-jobs.patch b/bacula/patches/2.4.x/2.4.3-orphaned-jobs.patch new file mode 100644 index 0000000000..6162c9e95a --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-orphaned-jobs.patch @@ -0,0 +1,24 @@ + + This patch fixes a case of orphaned jobs (and possible deadlock) + during pruning. + Apply it to Bacula 2.4.3 (possibly earlier versions) with: + + cd + patch -p0 <2.4.3-orphaned-jobs.patch + ./configure + make + ... + make install + +Index: src/dird/ua_prune.c +=================================================================== +--- src/dird/ua_prune.c (revision 7949) ++++ src/dird/ua_prune.c (working copy) +@@ -468,6 +468,7 @@ + break; + } + } ++ endeach_jcr(jcr); + if (skip) { + continue; + } diff --git a/bacula/patches/2.4.x/2.4.3-prune.patch b/bacula/patches/2.4.x/2.4.3-prune.patch new file mode 100644 index 0000000000..7af00a7bec --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-prune.patch @@ -0,0 +1,57 @@ + + This patch should fix the bug reported on the bacula-users list where + a retention period of 100 years does immediate prunning. + Apply it to 2.4.3 (or earlier versions) with: + + cd + patch -p0 <2.4.3-prune.patch + ./configure + make + ... + make install + +Index: src/dird/ua_prune.c +=================================================================== +--- src/dird/ua_prune.c (revision 7757) ++++ src/dird/ua_prune.c (working copy) +@@ -202,7 +202,7 @@ + now = (utime_t)time(NULL); + + /* Select Jobs -- for counting */ +- Mmsg(query, count_select_job, edit_uint64(now - period, ed1), ++ Mmsg(query, count_select_job, edit_int64(now - period, ed1), + edit_int64(cr.ClientId, ed2)); + Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, + (uint32_t)period, query.c_str()); +@@ -230,7 +230,7 @@ + del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids); + + /* Now process same set but making a delete list */ +- Mmsg(query, select_job, edit_uint64(now - period, ed1), ++ Mmsg(query, select_job, edit_int64(now - period, ed1), + edit_int64(cr.ClientId, ed2)); + db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del); + +@@ -318,7 +318,7 @@ + * Select all files that are older than the JobRetention period + * and stuff them into the "DeletionCandidates" table. + */ +- edit_uint64(now - period, ed1); ++ edit_int64(now - period, ed1); + Mmsg(query, insert_delcand, (char)JobType, ed1, + edit_int64(cr.ClientId, ed2)); + if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) { +@@ -443,10 +443,10 @@ + edit_int64(mr->MediaId, ed1); + period = mr->VolRetention; + now = (utime_t)time(NULL); +- edit_uint64(now-period, ed2); ++ edit_int64(now-period, ed2); + Mmsg(query, sel_JobMedia, ed1, ed2); +- Dmsg3(250, "Now=%d period=%d now-period=%d\n", (int)now, (int)period, +- (int)(now-period)); ++ Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period, ++ ed2); + + Dmsg1(050, "Query=%s\n", query.c_str()); + if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) { diff --git a/bacula/patches/2.4.x/2.4.3-purge-bug.patch b/bacula/patches/2.4.x/2.4.3-purge-bug.patch new file mode 100644 index 0000000000..4682962e44 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-purge-bug.patch @@ -0,0 +1,29 @@ + + This patch corrects appears to fix bug #1188, where a Volume can + be purged while it is being written. + + Apply it to Bacula 2.4.3 (possibly earlier versions) + with: + + cd + patch -p0 <2.4.3-purge-bug.patch + ./configure + make + ... + make install + + +Index: src/dird/ua_purge.c +=================================================================== +--- src/dird/ua_purge.c (revision 8054) ++++ src/dird/ua_purge.c (working copy) +@@ -463,6 +463,9 @@ + bool purged = false; + char ed1[50]; + ++ if (mr->FirstWritten == 0 || mr->LastWritten == 0) { ++ goto bail_out; /* not written cannot purge */ ++ } + if (strcmp(mr->VolStatus, "Purged") == 0) { + purged = true; + goto bail_out; diff --git a/bacula/patches/2.4.x/2.4.3-win32-runscript-unicode-path.patch b/bacula/patches/2.4.x/2.4.3-win32-runscript-unicode-path.patch new file mode 100644 index 0000000000..b4b06747a7 --- /dev/null +++ b/bacula/patches/2.4.x/2.4.3-win32-runscript-unicode-path.patch @@ -0,0 +1,289 @@ + + This patch fix #1110 about a problem when executing a program with + Unicode path. + + It can be applied to 2.4.3 (and previous versions) with: + + cd + patch -p0 <2.4.3-win32-runscript-unicode-path.patch + ./configure + make + ... + make install + + +Index: src/win32/compat/compat.cpp +=================================================================== +--- src/win32/compat/compat.cpp (révision 7772) ++++ src/win32/compat/compat.cpp (copie de travail) +@@ -1807,6 +1807,97 @@ + } + + /** ++ * Create the process with UTF8 API ++ */ ++static BOOL ++CreateChildProcessW(const char *comspec, const char *cmdLine, ++ PROCESS_INFORMATION *hProcInfo, ++ HANDLE in, HANDLE out, HANDLE err) ++{ ++ STARTUPINFOW siStartInfo; ++ BOOL bFuncRetn = FALSE; ++ ++ // Set up members of the STARTUPINFO structure. ++ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); ++ siStartInfo.cb = sizeof(siStartInfo); ++ // setup new process to use supplied handles for stdin,stdout,stderr ++ ++ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ++ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; ++ ++ siStartInfo.hStdInput = in; ++ siStartInfo.hStdOutput = out; ++ siStartInfo.hStdError = err; ++ ++ // Convert argument to WCHAR ++ POOLMEM *cmdLine_wchar = get_pool_memory(PM_FNAME); ++ POOLMEM *comspec_wchar = get_pool_memory(PM_FNAME); ++ ++ UTF8_2_wchar(&cmdLine_wchar, cmdLine); ++ UTF8_2_wchar(&comspec_wchar, comspec); ++ ++ // Create the child process. ++ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar); ++ ++ // try to execute program ++ bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar, ++ (WCHAR*)cmdLine_wchar,// command line ++ NULL, // process security attributes ++ NULL, // primary thread security attributes ++ TRUE, // handles are inherited ++ 0, // creation flags ++ NULL, // use parent's environment ++ NULL, // use parent's current directory ++ &siStartInfo, // STARTUPINFO pointer ++ hProcInfo); // receives PROCESS_INFORMATION ++ ++ free_pool_memory(cmdLine_wchar); ++ free_pool_memory(comspec_wchar); ++ ++ return bFuncRetn; ++} ++ ++ ++/** ++ * Create the process with ANSI API ++ */ ++static BOOL ++CreateChildProcessA(const char *comspec, char *cmdLine, ++ PROCESS_INFORMATION *hProcInfo, ++ HANDLE in, HANDLE out, HANDLE err) ++{ ++ STARTUPINFOA siStartInfo; ++ BOOL bFuncRetn = FALSE; ++ ++ // Set up members of the STARTUPINFO structure. ++ ZeroMemory( &siStartInfo, sizeof(siStartInfo) ); ++ siStartInfo.cb = sizeof(siStartInfo); ++ // setup new process to use supplied handles for stdin,stdout,stderr ++ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ++ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; ++ ++ siStartInfo.hStdInput = in; ++ siStartInfo.hStdOutput = out; ++ siStartInfo.hStdError = err; ++ ++ // Create the child process. ++ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); ++ ++ // try to execute program ++ bFuncRetn = p_CreateProcessA(comspec, ++ cmdLine, // command line ++ NULL, // process security attributes ++ NULL, // primary thread security attributes ++ TRUE, // handles are inherited ++ 0, // creation flags ++ NULL, // use parent's environment ++ NULL, // use parent's current directory ++ &siStartInfo,// STARTUPINFO pointer ++ hProcInfo);// receives PROCESS_INFORMATION ++ return bFuncRetn; ++} ++ ++/** + * OK, so it would seem CreateProcess only handles true executables: + * .com or .exe files. So grab $COMSPEC value and pass command line to it. + */ +@@ -1815,44 +1906,30 @@ + { + static const char *comspec = NULL; + PROCESS_INFORMATION piProcInfo; +- STARTUPINFOA siStartInfo; + BOOL bFuncRetn = FALSE; + +- if (comspec == NULL) { ++ if (!p_CreateProcessA || !p_CreateProcessW) ++ return INVALID_HANDLE_VALUE; ++ ++ if (comspec == NULL) + comspec = getenv("COMSPEC"); +- } + if (comspec == NULL) // should never happen + return INVALID_HANDLE_VALUE; + + // Set up members of the PROCESS_INFORMATION structure. + ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); + +- // Set up members of the STARTUPINFO structure. +- +- ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); +- siStartInfo.cb = sizeof(STARTUPINFO); +- // setup new process to use supplied handles for stdin,stdout,stderr + // if supplied handles are not used the send a copy of our STD_HANDLE + // as appropriate +- siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; +- siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; ++ if (in == INVALID_HANDLE_VALUE) ++ in = GetStdHandle(STD_INPUT_HANDLE); + +- if (in != INVALID_HANDLE_VALUE) +- siStartInfo.hStdInput = in; +- else +- siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); ++ if (out == INVALID_HANDLE_VALUE) ++ out = GetStdHandle(STD_OUTPUT_HANDLE); + +- if (out != INVALID_HANDLE_VALUE) +- siStartInfo.hStdOutput = out; +- else +- siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); +- if (err != INVALID_HANDLE_VALUE) +- siStartInfo.hStdError = err; +- else +- siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); ++ if (err == INVALID_HANDLE_VALUE) ++ err = GetStdHandle(STD_ERROR_HANDLE); + +- // Create the child process. +- + char *exeFile; + const char *argStart; + +@@ -1860,43 +1937,32 @@ + return INVALID_HANDLE_VALUE; + } + +- int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1; ++ POOL_MEM cmdLine(PM_FNAME); ++ Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart); + +- char *cmdLine = (char *)alloca(cmdLen); +- +- snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart); +- + free(exeFile); + +- Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine); ++ if (p_CreateProcessW && p_MultiByteToWideChar) { ++ bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo, ++ in, out, err); ++ } else { ++ bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo, ++ in, out, err); ++ } + +- // try to execute program +- bFuncRetn = CreateProcessA(comspec, +- cmdLine, // command line +- NULL, // process security attributes +- NULL, // primary thread security attributes +- TRUE, // handles are inherited +- 0, // creation flags +- NULL, // use parent's environment +- NULL, // use parent's current directory +- &siStartInfo, // STARTUPINFO pointer +- &piProcInfo); // receives PROCESS_INFORMATION +- + if (bFuncRetn == 0) { + ErrorExit("CreateProcess failed\n"); + const char *err = errorString(); +- Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", comspec, cmdLine, err); ++ Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err); + LocalFree((void *)err); + return INVALID_HANDLE_VALUE; + } + // we don't need a handle on the process primary thread so we close + // this now. + CloseHandle(piProcInfo.hThread); +- + return piProcInfo.hProcess; + } + +- + void + ErrorExit (LPCSTR lpszMessage) + { +Index: src/win32/compat/winapi.c +=================================================================== +--- src/win32/compat/winapi.c (révision 7772) ++++ src/win32/compat/winapi.c (copie de travail) +@@ -88,6 +88,9 @@ + + t_SHGetFolderPath p_SHGetFolderPath = NULL; + ++t_CreateProcessA p_CreateProcessA = NULL; ++t_CreateProcessW p_CreateProcessW = NULL; ++ + void + InitWinAPIWrapper() + { +@@ -104,6 +107,12 @@ + + HMODULE hLib = LoadLibraryA("KERNEL32.DLL"); + if (hLib) { ++ /* create process calls */ ++ p_CreateProcessA = (t_CreateProcessA) ++ GetProcAddress(hLib, "CreateProcessA"); ++ p_CreateProcessW = (t_CreateProcessW) ++ GetProcAddress(hLib, "CreateProcessW"); ++ + /* create file calls */ + p_CreateFileA = (t_CreateFileA) + GetProcAddress(hLib, "CreateFileA"); +Index: src/win32/winapi.h +=================================================================== +--- src/win32/winapi.h (révision 7772) ++++ src/win32/winapi.h (copie de travail) +@@ -138,6 +138,32 @@ + + typedef BOOL (WINAPI * t_AttachConsole) (DWORD); + ++typedef BOOL (WINAPI *t_CreateProcessA) ( ++ LPCSTR, ++ LPSTR, ++ LPSECURITY_ATTRIBUTES, ++ LPSECURITY_ATTRIBUTES, ++ BOOL, ++ DWORD, ++ PVOID, ++ LPCSTR, ++ LPSTARTUPINFOA, ++ LPPROCESS_INFORMATION); ++typedef BOOL (WINAPI *t_CreateProcessW) ( ++ LPCWSTR, ++ LPWSTR, ++ LPSECURITY_ATTRIBUTES, ++ LPSECURITY_ATTRIBUTES, ++ BOOL, ++ DWORD, ++ PVOID, ++ LPCWSTR, ++ LPSTARTUPINFOW, ++ LPPROCESS_INFORMATION); ++ ++extern t_CreateProcessA DLL_IMP_EXP p_CreateProcessA; ++extern t_CreateProcessW DLL_IMP_EXP p_CreateProcessW; ++ + extern t_GetFileAttributesA DLL_IMP_EXP p_GetFileAttributesA; + extern t_GetFileAttributesW DLL_IMP_EXP p_GetFileAttributesW; +