From: Kern Sibbald Date: Sun, 12 Dec 2004 15:42:50 +0000 (+0000) Subject: Integrated Preben 'Peppe' Guldberg X-Git-Tag: Release-1.38.0~706 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8ac13167ad6fe6f4543c7ab61e4aeb878d228564;p=bacula%2Fbacula Integrated Preben 'Peppe' Guldberg three cleanup patches (btest, verify, find). git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1758 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index e379811a33..0cc64ea907 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -140,7 +140,7 @@ int start_storage_daemon_job(JCR *jcr) * Send use device = xxx media = yyy pool = zzz */ - for (i=0; i < 1; /* MAX_STORE */ i++) { + for (i=0; i < MAX_STORE; i++) { if (jcr->storage[i]) { storage = (STORE *)jcr->storage[i]->first(); pm_strcpy(device_name, storage->dev_name); diff --git a/bacula/src/filed/Makefile.in b/bacula/src/filed/Makefile.in index 3909c4a784..551541b3da 100755 --- a/bacula/src/filed/Makefile.in +++ b/bacula/src/filed/Makefile.in @@ -23,10 +23,10 @@ first_rule: all dummy: # -SVRSRCS = filed.c authenticate.c backup.c estimate.c \ +SVRSRCS = filed.c authenticate.c backup.c chksum.c estimate.c \ filed_conf.c heartbeat.c job.c \ restore.c status.c verify.c verify_vol.c -SVROBJS = filed.o authenticate.o backup.o estimate.o \ +SVROBJS = filed.o authenticate.o backup.o chksum.o estimate.o \ filed_conf.o heartbeat.o job.o \ restore.o status.o verify.o verify_vol.o diff --git a/bacula/src/filed/Makefile.mingw b/bacula/src/filed/Makefile.mingw index 0b1e154c85..05ea039ff1 100644 --- a/bacula/src/filed/Makefile.mingw +++ b/bacula/src/filed/Makefile.mingw @@ -98,10 +98,10 @@ first_rule: all dummy: # -SVRSRCS = filed.c authenticate.c backup.c estimate.c \ +SVRSRCS = filed.c authenticate.c backup.c chksum.c estimate.c \ filed_conf.c heartbeat.c job.c \ restore.c status.c verify.c verify_vol.c -SVROBJS = filed.o authenticate.o backup.o estimate.o \ +SVROBJS = filed.o authenticate.o backup.o chksum.o estimate.o \ filed_conf.o heartbeat.o job.o \ restore.o status.o verify.o verify_vol.o diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 9fbe3f7c9b..e6dafd5482 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -35,10 +35,6 @@ #include #endif -#ifdef HAVE_DARWIN_OS -#include -#endif - static int save_file(FF_PKT *ff_pkt, void *pkt); /* diff --git a/bacula/src/filed/chksum.c b/bacula/src/filed/chksum.c new file mode 100644 index 0000000000..4453d7d6af --- /dev/null +++ b/bacula/src/filed/chksum.c @@ -0,0 +1,90 @@ +/* + * General routines for handling the various checksum supported. + * + * Written by Preben 'Peppe' Guldberg, December MMIV + */ + +/* + Copyright (C) 2004 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. + + 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. + + */ + +#include "bacula.h" +#include "filed.h" + +/* return 0 on success, otherwise some handler specific error code. */ +int chksum_init(CHKSUM *chksum, int flags) +{ + int status = 0; + + chksum->type = CHKSUM_NONE; + bstrncpy(chksum->name, "NONE", sizeof(chksum->name)); + chksum->updated = false; + if (flags & CHKSUM_MD5) { + chksum->length = 16; + MD5Init(&chksum->context.md5); + chksum->type = CHKSUM_MD5; + bstrncpy(chksum->name, "MD5", sizeof(chksum->name)); + } else if (flags * CHKSUM_SHA1) { + chksum->length = 20; + status = SHA1Init(&chksum->context.sha1); + if (status == 0) { + chksum->type = CHKSUM_SHA1; + bstrncpy(chksum->name, "SHA1", sizeof(chksum->name)); + } + } + return status; +} + +/* return 0 on success, otherwise some handler specific error code. */ +int chksum_update(CHKSUM *chksum, void *buf, unsigned len) +{ + int status; + switch (chksum->type) { + case CHKSUM_NONE: + return 0; + case CHKSUM_MD5: + MD5Update(&chksum->context.md5, (unsigned char *)buf, len); + chksum->updated = true; + return 0; + case CHKSUM_SHA1: + status = SHA1Update(&chksum->context.sha1, (uint8_t *)buf, len); + if (status == 0) { + chksum->updated = true; + } + return status; + default: + return -1; + } +} + +/* return 0 on success, otherwise some handler specific error code. */ +int chksum_final(CHKSUM *chksum) +{ + switch (chksum->type) { + case CHKSUM_NONE: + return 0; + case CHKSUM_MD5: + MD5Final(chksum->signature, &chksum->context.md5); + return 0; + case CHKSUM_SHA1: + return SHA1Final(&chksum->context.sha1, chksum->signature); + default: + return -1; + } +} diff --git a/bacula/src/filed/chksum.h b/bacula/src/filed/chksum.h new file mode 100644 index 0000000000..7d0d45bf1a --- /dev/null +++ b/bacula/src/filed/chksum.h @@ -0,0 +1,58 @@ +/* + * General routines for handling the various checksum supported. + */ + +/* + Copyright (C) 2004 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. + + 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. + + */ + +#ifndef _CHKSUM_H_ +#define _CHKSUM_H_ + +#include "bacula.h" + +/* + * Link these to findlib options. Doing so allows for simpler handling of + * signatures in the callers. + * If multiple signatures are specified, the order in chksum_init() matters. + * Still, spell out our own names in case we want to change the approach. + */ +#define CHKSUM_NONE 0 +#define CHKSUM_MD5 FO_MD5 +#define CHKSUM_SHA1 FO_SHA1 + +union chksumContext { + MD5Context md5; + SHA1Context sha1; +}; + +struct CHKSUM { + int type; /* One of CHKSUM_* above */ + char name[5]; /* Big enough for NONE, MD5, SHA1, etc. */ + bool updated; /* True if updated by chksum_update() */ + chksumContext context; /* Context for the algorithm at hand */ + int length; /* Length of signature */ + unsigned char signature[30]; /* Large enough for either signature */ +}; + +int chksum_init(CHKSUM *chksum, int flags); +int chksum_update(CHKSUM *chksum, void *buf, unsigned len); +int chksum_final(CHKSUM *chksum); + +#endif diff --git a/bacula/src/filed/filed.h b/bacula/src/filed/filed.h index 451d601bcd..48817cd136 100644 --- a/bacula/src/filed/filed.h +++ b/bacula/src/filed/filed.h @@ -27,6 +27,7 @@ #define FILE_DAEMON 1 #include "filed_conf.h" +#include "chksum.h" #include "findlib/find.h" #include "jcr.h" #include "protos.h" /* file daemon prototypes */ diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 7c4d7173ae..f89537c085 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -36,7 +36,6 @@ #ifdef HAVE_DARWIN_OS #include -#include #endif /* Data received from Storage Daemon */ @@ -181,11 +180,7 @@ void do_restore(JCR *jcr) * close the output file. */ if (extract) { - if (!is_bopen(&bfd) -#ifdef HAVE_DARWIN_OS - && !is_bopen(&rsrc_bfd) -#endif - ) { + if (!is_bopen(&bfd) && !is_bopen(&rsrc_bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error output file should be open\n")); } #ifdef HAVE_DARWIN_OS diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 7deceb5f49..4e125f439f 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -29,10 +29,6 @@ #include "bacula.h" #include "filed.h" -#ifdef HAVE_DARWIN_OS -#include -#endif - static int verify_file(FF_PKT *ff_pkt, void *my_pkt); /* diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 03cd5c5078..8a5d3015da 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -136,6 +136,7 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); ff->flags |= fo->flags; ff->GZIP_level = fo->GZIP_level; + ff->fstypes = &(fo->fstype); bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); } for (j=0; jname_list.size(); j++) { diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index e4b1bcfead..67aa836890 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -75,7 +75,7 @@ static int accept_fstype(FF_PKT *ff, void *dummy) { if (fs == NULL) { Dmsg1(50, "Cannot determine file system type for \"%s\"\n", ff->fname); } else { - for (i = 0; i fstypes->size(); ++i) { + for (i = 0; i < ff->fstypes->size(); ++i) { if (strcmp(fs, (char *)ff->fstypes->get(i)) == 0) { Dmsg2(100, "Accepting fstype %s for \"%s\"\n", fs, ff->fname); accept = true; @@ -114,23 +114,6 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), return handle_file(ff_pkt, pkt); } -#ifdef HAVE_DARWIN_OS - if (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->flags & FO_HFSPLUS) { - /* TODO: initialise attrList once elsewhere? */ - struct attrlist attrList; - memset(&attrList, 0, sizeof(attrList)); - attrList.bitmapcount = ATTR_BIT_MAP_COUNT; - attrList.commonattr = ATTR_CMN_FNDRINFO; - attrList.fileattr = ATTR_FILE_RSRCLENGTH; - if (getattrlist(fname, &attrList, &ff_pkt->hfsinfo, - sizeof(ff_pkt->hfsinfo), 0) != 0) { - ff_pkt->type = FT_NOSTAT; - ff_pkt->ff_errno = errno; - return handle_file(ff_pkt, pkt); - } - } -#endif - Dmsg1(300, "File ----: %s\n", fname); /* Save current times of this directory in case we need to @@ -139,26 +122,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), restore_times.actime = ff_pkt->statp.st_atime; restore_times.modtime = ff_pkt->statp.st_mtime; - if (top_level) { - /* - * Check if we start with an allowed file system. - * - * handle_file() calls accept_file() which fills in ff_pkt->fstypes - * Temporarily use our own handler with a fake, but probable, type. - */ - int (*callback)(FF_PKT *, void *) = ff_pkt->callback; - ff_pkt->callback = accept_fstype; - ff_pkt->type = FT_DIRBEGIN; - rtn_stat = handle_file(ff_pkt, pkt); - ff_pkt->callback = callback; - if (!rtn_stat) { - ff_pkt->type = FT_INVALIDFS; - if (ff_pkt->flags & FO_KEEPATIME) { - utime(fname, &restore_times); - } - Jmsg1(jcr, M_ERROR, 0, _("Top level entry \"%s\" has an unlisted fstype\n"), fname); - return rtn_stat; + /* + * We check for allowed fstypes at top_level and fstype change (below). + */ + if (top_level && !accept_fstype(ff_pkt, NULL)) { + ff_pkt->type = FT_INVALIDFS; + if (ff_pkt->flags & FO_KEEPATIME) { + utime(fname, &restore_times); } + Jmsg1(jcr, M_ERROR, 0, _("Top level directory \"%s\" has an unlisted fstype\n"), fname); + return 1; /* Just ignore this error - or the whole backup is cancelled */ } /* @@ -178,6 +151,23 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), } } +#ifdef HAVE_DARWIN_OS + if (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->flags & FO_HFSPLUS) { + /* TODO: initialise attrList once elsewhere? */ + struct attrlist attrList; + memset(&attrList, 0, sizeof(attrList)); + attrList.bitmapcount = ATTR_BIT_MAP_COUNT; + attrList.commonattr = ATTR_CMN_FNDRINFO; + attrList.fileattr = ATTR_FILE_RSRCLENGTH; + if (getattrlist(fname, &attrList, &ff_pkt->hfsinfo, + sizeof(ff_pkt->hfsinfo), 0) != 0) { + ff_pkt->type = FT_NOSTAT; + ff_pkt->ff_errno = errno; + return handle_file(ff_pkt, pkt); + } + } +#endif + /* ***FIXME*** implement this */ #if xxxxxxx /* See if we are trying to dump the archive. */ diff --git a/bacula/src/lib/alist.h b/bacula/src/lib/alist.h index 2e43d564dd..fee12c3c1c 100644 --- a/bacula/src/lib/alist.h +++ b/bacula/src/lib/alist.h @@ -86,7 +86,8 @@ inline void * alist::operator [](int index) const { inline bool alist::empty() const { - return num_items == 0; + /* Check for null pointer */ + return this ? num_items == 0 : true; } /* @@ -117,7 +118,12 @@ inline alist::~alist() { /* Current size of list */ inline int alist::size() const { - return num_items; + /* + * Check for null pointer, which allows test + * on size to succeed even if nothing put in + * alist. + */ + return this ? num_items : 0; } /* How much to grow by each time */ diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 9179482924..50a8bf52e2 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1330,7 +1330,7 @@ bail_out: } Pmsg0(-1, "You must correct this error or Bacula will not work.\n" "Some systems, e.g. OpenBSD, require you to set\n" - " File Block Bookkeeping = no\n" + " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n"); return -2; } @@ -1411,7 +1411,7 @@ failed: "Fixed block sizes, however, are not normally an ideal solution.\n" "\n" "Some systems, e.g. OpenBSD, require you to set\n" - " File Block Bookkeeping = no\n" + " Use MTIOCGET= no\n" "in your device resource. Use with caution.\n"); return; } diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index fd13c59596..d1ca3002a8 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -42,7 +42,8 @@ static bool use_device_cmd(JCR *jcr); static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s " "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s " "SpoolData=%d"; -static char use_device[] = "use device=%127s media_type=%127s pool_name=%127s pool_type=%127s\n"; +static char use_device[] = "use device=%127s media_type=%127s pool_name=%127s pool_type=%127s\n"; +static char use_devices[] = "use devices=%127s media_type=%127s pool_name=%127s pool_type=%127s\n"; /* Responses sent to Director daemon */ static char OKjob[] = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n"; @@ -241,59 +242,76 @@ static bool use_device_cmd(JCR *jcr) POOL_MEM dev_name, media_type, pool_name, pool_type; BSOCK *dir = jcr->dir_bsock; DEVRES *device; - - if (bnet_recv(dir) <= 0) { - Jmsg0(jcr, M_FATAL, 0, _("No Device from Director\n")); - return false; - } + bool quit = false; - Dmsg1(120, "Use device: %s", dir->msg); - if (sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(), - pool_name.c_str(), pool_type.c_str()) == 4) { - unbash_spaces(dev_name); - unbash_spaces(media_type); - unbash_spaces(pool_name); - unbash_spaces(pool_type); - LockRes(); - foreach_res(device, R_DEVICE) { - /* Find resource, and make sure we were able to open it */ - if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 && - device->dev && strcmp(device->media_type, media_type.c_str()) == 0) { - const int name_len = MAX_NAME_LENGTH; - DCR *dcr; - UnlockRes(); - dcr = new_dcr(jcr, device->dev); - if (!dcr) { - return false; + while (!quit) { + bool ok; + if (bnet_recv(dir) <= 0) { + Jmsg0(jcr, M_FATAL, 0, _("No Device from Director\n")); + return false; + } + + Dmsg1(120, "Use device: %s", dir->msg); + /* + * If there are multiple devices, the director sends us + * use_devices (note plurel) until the last one, at which + * time, it sends us a use_device command (note singlular) + * so we stop looking after getting the use_device. + */ + ok = sscanf(dir->msg, use_device, dev_name.c_str(), media_type.c_str(), + pool_name.c_str(), pool_type.c_str()) == 4; + if (ok) { + quit = true; /* got last device */ + } else { + ok = sscanf(dir->msg, use_devices, dev_name.c_str(), media_type.c_str(), + pool_name.c_str(), pool_type.c_str()) == 4; + } + if (ok) { + unbash_spaces(dev_name); + unbash_spaces(media_type); + unbash_spaces(pool_name); + unbash_spaces(pool_type); + LockRes(); + foreach_res(device, R_DEVICE) { + /* Find resource, and make sure we were able to open it */ + if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 && + device->dev && strcmp(device->media_type, media_type.c_str()) == 0) { + const int name_len = MAX_NAME_LENGTH; + DCR *dcr; + UnlockRes(); + dcr = new_dcr(jcr, device->dev); + if (!dcr) { + return false; + } + Dmsg1(120, "Found device %s\n", device->hdr.name); + bstrncpy(dcr->pool_name, pool_name, name_len); + bstrncpy(dcr->pool_type, pool_type, name_len); + bstrncpy(dcr->media_type, media_type, name_len); + bstrncpy(dcr->dev_name, dev_name, name_len); + jcr->device = device; + Dmsg1(220, "Got: %s", dir->msg); + return bnet_fsend(dir, OK_device); } - Dmsg1(120, "Found device %s\n", device->hdr.name); - bstrncpy(dcr->pool_name, pool_name, name_len); - bstrncpy(dcr->pool_type, pool_type, name_len); - bstrncpy(dcr->media_type, media_type, name_len); - bstrncpy(dcr->dev_name, dev_name, name_len); - jcr->device = device; - Dmsg1(220, "Got: %s", dir->msg); - return bnet_fsend(dir, OK_device); } - } - UnlockRes(); - if (verbose) { + UnlockRes(); + if (verbose) { + unbash_spaces(dir->msg); + pm_strcpy(jcr->errmsg, dir->msg); + Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); + } + Jmsg(jcr, M_FATAL, 0, _("\n" + " Device \"%s\" with MediaType \"%s\" requested by Dir not found in SD Device resources.\n"), + dev_name.c_str(), media_type.c_str()); + bnet_fsend(dir, NO_device, dev_name.c_str()); + } else { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); - Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); - } - Jmsg(jcr, M_FATAL, 0, _("\n" - " Device \"%s\" with MediaType \"%s\" requested by Dir not found in SD Device resources.\n"), - dev_name.c_str(), media_type.c_str()); - bnet_fsend(dir, NO_device, dev_name.c_str()); - } else { - unbash_spaces(dir->msg); - pm_strcpy(jcr->errmsg, dir->msg); - if (verbose) { - Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); + if (verbose) { + Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); + } + Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg); + bnet_fsend(dir, BAD_use, jcr->errmsg); } - Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg); - bnet_fsend(dir, BAD_use, jcr->errmsg); } return false; /* ERROR return */ diff --git a/bacula/src/version.h b/bacula/src/version.h index 859b77eab4..5ab0248cc0 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION #define VERSION "1.37.1" -#define BDATE "09 December 2004" -#define LSMDATE "09Dec04" +#define BDATE "12 December 2004" +#define LSMDATE "12Dec04" /* Debug flags */ #undef DEBUG