From e0097c86a4fc9507ec8b00ee6189a78998df4cda Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 10 Jun 2005 22:30:48 +0000 Subject: [PATCH] - Start removing #ifdef HAVE_TLS by sneaky tricks. - Begin implementation of TLS in wx-console - Remove ignoring SIGCHLD from console. - Rework the dlist binary search routines for implemenation of the Volume reservation code -- make it more general. - Strip double slashes // from Win32 filenames in an attempt to resolve restore problems on some systems. - Fix a minor bugs in the trace code that caused the first line output to be lost. - Implement a good first cut at adding Volume reservation code to the storage daemon (in file reserve.c). - Remove old unused code from the tree.c routines. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2119 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 1 + bacula/kes-1.37 | 16 + bacula/src/baconfig.h | 6 + bacula/src/console/authenticate.c | 64 +-- bacula/src/console/conio.c | 17 +- bacula/src/console/console.c | 46 +- bacula/src/console/console_conf.c | 123 +++-- bacula/src/console/console_conf.h | 36 +- bacula/src/dird/authenticate.c | 19 +- bacula/src/dird/dird.c | 38 +- bacula/src/dird/dird_conf.c | 20 - bacula/src/dird/dird_conf.h | 15 +- bacula/src/dird/run_conf.c | 654 +++++++++++++-------------- bacula/src/dird/ua_label.c | 460 ++++++++++--------- bacula/src/dird/ua_query.c | 152 +++---- bacula/src/dird/ua_status.c | 2 +- bacula/src/dird/ua_tree.c | 322 +++++++------ bacula/src/filed/authenticate.c | 40 +- bacula/src/filed/filed.c | 31 +- bacula/src/filed/filed_conf.c | 36 +- bacula/src/filed/filed_conf.h | 25 +- bacula/src/filed/restore.c | 397 ++++++++-------- bacula/src/findlib/create_file.c | 17 +- bacula/src/findlib/find.c | 17 +- bacula/src/findlib/match.c | 15 +- bacula/src/lib/attr.c | 132 +++--- bacula/src/lib/bnet.c | 441 +++++++++--------- bacula/src/lib/dlist.c | 115 ++++- bacula/src/lib/dlist.h | 9 +- bacula/src/lib/message.c | 560 +++++++++++------------ bacula/src/lib/protos.h | 2 - bacula/src/lib/tree.c | 173 ++----- bacula/src/lib/tree.h | 166 ++----- bacula/src/stored/acquire.c | 4 +- bacula/src/stored/ansi_label.c | 292 ++++++------ bacula/src/stored/askdir.c | 45 +- bacula/src/stored/autochanger.c | 4 +- bacula/src/stored/bcopy.c | 2 + bacula/src/stored/bextract.c | 2 + bacula/src/stored/bls.c | 3 + bacula/src/stored/bscan.c | 4 +- bacula/src/stored/btape.c | 33 +- bacula/src/stored/butil.c | 4 +- bacula/src/stored/dev.c | 528 +++++++++++---------- bacula/src/stored/dev.h | 11 + bacula/src/stored/device.c | 45 +- bacula/src/stored/dircmd.c | 23 +- bacula/src/stored/label.c | 324 +++++++------ bacula/src/stored/mount.c | 81 ++-- bacula/src/stored/parse_bsr.c | 312 ++++++------- bacula/src/stored/protos.h | 40 +- bacula/src/stored/read.c | 24 +- bacula/src/stored/reserve.c | 132 +++++- bacula/src/stored/status.c | 21 +- bacula/src/stored/stored.c | 23 +- bacula/src/version.h | 6 +- bacula/src/wx-console/authenticate.c | 83 +++- bacula/src/wx-console/console_conf.c | 116 +++-- bacula/src/wx-console/console_conf.h | 37 +- 59 files changed, 3235 insertions(+), 3131 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index fa891f1372..432033c103 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -91,6 +91,7 @@ For 1.37: - Add global lock on all devices when creating a device structure. Maybe in 1.37: +- Add start/end date editing in messages (%t %T, %e?) ... - Add ClientDefs similar to JobDefs. - Print more info when bextract -p accepts a bad block. - To mark files as deleted, run essentially a Verify to disk, and diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index aae8e7fbc2..beef32cb93 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -3,7 +3,23 @@ General: +Changes to 1.37.22: +10Jun05 +- Start removing #ifdef HAVE_TLS by sneaky tricks. +- Begin implementation of TLS in wx-console +- Remove ignoring SIGCHLD from console. +- Rework the dlist binary search routines for implemenation + of the Volume reservation code -- make it more general. +- Strip double slashes // from Win32 filenames in an attempt + to resolve restore problems on some systems. +- Fix a minor bugs in the trace code that caused the first + line output to be lost. +- Implement a good first cut at adding Volume reservation code + to the storage daemon (in file reserve.c). +- Remove old unused code from the tree.c routines. + Changes to 1.37.21: +06Jun05 - Fix compile problems on Win32 - Start writing Volume reservation list (already exists, but is not really very good). diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index db4c77f255..4ea7b79a50 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -30,6 +30,12 @@ #define TRUE 1 #define FALSE 0 +#ifdef HAVE_TLS +#define have_tls 1 +#else +#define have_tls 0 +#endif + #ifndef ETIME #define ETIME ETIMEDOUT #endif diff --git a/bacula/src/console/authenticate.c b/bacula/src/console/authenticate.c index 13f456cf54..66a1d67faf 100644 --- a/bacula/src/console/authenticate.c +++ b/bacula/src/console/authenticate.c @@ -54,11 +54,8 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; char bashed_name[MAX_NAME_LENGTH]; - bool auth_success = false; char *password; -#ifdef HAVE_TLS TLS_CONTEXT *tls_ctx = NULL; -#endif /* HAVE_TLS */ /* * Send my name to the Director then do authentication @@ -67,7 +64,6 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name)); bash_spaces(bashed_name); password = cons->password; -#ifdef HAVE_TLS /* TLS Requirement */ if (cons->tls_enable) { if (cons->tls_require) { @@ -78,11 +74,9 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) } tls_ctx = cons->tls_ctx; -#endif /* HAVE_TLS */ } else { bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); password = director->password; -#ifdef HAVE_TLS /* TLS Requirement */ if (director->tls_enable) { if (director->tls_require) { @@ -93,7 +87,6 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) } tls_ctx = director->tls_ctx; -#endif /* HAVE_TLS */ } @@ -103,51 +96,32 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) if (!cram_md5_get_auth(dir, password, &tls_remote_need) || !cram_md5_auth(dir, password, tls_local_need)) { - auth_success = false; - goto auth_done; - } else { - auth_success = true; - /* Continue on, soldier ... */ + goto bail_out; } /* Verify that the remote host is willing to meet our TLS requirements */ if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { sendit(_("Authorization problem:" " Remote server did not advertise required TLS support.\n")); - auth_success = false; - goto auth_done; + goto bail_out; } /* Verify that we are willing to meet the remote host's requirements */ if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { sendit(_("Authorization problem:" " Remote server requires TLS.\n")); - auth_success = false; - goto auth_done; + goto bail_out; } -#ifdef HAVE_TLS /* Is TLS Enabled? */ - if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { - /* Engage TLS! Full Speed Ahead! */ - if (!bnet_tls_client(tls_ctx, dir)) { - sendit(_("TLS negotiation failed\n")); - auth_success = false; - goto auth_done; + if (have_tls) { + if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { + /* Engage TLS! Full Speed Ahead! */ + if (!bnet_tls_client(tls_ctx, dir)) { + sendit(_("TLS negotiation failed\n")); + goto bail_out; + } } - auth_success = true; - } -#endif /* HAVE_TLS */ - -/* Authorization Completed */ -auth_done: - if (!auth_success) { - stop_bsock_timer(tid); - sendit( _("Director authorization problem.\n" - "Most likely the passwords do not agree.\n" - "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n" - "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n")); - return 0; } /* @@ -156,20 +130,26 @@ auth_done: */ Dmsg1(6, ">dird: %s", dir->msg); if (bnet_recv(dir) <= 0) { - stop_bsock_timer(tid); senditf(_("Bad response to Hello command: ERR=%s\n"), bnet_strerror(dir)); - senditf(_("If you are using TLS, it is possible that your client" - " certificate was not accepted. Check the server messages.\n")); - return 0; + goto bail_out; } + Dmsg1(10, "msg); - stop_bsock_timer(tid); if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) { sendit(_("Director rejected Hello command\n")); - return 0; + goto bail_out; } else { sendit(dir->msg); } + stop_bsock_timer(tid); return 1; + +bail_out: + stop_bsock_timer(tid); + sendit( _("Director authorization problem.\n" + "Most likely the passwords do not agree.\n" + "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n" + "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n")); + return 0; } diff --git a/bacula/src/console/conio.c b/bacula/src/console/conio.c index e0a037a567..04828767d8 100755 --- a/bacula/src/console/conio.c +++ b/bacula/src/console/conio.c @@ -13,19 +13,14 @@ Yes, that is 1981 no error. 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 ammended 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. */ @@ -970,7 +965,7 @@ static void rawmode(FILE *input) signal(SIGINT, sigintcatcher); signal(SIGWINCH, SIG_IGN); signal(SIGQUIT, SIG_IGN); - signal(SIGCHLD, SIG_IGN); +// signal(SIGCHLD, SIG_IGN); // signal(SIGTSTP, SIG_IGN); if (!termtype) { diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 02ce549bd0..2c9eb6b3f6 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* Copyright (C) 2000-2005 Kern Sibbald - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as ammended with additional clauses defined in the + file LICENSE in the main source directory. - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; 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. */ @@ -295,7 +289,6 @@ static void read_and_process_input(FILE *input, BSOCK *UA_sock) } } -#ifdef HAVE_TLS /* * Call-back for reading a passphrase for an encrypted PEM file * This function uses getpass(), which uses a static buffer and is NOT thread-safe. @@ -310,7 +303,6 @@ static int tls_pem_callback(char *buf, int size, const void *userdata) return (strlen(buf)); } -#endif /********************************************************************* @@ -373,7 +365,7 @@ int main(int argc, char *argv[]) #if !defined(HAVE_WIN32) /* Override Bacula default signals */ - signal(SIGCHLD, SIG_IGN); +// signal(SIGCHLD, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, got_sigstop); signal(SIGCONT, got_sigcontinue); @@ -455,7 +447,6 @@ try_again: senditf(_("Connecting to Director %s:%d\n"), dir->address,dir->DIRport); -#ifdef HAVE_TLS char buf[1024]; /* Initialize Console TLS context */ if (cons && (cons->tls_enable || cons->tls_require)) { @@ -497,7 +488,6 @@ try_again: return 1; } } -#endif /* HAVE_TLS */ UA_sock = bnet_connect(NULL, 5, 15, "Director daemon", dir->address, NULL, dir->DIRport, 0); @@ -577,10 +567,15 @@ static int check_resources() foreach_res(director, R_DIRECTOR) { numdir++; -#ifdef HAVE_TLS /* tls_require implies tls_enable */ if (director->tls_require) { - director->tls_enable = true; + if (have_tls) { + director->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; + } } if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) { @@ -590,7 +585,6 @@ static int check_resources() director->hdr.name, configfile); OK = false; } -#endif /* HAVE_TLS */ } if (numdir == 0) { @@ -599,13 +593,18 @@ static int check_resources() OK = false; } -#ifdef HAVE_TLS CONRES *cons; /* Loop over Consoles */ foreach_res(cons, R_CONSOLE) { /* tls_require implies tls_enable */ if (cons->tls_require) { - cons->tls_enable = true; + if (have_tls) { + cons->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; + } } if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) { @@ -615,7 +614,6 @@ static int check_resources() OK = false; } } -#endif /* HAVE_TLS */ UnlockRes(); diff --git a/bacula/src/console/console_conf.c b/bacula/src/console/console_conf.c index ace2b900f2..60e2ad0a88 100644 --- a/bacula/src/console/console_conf.c +++ b/bacula/src/console/console_conf.c @@ -8,34 +8,30 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, January MM, September MM */ - /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2005 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. + version 2 as ammended 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional 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" @@ -80,14 +76,12 @@ static RES_ITEM cons_items[] = { {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0}, {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0}, {"password", store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_cons.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_cons.tls_require), 1, ITEM_DEFAULT, 0}, {"tlscacertificatefile", store_dir, ITEM(res_cons.tls_ca_certfile), 0, 0, 0}, {"tlscacertificatedir", store_dir, ITEM(res_cons.tls_ca_certdir), 0, 0, 0}, {"tlscertificate", store_dir, ITEM(res_cons.tls_certfile), 0, 0, 0}, {"tlskey", store_dir, ITEM(res_cons.tls_keyfile), 0, 0, 0}, -#endif {NULL, NULL, NULL, 0, 0, 0} }; @@ -99,14 +93,12 @@ static RES_ITEM dir_items[] = { {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101}, {"address", store_str, ITEM(res_dir.address), 0, 0, 0}, {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_dir.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_dir.tls_require), 1, ITEM_DEFAULT, 0}, {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0}, {"tlscacertificatedir", store_dir, ITEM(res_dir.tls_ca_certdir), 0, 0, 0}, {"tlscertificate", store_dir, ITEM(res_dir.tls_certfile), 0, 0, 0}, {"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0}, -#endif {NULL, NULL, NULL, 0, 0, 0} }; @@ -117,7 +109,7 @@ static RES_ITEM dir_items[] = { RES_TABLE resources[] = { {"console", cons_items, R_CONSOLE}, {"director", dir_items, R_DIRECTOR}, - {NULL, NULL, 0} + {NULL, NULL, 0} }; @@ -131,18 +123,18 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm printf("No record for %d %s\n", type, res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { case R_CONSOLE: printf("Console: name=%s rcfile=%s histfile=%s\n", reshdr->name, - res->res_cons.rc_file, res->res_cons.hist_file); + res->res_cons.rc_file, res->res_cons.hist_file); break; case R_DIRECTOR: printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, - res->res_dir.address, res->res_dir.DIRport); + res->res_dir.address, res->res_dir.DIRport); break; default: printf("Unknown resource type %d\n", type); @@ -179,49 +171,46 @@ void free_resource(RES *sres, int type) switch (type) { case R_CONSOLE: if (res->res_cons.rc_file) { - free(res->res_cons.rc_file); + free(res->res_cons.rc_file); } if (res->res_cons.hist_file) { - free(res->res_cons.hist_file); + free(res->res_cons.hist_file); } -#ifdef HAVE_TLS if (res->res_cons.tls_ctx) { free_tls_context(res->res_cons.tls_ctx); } if (res->res_cons.tls_ca_certfile) { - free(res->res_cons.tls_ca_certfile); + free(res->res_cons.tls_ca_certfile); } if (res->res_cons.tls_ca_certdir) { - free(res->res_cons.tls_ca_certdir); + free(res->res_cons.tls_ca_certdir); } if (res->res_cons.tls_certfile) { - free(res->res_cons.tls_certfile); + free(res->res_cons.tls_certfile); } if (res->res_cons.tls_keyfile) { - free(res->res_cons.tls_keyfile); + free(res->res_cons.tls_keyfile); } -#endif /* HAVE_TLS */ break; case R_DIRECTOR: - if (res->res_dir.address) - free(res->res_dir.address); -#ifdef HAVE_TLS + if (res->res_dir.address) { + free(res->res_dir.address); + } if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { - free(res->res_dir.tls_ca_certfile); + free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { - free(res->res_dir.tls_ca_certdir); + free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_certfile) { - free(res->res_dir.tls_certfile); + free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { - free(res->res_dir.tls_keyfile); + free(res->res_dir.tls_keyfile); } -#endif /* HAVE_TLS */ break; default: printf("Unknown resource type %d\n", type); @@ -249,10 +238,10 @@ void save_resource(int type, RES_ITEM *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { - Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n", - items[i].name, resources[rindex]); - } + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n", + items[i].name, resources[rindex]); + } } } @@ -263,26 +252,26 @@ void save_resource(int type, RES_ITEM *items, int pass) */ if (pass == 2) { switch (type) { - /* Resources not containing a resource */ - case R_CONSOLE: - case R_DIRECTOR: - break; + /* Resources not containing a resource */ + case R_CONSOLE: + case R_DIRECTOR: + break; - default: - Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); - error = 1; - break; + default: + Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); + error = 1; + break; } /* Note, the resoure name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -306,19 +295,19 @@ void save_resource(int type, RES_ITEM *items, int pass) res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!res_head[rindex]) { - res_head[rindex] = (RES *)res; /* store first entry */ + res_head[rindex] = (RES *)res; /* store first entry */ } else { - RES *next; - for (next=res_head[rindex]; next->next; next=next->next) { - if (strcmp(next->name, res->res_dir.hdr.name) == 0) { - Emsg2(M_ERROR_TERM, 0, - _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), - resources[rindex].name, res->res_dir.hdr.name); - } - } - next->next = (RES *)res; - Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + RES *next; + for (next=res_head[rindex]; next->next; next=next->next) { + if (strcmp(next->name, res->res_dir.hdr.name) == 0) { + Emsg2(M_ERROR_TERM, 0, + _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), + resources[rindex].name, res->res_dir.hdr.name); + } + } + next->next = (RES *)res; + Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), + res->res_dir.hdr.name); } } } diff --git a/bacula/src/console/console_conf.h b/bacula/src/console/console_conf.h index 022f73e2dd..4bc3115a4f 100644 --- a/bacula/src/console/console_conf.h +++ b/bacula/src/console/console_conf.h @@ -5,6 +5,20 @@ * * Version $Id$ */ +/* + Copyright (C) 2000-2005 Kern Sibbald + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as ammended 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 + the file LICENSE for additional details. + + */ /* * Resource codes -- they must be sequential for indexing @@ -14,7 +28,7 @@ enum { R_CONSOLE = 1001, R_DIRECTOR, R_FIRST = R_CONSOLE, - R_LAST = R_DIRECTOR /* Keep this updated */ + R_LAST = R_DIRECTOR /* Keep this updated */ }; /* @@ -33,11 +47,10 @@ enum { /* Console "globals" */ struct CONRES { - RES hdr; - char *rc_file; /* startup file */ - char *hist_file; /* command history file */ - char *password; /* UA server password */ -#ifdef HAVE_TLS + RES hdr; + char *rc_file; /* startup file */ + char *hist_file; /* command history file */ + char *password; /* UA server password */ int tls_enable; /* Enable TLS on all connections */ int tls_require; /* Require TLS on all connections */ char *tls_ca_certfile; /* TLS CA Certificate File */ @@ -46,16 +59,14 @@ struct CONRES { char *tls_keyfile; /* TLS Client Key File */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ -#endif /* HAVE_TLS */ }; /* Director */ struct DIRRES { - RES hdr; - int DIRport; /* UA server port */ - char *address; /* UA server address */ - char *password; /* UA server password */ -#ifdef HAVE_TLS + RES hdr; + int DIRport; /* UA server port */ + char *address; /* UA server address */ + char *password; /* UA server password */ int tls_enable; /* Enable TLS */ int tls_require; /* Require TLS */ char *tls_ca_certfile; /* TLS CA Certificate File */ @@ -64,7 +75,6 @@ struct DIRRES { char *tls_keyfile; /* TLS Client Key File */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ -#endif /* HAVE_TLS */ }; diff --git a/bacula/src/dird/authenticate.c b/bacula/src/dird/authenticate.c index 1e178b2b29..bb73cd3de2 100644 --- a/bacula/src/dird/authenticate.c +++ b/bacula/src/dird/authenticate.c @@ -11,22 +11,17 @@ * */ /* - Copyright (C) 2001-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 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 ammended 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. */ @@ -74,7 +69,6 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) return 0; } -#ifdef HAVE_TLS /* TLS Requirement */ if (store->tls_enable) { if (store->tls_require) { @@ -83,7 +77,6 @@ bool authenticate_storage_daemon(JCR *jcr, STORE *store) tls_local_need = BNET_TLS_OK; } } -#endif auth_success = cram_md5_get_auth(sd, store->password, &tls_remote_need); if (auth_success) { diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index e0ff0aa264..909533ad43 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -485,10 +485,14 @@ static int check_resources() configfile); OK = false; } -#ifdef HAVE_TLS /* tls_require implies tls_enable */ if (director->tls_require) { - director->tls_enable = true; + if (have_tls) { + director->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + } } if (!director->tls_certfile && director->tls_enable) { @@ -528,7 +532,6 @@ static int check_resources() OK = false; } } -#endif /* HAVE_TLS */ } if (!job) { @@ -697,10 +700,14 @@ static int check_resources() db_update_storage_record(NULL, db, &sr); } -#ifdef HAVE_TLS /* tls_require implies tls_enable */ if (store->tls_require) { - store->tls_enable = true; + if (have_tls) { + store->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + } } if ((!store->tls_ca_certfile && !store->tls_ca_certdir) && store->tls_enable) { @@ -725,7 +732,6 @@ static int check_resources() OK = false; } } -#endif /* HAVE_TLS */ } /* Loop over all counters, defining them in each database */ @@ -757,13 +763,18 @@ static int check_resources() db_close_database(NULL, db); } -#ifdef HAVE_TLS /* Loop over Consoles */ CONRES *cons; foreach_res(cons, R_CONSOLE) { /* tls_require implies tls_enable */ if (cons->tls_require) { - cons->tls_enable = true; + if (have_tls) { + cons->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; + } } if (!cons->tls_certfile && cons->tls_enable) { @@ -803,15 +814,19 @@ static int check_resources() } } -#endif /* HAVE_TLS */ -#ifdef HAVE_TLS /* Loop over Clients */ CLIENT *client; foreach_res(client, R_CLIENT) { /* tls_require implies tls_enable */ if (client->tls_require) { - client->tls_enable = true; + if (have_tls) { + client->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; + } } if ((!client->tls_ca_certfile && !client->tls_ca_certdir) && client->tls_enable) { @@ -838,7 +853,6 @@ static int check_resources() } } } -#endif /* HAVE_TLS */ UnlockRes(); if (OK) { diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 2c425cbc78..c0124b8635 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -102,7 +102,6 @@ static RES_ITEM dir_items[] = { {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, {"fdconnecttimeout", store_time,ITEM(res_dir.FDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30}, {"sdconnecttimeout", store_time,ITEM(res_dir.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_dir.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_dir.tls_require), 1, ITEM_DEFAULT, 0}, {"tlsverifypeer", store_yesno, ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 0}, @@ -112,7 +111,6 @@ static RES_ITEM dir_items[] = { {"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0}, {"tlsdhfile", store_dir, ITEM(res_dir.tls_dhfile), 0, 0, 0}, {"tlsallowedcn", store_alist_str, ITEM(res_dir.tls_allowed_cns), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -134,7 +132,6 @@ static RES_ITEM con_items[] = { {"commandacl", store_acl, ITEM(res_con.ACL_lists), Command_ACL, 0, 0}, {"filesetacl", store_acl, ITEM(res_con.ACL_lists), FileSet_ACL, 0, 0}, {"catalogacl", store_acl, ITEM(res_con.ACL_lists), Catalog_ACL, 0, 0}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_con.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_con.tls_require), 1, ITEM_DEFAULT, 0}, {"tlsverifypeer", store_yesno, ITEM(res_con.tls_verify_peer), 1, ITEM_DEFAULT, 0}, @@ -144,7 +141,6 @@ static RES_ITEM con_items[] = { {"tlskey", store_dir, ITEM(res_con.tls_keyfile), 0, 0, 0}, {"tlsdhfile", store_dir, ITEM(res_con.tls_dhfile), 0, 0, 0}, {"tlsallowedcn", store_alist_str, ITEM(res_con.tls_allowed_cns), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -168,14 +164,12 @@ static RES_ITEM cli_items[] = { {"jobretention", store_time, ITEM(res_client.JobRetention), 0, ITEM_DEFAULT, 60*60*24*180}, {"autoprune", store_yesno, ITEM(res_client.AutoPrune), 1, ITEM_DEFAULT, 1}, {"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_client.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_client.tls_require), 1, ITEM_DEFAULT, 0}, {"tlscacertificatefile", store_dir, ITEM(res_client.tls_ca_certfile), 0, 0, 0}, {"tlscacertificatedir", store_dir, ITEM(res_client.tls_ca_certdir), 0, 0, 0}, {"tlscertificate", store_dir, ITEM(res_client.tls_certfile), 0, 0, 0}, {"tlskey", store_dir, ITEM(res_client.tls_keyfile), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -196,14 +190,12 @@ static RES_ITEM store_items[] = { {"autochanger", store_yesno, ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0}, {"maximumconcurrentjobs", store_pint, ITEM(res_store.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1}, {"sddport", store_pint, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */ -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_store.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_store.tls_require), 1, ITEM_DEFAULT, 0}, {"tlscacertificatefile", store_dir, ITEM(res_store.tls_ca_certfile), 0, 0, 0}, {"tlscacertificatedir", store_dir, ITEM(res_store.tls_ca_certdir), 0, 0, 0}, {"tlscertificate", store_dir, ITEM(res_store.tls_certfile), 0, 0, 0}, {"tlskey", store_dir, ITEM(res_store.tls_keyfile), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -878,7 +870,6 @@ void free_resource(RES *sres, int type) if (res->res_dir.DIRaddrs) { free_addresses(res->res_dir.DIRaddrs); } -#ifdef HAVE_TLS if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } @@ -900,7 +891,6 @@ void free_resource(RES *sres, int type) if (res->res_dir.tls_allowed_cns) { delete res->res_dir.tls_allowed_cns; } -#endif /* HAVE_TLS */ break; case R_DEVICE: case R_COUNTER: @@ -909,7 +899,6 @@ void free_resource(RES *sres, int type) if (res->res_con.password) { free(res->res_con.password); } -#ifdef HAVE_TLS if (res->res_con.tls_ctx) { free_tls_context(res->res_con.tls_ctx); } @@ -931,7 +920,6 @@ void free_resource(RES *sres, int type) if (res->res_con.tls_allowed_cns) { delete res->res_con.tls_allowed_cns; } -#endif /* HAVE_TLS */ for (int i=0; ires_con.ACL_lists[i]) { delete res->res_con.ACL_lists[i]; @@ -946,7 +934,6 @@ void free_resource(RES *sres, int type) if (res->res_client.password) { free(res->res_client.password); } -#ifdef HAVE_TLS if (res->res_client.tls_ctx) { free_tls_context(res->res_client.tls_ctx); } @@ -962,7 +949,6 @@ void free_resource(RES *sres, int type) if (res->res_client.tls_keyfile) { free(res->res_client.tls_keyfile); } -#endif /* HAVE_TLS */ break; case R_STORAGE: if (res->res_store.address) { @@ -977,7 +963,6 @@ void free_resource(RES *sres, int type) if (res->res_store.device) { delete res->res_store.device; } -#ifdef HAVE_TLS if (res->res_store.tls_ctx) { free_tls_context(res->res_store.tls_ctx); } @@ -993,7 +978,6 @@ void free_resource(RES *sres, int type) if (res->res_store.tls_keyfile) { free(res->res_store.tls_keyfile); } -#endif /* HAVE_TLS */ break; case R_CATALOG: if (res->res_cat.db_address) { @@ -1168,18 +1152,14 @@ void save_resource(int type, RES_ITEM *items, int pass) if ((res = (URES *)GetResWithName(R_CONSOLE, res_all.res_con.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Console resource %s\n", res_all.res_con.hdr.name); } -#ifdef HAVE_TLS res->res_con.tls_allowed_cns = res_all.res_con.tls_allowed_cns; -#endif break; case R_DIRECTOR: if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name); } res->res_dir.messages = res_all.res_dir.messages; -#ifdef HAVE_TLS res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; -#endif break; case R_STORAGE: if ((res = (URES *)GetResWithName(type, res_all.res_store.hdr.name)) == NULL) { diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index b029df0e44..a0f6dcf649 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -9,19 +9,14 @@ Copyright (C) 2000-2005 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 ammended 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. */ diff --git a/bacula/src/dird/run_conf.c b/bacula/src/dird/run_conf.c index ff6a9112cb..580c228446 100644 --- a/bacula/src/dird/run_conf.c +++ b/bacula/src/dird/run_conf.c @@ -42,14 +42,14 @@ enum e_state { s_weekly, s_monthly, s_hourly, - s_wom, /* 1st, 2nd, ...*/ - s_woy /* week of year w00 - w53 */ + s_wom, /* 1st, 2nd, ...*/ + s_woy /* week of year w00 - w53 */ }; struct s_keyw { - const char *name; /* keyword */ - enum e_state state; /* parser state */ - int code; /* state value */ + const char *name; /* keyword */ + enum e_state state; /* parser state */ + int code; /* state value */ }; /* Keywords understood by parser */ @@ -112,7 +112,7 @@ static struct s_keyw keyw[] = { {N_("third"), s_wom, 2}, {N_("fourth"), s_wom, 3}, {N_("fifth"), s_wom, 4}, - {NULL, s_none, 0} + {NULL, s_none, 0} }; static bool have_hour, have_mday, have_wday, have_month, have_wom; @@ -144,7 +144,7 @@ static struct s_kw RunFields[] = { {"priority", 'p'}, {"spooldata", 's'}, {"writepartafterjob", 'W'}, - {NULL, 0} + {NULL, 0} }; /* @@ -182,128 +182,128 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) found = false; token = lex_get_token(lc, T_NAME); for (i=0; RunFields[i].name; i++) { - if (strcasecmp(lc->str, RunFields[i].name) == 0) { - found = true; - if (lex_get_token(lc, T_ALL) != T_EQUALS) { + if (strcasecmp(lc->str, RunFields[i].name) == 0) { + found = true; + if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); - /* NOT REACHED */ - } - switch (RunFields[i].token) { + /* NOT REACHED */ + } + switch (RunFields[i].token) { case 's': /* Data spooling */ - token = lex_get_token(lc, T_NAME); + token = lex_get_token(lc, T_NAME); if (strcasecmp(lc->str, "yes") == 0) { - lrun.spool_data = true; - lrun.spool_data_set = true; + lrun.spool_data = true; + lrun.spool_data_set = true; } else if (strcasecmp(lc->str, "no") == 0) { - lrun.spool_data = false; - lrun.spool_data_set = true; - } else { + lrun.spool_data = false; + lrun.spool_data_set = true; + } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); - } - break; + } + break; case 'W': /* Write part after job */ - token = lex_get_token(lc, T_NAME); + token = lex_get_token(lc, T_NAME); if (strcasecmp(lc->str, "yes") == 0) { - lrun.write_part_after_job = true; - lrun.write_part_after_job_set = true; + lrun.write_part_after_job = true; + lrun.write_part_after_job_set = true; } else if (strcasecmp(lc->str, "no") == 0) { - lrun.write_part_after_job = false; - lrun.write_part_after_job_set = true; - } else { + lrun.write_part_after_job = false; + lrun.write_part_after_job_set = true; + } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); - } - break; + } + break; case 'L': /* level */ - token = lex_get_token(lc, T_NAME); - for (j=0; joblevels[j].level_name; j++) { - if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { - lrun.level = joblevels[j].level; - lrun.job_type = joblevels[j].job_type; - j = 0; - break; - } - } - if (j != 0) { + token = lex_get_token(lc, T_NAME); + for (j=0; joblevels[j].level_name; j++) { + if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { + lrun.level = joblevels[j].level; + lrun.job_type = joblevels[j].job_type; + j = 0; + break; + } + } + if (j != 0) { scan_err1(lc, _("Job level field: %s not found in run record"), lc->str); - /* NOT REACHED */ - } - break; + /* NOT REACHED */ + } + break; case 'p': /* Priority */ - token = lex_get_token(lc, T_PINT32); - if (pass == 2) { - lrun.Priority = lc->pint32_val; - } - break; + token = lex_get_token(lc, T_PINT32); + if (pass == 2) { + lrun.Priority = lc->pint32_val; + } + break; case 'P': /* Pool */ case 'f': /* FullPool */ case 'i': /* IncPool */ case 'd': /* DifPool */ - token = lex_get_token(lc, T_NAME); - if (pass == 2) { - res = GetResWithName(R_POOL, lc->str); - if (res == NULL) { + token = lex_get_token(lc, T_NAME); + if (pass == 2) { + res = GetResWithName(R_POOL, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Pool Resource: %s", - lc->str); - /* NOT REACHED */ - } - switch(RunFields[i].token) { + lc->str); + /* NOT REACHED */ + } + switch(RunFields[i].token) { case 'P': - lrun.pool = (POOL *)res; - break; + lrun.pool = (POOL *)res; + break; case 'f': - lrun.full_pool = (POOL *)res; - break; + lrun.full_pool = (POOL *)res; + break; case 'i': - lrun.inc_pool = (POOL *)res; - break; + lrun.inc_pool = (POOL *)res; + break; case 'd': - lrun.dif_pool = (POOL *)res; - break; - } - } - break; + lrun.dif_pool = (POOL *)res; + break; + } + } + break; case 'S': /* storage */ - token = lex_get_token(lc, T_NAME); - if (pass == 2) { - res = GetResWithName(R_STORAGE, lc->str); - if (res == NULL) { + token = lex_get_token(lc, T_NAME); + if (pass == 2) { + res = GetResWithName(R_STORAGE, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Storage Resource: %s", - lc->str); - /* NOT REACHED */ - } - lrun.storage = (STORE *)res; - } - break; + lc->str); + /* NOT REACHED */ + } + lrun.storage = (STORE *)res; + } + break; case 'M': /* messages */ - token = lex_get_token(lc, T_NAME); - if (pass == 2) { - res = GetResWithName(R_MSGS, lc->str); - if (res == NULL) { + token = lex_get_token(lc, T_NAME); + if (pass == 2) { + res = GetResWithName(R_MSGS, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Messages Resource: %s", - lc->str); - /* NOT REACHED */ - } - lrun.msgs = (MSGS *)res; - } - break; - default: + lc->str); + /* NOT REACHED */ + } + lrun.msgs = (MSGS *)res; + } + break; + default: scan_err1(lc, "Expected a keyword name, got: %s", lc->str); - /* NOT REACHED */ - break; - } /* end switch */ - } /* end if strcasecmp */ + /* NOT REACHED */ + break; + } /* end switch */ + } /* end if strcasecmp */ } /* end for RunFields */ /* At this point, it is not a keyword. Check for old syle * Job Levels without keyword. This form is depreciated!!! */ for (j=0; joblevels[j].level_name; j++) { - if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { - lrun.level = joblevels[j].level; - lrun.job_type = joblevels[j].job_type; - found = true; - break; - } + if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { + lrun.level = joblevels[j].level; + lrun.job_type = joblevels[j].job_type; + found = true; + break; + } } } /* end for found */ @@ -319,274 +319,274 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) int len, pm = 0; switch (token) { case T_NUMBER: - state = s_mday; - code = atoi(lc->str) - 1; - if (code < 0 || code > 30) { + state = s_mday; + code = atoi(lc->str) - 1; + if (code < 0 || code > 30) { scan_err0(lc, _("Day number out of range (1-31)")); - } - break; - case T_NAME: /* this handles drop through from keyword */ + } + break; + case T_NAME: /* this handles drop through from keyword */ case T_UNQUOTED_STRING: if (strchr(lc->str, (int)'-')) { - state = s_range; - break; - } + state = s_range; + break; + } if (strchr(lc->str, (int)':')) { - state = s_time; - break; - } + state = s_time; + break; + } if (lc->str_len == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && - is_an_integer(lc->str+1)) { - code = atoi(lc->str+1); - if (code < 0 || code > 53) { + is_an_integer(lc->str+1)) { + code = atoi(lc->str+1); + if (code < 0 || code > 53) { scan_err0(lc, _("Week number out of range (0-53)")); - } - state = s_woy; /* week of year */ - break; - } - /* everything else must be a keyword */ - for (i=0; keyw[i].name; i++) { - if (strcasecmp(lc->str, keyw[i].name) == 0) { - state = keyw[i].state; - code = keyw[i].code; - i = 0; - break; - } - } - if (i != 0) { + } + state = s_woy; /* week of year */ + break; + } + /* everything else must be a keyword */ + for (i=0; keyw[i].name; i++) { + if (strcasecmp(lc->str, keyw[i].name) == 0) { + state = keyw[i].state; + code = keyw[i].code; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, _("Job type field: %s in run record not found"), lc->str); - /* NOT REACHED */ - } - break; + /* NOT REACHED */ + } + break; case T_COMMA: - continue; + continue; default: scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str); - /* NOT REACHED */ - break; + /* NOT REACHED */ + break; } switch (state) { case s_none: - continue; - case s_mday: /* day of month */ - if (!have_mday) { - clear_bits(0, 30, lrun.mday); - have_mday = true; - } - set_bit(code, lrun.mday); - break; - case s_month: /* month of year */ - if (!have_month) { - clear_bits(0, 11, lrun.month); - have_month = true; - } - set_bit(code, lrun.month); - break; - case s_wday: /* week day */ - if (!have_wday) { - clear_bits(0, 6, lrun.wday); - have_wday = true; - } - set_bit(code, lrun.wday); - break; - case s_wom: /* Week of month 1st, ... */ - if (!have_wom) { - clear_bits(0, 4, lrun.wom); - have_wom = true; - } - set_bit(code, lrun.wom); - break; + continue; + case s_mday: /* day of month */ + if (!have_mday) { + clear_bits(0, 30, lrun.mday); + have_mday = true; + } + set_bit(code, lrun.mday); + break; + case s_month: /* month of year */ + if (!have_month) { + clear_bits(0, 11, lrun.month); + have_month = true; + } + set_bit(code, lrun.month); + break; + case s_wday: /* week day */ + if (!have_wday) { + clear_bits(0, 6, lrun.wday); + have_wday = true; + } + set_bit(code, lrun.wday); + break; + case s_wom: /* Week of month 1st, ... */ + if (!have_wom) { + clear_bits(0, 4, lrun.wom); + have_wom = true; + } + set_bit(code, lrun.wom); + break; case s_woy: - if (!have_woy) { - clear_bits(0, 53, lrun.woy); - have_woy = true; - } - set_bit(code, lrun.woy); - break; - case s_time: /* time */ - if (!have_at) { + if (!have_woy) { + clear_bits(0, 53, lrun.woy); + have_woy = true; + } + set_bit(code, lrun.woy); + break; + case s_time: /* time */ + if (!have_at) { scan_err0(lc, _("Time must be preceded by keyword AT.")); - /* NOT REACHED */ - } - if (!have_hour) { - clear_bits(0, 23, lrun.hour); - } + /* NOT REACHED */ + } + if (!have_hour) { + clear_bits(0, 23, lrun.hour); + } p = strchr(lc->str, ':'); - if (!p) { + if (!p) { scan_err0(lc, _("Time logic error.\n")); - /* NOT REACHED */ - } - *p++ = 0; /* separate two halves */ - code = atoi(lc->str); /* pick up hour */ - len = strlen(p); + /* NOT REACHED */ + } + *p++ = 0; /* separate two halves */ + code = atoi(lc->str); /* pick up hour */ + len = strlen(p); if (len > 2 && p[len-1] == 'm') { if (p[len-2] == 'a') { - pm = 0; + pm = 0; } else if (p[len-2] == 'p') { - pm = 1; - } else { + pm = 1; + } else { scan_err0(lc, _("Bad time specification.")); - /* NOT REACHED */ - } - } else { - pm = 0; - } - code2 = atoi(p); /* pick up minutes */ - if (pm) { - /* Convert to 24 hour time */ - if (code == 12) { - code -= 12; - } else { - code += 12; - } - } - if (code < 0 || code > 23 || code2 < 0 || code2 > 59) { + /* NOT REACHED */ + } + } else { + pm = 0; + } + code2 = atoi(p); /* pick up minutes */ + if (pm) { + /* Convert to 24 hour time */ + if (code == 12) { + code -= 12; + } else { + code += 12; + } + } + if (code < 0 || code > 23 || code2 < 0 || code2 > 59) { scan_err0(lc, _("Bad time specification.")); - /* NOT REACHED */ - } - set_bit(code, lrun.hour); - lrun.minute = code2; - have_hour = true; - break; + /* NOT REACHED */ + } + set_bit(code, lrun.hour); + lrun.minute = code2; + have_hour = true; + break; case s_at: - have_at = true; - break; + have_at = true; + break; case s_range: p = strchr(lc->str, '-'); - if (!p) { + if (!p) { scan_err0(lc, _("Range logic error.\n")); - } - *p++ = 0; /* separate two halves */ + } + *p++ = 0; /* separate two halves */ - /* Check for day range */ - if (is_an_integer(lc->str) && is_an_integer(p)) { - code = atoi(lc->str) - 1; - code2 = atoi(p) - 1; - if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { + /* Check for day range */ + if (is_an_integer(lc->str) && is_an_integer(p)) { + code = atoi(lc->str) - 1; + code2 = atoi(p) - 1; + if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { scan_err0(lc, _("Bad day range specification.")); - } - if (!have_mday) { - clear_bits(0, 30, lrun.mday); - have_mday = true; - } - if (code < code2) { - set_bits(code, code2, lrun.mday); - } else { - set_bits(code, 30, lrun.mday); - set_bits(0, code2, lrun.mday); - } - break; - } - /* Check for week of year range */ - if (strlen(lc->str) == 3 && strlen(p) == 3 && + } + if (!have_mday) { + clear_bits(0, 30, lrun.mday); + have_mday = true; + } + if (code < code2) { + set_bits(code, code2, lrun.mday); + } else { + set_bits(code, 30, lrun.mday); + set_bits(0, code2, lrun.mday); + } + break; + } + /* Check for week of year range */ + if (strlen(lc->str) == 3 && strlen(p) == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && (p[0] == 'w' || p[0] == 'W') && - is_an_integer(lc->str+1) && is_an_integer(p+1)) { - code = atoi(lc->str+1); - code2 = atoi(p+1); - if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { + is_an_integer(lc->str+1) && is_an_integer(p+1)) { + code = atoi(lc->str+1); + code2 = atoi(p+1); + if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { scan_err0(lc, _("Week number out of range (0-53)")); - } - if (!have_woy) { - clear_bits(0, 53, lrun.woy); - have_woy = true; - } - if (code < code2) { - set_bits(code, code2, lrun.woy); - } else { - set_bits(code, 53, lrun.woy); - set_bits(0, code2, lrun.woy); - } - break; - } - /* lookup first half of keyword range (week days or months) */ - lcase(lc->str); - for (i=0; keyw[i].name; i++) { - if (strcmp(lc->str, keyw[i].name) == 0) { - state = keyw[i].state; - code = keyw[i].code; - i = 0; - break; - } - } - if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) { + } + if (!have_woy) { + clear_bits(0, 53, lrun.woy); + have_woy = true; + } + if (code < code2) { + set_bits(code, code2, lrun.woy); + } else { + set_bits(code, 53, lrun.woy); + set_bits(0, code2, lrun.woy); + } + break; + } + /* lookup first half of keyword range (week days or months) */ + lcase(lc->str); + for (i=0; keyw[i].name; i++) { + if (strcmp(lc->str, keyw[i].name) == 0) { + state = keyw[i].state; + code = keyw[i].code; + i = 0; + break; + } + } + if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) { scan_err0(lc, _("Invalid month, week or position day range")); - /* NOT REACHED */ - } + /* NOT REACHED */ + } - /* Lookup end of range */ - lcase(p); - for (i=0; keyw[i].name; i++) { - if (strcmp(p, keyw[i].name) == 0) { - state2 = keyw[i].state; - code2 = keyw[i].code; - i = 0; - break; - } - } - if (i != 0 || state != state2 || code == code2) { + /* Lookup end of range */ + lcase(p); + for (i=0; keyw[i].name; i++) { + if (strcmp(p, keyw[i].name) == 0) { + state2 = keyw[i].state; + code2 = keyw[i].code; + i = 0; + break; + } + } + if (i != 0 || state != state2 || code == code2) { scan_err0(lc, _("Invalid month, weekday or position range")); - /* NOT REACHED */ - } - if (state == s_wday) { - if (!have_wday) { - clear_bits(0, 6, lrun.wday); - have_wday = true; - } - if (code < code2) { - set_bits(code, code2, lrun.wday); - } else { - set_bits(code, 6, lrun.wday); - set_bits(0, code2, lrun.wday); - } - } else if (state == s_month) { - if (!have_month) { - clear_bits(0, 11, lrun.month); - have_month = true; - } - if (code < code2) { - set_bits(code, code2, lrun.month); - } else { - /* this is a bit odd, but we accept it anyway */ - set_bits(code, 11, lrun.month); - set_bits(0, code2, lrun.month); - } - } else { - /* Must be position */ - if (!have_wom) { - clear_bits(0, 4, lrun.wom); - have_wom = true; - } - if (code < code2) { - set_bits(code, code2, lrun.wom); - } else { - set_bits(code, 4, lrun.wom); - set_bits(0, code2, lrun.wom); - } - } - break; + /* NOT REACHED */ + } + if (state == s_wday) { + if (!have_wday) { + clear_bits(0, 6, lrun.wday); + have_wday = true; + } + if (code < code2) { + set_bits(code, code2, lrun.wday); + } else { + set_bits(code, 6, lrun.wday); + set_bits(0, code2, lrun.wday); + } + } else if (state == s_month) { + if (!have_month) { + clear_bits(0, 11, lrun.month); + have_month = true; + } + if (code < code2) { + set_bits(code, code2, lrun.month); + } else { + /* this is a bit odd, but we accept it anyway */ + set_bits(code, 11, lrun.month); + set_bits(0, code2, lrun.month); + } + } else { + /* Must be position */ + if (!have_wom) { + clear_bits(0, 4, lrun.wom); + have_wom = true; + } + if (code < code2) { + set_bits(code, code2, lrun.wom); + } else { + set_bits(code, 4, lrun.wom); + set_bits(0, code2, lrun.wom); + } + } + break; case s_hourly: - have_hour = true; - set_bits(0, 23, lrun.hour); - break; + have_hour = true; + set_bits(0, 23, lrun.hour); + break; case s_weekly: - have_mday = have_wom = have_woy = true; - set_bits(0, 30, lrun.mday); - set_bits(0, 4, lrun.wom); - set_bits(0, 53, lrun.woy); - break; + have_mday = have_wom = have_woy = true; + set_bits(0, 30, lrun.mday); + set_bits(0, 4, lrun.wom); + set_bits(0, 53, lrun.woy); + break; case s_daily: - have_mday = true; - set_bits(0, 6, lrun.wday); - break; + have_mday = true; + set_bits(0, 6, lrun.wday); + break; case s_monthly: - have_month = true; - set_bits(0, 11, lrun.month); - break; + have_month = true; + set_bits(0, 11, lrun.month); + break; default: scan_err0(lc, _("Unexpected run state\n")); - /* NOT REACHED */ - break; + /* NOT REACHED */ + break; } } @@ -598,11 +598,11 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) trun = (RUN *)malloc(sizeof(RUN)); memcpy(trun, &lrun, sizeof(RUN)); if (*run) { - trun->next = *run; + trun->next = *run; } *run = trun; } - lc->options = options; /* restore scanner options */ + lc->options = options; /* restore scanner options */ set_bit(index, res_all.res_sch.hdr.item_present); } diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index bea22f84fe..e710da0c7c 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2003-2005 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 ammended 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. */ @@ -42,7 +36,7 @@ typedef struct s_vol_list { static int do_label(UAContext *ua, const char *cmd, int relabel); static void label_from_barcodes(UAContext *ua); static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, - POOL_DBR *pr, int relabel, bool media_record_exits); + POOL_DBR *pr, int relabel, bool media_record_exits); static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan); static void free_vol_list(vol_list_t *vol_list); static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr); @@ -83,58 +77,58 @@ static bool get_user_slot_list(UAContext *ua, char *slot_list, int num_slots) strip_trailing_junk(ua->argv[i]); for (p=ua->argv[i]; p && *p; p=e) { - /* Check for list */ + /* Check for list */ e = strchr(p, ','); - if (e) { - *e++ = 0; - } - /* Check for range */ + if (e) { + *e++ = 0; + } + /* Check for range */ h = strchr(p, '-'); /* range? */ - if (h == p) { + if (h == p) { msg = _("Negative numbers not permitted\n"); - goto bail_out; - } - if (h) { - *h++ = 0; - if (!is_an_integer(h)) { + goto bail_out; + } + if (h) { + *h++ = 0; + if (!is_an_integer(h)) { msg = _("Range end is not integer.\n"); - goto bail_out; - } - skip_spaces(&p); - if (!is_an_integer(p)) { + goto bail_out; + } + skip_spaces(&p); + if (!is_an_integer(p)) { msg = _("Range start is not an integer.\n"); - goto bail_out; - } - beg = atoi(p); - end = atoi(h); - if (end < beg) { + goto bail_out; + } + beg = atoi(p); + end = atoi(h); + if (end < beg) { msg = _("Range end not bigger than start.\n"); - goto bail_out; - } - } else { - skip_spaces(&p); - if (!is_an_integer(p)) { + goto bail_out; + } + } else { + skip_spaces(&p); + if (!is_an_integer(p)) { msg = _("Input value is not an integer.\n"); - goto bail_out; - } - beg = end = atoi(p); - } - if (beg <= 0 || end <= 0) { + goto bail_out; + } + beg = end = atoi(p); + } + if (beg <= 0 || end <= 0) { msg = _("Values must be be greater than zero.\n"); - goto bail_out; - } - if (end >= num_slots) { + goto bail_out; + } + if (end >= num_slots) { msg = _("Slot too large.\n"); - goto bail_out; - } - for (i=beg; i<=end; i++) { - slot_list[i] = 1; /* Turn on specified range */ - } + goto bail_out; + } + for (i=beg; i<=end; i++) { + slot_list[i] = 1; /* Turn on specified range */ + } } } else { /* Turn everything on */ for (i=0; i <= num_slots; i++) { - slot_list[i] = 1; + slot_list[i] = 1; } } #ifdef xxx_debug @@ -197,61 +191,61 @@ int update_slots(UAContext *ua) for (vl=vol_list; vl; vl=vl->next) { if (vl->Slot > max_slots) { bsendmsg(ua, _("Slot %d larger than max %d ignored.\n"), - vl->Slot, max_slots); - continue; + vl->Slot, max_slots); + continue; } /* Check if user wants us to look at this slot */ if (!slot_list[vl->Slot]) { Dmsg1(100, "Skipping slot=%d\n", vl->Slot); - continue; + continue; } /* If scanning, we read the label rather than the barcode */ if (scan) { - if (vl->VolName) { - free(vl->VolName); - vl->VolName = NULL; - } - vl->VolName = get_volume_name_from_SD(ua, vl->Slot); + if (vl->VolName) { + free(vl->VolName); + vl->VolName = NULL; + } + vl->VolName = get_volume_name_from_SD(ua, vl->Slot); Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot); } - slot_list[vl->Slot] = 0; /* clear Slot */ + slot_list[vl->Slot] = 0; /* clear Slot */ if (!vl->VolName) { Dmsg1(100, "No VolName for Slot=%d setting InChanger to zero.\n", vl->Slot); - memset(&mr, 0, sizeof(mr)); - mr.Slot = vl->Slot; - mr.InChanger = 1; - mr.StorageId = store->StorageId; - /* Set InChanger to zero for this Slot */ - db_lock(ua->db); - db_make_inchanger_unique(ua->jcr, ua->db, &mr); - db_unlock(ua->db); + memset(&mr, 0, sizeof(mr)); + mr.Slot = vl->Slot; + mr.InChanger = 1; + mr.StorageId = store->StorageId; + /* Set InChanger to zero for this Slot */ + db_lock(ua->db); + db_make_inchanger_unique(ua->jcr, ua->db, &mr); + db_unlock(ua->db); bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), vl->Slot); - continue; + continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); db_lock(ua->db); if (db_get_media_record(ua->jcr, ua->db, &mr)) { - if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store->StorageId) { - mr.Slot = vl->Slot; - mr.InChanger = 1; - mr.StorageId = store->StorageId; - if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + if (mr.Slot != vl->Slot || !mr.InChanger || mr.StorageId != store->StorageId) { + mr.Slot = vl->Slot; + mr.InChanger = 1; + mr.StorageId = store->StorageId; + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } else { - bsendmsg(ua, _( + } else { + bsendmsg(ua, _( "Catalog record for Volume \"%s\" updated to reference slot %d.\n"), - mr.VolumeName, mr.Slot); - } - } else { + mr.VolumeName, mr.Slot); + } + } else { bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"), - mr.VolumeName); - } - db_unlock(ua->db); - continue; + mr.VolumeName); + } + db_unlock(ua->db); + continue; } else { bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"), - mr.VolumeName); + mr.VolumeName); } db_unlock(ua->db); } @@ -261,9 +255,9 @@ int update_slots(UAContext *ua) db_lock(ua->db); for (int i=1; i <= max_slots; i++) { if (slot_list[i]) { - mr.Slot = i; - /* Set InChanger to zero for this Slot */ - db_make_inchanger_unique(ua->jcr, ua->db, &mr); + mr.Slot = i; + /* Set InChanger to zero for this Slot */ + db_make_inchanger_unique(ua->jcr, ua->db, &mr); } } db_unlock(ua->db); @@ -318,24 +312,24 @@ static int do_label(UAContext *ua, const char *cmd, int relabel) /* Check for oldvolume=name */ i = find_arg_with_value(ua, "oldvolume"); if (i >= 0) { - memset(&omr, 0, sizeof(omr)); - bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName)); - if (db_get_media_record(ua->jcr, ua->db, &omr)) { - goto checkVol; - } + memset(&omr, 0, sizeof(omr)); + bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName)); + if (db_get_media_record(ua->jcr, ua->db, &omr)) { + goto checkVol; + } bsendmsg(ua, "%s", db_strerror(ua->db)); } /* No keyword or Vol not found, ask user to select */ if (!select_media_dbr(ua, &omr)) { - return 1; + return 1; } /* Require Volume to be Purged or Recycled */ checkVol: if (strcmp(omr.VolStatus, "Purged") != 0 && strcmp(omr.VolStatus, "Recycle") != 0) { bsendmsg(ua, _("Volume \"%s\" has VolStatus %s. It must be Purged or Recycled before relabeling.\n"), - omr.VolumeName, omr.VolStatus); - return 1; + omr.VolumeName, omr.VolStatus); + return 1; } } @@ -350,38 +344,38 @@ checkVol: for ( ;; ) { media_record_exists = false; if (!get_cmd(ua, _("Enter new Volume name: "))) { - return 1; + return 1; } checkName: if (!is_volume_name_legal(ua, ua->cmd)) { - continue; + continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, ua->cmd, sizeof(mr.VolumeName)); /* If VolBytes are zero the Volume is not labeled */ if (db_get_media_record(ua->jcr, ua->db, &mr)) { - if (mr.VolBytes != 0) { + if (mr.VolBytes != 0) { bsendmsg(ua, _("Media record for new Volume \"%s\" already exists.\n"), - mr.VolumeName); - continue; - } - media_record_exists = true; + mr.VolumeName); + continue; + } + media_record_exists = true; } - break; /* Got it */ + break; /* Got it */ } /* If autochanger, request slot */ if (store->autochanger) { i = find_arg_with_value(ua, "slot"); if (i >= 0) { - mr.Slot = atoi(ua->argv[i]); + mr.Slot = atoi(ua->argv[i]); } else if (!get_pint(ua, _("Enter slot (0 or Enter for none): "))) { - return 1; + return 1; } else { - mr.Slot = ua->pint32_val; + mr.Slot = ua->pint32_val; } - mr.InChanger = 1; /* assumed if we are labeling it */ + mr.InChanger = 1; /* assumed if we are labeling it */ } mr.StorageId = store->StorageId; @@ -391,7 +385,7 @@ checkName: if (pr.PoolId == 0) { memset(&pr, 0, sizeof(pr)); if (!select_pool_dbr(ua, &pr)) { - return 1; + return 1; } } @@ -400,39 +394,39 @@ checkName: if (ok) { sd = ua->jcr->store_bsock; if (relabel) { - /* Delete the old media record */ - if (!db_delete_media_record(ua->jcr, ua->db, &omr)) { + /* Delete the old media record */ + if (!db_delete_media_record(ua->jcr, ua->db, &omr)) { bsendmsg(ua, _("Delete of Volume \"%s\" failed. ERR=%s"), - omr.VolumeName, db_strerror(ua->db)); - } else { + omr.VolumeName, db_strerror(ua->db)); + } else { bsendmsg(ua, _("Old volume \"%s\" deleted from catalog.\n"), - omr.VolumeName); - /* Update the number of Volumes in the pool */ - pr.NumVols--; - if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { + omr.VolumeName); + /* Update the number of Volumes in the pool */ + pr.NumVols--; + if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } - } + } + } } if (ua->automount) { - bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); + bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name); - bash_spaces(dev_name); + bash_spaces(dev_name); bnet_fsend(sd, "mount %s", dev_name); - unbash_spaces(dev_name); - while (bnet_recv(sd) >= 0) { + unbash_spaces(dev_name); + while (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); - /* Here we can get - * 3001 OK mount. Device=xxx or - * 3001 Mounted Volume vvvv - * 3906 is cannot mount non-tape - * So for those, no need to print a reminder - */ + /* Here we can get + * 3001 OK mount. Device=xxx or + * 3001 Mounted Volume vvvv + * 3906 is cannot mount non-tape + * So for those, no need to print a reminder + */ if (strncmp(sd->msg, "3001 ", 5) == 0 || strncmp(sd->msg, "3906 ", 5) == 0) { - print_reminder = false; - } - } + print_reminder = false; + } + } } } if (print_reminder) { @@ -481,7 +475,7 @@ static void label_from_barcodes(UAContext *ua) "==============\n")); for (vl=vol_list; vl; vl=vl->next) { if (!vl->VolName || !slot_list[vl->Slot]) { - continue; + continue; } bsendmsg(ua, "%4d %s\n", vl->Slot, vl->VolName); } @@ -499,24 +493,24 @@ static void label_from_barcodes(UAContext *ua) /* Fire off the label requests */ for (vl=vol_list; vl; vl=vl->next) { if (!vl->VolName || !slot_list[vl->Slot]) { - continue; + continue; } memset(&mr, 0, sizeof(mr)); bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); media_record_exists = false; if (db_get_media_record(ua->jcr, ua->db, &mr)) { - if (mr.VolBytes != 0) { + if (mr.VolBytes != 0) { bsendmsg(ua, _("Media record for Slot %d Volume \"%s\" already exists.\n"), - vl->Slot, mr.VolumeName); - mr.Slot = vl->Slot; - mr.InChanger = 1; - mr.StorageId = store->StorageId; - if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + vl->Slot, mr.VolumeName); + mr.Slot = vl->Slot; + mr.InChanger = 1; + mr.StorageId = store->StorageId; + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, "Error setting InChanger: ERR=%s", db_strerror(ua->db)); - } - continue; - } - media_record_exists = true; + } + continue; + } + media_record_exists = true; } mr.InChanger = 1; mr.StorageId = store->StorageId; @@ -525,25 +519,25 @@ static void label_from_barcodes(UAContext *ua) * send_label_request() below */ if (is_cleaning_tape(ua, &mr, &pr)) { - if (media_record_exists) { /* we update it */ - mr.VolBytes = 1; - if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + if (media_record_exists) { /* we update it */ + mr.VolBytes = 1; + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } - } else { /* create the media record */ - set_pool_dbr_defaults_in_media_dbr(&mr, &pr); - if (db_create_media_record(ua->jcr, ua->db, &mr)) { + } + } else { /* create the media record */ + set_pool_dbr_defaults_in_media_dbr(&mr, &pr); + if (db_create_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"), - mr.VolumeName); - pr.NumVols++; /* this is a bit suspect */ - if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { + mr.VolumeName); + pr.NumVols++; /* this is a bit suspect */ + if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } - } else { + } + } else { bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db)); - } - } - continue; /* done, go handle next volume */ + } + } + continue; /* done, go handle next volume */ } bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); @@ -573,7 +567,7 @@ bool is_volume_name_legal(UAContext *ua, const char *name) /* Restrict the characters permitted in the Volume name */ for (p=name; *p; p++) { if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { - continue; + continue; } if (ua) { bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p); @@ -600,7 +594,7 @@ bool is_volume_name_legal(UAContext *ua, const char *name) * NOTE! This routine opens the SD socket but leaves it open */ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, - POOL_DBR *pr, int relabel, bool media_record_exists) + POOL_DBR *pr, int relabel, bool media_record_exists) { BSOCK *sd; char dev_name[MAX_NAME_LENGTH]; @@ -617,22 +611,22 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, if (relabel) { bash_spaces(omr->VolumeName); bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d", - dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"), - omr->VolumeName, mr->VolumeName); + omr->VolumeName, mr->VolumeName); } else { bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d", - dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"), - mr->VolumeName, mr->Slot); + mr->VolumeName, mr->Slot); Dmsg5(200, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d\n", - dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); } while (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); if (strncmp(sd->msg, "3000 OK label.", 14) == 0) { - ok = true; + ok = true; } } unbash_spaces(mr->VolumeName); @@ -642,28 +636,28 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, mr->set_label_date = true; if (ok) { if (media_record_exists) { /* we update it */ - mr->VolBytes = 1; - mr->InChanger = 1; - if (!db_update_media_record(ua->jcr, ua->db, mr)) { + mr->VolBytes = 1; + mr->InChanger = 1; + if (!db_update_media_record(ua->jcr, ua->db, mr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - ok = false; - } - } else { /* create the media record */ - set_pool_dbr_defaults_in_media_dbr(mr, pr); - mr->VolBytes = 1; /* flag indicating Volume labeled */ - mr->InChanger = 1; - if (db_create_media_record(ua->jcr, ua->db, mr)) { + ok = false; + } + } else { /* create the media record */ + set_pool_dbr_defaults_in_media_dbr(mr, pr); + mr->VolBytes = 1; /* flag indicating Volume labeled */ + mr->InChanger = 1; + if (db_create_media_record(ua->jcr, ua->db, mr)) { bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d successfully created.\n"), - mr->VolumeName, mr->Slot); - /* Update number of volumes in pool */ - pr->NumVols++; - if (!db_update_pool_record(ua->jcr, ua->db, pr)) { + mr->VolumeName, mr->Slot); + /* Update number of volumes in pool */ + pr->NumVols++; + if (!db_update_pool_record(ua->jcr, ua->db, pr)) { bsendmsg(ua, "%s", db_strerror(ua->db)); - } - } else { + } + } else { bsendmsg(ua, "%s", db_strerror(ua->db)); - ok = false; - } + ok = false; + } } } else { bsendmsg(ua, _("Label command failed for Volume %s.\n"), mr->VolumeName); @@ -677,10 +671,10 @@ static BSOCK *open_sd_bsock(UAContext *ua) if (!ua->jcr->store_bsock) { bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"), - store->hdr.name, store->address, store->SDport); + store->hdr.name, store->address, store->SDport); if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) { bsendmsg(ua, _("Failed to connect to Storage daemon.\n")); - return NULL; + return NULL; } } return ua->jcr->store_bsock; @@ -718,12 +712,12 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot) bsendmsg(ua, "%s", sd->msg); Dmsg1(100, "Got: %s", sd->msg); if (strncmp(sd->msg, "3001 Volume=", 12) == 0) { - VolName = (char *)malloc(sd->msglen); + VolName = (char *)malloc(sd->msglen); if (sscanf(sd->msg, "3001 Volume=%s Slot=%d", VolName, &rtn_slot) == 2) { - break; - } - free(VolName); - VolName = NULL; + break; + } + free(VolName); + VolName = NULL; } } close_sd_bsock(ua); @@ -762,42 +756,42 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan) /* Check for returned SD messages */ if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) && - B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && + B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && sd->msg[4] == ' ') { bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */ - continue; + continue; } - /* Validate Slot: if scanning, otherwise Slot:Barcode */ + /* Validate Slot: if scanning, otherwise Slot:Barcode */ p = strchr(sd->msg, ':'); if (scan && p) { - /* Scanning -- require only valid slot */ - Slot = atoi(sd->msg); - if (Slot <= 0) { - p--; + /* Scanning -- require only valid slot */ + Slot = atoi(sd->msg); + if (Slot <= 0) { + p--; *p = ':'; bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg); - continue; - } + continue; + } } else { - /* Not scanning */ - if (p && strlen(p) > 1) { - *p++ = 0; - if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) { - p--; + /* Not scanning */ + if (p && strlen(p) > 1) { + *p++ = 0; + if (!is_an_integer(sd->msg) || (Slot=atoi(sd->msg)) <= 0) { + p--; *p = ':'; bsendmsg(ua, _("Invalid Slot number: %s\n"), sd->msg); - continue; - } - } else { - continue; - } - if (!is_volume_name_legal(ua, p)) { - p--; + continue; + } + } else { + continue; + } + if (!is_volume_name_legal(ua, p)) { + p--; *p = ':'; bsendmsg(ua, _("Invalid Volume name: %s\n"), sd->msg); - continue; - } + continue; + } } /* Add Slot and VolumeName to list */ @@ -805,25 +799,25 @@ static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan) vl->Slot = Slot; if (p) { if (*p == ':') { - p++; /* skip separator */ - } - vl->VolName = bstrdup(p); + p++; /* skip separator */ + } + vl->VolName = bstrdup(p); } else { - vl->VolName = NULL; + vl->VolName = NULL; } Dmsg2(100, "Add slot=%d Vol=%s to SD list.\n", vl->Slot, NPRT(vl->VolName)); if (!vol_list) { - vl->next = vol_list; - vol_list = vl; + vl->next = vol_list; + vol_list = vl; } else { - /* Add new entry to end of list */ - for (vol_list_t *tvl=vol_list; tvl; tvl=tvl->next) { - if (!tvl->next) { - tvl->next = vl; - vl->next = NULL; - break; - } - } + /* Add new entry to end of list */ + for (vol_list_t *tvl=vol_list; tvl; tvl=tvl->next) { + if (!tvl->next) { + tvl->next = vl; + vl->next = NULL; + break; + } + } } } close_sd_bsock(ua); @@ -838,7 +832,7 @@ static void free_vol_list(vol_list_t *vol_list) for (vl=vol_list; vl; ) { vol_list_t *ovl; if (vl->VolName) { - free(vl->VolName); + free(vl->VolName); } ovl = vl; vl = vl->next; @@ -868,7 +862,7 @@ static int get_num_slots_from_SD(UAContext *ua) while (bnet_recv(sd) >= 0) { if (sscanf(sd->msg, "slots=%d\n", &slots) == 1) { - break; + break; } else { bsendmsg(ua, "%s", sd->msg); } @@ -900,7 +894,7 @@ static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr) ua->jcr->pool->cleaning_prefix, mr->VolumeName, strlen(ua->jcr->pool->cleaning_prefix), strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix, - strlen(ua->jcr->pool->cleaning_prefix))); + strlen(ua->jcr->pool->cleaning_prefix))); return strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix, - strlen(ua->jcr->pool->cleaning_prefix)) == 0; + strlen(ua->jcr->pool->cleaning_prefix)) == 0; } diff --git a/bacula/src/dird/ua_query.c b/bacula/src/dird/ua_query.c index 8c22b60204..a4e42c7771 100644 --- a/bacula/src/dird/ua_query.c +++ b/bacula/src/dird/ua_query.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2001-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 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 ammended 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. */ @@ -33,14 +27,14 @@ extern DIRRES *director; static POOLMEM *substitute_prompts(UAContext *ua, - POOLMEM *query, char **prompt, int nprompt); + POOLMEM *query, char **prompt, int nprompt); /* * Read a file containing SQL queries and prompt * the user to select which one. * * File format: - * # => comment + * # => comment * :prompt for query * *prompt for subst %1 * *prompt for subst %2 @@ -63,15 +57,15 @@ int querycmd(UAContext *ua, const char *cmd) } if ((fd=fopen(query_file, "r")) == NULL) { bsendmsg(ua, "Could not open %s: ERR=%s\n", query_file, - strerror(errno)); + strerror(errno)); goto bail_out; } start_prompt(ua, _("Available queries:\n")); while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == ':') { - strip_trailing_junk(line); - add_prompt(ua, line+1); + strip_trailing_junk(line); + add_prompt(ua, line+1); } } if ((item=do_prompt(ua, "", _("Choose a query"), NULL, 0)) < 0) { @@ -81,10 +75,10 @@ int querycmd(UAContext *ua, const char *cmd) i = -1; while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == ':') { - i++; + i++; } if (i == item) { - break; + break; } } if (i != item) { @@ -97,40 +91,40 @@ int querycmd(UAContext *ua, const char *cmd) } while (fgets(line, sizeof(line), fd) != NULL) { if (line[0] == '#') { - continue; + continue; } if (line[0] == ':') { - break; + break; } strip_trailing_junk(line); len = strlen(line); if (line[0] == '*') { /* prompt */ - if (nprompt >= 9) { + if (nprompt >= 9) { bsendmsg(ua, _("Too many prompts in query, max is 9.\n")); - } else { + } else { line[len++] = ' '; - line[len] = 0; - prompt[nprompt++] = bstrdup(line+1); - continue; - } + line[len] = 0; + prompt[nprompt++] = bstrdup(line+1); + continue; + } } if (*query != 0) { pm_strcat(query, " "); } pm_strcat(query, line); if (line[len-1] != ';') { - continue; + continue; } - line[len-1] = 0; /* zap ; */ + line[len-1] = 0; /* zap ; */ if (query[0] != 0) { - query = substitute_prompts(ua, query, prompt, nprompt); + query = substitute_prompts(ua, query, prompt, nprompt); Dmsg1(100, "Query2=%s\n", query); if (query[0] == '!') { - db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST); - } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) { + db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST); + } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) { bsendmsg(ua, "%s\n", query); - } - query[0] = 0; + } + query[0] = 0; } } /* end while */ @@ -138,10 +132,10 @@ int querycmd(UAContext *ua, const char *cmd) query = substitute_prompts(ua, query, prompt, nprompt); Dmsg1(100, "Query2=%s\n", query); if (query[0] == '!') { - db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST); - } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) { + db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST); + } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) { bsendmsg(ua, "%s\n", query); - } + } } bail_out: @@ -156,7 +150,7 @@ bail_out: } static POOLMEM *substitute_prompts(UAContext *ua, - POOLMEM *query, char **prompt, int nprompt) + POOLMEM *query, char **prompt, int nprompt) { char *p, *q, *o; POOLMEM *new_query; @@ -173,14 +167,14 @@ static POOLMEM *substitute_prompts(UAContext *ua, o = new_query; for (q=query; (p=strchr(q, '%')); ) { if (p) { - olen = o - new_query; - new_query = check_pool_memory_size(new_query, olen + p - q + 10); - o = new_query + olen; - while (q < p) { /* copy up to % */ - *o++ = *q++; - } - p++; - switch (*p) { + olen = o - new_query; + new_query = check_pool_memory_size(new_query, olen + p - q + 10); + o = new_query + olen; + while (q < p) { /* copy up to % */ + *o++ = *q++; + } + p++; + switch (*p) { case '1': case '2': case '3': @@ -191,37 +185,37 @@ static POOLMEM *substitute_prompts(UAContext *ua, case '8': case '9': n = (int)(*p) - (int)'1'; - if (prompt[n]) { - if (!subst[n]) { - if (!get_cmd(ua, prompt[n])) { - q += 2; - break; - } - } - len = strlen(ua->cmd); - p = (char *)malloc(len * 2 + 1); - db_escape_string(p, ua->cmd, len); - subst[n] = p; - olen = o - new_query; - new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10); - o = new_query + olen; - while (*p) { - *o++ = *p++; - } - } else { + if (prompt[n]) { + if (!subst[n]) { + if (!get_cmd(ua, prompt[n])) { + q += 2; + break; + } + } + len = strlen(ua->cmd); + p = (char *)malloc(len * 2 + 1); + db_escape_string(p, ua->cmd, len); + subst[n] = p; + olen = o - new_query; + new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10); + o = new_query + olen; + while (*p) { + *o++ = *p++; + } + } else { bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1); - } - q += 2; - break; + } + q += 2; + break; case '%': *o++ = '%'; - q += 2; - break; - default: + q += 2; + break; + default: *o++ = '%'; - q++; - break; - } + q++; + break; + } } } olen = o - new_query; @@ -233,7 +227,7 @@ static POOLMEM *substitute_prompts(UAContext *ua, *o = 0; for (i=0; i<9; i++) { if (subst[i]) { - free(subst[i]); + free(subst[i]); } } free_pool_memory(query); @@ -263,7 +257,7 @@ int sqlquerycmd(UAContext *ua, const char *cmd) len = strlen(ua->cmd); Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd); if (len == 0) { - break; + break; } query = check_pool_memory_size(query, len + 1); if (*query != 0) { @@ -271,10 +265,10 @@ int sqlquerycmd(UAContext *ua, const char *cmd) } pm_strcat(query, ua->cmd); if (ua->cmd[len-1] == ';') { - ua->cmd[len-1] = 0; /* zap ; */ - /* Submit query */ - db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST); - *query = 0; /* start new query */ + ua->cmd[len-1] = 0; /* zap ; */ + /* Submit query */ + db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST); + *query = 0; /* start new query */ msg = _("Enter SQL query: "); } else { msg = _("Add to SQL query: "); diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 499d0c8c73..1d2a390f87 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -462,7 +462,7 @@ static void list_scheduled_jobs(UAContext *ua) sp->priority = priority; sp->runtime = runtime; sp->pool = run->pool; - sched.binary_insert(sp, my_compare); + sched.binary_insert_multiple(sp, my_compare); num_jobs++; } } /* end for loop over resources */ diff --git a/bacula/src/dird/ua_tree.c b/bacula/src/dird/ua_tree.c index 3b5ae11428..0d3bb6d31e 100644 --- a/bacula/src/dird/ua_tree.c +++ b/bacula/src/dird/ua_tree.c @@ -1,31 +1,25 @@ /* * * Bacula Director -- User Agent Database File tree for Restore - * command. This file interacts with the user implementing the - * UA tree commands. + * command. This file interacts with the user implementing the + * UA tree commands. * * Kern Sibbald, July MMII * * Version $Id$ */ - /* Copyright (C) 2002-2005 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 ammended 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. */ @@ -77,7 +71,7 @@ static struct cmdstruct commands[] = { { N_("unmarkdir"), unmarkdircmd, _("unmark directory name only no recursion")}, { N_("quit"), quitcmd, _("quit and do not do restore")}, { N_("?"), helpcmd, _("print help")}, - }; + }; #define comsize (sizeof(commands)/sizeof(struct cmdstruct)) @@ -109,34 +103,34 @@ bool user_select_files_from_tree(TREE_CTX *tree) for ( ;; ) { int found, len, i; if (!get_cmd(ua, "$ ")) { - break; + break; } parse_ua_args(ua); if (ua->argc == 0) { - break; + break; } len = strlen(ua->argk[0]); found = 0; stat = false; - for (i=0; i<(int)comsize; i++) /* search for command */ - if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) { - stat = (*commands[i].func)(ua, tree); /* go execute command */ - found = 1; - break; - } + for (i=0; i<(int)comsize; i++) /* search for command */ + if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) { + stat = (*commands[i].func)(ua, tree); /* go execute command */ + found = 1; + break; + } if (!found) { bsendmsg(tree->ua, _("Illegal command. Enter \"done\" to exit.\n")); - continue; + continue; } if (!stat) { - break; + break; } } ua->UA_sock = NULL; /* don't release restore socket */ stat = !ua->quit; ua->quit = false; - free_ua_context(ua); /* get rid of temp UA context */ + free_ua_context(ua); /* get rid of temp UA context */ return stat; } @@ -149,8 +143,8 @@ bool user_select_files_from_tree(TREE_CTX *tree) * recent file entered (i.e. the JobIds are assumed to be sorted) * * See uar_sel_files in sql_cmds.c for query that calls us. - * row[0]=Path, row[1]=Filename, row[2]=FileIndex - * row[3]=JobId row[4]=LStat + * row[0]=Path, row[1]=Filename, row[2]=FileIndex + * row[3]=JobId row[4]=LStat */ int insert_tree_handler(void *ctx, int num_fields, char **row) { @@ -162,11 +156,11 @@ int insert_tree_handler(void *ctx, int num_fields, char **row) int FileIndex; JobId_t JobId; - if (*row[1] == 0) { /* no filename => directory */ + if (*row[1] == 0) { /* no filename => directory */ if (*row[0] != '/') { /* Must be Win32 directory */ - type = TN_DIR_NLS; + type = TN_DIR_NLS; } else { - type = TN_DIR; + type = TN_DIR; } } else { type = TN_FILE; @@ -178,9 +172,9 @@ int insert_tree_handler(void *ctx, int num_fields, char **row) /* * - The first time we see a file (node->inserted==true), we accept it. * - In the same JobId, we accept only the first copy of a - * hard linked file (the others are simply pointers). + * hard linked file (the others are simply pointers). * - In the same JobId, we accept the last copy of any other - * file -- in particular directories. + * file -- in particular directories. * * All the code to set ok could be condensed to a single * line, but it would be even harder to read. @@ -188,8 +182,8 @@ int insert_tree_handler(void *ctx, int num_fields, char **row) ok = true; if (!node->inserted && JobId == node->JobId) { if ((hard_link && FileIndex > node->FileIndex) || - (!hard_link && FileIndex < node->FileIndex)) { - ok = false; + (!hard_link && FileIndex < node->FileIndex)) { + ok = false; } } if (ok) { @@ -199,17 +193,17 @@ int insert_tree_handler(void *ctx, int num_fields, char **row) node->type = type; node->soft_link = S_ISLNK(statp.st_mode) != 0; if (tree->all) { - node->extract = true; /* extract all by default */ - if (type == TN_DIR || type == TN_DIR_NLS) { - node->extract_dir = true; /* if dir, extract it */ - } + node->extract = true; /* extract all by default */ + if (type == TN_DIR || type == TN_DIR_NLS) { + node->extract_dir = true; /* if dir, extract it */ + } } } if (node->inserted) { tree->FileCount++; if (tree->DeltaCount > 0 && (tree->FileCount-tree->LastCount) > tree->DeltaCount) { bsendmsg(tree->ua, "+"); - tree->LastCount = tree->FileCount; + tree->LastCount = tree->FileCount; } } tree->cnt++; @@ -240,17 +234,17 @@ static int set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, bool extr if (node->type != TN_FILE || (node->soft_link && tree_node_has_child(node))) { /* Recursive set children within directory */ foreach_child(n, node) { - count += set_extract(ua, n, tree, extract); + count += set_extract(ua, n, tree, extract); } /* * Walk up tree marking any unextracted parent to be * extracted. */ if (extract) { - while (node->parent && !node->parent->extract_dir) { - node = node->parent; - node->extract_dir = true; - } + while (node->parent && !node->parent->extract_dir) { + node = node->parent; + node->extract_dir = true; + } } } else if (extract) { char cwd[2000]; @@ -263,24 +257,24 @@ static int set_extract(UAContext *ua, TREE_NODE *node, TREE_CTX *tree, bool extr fdbr.FileId = 0; fdbr.JobId = node->JobId; if (node->hard_link && db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) { - int32_t LinkFI; - decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ - /* - * If we point to a hard linked file, traverse the tree to - * find that file, and mark it to be restored as well. It - * must have the Link we just obtained and the same JobId. - */ - if (LinkFI) { - for (n=first_tree_node(tree->root); n; n=next_tree_node(n)) { - if (n->FileIndex == LinkFI && n->JobId == node->JobId) { - n->extract = true; - if (n->type == TN_DIR || n->type == TN_DIR_NLS) { - n->extract_dir = true; - } - break; - } - } - } + int32_t LinkFI; + decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ + /* + * If we point to a hard linked file, traverse the tree to + * find that file, and mark it to be restored as well. It + * must have the Link we just obtained and the same JobId. + */ + if (LinkFI) { + for (n=first_tree_node(tree->root); n; n=next_tree_node(n)) { + if (n->FileIndex == LinkFI && n->JobId == node->JobId) { + n->extract = true; + if (n->type == TN_DIR || n->type == TN_DIR_NLS) { + n->extract_dir = true; + } + break; + } + } + } } } return count; @@ -302,9 +296,9 @@ static int markcmd(UAContext *ua, TREE_CTX *tree) } for (int i=1; i < ua->argc; i++) { foreach_child(node, tree->node) { - if (fnmatch(ua->argk[i], node->fname, 0) == 0) { - count += set_extract(ua, node, tree, true); - } + if (fnmatch(ua->argk[i], node->fname, 0) == 0) { + count += set_extract(ua, node, tree, true); + } } } if (count == 0) { @@ -328,12 +322,12 @@ static int markdircmd(UAContext *ua, TREE_CTX *tree) } for (int i=1; i < ua->argc; i++) { foreach_child(node, tree->node) { - if (fnmatch(ua->argk[i], node->fname, 0) == 0) { - if (node->type == TN_DIR || node->type == TN_DIR_NLS) { - node->extract_dir = true; - count++; - } - } + if (fnmatch(ua->argk[i], node->fname, 0) == 0) { + if (node->type == TN_DIR || node->type == TN_DIR_NLS) { + node->extract_dir = true; + count++; + } + } } } if (count == 0) { @@ -354,15 +348,15 @@ static int countcmd(UAContext *ua, TREE_CTX *tree) total = num_extract = 0; for (TREE_NODE *node=first_tree_node(tree->root); node; node=next_tree_node(node)) { if (node->type != TN_NEWDIR) { - total++; - if (node->extract || node->extract_dir) { - num_extract++; - } + total++; + if (node->extract || node->extract_dir) { + num_extract++; + } } } bsendmsg(ua, "%s total files/dirs. %s marked to be restored.\n", - edit_uint64_with_commas(total, ec1), - edit_uint64_with_commas(num_extract, ec2)); + edit_uint64_with_commas(total, ec1), + edit_uint64_with_commas(num_extract, ec2)); return 1; } @@ -377,18 +371,18 @@ static int findcmd(UAContext *ua, TREE_CTX *tree) for (int i=1; i < ua->argc; i++) { for (TREE_NODE *node=first_tree_node(tree->root); node; node=next_tree_node(node)) { - if (fnmatch(ua->argk[i], node->fname, 0) == 0) { - const char *tag; - tree_getpath(node, cwd, sizeof(cwd)); - if (node->extract) { + if (fnmatch(ua->argk[i], node->fname, 0) == 0) { + const char *tag; + tree_getpath(node, cwd, sizeof(cwd)); + if (node->extract) { tag = "*"; - } else if (node->extract_dir) { + } else if (node->extract_dir) { tag = "+"; - } else { + } else { tag = ""; - } + } bsendmsg(ua, "%s%s\n", tag, cwd); - } + } } } return 1; @@ -405,14 +399,14 @@ static int lscmd(UAContext *ua, TREE_CTX *tree) } foreach_child(node, tree->node) { if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { - const char *tag; - if (node->extract) { + const char *tag; + if (node->extract) { tag = "*"; - } else if (node->extract_dir) { + } else if (node->extract_dir) { tag = "+"; - } else { + } else { tag = ""; - } + } bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":""); } } @@ -430,19 +424,19 @@ static void rlsmark(UAContext *ua, TREE_NODE *tnode) } foreach_child(node, tnode) { if ((ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) && - (node->extract || node->extract_dir)) { - const char *tag; - if (node->extract) { + (node->extract || node->extract_dir)) { + const char *tag; + if (node->extract) { tag = "*"; - } else if (node->extract_dir) { + } else if (node->extract_dir) { tag = "+"; - } else { + } else { tag = ""; - } + } bsendmsg(ua, "%s%s%s\n", tag, node->fname, tree_node_has_child(node)?"/":""); - if (tree_node_has_child(node)) { - rlsmark(ua, node); - } + if (tree_node_has_child(node)) { + rlsmark(ua, node); + } } } } @@ -473,7 +467,7 @@ static void ls_output(char *buf, const char *fname, const char *tag, struct stat n = sprintf(p, " %2d ", (uint32_t)statp->st_nlink); p += n; n = sprintf(p, "%-8.8s %-8.8s", getuser(statp->st_uid, en1, sizeof(en1)), - getgroup(statp->st_gid, en2, sizeof(en2))); + getgroup(statp->st_gid, en2, sizeof(en2))); p += n; n = sprintf(p, "%8.8s ", edit_uint64(statp->st_size, ec1)); p += n; @@ -506,41 +500,41 @@ static int dircmd(UAContext *ua, TREE_CTX *tree) foreach_child(node, tree->node) { const char *tag; if (ua->argc == 1 || fnmatch(ua->argk[1], node->fname, 0) == 0) { - if (node->extract) { + if (node->extract) { tag = "*"; - } else if (node->extract_dir) { + } else if (node->extract_dir) { tag = "+"; - } else { + } else { tag = " "; - } - tree_getpath(node, cwd, sizeof(cwd)); - fdbr.FileId = 0; - fdbr.JobId = node->JobId; - /* - * Strip / from soft links to directories. - * This is because soft links to files have a trailing slash - * when returned from tree_getpath, but db_get_file_attr... - * treats soft links as files, so they do not have a trailing - * slash like directory names. - */ - if (node->type == TN_FILE && tree_node_has_child(node)) { - bstrncpy(buf, cwd, sizeof(buf)); - pcwd = buf; - int len = strlen(buf); - if (len > 1) { - buf[len-1] = 0; /* strip trailing / */ - } - } else { - pcwd = cwd; - } - if (db_get_file_attributes_record(ua->jcr, ua->db, pcwd, NULL, &fdbr)) { - int32_t LinkFI; - decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ - } else { - /* Something went wrong getting attributes -- print name */ - memset(&statp, 0, sizeof(statp)); - } - ls_output(buf, cwd, tag, &statp); + } + tree_getpath(node, cwd, sizeof(cwd)); + fdbr.FileId = 0; + fdbr.JobId = node->JobId; + /* + * Strip / from soft links to directories. + * This is because soft links to files have a trailing slash + * when returned from tree_getpath, but db_get_file_attr... + * treats soft links as files, so they do not have a trailing + * slash like directory names. + */ + if (node->type == TN_FILE && tree_node_has_child(node)) { + bstrncpy(buf, cwd, sizeof(buf)); + pcwd = buf; + int len = strlen(buf); + if (len > 1) { + buf[len-1] = 0; /* strip trailing / */ + } + } else { + pcwd = cwd; + } + if (db_get_file_attributes_record(ua->jcr, ua->db, pcwd, NULL, &fdbr)) { + int32_t LinkFI; + decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ + } else { + /* Something went wrong getting attributes -- print name */ + memset(&statp, 0, sizeof(statp)); + } + ls_output(buf, cwd, tag, &statp); bsendmsg(ua, "%s\n", buf); } } @@ -560,28 +554,28 @@ static int estimatecmd(UAContext *ua, TREE_CTX *tree) total = num_extract = 0; for (TREE_NODE *node=first_tree_node(tree->root); node; node=next_tree_node(node)) { if (node->type != TN_NEWDIR) { - total++; - /* If regular file, get size */ - if (node->extract && node->type == TN_FILE) { - num_extract++; - tree_getpath(node, cwd, sizeof(cwd)); - fdbr.FileId = 0; - fdbr.JobId = node->JobId; - if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) { - int32_t LinkFI; - decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ - if (S_ISREG(statp.st_mode) && statp.st_size > 0) { - total_bytes += statp.st_size; - } - } - /* Directory, count only */ - } else if (node->extract || node->extract_dir) { - num_extract++; - } + total++; + /* If regular file, get size */ + if (node->extract && node->type == TN_FILE) { + num_extract++; + tree_getpath(node, cwd, sizeof(cwd)); + fdbr.FileId = 0; + fdbr.JobId = node->JobId; + if (db_get_file_attributes_record(ua->jcr, ua->db, cwd, NULL, &fdbr)) { + int32_t LinkFI; + decode_stat(fdbr.LStat, &statp, &LinkFI); /* decode stat pkt */ + if (S_ISREG(statp.st_mode) && statp.st_size > 0) { + total_bytes += statp.st_size; + } + } + /* Directory, count only */ + } else if (node->extract || node->extract_dir) { + num_extract++; + } } } bsendmsg(ua, "%d total files; %d marked to be restored; %s bytes.\n", - total, num_extract, edit_uint64_with_commas(total_bytes, ec1)); + total, num_extract, edit_uint64_with_commas(total_bytes, ec1)); return 1; } @@ -600,7 +594,7 @@ static int helpcmd(UAContext *ua, TREE_CTX *tree) } /* - * Change directories. Note, if the user specifies x: and it fails, + * Change directories. Note, if the user specifies x: and it fails, * we assume it is a Win32 absolute cd rather than relative and * try a second time with /x: ... Win32 kludge. */ @@ -617,13 +611,13 @@ static int cdcmd(UAContext *ua, TREE_CTX *tree) /* Try once more if Win32 drive -- make absolute */ if (ua->argk[1][1] == ':') { /* win32 drive */ bstrncpy(cwd, "/", sizeof(cwd)); - bstrncat(cwd, ua->argk[1], sizeof(cwd)); - node = tree_cwd(cwd, tree->root, tree->node); + bstrncat(cwd, ua->argk[1], sizeof(cwd)); + node = tree_cwd(cwd, tree->root, tree->node); } if (!node) { bsendmsg(ua, _("Invalid path given.\n")); } else { - tree->node = node; + tree->node = node; } } else { tree->node = node; @@ -653,9 +647,9 @@ static int unmarkcmd(UAContext *ua, TREE_CTX *tree) } for (int i=1; i < ua->argc; i++) { foreach_child(node, tree->node) { - if (fnmatch(ua->argk[i], node->fname, 0) == 0) { - count += set_extract(ua, node, tree, false); - } + if (fnmatch(ua->argk[i], node->fname, 0) == 0) { + count += set_extract(ua, node, tree, false); + } } } if (count == 0) { @@ -678,12 +672,12 @@ static int unmarkdircmd(UAContext *ua, TREE_CTX *tree) for (int i=1; i < ua->argc; i++) { foreach_child(node, tree->node) { - if (fnmatch(ua->argk[i], node->fname, 0) == 0) { - if (node->type == TN_DIR || node->type == TN_DIR_NLS) { - node->extract_dir = false; - count++; - } - } + if (fnmatch(ua->argk[i], node->fname, 0) == 0) { + if (node->type == TN_DIR || node->type == TN_DIR_NLS) { + node->extract_dir = false; + count++; + } + } } } diff --git a/bacula/src/filed/authenticate.c b/bacula/src/filed/authenticate.c index 1c173ae7df..d44655d13a 100644 --- a/bacula/src/filed/authenticate.c +++ b/bacula/src/filed/authenticate.c @@ -43,9 +43,7 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; bool auth_success = false; -#ifdef HAVE_TLS alist *verify_list = NULL; -#endif /* HAVE_TLS */ if (rcode != R_DIRECTOR) { Dmsg1(50, _("I only authenticate directors, not %d\n"), rcode); @@ -88,20 +86,20 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) return 0; } -#ifdef HAVE_TLS - /* TLS Requirement */ - if (director->tls_enable) { - if (director->tls_require) { - tls_local_need = BNET_TLS_REQUIRED; - } else { - tls_local_need = BNET_TLS_OK; + if (have_tls) { + /* TLS Requirement */ + if (director->tls_enable) { + if (director->tls_require) { + tls_local_need = BNET_TLS_REQUIRED; + } else { + tls_local_need = BNET_TLS_OK; + } } - } - if (director->tls_verify_peer) { - verify_list = director->tls_allowed_cns; + if (director->tls_verify_peer) { + verify_list = director->tls_allowed_cns; + } } -#endif /* HAVE_TLS */ btimer_t *tid = start_bsock_timer(bs, AUTH_TIMEOUT); auth_success = cram_md5_auth(bs, director->password, tls_local_need); @@ -136,16 +134,16 @@ static int authenticate(int rcode, BSOCK *bs, JCR* jcr) goto auth_fatal; } -#ifdef HAVE_TLS - if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { - /* Engage TLS! Full Speed Ahead! */ - if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) { - Emsg0(M_FATAL, 0, "TLS negotiation failed.\n"); - director = NULL; - goto auth_fatal; + if (have_tls) { + if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { + /* Engage TLS! Full Speed Ahead! */ + if (!bnet_tls_server(director->tls_ctx, bs, verify_list)) { + Emsg0(M_FATAL, 0, "TLS negotiation failed.\n"); + director = NULL; + goto auth_fatal; + } } } -#endif /* HAVE_TLS */ auth_fatal: stop_bsock_timer(tid); diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 7f6fb12ff7..8d2ff77b05 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -10,19 +10,14 @@ Copyright (C) 2000-2005 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 ammended 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. */ @@ -298,10 +293,14 @@ static int check_resources() OK = false; } } -#ifdef HAVE_TLS /* tls_require implies tls_enable */ if (me->tls_require) { +#ifndef HAVE_TLS + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; +#else me->tls_enable = true; +#endif } if ((!me->tls_ca_certfile && !me->tls_ca_certdir) && me->tls_enable) { @@ -326,8 +325,6 @@ static int check_resources() OK = false; } } - -#endif /* HAVE_TLS */ } @@ -341,11 +338,16 @@ static int check_resources() OK = false; } -#ifdef HAVE_TLS foreach_res(director, R_DIRECTOR) { /* tls_require implies tls_enable */ if (director->tls_require) { +#ifndef HAVE_TLS + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; +#else director->tls_enable = true; +#endif } if (!director->tls_certfile && director->tls_enable) { @@ -386,7 +388,6 @@ static int check_resources() } } } -#endif /* HAVE_TLS */ UnlockRes(); diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 890870a6af..bb14299558 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -95,14 +95,12 @@ static RES_ITEM cli_items[] = { {"heartbeatinterval", store_time, ITEM(res_client.heartbeat_interval), 0, ITEM_DEFAULT, 0}, {"sdconnecttimeout", store_time,ITEM(res_client.SDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30}, {"maximumnetworkbuffersize", store_pint, ITEM(res_client.max_network_buffer_size), 0, 0, 0}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_client.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_client.tls_require), 1, ITEM_DEFAULT, 0}, {"tlscacertificatefile", store_dir, ITEM(res_client.tls_ca_certfile), 0, 0, 0}, {"tlscacertificatedir", store_dir, ITEM(res_client.tls_ca_certdir), 0, 0, 0}, {"tlscertificate", store_dir, ITEM(res_client.tls_certfile), 0, 0, 0}, {"tlskey", store_dir, ITEM(res_client.tls_keyfile), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -113,7 +111,6 @@ static RES_ITEM dir_items[] = { {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, {"address", store_str, ITEM(res_dir.address), 0, 0, 0}, {"monitor", store_yesno, ITEM(res_dir.monitor), 1, ITEM_DEFAULT, 0}, -#ifdef HAVE_TLS {"tlsenable", store_yesno, ITEM(res_dir.tls_enable), 1, ITEM_DEFAULT, 0}, {"tlsrequire", store_yesno, ITEM(res_dir.tls_require), 1, ITEM_DEFAULT, 0}, {"tlsverifypeer", store_yesno, ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 0}, @@ -123,7 +120,6 @@ static RES_ITEM dir_items[] = { {"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0}, {"tlsdhfile", store_dir, ITEM(res_dir.tls_dhfile), 0, 0, 0}, {"tlsallowedcn", store_alist_str, ITEM(res_dir.tls_allowed_cns), 0, 0, 0}, -#endif /* HAVE_TLS */ {NULL, NULL, NULL, 0, 0, 0} }; @@ -212,29 +208,27 @@ void free_resource(RES *sres, int type) if (res->res_dir.address) { free(res->res_dir.address); } -#ifdef HAVE_TLS if (res->res_dir.tls_ctx) { free_tls_context(res->res_dir.tls_ctx); } if (res->res_dir.tls_ca_certfile) { - free(res->res_dir.tls_ca_certfile); + free(res->res_dir.tls_ca_certfile); } if (res->res_dir.tls_ca_certdir) { - free(res->res_dir.tls_ca_certdir); + free(res->res_dir.tls_ca_certdir); } if (res->res_dir.tls_certfile) { - free(res->res_dir.tls_certfile); + free(res->res_dir.tls_certfile); } if (res->res_dir.tls_keyfile) { - free(res->res_dir.tls_keyfile); + free(res->res_dir.tls_keyfile); } if (res->res_dir.tls_dhfile) { - free(res->res_dir.tls_dhfile); + free(res->res_dir.tls_dhfile); } if (res->res_dir.tls_allowed_cns) { - delete res->res_dir.tls_allowed_cns; + delete res->res_dir.tls_allowed_cns; } -#endif /* HAVE_TLS */ break; case R_CLIENT: if (res->res_client.working_directory) { @@ -252,23 +246,21 @@ void free_resource(RES *sres, int type) if (res->res_client.FDaddrs) { free_addresses(res->res_client.FDaddrs); } -#ifdef HAVE_TLS if (res->res_client.tls_ctx) { free_tls_context(res->res_client.tls_ctx); } if (res->res_client.tls_ca_certfile) { - free(res->res_client.tls_ca_certfile); + free(res->res_client.tls_ca_certfile); } if (res->res_client.tls_ca_certdir) { - free(res->res_client.tls_ca_certdir); + free(res->res_client.tls_ca_certdir); } if (res->res_client.tls_certfile) { - free(res->res_client.tls_certfile); + free(res->res_client.tls_certfile); } if (res->res_client.tls_keyfile) { - free(res->res_client.tls_keyfile); + free(res->res_client.tls_keyfile); } -#endif /* HAVE_TLS */ break; case R_MSGS: if (res->res_msgs.mail_cmd) @@ -325,14 +317,12 @@ void save_resource(int type, RES_ITEM *items, int pass) break; /* Resources containing another resource */ - case R_DIRECTOR: + case R_DIRECTOR: if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name); } -#ifdef HAVE_TLS - res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; -#endif - break; + res->res_dir.tls_allowed_cns = res_all.res_dir.tls_allowed_cns; + break; case R_CLIENT: if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name); diff --git a/bacula/src/filed/filed_conf.h b/bacula/src/filed/filed_conf.h index 1eb21ea636..6ae6cab79f 100644 --- a/bacula/src/filed/filed_conf.h +++ b/bacula/src/filed/filed_conf.h @@ -6,22 +6,17 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2005 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 ammended 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. */ @@ -51,9 +46,8 @@ struct DIRRES { char *password; /* Director password */ char *address; /* Director address or zero */ int monitor; /* Have only access to status and .status functions */ -#ifdef HAVE_TLS int tls_enable; /* Enable TLS */ - int tls_require; /* Require TLS */ + int tls_require; /* Require TLS */ int tls_verify_peer; /* TLS Verify Client Certificate */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ @@ -63,7 +57,6 @@ struct DIRRES { alist *tls_allowed_cns; /* TLS Allowed Clients */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ -#endif /* HAVE_TLS */ }; struct CLIENT { @@ -78,16 +71,14 @@ struct CLIENT { utime_t heartbeat_interval; /* Interval to send heartbeats to Dir */ utime_t SDConnectTimeout; /* timeout in seconds */ uint32_t max_network_buffer_size; /* max network buf size */ -#ifdef HAVE_TLS int tls_enable; /* Enable TLS */ - int tls_require; /* Require TLS */ + int tls_require; /* Require TLS */ char *tls_ca_certfile; /* TLS CA Certificate File */ char *tls_ca_certdir; /* TLS CA Certificate Directory */ char *tls_certfile; /* TLS Client Certificate File */ char *tls_keyfile; /* TLS Client Key File */ TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ -#endif /* HAVE_TLS */ }; diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index c29f8fc513..d9a27846b0 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -1,5 +1,5 @@ /* - * Bacula File Daemon restore.c Restorefiles. + * Bacula File Daemon restore.c Restorefiles. * * Kern Sibbald, November MM * @@ -10,19 +10,14 @@ Copyright (C) 2000-2005 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 ammended 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. */ @@ -43,7 +38,7 @@ static const char *zlib_strerror(int stat); int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, uint64_t *addr, int flags); -#define RETRY 10 /* retry wait time */ +#define RETRY 10 /* retry wait time */ /* * Close a bfd check that we are at the expected file offset. @@ -55,11 +50,11 @@ int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize) off_t fsize; fsize = blseek(bfd, 0, SEEK_CUR); - bclose(bfd); /* first close file */ + bclose(bfd); /* first close file */ if (fsize > 0 && fsize != osize) { Jmsg3(jcr, M_ERROR, 0, _("Size of data or stream of %s not correct. Original %s, restored %s.\n"), - jcr->last_fname, edit_uint64(osize, ec1), - edit_uint64(fsize, ec2)); + jcr->last_fname, edit_uint64(osize, ec1), + edit_uint64(fsize, ec2)); return -1; } return 0; @@ -77,15 +72,15 @@ void do_restore(JCR *jcr) uint32_t VolSessionId, VolSessionTime; bool extract = false; int32_t file_index; - char ec1[50]; /* Buffer printing huge values */ - - BFILE bfd; /* File content */ - uint64_t fileAddr = 0; /* file write address */ - uint32_t size; /* Size of file */ - BFILE altbfd; /* Alternative data stream */ - uint64_t alt_addr = 0; /* Write address for alternative stream */ - intmax_t alt_size = 0; /* Size of alternate stream */ - int flags; /* Options for extract_data() */ + char ec1[50]; /* Buffer printing huge values */ + + BFILE bfd; /* File content */ + uint64_t fileAddr = 0; /* file write address */ + uint32_t size; /* Size of file */ + BFILE altbfd; /* Alternative data stream */ + uint64_t alt_addr = 0; /* Write address for alternative stream */ + intmax_t alt_size = 0; /* Size of alternate stream */ + int flags; /* Options for extract_data() */ int stat; ATTR *attr; @@ -99,7 +94,7 @@ void do_restore(JCR *jcr) /* Finally, set up for special configurations */ #ifdef HAVE_DARWIN_OS - intmax_t rsrc_len = 0; /* Original length of resource fork */ + intmax_t rsrc_len = 0; /* Original length of resource fork */ struct attrlist attrList; memset(&attrList, 0, sizeof(attrList)); @@ -117,7 +112,7 @@ void do_restore(JCR *jcr) if (client) { buf_size = client->max_network_buffer_size; } else { - buf_size = 0; /* use default */ + buf_size = 0; /* use default */ } if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) { set_jcr_job_status(jcr, JS_ErrorTerminated); @@ -133,27 +128,27 @@ void do_restore(JCR *jcr) /* * Get a record from the Storage daemon. We are guaranteed to - * receive records in the following order: - * 1. Stream record header - * 2. Stream data - * a. Attributes (Unix or Win32) - * or b. File data for the file - * or c. Alternate data stream (e.g. Resource Fork) - * or d. Finder info - * or e. ACLs - * or f. Possibly MD5 or SHA1 record - * 3. Repeat step 1 + * receive records in the following order: + * 1. Stream record header + * 2. Stream data + * a. Attributes (Unix or Win32) + * or b. File data for the file + * or c. Alternate data stream (e.g. Resource Fork) + * or d. Finder info + * or e. ACLs + * or f. Possibly MD5 or SHA1 record + * 3. Repeat step 1 * * NOTE: We keep track of two bacula file descriptors: - * 1. bfd for file data. - * This fd is opened for non empty files when an attribute stream is - * encountered and closed when we find the next attribute stream. - * 2. alt_bfd for alternate data streams - * This fd is opened every time we encounter a new alternate data - * stream for the current file. When we find any other stream, we - * close it again. - * The expected size of the stream, alt_len, should be set when - * opening the fd. + * 1. bfd for file data. + * This fd is opened for non empty files when an attribute stream is + * encountered and closed when we find the next attribute stream. + * 2. alt_bfd for alternate data streams + * This fd is opened every time we encounter a new alternate data + * stream for the current file. When we find any other stream, we + * close it again. + * The expected size of the stream, alt_len, should be set when + * opening the fd. */ binit(&bfd); binit(&altbfd); @@ -166,30 +161,30 @@ void do_restore(JCR *jcr) /* First we expect a Stream Record Header */ if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index, - &stream, &size) != 5) { + &stream, &size) != 5) { Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg); - goto bail_out; + goto bail_out; } Dmsg2(30, "Got hdr: FilInx=%d Stream=%d.\n", file_index, stream); /* * Now we expect the Stream Data */ if (bget_msg(sd) < 0) { Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), bnet_strerror(sd)); - goto bail_out; + goto bail_out; } if (size != (uint32_t)sd->msglen) { Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size); - goto bail_out; + goto bail_out; } Dmsg1(30, "Got stream data, len=%d\n", sd->msglen); /* If we change streams, close and reset alternate data streams */ if (prev_stream != stream) { - if (is_bopen(&altbfd)) { - bclose_chksize(jcr, &altbfd, alt_size); - } - alt_size = -1; /* Use an impossible value and set a proper one below */ - alt_addr = 0; + if (is_bopen(&altbfd)) { + bclose_chksize(jcr, &altbfd, alt_size); + } + alt_size = -1; /* Use an impossible value and set a proper one below */ + alt_addr = 0; } /* File Attributes stream */ @@ -197,85 +192,85 @@ void do_restore(JCR *jcr) case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract); - /* - * If extracting, it was from previous stream, so - * close the output file. - */ - if (extract) { - if (size > 0 && !is_bopen(&bfd)) { + /* + * If extracting, it was from previous stream, so + * close the output file. + */ + if (extract) { + if (size > 0 && !is_bopen(&bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); - } - set_attributes(jcr, attr, &bfd); - extract = false; + } + set_attributes(jcr, attr, &bfd); + extract = false; Dmsg0(30, "Stop extracting.\n"); - } else if (is_bopen(&bfd)) { + } else if (is_bopen(&bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); - bclose(&bfd); - } - - /* - * Unpack and do sanity check fo attributes. - */ - if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) { - goto bail_out; - } - if (file_index != attr->file_index) { + bclose(&bfd); + } + + /* + * Unpack and do sanity check fo attributes. + */ + if (!unpack_attributes_record(jcr, stream, sd->msg, attr)) { + goto bail_out; + } + if (file_index != attr->file_index) { Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"), - file_index, attr->file_index); + file_index, attr->file_index); Dmsg0(100, "File index error\n"); - goto bail_out; - } + goto bail_out; + } Dmsg3(200, "File %s\nattrib=%s\nattribsEx=%s\n", attr->fname, - attr->attr, attr->attrEx); + attr->attr, attr->attrEx); - attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI); + attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI); - if (!is_stream_supported(attr->data_stream)) { - if (!non_support_data++) { + if (!is_stream_supported(attr->data_stream)) { + if (!non_support_data++) { Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"), - stream_to_ascii(attr->data_stream)); - } - continue; - } + stream_to_ascii(attr->data_stream)); + } + continue; + } - build_attr_output_fnames(jcr, attr); + build_attr_output_fnames(jcr, attr); - /* - * Now determine if we are extracting or not. - */ - jcr->num_files_examined++; + /* + * Now determine if we are extracting or not. + */ + jcr->num_files_examined++; Dmsg1(30, "Outfile=%s\n", attr->ofname); - extract = false; - stat = create_file(jcr, attr, &bfd, jcr->replace); - switch (stat) { - case CF_ERROR: - case CF_SKIP: - break; - case CF_EXTRACT: /* File created and we expect file data */ - extract = true; - /* FALLTHROUGH */ - case CF_CREATED: /* File created, but there is no content */ - P(jcr->mutex); - pm_strcpy(jcr->last_fname, attr->ofname); - V(jcr->mutex); - jcr->JobFiles++; - fileAddr = 0; - print_ls_output(jcr, attr); + extract = false; + stat = create_file(jcr, attr, &bfd, jcr->replace); + switch (stat) { + case CF_ERROR: + case CF_SKIP: + break; + case CF_EXTRACT: /* File created and we expect file data */ + extract = true; + /* FALLTHROUGH */ + case CF_CREATED: /* File created, but there is no content */ + P(jcr->mutex); + pm_strcpy(jcr->last_fname, attr->ofname); + V(jcr->mutex); + jcr->JobFiles++; + fileAddr = 0; + print_ls_output(jcr, attr); #ifdef HAVE_DARWIN_OS - /* Only restore the resource fork for regular files */ - from_base64(&rsrc_len, attr->attrEx); - if (attr->type == FT_REG && rsrc_len > 0) { - extract = true; - } + /* Only restore the resource fork for regular files */ + from_base64(&rsrc_len, attr->attrEx); + if (attr->type == FT_REG && rsrc_len > 0) { + extract = true; + } #endif - if (!extract) { - /* set attributes now because file will not be extracted */ - set_attributes(jcr, attr, &bfd); - } - break; - } - break; + if (!extract) { + /* set attributes now because file will not be extracted */ + set_attributes(jcr, attr, &bfd); + } + break; + } + break; /* Data stream */ case STREAM_FILE_DATA: @@ -284,118 +279,118 @@ void do_restore(JCR *jcr) case STREAM_GZIP_DATA: case STREAM_SPARSE_GZIP_DATA: case STREAM_WIN32_GZIP_DATA: - /* Force an expected, consistent stream type here */ - if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES - || prev_stream == STREAM_UNIX_ATTRIBUTES_EX)) { - flags = 0; - if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) { - flags |= FO_SPARSE; - } - if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA - || stream == STREAM_WIN32_GZIP_DATA) { - flags |= FO_GZIP; - } - if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags) < 0) { - extract = false; - bclose(&bfd); - continue; - } - } - break; + /* Force an expected, consistent stream type here */ + if (extract && (prev_stream == stream || prev_stream == STREAM_UNIX_ATTRIBUTES + || prev_stream == STREAM_UNIX_ATTRIBUTES_EX)) { + flags = 0; + if (stream == STREAM_SPARSE_DATA || stream == STREAM_SPARSE_GZIP_DATA) { + flags |= FO_SPARSE; + } + if (stream == STREAM_GZIP_DATA || stream == STREAM_SPARSE_GZIP_DATA + || stream == STREAM_WIN32_GZIP_DATA) { + flags |= FO_GZIP; + } + if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags) < 0) { + extract = false; + bclose(&bfd); + continue; + } + } + break; /* Resource fork stream - only recorded after a file to be restored */ /* Silently ignore if we cannot write - we already reported that */ case STREAM_MACOS_FORK_DATA: #ifdef HAVE_DARWIN_OS - if (extract) { - if (prev_stream != stream) { - if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { + if (extract) { + if (prev_stream != stream) { + if (bopen_rsrc(&altbfd, jcr->last_fname, O_WRONLY | O_TRUNC | O_BINARY, 0) < 0) { Jmsg(jcr, M_ERROR, 0, _(" Cannot open resource fork for %s\n"), jcr->last_fname); - extract = false; - continue; - } - alt_size = rsrc_len; + extract = false; + continue; + } + alt_size = rsrc_len; Dmsg0(30, "Restoring resource fork\n"); - } - flags = 0; - if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags) < 0) { - extract = false; - bclose(&altbfd); - continue; - } - } + } + flags = 0; + if (extract_data(jcr, &altbfd, sd->msg, sd->msglen, &alt_addr, flags) < 0) { + extract = false; + bclose(&altbfd); + continue; + } + } #else - non_support_rsrc++; + non_support_rsrc++; #endif - break; + break; case STREAM_HFSPLUS_ATTRIBUTES: #ifdef HAVE_DARWIN_OS Dmsg0(30, "Restoring Finder Info\n"); - if (sd->msglen != 32) { + if (sd->msglen != 32) { Jmsg(jcr, M_ERROR, 0, _(" Invalid length of Finder Info (got %d, not 32)\n"), sd->msglen); - continue; - } - if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) { + continue; + } + if (setattrlist(jcr->last_fname, &attrList, sd->msg, sd->msglen, 0) != 0) { Jmsg(jcr, M_ERROR, 0, _(" Could not set Finder Info on %s\n"), jcr->last_fname); - continue; - } + continue; + } #else - non_support_finfo++; + non_support_finfo++; #endif case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL: #ifdef HAVE_ACL - pm_strcpy(jcr->acl_text, sd->msg); + pm_strcpy(jcr->acl_text, sd->msg); Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text); - if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) { + if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) { Jmsg1(jcr, M_WARNING, 0, "Can't restore ACL of %s\n", jcr->last_fname); - } + } #else - non_support_acl++; + non_support_acl++; #endif - break; + break; case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL: #ifdef HAVE_ACL - pm_strcpy(jcr->acl_text, sd->msg); + pm_strcpy(jcr->acl_text, sd->msg); Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text); - if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) { + if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) { Jmsg1(jcr, M_WARNING, 0, "Can't restore default ACL of %s\n", jcr->last_fname); - } + } #else - non_support_acl++; + non_support_acl++; #endif - break; + break; case STREAM_MD5_SIGNATURE: case STREAM_SHA1_SIGNATURE: - break; + break; case STREAM_PROGRAM_NAMES: case STREAM_PROGRAM_DATA: - if (!non_support_progname) { + if (!non_support_progname) { Pmsg0(000, "Got Program Name or Data Stream. Ignored.\n"); - non_support_progname++; - } - break; + non_support_progname++; + } + break; default: - /* If extracting, wierd stream (not 1 or 2), close output file anyway */ - if (extract) { + /* If extracting, wierd stream (not 1 or 2), close output file anyway */ + if (extract) { Dmsg1(30, "Found wierd stream %d\n", stream); - if (size > 0 && !is_bopen(&bfd)) { + if (size > 0 && !is_bopen(&bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should be open\n")); - } - set_attributes(jcr, attr, &bfd); - extract = false; - } else if (is_bopen(&bfd)) { + } + set_attributes(jcr, attr, &bfd); + extract = false; + } else if (is_bopen(&bfd)) { Jmsg0(jcr, M_ERROR, 0, _("Logic error: output file should not be open\n")); - bclose(&bfd); - } + bclose(&bfd); + } Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream); Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg); - break; + break; } /* end switch(stream) */ } /* end while get_msg() */ @@ -431,7 +426,7 @@ ok_out: edit_uint64(jcr->JobBytes, ec1)); if (non_support_data > 1 || non_support_attr > 1) { Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"), - non_support_data, non_support_attr); + non_support_data, non_support_attr); } if (non_support_rsrc) { Jmsg(jcr, M_INFO, 0, _("%d non-supported resource fork streams ignored.\n"), non_support_rsrc); @@ -483,10 +478,10 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, uint64_t *addr, int flags) { int stat; - char *wbuf; /* write buffer */ - uint32_t wsize; /* write size */ - uint32_t rsize; /* read size */ - char ec1[50]; /* Buffer printing huge values */ + char *wbuf; /* write buffer */ + uint32_t wsize; /* write size */ + uint32_t rsize; /* read size */ + char ec1[50]; /* Buffer printing huge values */ if (flags & FO_SPARSE) { ser_declare; @@ -497,14 +492,14 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, ser_begin(buf, SPARSE_FADDR_SIZE); unser_uint64(faddr); if (*addr != faddr) { - *addr = faddr; - if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) { - berrno be; + *addr = faddr; + if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) { + berrno be; Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), - edit_uint64(*addr, ec1), jcr->last_fname, - be.strerror(bfd->berrno)); - return -1; - } + edit_uint64(*addr, ec1), jcr->last_fname, + be.strerror(bfd->berrno)); + return -1; + } } } else { wbuf = buf; @@ -523,10 +518,10 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, compress_len = jcr->compress_buf_size; Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize); if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len, - (const Byte *)wbuf, (uLong)rsize)) != Z_OK) { + (const Byte *)wbuf, (uLong)rsize)) != Z_OK) { Jmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"), - jcr->last_fname, zlib_strerror(stat)); - return -1; + jcr->last_fname, zlib_strerror(stat)); + return -1; } wbuf = jcr->compress_buf; wsize = compress_len; @@ -542,7 +537,7 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen, if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) { berrno be; Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), - jcr->last_fname, be.strerror(bfd->berrno)); + jcr->last_fname, be.strerror(bfd->berrno)); return -1; } diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index b7f196d3a4..8b01761b77 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -7,22 +7,17 @@ * */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2005 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 ammended 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. */ diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index d38034b475..ce6d210a73 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -13,19 +13,14 @@ Copyright (C) 2000-2005 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 ammended 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. */ @@ -126,7 +121,7 @@ get_win32_driveletters(FF_PKT *ff, char* szDrives) for (j=0; jname_list.size(); j++) { char *fname = (char *)incexe->name_list.get(j); /* fname should match x:/ */ - if (strlen (fname) > 3 && B_ISALPHA (fname[0]) + if (strlen (fname) > 3 && B_ISALPHA(fname[0]) && fname[1] == ':' && fname[2] == '/') { /* always add in uppercase */ diff --git a/bacula/src/findlib/match.c b/bacula/src/findlib/match.c index 27014d54b5..6d48c304fb 100644 --- a/bacula/src/findlib/match.c +++ b/bacula/src/findlib/match.c @@ -16,19 +16,14 @@ Copyright (C) 2001-2005 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 ammended 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. */ diff --git a/bacula/src/lib/attr.c b/bacula/src/lib/attr.c index 443260f1d7..53ca134a34 100644 --- a/bacula/src/lib/attr.c +++ b/bacula/src/lib/attr.c @@ -1,28 +1,22 @@ /* * attr.c Unpack an Attribute record returned from the tape * - * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated) + * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated) * * Version $Id$ */ - /* - Copyright (C) 2003-2004 Kern Sibbald and John Walker + Copyright (C) 2003-2005 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 ammended 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. */ @@ -54,14 +48,14 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) char *p; /* * An Attributes record consists of: - * File_index - * Type (FT_types) - * Filename - * Attributes - * Link name (if file linked i.e. FT_LNK) - * Extended attributes (Win32) + * File_index + * Type (FT_types) + * Filename + * Attributes + * Link name (if file linked i.e. FT_LNK) + * Extended attributes (Win32) * plus optional values determined by AR_ flags in upper bits of Type - * Data_stream + * Data_stream * */ attr->stream = stream; @@ -77,28 +71,28 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) } else { attr->data_stream = 0; } - attr->type &= FT_MASK; /* keep only type bits */ + attr->type &= FT_MASK; /* keep only type bits */ p = rec; while (*p++ != ' ') /* skip record file index */ { } while (*p++ != ' ') /* skip type */ { } - attr->fname = p; /* set filname position */ - while (*p++ != 0) /* skip filename */ + attr->fname = p; /* set filname position */ + while (*p++ != 0) /* skip filename */ { } - attr->attr = p; /* set attributes position */ - while (*p++ != 0) /* skip attributes */ + attr->attr = p; /* set attributes position */ + while (*p++ != 0) /* skip attributes */ { } - attr->lname = p; /* set link position */ - while (*p++ != 0) /* skip link */ + attr->lname = p; /* set link position */ + while (*p++ != 0) /* skip link */ { } - pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */ + pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */ if (attr->data_stream) { int64_t val; - while (*p++ != 0) /* skip extended attributes */ - { } + while (*p++ != 0) /* skip extended attributes */ + { } from_base64(&val, p); attr->data_stream = (int32_t)val; } @@ -110,9 +104,23 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) return 1; } +static void strip_double_slashes(char *fname) +{ + char *p = fname; + while (p && *p) { + p = strchr(p, '/'); + if (p && p[1] == '/') { + strcpy(p, p+1); + } + if (p) { + p++; + } + } +} + /* * Build attr->ofname from attr->fname and - * attr->olname from attr->olname + * attr->olname from attr->olname */ void build_attr_output_fnames(JCR *jcr, ATTR *attr) { @@ -121,9 +129,9 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) * files are put where the user wants. * * We do a little jig here to handle Win32 files with - * a drive letter -- we simply change the drive - * from, for example, c: to c/ for - * every filename if a prefix is supplied. + * a drive letter -- we simply change the drive + * from, for example, c: to c/ for + * every filename if a prefix is supplied. * */ if (jcr->where[0] == 0) { @@ -134,41 +142,45 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) int wherelen = strlen(jcr->where); pm_strcpy(attr->ofname, jcr->where); /* copy prefix */ if (win32_client && attr->fname[1] == ':') { - attr->fname[1] = '/'; /* convert : to / */ + attr->fname[1] = '/'; /* convert : to / */ } - fn = attr->fname; /* take whole name */ + fn = attr->fname; /* take whole name */ /* Ensure where is terminated with a slash */ if (jcr->where[wherelen-1] != '/' && fn[0] != '/') { - pm_strcat(attr->ofname, "/"); + pm_strcat(attr->ofname, "/"); } pm_strcat(attr->ofname, fn); /* copy rest of name */ /* * Fixup link name -- if it is an absolute path */ if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { - bool add_link; - /* Always add prefix to hard links (FT_LNKSAVED) and - * on user request to soft links - */ - if (attr->lname[0] == '/' && - (attr->type == FT_LNKSAVED || jcr->prefix_links)) { - pm_strcpy(attr->olname, jcr->where); - add_link = true; - } else { - attr->olname[0] = 0; - add_link = false; - } - if (win32_client && attr->lname[1] == ':') { - attr->lname[1] = '/'; /* turn : into / */ - } - fn = attr->lname; /* take whole name */ - /* Ensure where is terminated with a slash */ - if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') { - pm_strcat(attr->olname, "/"); - } - pm_strcat(attr->olname, fn); /* copy rest of link */ + bool add_link; + /* Always add prefix to hard links (FT_LNKSAVED) and + * on user request to soft links + */ + if (attr->lname[0] == '/' && + (attr->type == FT_LNKSAVED || jcr->prefix_links)) { + pm_strcpy(attr->olname, jcr->where); + add_link = true; + } else { + attr->olname[0] = 0; + add_link = false; + } + if (win32_client && attr->lname[1] == ':') { + attr->lname[1] = '/'; /* turn : into / */ + } + fn = attr->lname; /* take whole name */ + /* Ensure where is terminated with a slash */ + if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') { + pm_strcat(attr->olname, "/"); + } + pm_strcat(attr->olname, fn); /* copy rest of link */ } } + if (win32_client) { + strip_double_slashes(attr->ofname); + strip_double_slashes(attr->olname); + } } extern char *getuser(uid_t uid, char *name, int len); @@ -187,7 +199,7 @@ void print_ls_output(JCR *jcr, ATTR *attr) p = encode_mode(attr->statp.st_mode, buf); p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid, en1, sizeof(en1)), - getgroup(attr->statp.st_gid, en2, sizeof(en2))); + getgroup(attr->statp.st_gid, en2, sizeof(en2))); p += sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1)); p = encode_time(attr->statp.st_ctime, p); *p++ = ' '; @@ -202,7 +214,7 @@ void print_ls_output(JCR *jcr, ATTR *attr) *p++ = ' '; /* Copy link name */ for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) { - *p++ = *f++; + *p++ = *f++; } } *p++ = '\n'; diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index b07838db2a..79c337692f 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -31,21 +31,21 @@ extern time_t watchdog_time; #ifndef INADDR_NONE -#define INADDR_NONE -1 +#define INADDR_NONE -1 #endif -#ifndef ENODATA /* not defined on BSD systems */ +#ifndef ENODATA /* not defined on BSD systems */ #define ENODATA EPIPE #endif #ifdef HAVE_WIN32 #define socketRead(fd, buf, len) recv(fd, buf, len, 0) #define socketWrite(fd, buf, len) send(fd, buf, len, 0) -#define socketClose(fd) closesocket(fd) +#define socketClose(fd) closesocket(fd) #else #define socketRead(fd, buf, len) read(fd, buf, len) #define socketWrite(fd, buf, len) write(fd, buf, len) -#define socketClose(fd) close(fd) +#define socketClose(fd) close(fd) #endif static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -70,19 +70,19 @@ static int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) nleft = nbytes; while (nleft > 0) { do { - errno = 0; - nread = socketRead(bsock->fd, ptr, nleft); - if (bsock->timed_out || bsock->terminated) { - return nread; - } + errno = 0; + nread = socketRead(bsock->fd, ptr, nleft); + if (bsock->timed_out || bsock->terminated) { + return nread; + } } while (nread == -1 && (errno == EINTR || errno == EAGAIN)); if (nread <= 0) { - return nread; /* error, or EOF */ + return nread; /* error, or EOF */ } nleft -= nread; ptr += nread; } - return nbytes - nleft; /* return >= 0 */ + return nbytes - nleft; /* return >= 0 */ } /* @@ -97,13 +97,13 @@ static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) if (bsock->spool) { nwritten = fwrite(ptr, 1, nbytes, bsock->spool_fd); if (nwritten != nbytes) { - berrno be; - bsock->b_errno = errno; + berrno be; + bsock->b_errno = errno; Qmsg1(bsock->jcr, M_FATAL, 0, _("Attr spool write error. ERR=%s\n"), - be.strerror()); + be.strerror()); Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes); - errno = bsock->b_errno; - return -1; + errno = bsock->b_errno; + return -1; } return nbytes; } @@ -118,11 +118,11 @@ static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) nleft = nbytes; while (nleft > 0) { do { - errno = 0; - nwritten = socketWrite(bsock->fd, ptr, nleft); - if (bsock->timed_out || bsock->terminated) { - return nwritten; - } + errno = 0; + nwritten = socketWrite(bsock->fd, ptr, nleft); + if (bsock->timed_out || bsock->terminated) { + return nwritten; + } } while (nwritten == -1 && errno == EINTR); /* * If connection is non-blocking, we will get EAGAIN, so @@ -130,18 +130,18 @@ static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) * and try again. */ if (nwritten == -1 && errno == EAGAIN) { - fd_set fdset; - struct timeval tv; - - FD_ZERO(&fdset); - FD_SET((unsigned)bsock->fd, &fdset); - tv.tv_sec = 10; - tv.tv_usec = 0; - select(bsock->fd + 1, NULL, &fdset, NULL, &tv); - continue; + fd_set fdset; + struct timeval tv; + + FD_ZERO(&fdset); + FD_SET((unsigned)bsock->fd, &fdset); + tv.tv_sec = 10; + tv.tv_usec = 0; + select(bsock->fd + 1, NULL, &fdset, NULL, &tv); + continue; } if (nwritten <= 0) { - return nwritten; /* error */ + return nwritten; /* error */ } nleft -= nwritten; ptr += nwritten; @@ -156,7 +156,7 @@ static int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) * Returns number of bytes read (may return zero) * Returns -1 on signal (BNET_SIGNAL) * Returns -2 on hard end of file (BNET_HARDEOF) - * Returns -3 on error (BNET_ERROR) + * Returns -3 on error (BNET_ERROR) * * Unfortunately, it is a bit complicated because we have these * four return types: @@ -178,54 +178,54 @@ int32_t bnet_recv(BSOCK * bsock) return BNET_HARDEOF; } - bsock->read_seqno++; /* bump sequence number */ - bsock->timer_start = watchdog_time; /* set start wait time */ + bsock->read_seqno++; /* bump sequence number */ + bsock->timer_start = watchdog_time; /* set start wait time */ bsock->timed_out = 0; /* get data size -- in int32_t */ if ((nbytes = read_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t))) <= 0) { - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ /* probably pipe broken because client died */ if (errno == 0) { - bsock->b_errno = ENODATA; + bsock->b_errno = ENODATA; } else { - bsock->b_errno = errno; + bsock->b_errno = errno; } bsock->errors++; - return BNET_HARDEOF; /* assume hard EOF received */ + return BNET_HARDEOF; /* assume hard EOF received */ } - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ if (nbytes != sizeof(int32_t)) { bsock->errors++; bsock->b_errno = EIO; Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), - sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port); + sizeof(int32_t), nbytes, bsock->who, bsock->host, bsock->port); return BNET_ERROR; } - pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */ + pktsiz = ntohl(pktsiz); /* decode no. of bytes that follow */ - if (pktsiz == 0) { /* No data transferred */ - bsock->timer_start = 0; /* clear timer */ + if (pktsiz == 0) { /* No data transferred */ + bsock->timer_start = 0; /* clear timer */ bsock->in_msg_no++; bsock->msglen = 0; - return 0; /* zero bytes read */ + return 0; /* zero bytes read */ } /* If signal or packet size too big */ if (pktsiz < 0 || pktsiz > 1000000) { - if (pktsiz > 0) { /* if packet too big */ - Qmsg3(bsock->jcr, M_FATAL, 0, + if (pktsiz > 0) { /* if packet too big */ + Qmsg3(bsock->jcr, M_FATAL, 0, _("Packet size too big from \"%s:%s:%d. Terminating connection.\n"), - bsock->who, bsock->host, bsock->port); - pktsiz = BNET_TERMINATE; /* hang up */ + bsock->who, bsock->host, bsock->port); + pktsiz = BNET_TERMINATE; /* hang up */ } if (pktsiz == BNET_TERMINATE) { - bsock->terminated = 1; + bsock->terminated = 1; } - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ bsock->b_errno = ENODATA; - bsock->msglen = pktsiz; /* signal code */ - return BNET_SIGNAL; /* signal */ + bsock->msglen = pktsiz; /* signal code */ + return BNET_SIGNAL; /* signal */ } /* Make sure the buffer is big enough + one byte for EOS */ @@ -233,29 +233,29 @@ int32_t bnet_recv(BSOCK * bsock) bsock->msg = realloc_pool_memory(bsock->msg, pktsiz + 100); } - bsock->timer_start = watchdog_time; /* set start wait time */ + bsock->timer_start = watchdog_time; /* set start wait time */ bsock->timed_out = 0; /* now read the actual data */ if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) { - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ if (errno == 0) { - bsock->b_errno = ENODATA; + bsock->b_errno = ENODATA; } else { - bsock->b_errno = errno; + bsock->b_errno = errno; } bsock->errors++; Qmsg4(bsock->jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"), - bsock->who, bsock->host, bsock->port, bnet_strerror(bsock)); + bsock->who, bsock->host, bsock->port, bnet_strerror(bsock)); return BNET_ERROR; } - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ bsock->in_msg_no++; bsock->msglen = nbytes; if (nbytes != pktsiz) { bsock->b_errno = EIO; bsock->errors++; Qmsg5(bsock->jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"), - pktsiz, nbytes, bsock->who, bsock->host, bsock->port); + pktsiz, nbytes, bsock->who, bsock->host, bsock->port); return BNET_ERROR; } /* always add a zero by to properly terminate any @@ -264,7 +264,7 @@ int32_t bnet_recv(BSOCK * bsock) */ bsock->msg[nbytes] = 0; /* terminate in case it is a string */ sm_check(__FILE__, __LINE__, false); - return nbytes; /* return actual length of message */ + return nbytes; /* return actual length of message */ } @@ -300,7 +300,7 @@ void bnet_suppress_error_messages(BSOCK * bsock, bool flag) * Transmit spooled data now to a BSOCK */ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t size), - ssize_t tsize) + ssize_t tsize) { int32_t pktsiz; size_t nbytes; @@ -309,27 +309,27 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz rewind(bsock->spool_fd); while (fread((char *)&pktsiz, 1, sizeof(int32_t), bsock->spool_fd) == - sizeof(int32_t)) { + sizeof(int32_t)) { size += sizeof(int32_t); bsock->msglen = ntohl(pktsiz); if (bsock->msglen > 0) { - if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) { - bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1); - } - nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd); - if (nbytes != (size_t) bsock->msglen) { - berrno be; + if (bsock->msglen > (int32_t) sizeof_pool_memory(bsock->msg)) { + bsock->msg = realloc_pool_memory(bsock->msg, bsock->msglen + 1); + } + nbytes = fread(bsock->msg, 1, bsock->msglen, bsock->spool_fd); + if (nbytes != (size_t) bsock->msglen) { + berrno be; Dmsg2(400, "nbytes=%d msglen=%d\n", nbytes, bsock->msglen); Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), - be.strerror()); - update_attr_spool_size(tsize - last); - return 0; - } - size += nbytes; - if ((++count & 0x3F) == 0) { - update_attr_spool_size(size - last); - last = size; - } + be.strerror()); + update_attr_spool_size(tsize - last); + return 0; + } + size += nbytes; + if ((++count & 0x3F) == 0) { + update_attr_spool_size(size - last); + last = size; + } } bnet_send(bsock); } @@ -337,7 +337,7 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz if (ferror(bsock->spool_fd)) { berrno be; Qmsg1(bsock->jcr, M_FATAL, 0, _("fread attr spool error. ERR=%s\n"), - be.strerror()); + be.strerror()); return 0; } return 1; @@ -350,7 +350,7 @@ int bnet_despool_to_bsock(BSOCK * bsock, void update_attr_spool_size(ssize_t siz * the length of the data packet which follows. * * Returns: false on failure - * true on success + * true on success */ bool bnet_send(BSOCK * bsock) { @@ -362,63 +362,63 @@ bool bnet_send(BSOCK * bsock) } pktsiz = htonl((int32_t) bsock->msglen); /* send int32_t containing size of data packet */ - bsock->timer_start = watchdog_time; /* start timer */ + bsock->timer_start = watchdog_time; /* start timer */ bsock->timed_out = 0; rc = write_nbytes(bsock, (char *)&pktsiz, sizeof(int32_t)); - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ if (rc != sizeof(int32_t)) { - if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */ - bsock->terminated = 1; - return false; /* ignore any errors */ + if (bsock->msglen == BNET_TERMINATE) { /* if we were terminating */ + bsock->terminated = 1; + return false; /* ignore any errors */ } bsock->errors++; if (errno == 0) { - bsock->b_errno = EIO; + bsock->b_errno = EIO; } else { - bsock->b_errno = errno; + bsock->b_errno = errno; } if (rc < 0) { - if (!bsock->suppress_error_msgs && !bsock->timed_out) { - Qmsg4(bsock->jcr, M_ERROR, 0, + if (!bsock->suppress_error_msgs && !bsock->timed_out) { + Qmsg4(bsock->jcr, M_ERROR, 0, _("Write error sending len to %s:%s:%d: ERR=%s\n"), bsock->who, - bsock->host, bsock->port, bnet_strerror(bsock)); - } + bsock->host, bsock->port, bnet_strerror(bsock)); + } } else { - Qmsg5(bsock->jcr, M_ERROR, 0, + Qmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), bsock->who, - bsock->host, bsock->port, bsock->msglen, rc); + bsock->host, bsock->port, bsock->msglen, rc); } return false; } - bsock->out_msg_no++; /* increment message number */ - if (bsock->msglen <= 0) { /* length only? */ - return true; /* yes, no data */ + bsock->out_msg_no++; /* increment message number */ + if (bsock->msglen <= 0) { /* length only? */ + return true; /* yes, no data */ } /* send data packet */ - bsock->timer_start = watchdog_time; /* start timer */ + bsock->timer_start = watchdog_time; /* start timer */ bsock->timed_out = 0; rc = write_nbytes(bsock, bsock->msg, bsock->msglen); - bsock->timer_start = 0; /* clear timer */ + bsock->timer_start = 0; /* clear timer */ if (rc != bsock->msglen) { bsock->errors++; if (errno == 0) { - bsock->b_errno = EIO; + bsock->b_errno = EIO; } else { - bsock->b_errno = errno; + bsock->b_errno = errno; } if (rc < 0) { - if (!bsock->suppress_error_msgs) { - Qmsg5(bsock->jcr, M_ERROR, 0, + if (!bsock->suppress_error_msgs) { + Qmsg5(bsock->jcr, M_ERROR, 0, _("Write error sending %d bytes to %s:%s:%d: ERR=%s\n"), - bsock->msglen, bsock->who, - bsock->host, bsock->port, bnet_strerror(bsock)); - } + bsock->msglen, bsock->who, + bsock->host, bsock->port, bnet_strerror(bsock)); + } } else { - Qmsg5(bsock->jcr, M_ERROR, 0, + Qmsg5(bsock->jcr, M_ERROR, 0, _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"), - bsock->msglen, bsock->who, bsock->host, bsock->port, rc); + bsock->msglen, bsock->who, bsock->host, bsock->port, rc); } return false; } @@ -428,7 +428,7 @@ bool bnet_send(BSOCK * bsock) /* * Establish a TLS connection -- server side * Returns: 1 on success - * 0 failure + * 0 failure */ #ifdef HAVE_TLS int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) @@ -453,8 +453,8 @@ int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) if (!tls_postconnect_verify_cn(tls, verify_list)) { Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), - bsock->host); - goto err; + bsock->host); + goto err; } } @@ -469,13 +469,13 @@ err: /* * Establish a TLS connection -- client side * Returns: 1 on success - * 0 failure + * 0 failure */ int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock) { TLS_CONNECTION *tls; - tls = new_tls_connection(ctx, bsock->fd); + tls = new_tls_connection(ctx, bsock->fd); if (!tls) { Qmsg0(bsock->jcr, M_FATAL, 0, _("TLS connection initialization failed.\n")); return 0; @@ -500,6 +500,17 @@ err: bsock->tls = NULL; return 0; } +#else +int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) +{ + Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n")); + return 0; +} +int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock) +{ + Jmsg(bsock->jcr, M_ABORT, 0, _("TLS not configured.\n")); + return 0; +} #endif /* HAVE_TLS */ /* @@ -507,8 +518,8 @@ err: * the BSOCK connection. * * Returns: 1 if data available - * 0 if timeout - * -1 if error + * 0 if timeout + * -1 if error */ int bnet_wait_data(BSOCK * bsock, int sec) { @@ -521,18 +532,18 @@ int bnet_wait_data(BSOCK * bsock, int sec) tv.tv_usec = 0; for (;;) { switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) { - case 0: /* timeout */ - bsock->b_errno = 0; - return 0; + case 0: /* timeout */ + bsock->b_errno = 0; + return 0; case -1: - bsock->b_errno = errno; - if (errno == EINTR || errno == EAGAIN) { - continue; - } - return -1; /* error return */ + bsock->b_errno = errno; + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; /* error return */ default: - bsock->b_errno = 0; - return 1; + bsock->b_errno = 0; + return 1; } } } @@ -550,12 +561,12 @@ int bnet_wait_data_intr(BSOCK * bsock, int sec) tv.tv_sec = sec; tv.tv_usec = 0; switch (select(bsock->fd + 1, &fdset, NULL, NULL, &tv)) { - case 0: /* timeout */ + case 0: /* timeout */ bsock->b_errno = 0; return 0; case -1: bsock->b_errno = errno; - return -1; /* error return */ + return -1; /* error return */ default: bsock->b_errno = 0; } @@ -563,22 +574,22 @@ int bnet_wait_data_intr(BSOCK * bsock, int sec) } #ifndef NETDB_INTERNAL -#define NETDB_INTERNAL -1 /* See errno. */ +#define NETDB_INTERNAL -1 /* See errno. */ #endif #ifndef NETDB_SUCCESS -#define NETDB_SUCCESS 0 /* No problem. */ +#define NETDB_SUCCESS 0 /* No problem. */ #endif #ifndef HOST_NOT_FOUND -#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */ #endif #ifndef TRY_AGAIN -#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */ +#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */ #endif #ifndef NO_RECOVERY -#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */ #endif #ifndef NO_DATA -#define NO_DATA 4 /* Valid name, no data record of requested type. */ +#define NO_DATA 4 /* Valid name, no data record of requested type. */ #endif /* @@ -642,17 +653,17 @@ static const char *resolv_host(int family, const char *host, dlist * addr_list) } else { char **p; for (p = hp->h_addr_list; *p != 0; p++) { - IPADDR *addr = New(IPADDR(hp->h_addrtype)); - addr->set_type(IPADDR::R_MULTIPLE); - if (addr->get_family() == AF_INET) { - addr->set_addr4((struct in_addr*)*p); - } + IPADDR *addr = New(IPADDR(hp->h_addrtype)); + addr->set_type(IPADDR::R_MULTIPLE); + if (addr->get_family() == AF_INET) { + addr->set_addr4((struct in_addr*)*p); + } #ifdef HAVE_IPV6 - else { - addr->set_addr6((struct in6_addr*)*p); - } + else { + addr->set_addr6((struct in6_addr*)*p); + } #endif - addr_list->append(addr); + addr_list->append(addr); } V(ip_mutex); } @@ -674,11 +685,11 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) dlist *addr_list = New(dlist(addr, &addr->link)); if (!host || host[0] == '\0') { if (family != 0) { - addr_list->append(add_any(family)); + addr_list->append(add_any(family)); } else { - addr_list->append(add_any(AF_INET)); + addr_list->append(add_any(AF_INET)); #ifdef HAVE_IPV6 - addr_list->append(add_any(AF_INET6)); + addr_list->append(add_any(AF_INET6)); #endif } } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */ @@ -697,24 +708,24 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) #endif { if (family != 0) { - errmsg = resolv_host(family, host, addr_list); - if (errmsg) { - *errstr = errmsg; - free_addresses(addr_list); - return 0; - } + errmsg = resolv_host(family, host, addr_list); + if (errmsg) { + *errstr = errmsg; + free_addresses(addr_list); + return 0; + } } else { - errmsg = resolv_host(AF_INET, host, addr_list); + errmsg = resolv_host(AF_INET, host, addr_list); #ifdef HAVE_IPV6 - if (errmsg) { - errmsg = resolv_host(AF_INET6, host, addr_list); - } + if (errmsg) { + errmsg = resolv_host(AF_INET6, host, addr_list); + } #endif - if (errmsg) { - *errstr = errmsg; - free_addresses(addr_list); - return 0; - } + if (errmsg) { + *errstr = errmsg; + free_addresses(addr_list); + return 0; + } } } return addr_list; @@ -727,7 +738,7 @@ dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr) * */ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, - int port, int *fatal) + int port, int *fatal) { int sockfd = -1; dlist *addr_list; @@ -744,9 +755,9 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, if ((addr_list = bnet_host2ipaddrs(host, 0, &errstr)) == NULL) { /* Note errstr is not malloc'ed */ Qmsg2(jcr, M_ERROR, 0, "gethostbyname() for host \"%s\" failed: ERR=%s\n", - host, errstr); + host, errstr); Dmsg2(100, "bnet_host2ipaddrs() for host %s failed: ERR=%s\n", - host, errstr); + host, errstr); *fatal = 1; return NULL; } @@ -756,30 +767,30 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, char allbuf[256 * 10]; char curbuf[256]; Dmsg2(100, "Current %sAll %s\n", - ipaddr->build_address_str(curbuf, sizeof(curbuf)), - build_addresses_str(addr_list, allbuf, sizeof(allbuf))); + ipaddr->build_address_str(curbuf, sizeof(curbuf)), + build_addresses_str(addr_list, allbuf, sizeof(allbuf))); /* Open a TCP socket */ if ((sockfd = socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0) { - berrno be; - save_errno = errno; - *fatal = 1; + berrno be; + save_errno = errno; + *fatal = 1; Pmsg3(000, "Socket open error. proto=%d port=%d. ERR=%s\n", - ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror()); - continue; + ipaddr->get_family(), ipaddr->get_port_host_order(), be.strerror()); + continue; } /* * Keep socket from timing out from inactivity */ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { - berrno be; + berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), - be.strerror()); + be.strerror()); } /* connect to server */ if (connect(sockfd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0) { - save_errno = errno; - close(sockfd); - continue; + save_errno = errno; + close(sockfd); + continue; } *fatal = 0; connected = true; @@ -787,18 +798,18 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, } if (!connected) { - free_addresses(addr_list); + free_addresses(addr_list); errno = save_errno; return NULL; } /* * Keep socket from timing out from inactivity - * Do this a second time out of paranoia + * Do this a second time out of paranoia */ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (sockopt_val_t)&turnon, sizeof(turnon)) < 0) { berrno be; Qmsg1(jcr, M_WARNING, 0, _("Cannot set SO_KEEPALIVE on socket: %s\n"), - be.strerror()); + be.strerror()); } BSOCK* ret = init_bsock(jcr, sockfd, name, host, port, ipaddr->get_sockaddr()); free_addresses(addr_list); @@ -809,24 +820,24 @@ static BSOCK *bnet_open(JCR * jcr, const char *name, char *host, char *service, * Try to connect to host for max_retry_time at retry_time intervals. */ BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time, - const char *name, char *host, char *service, int port, - int verbose) + const char *name, char *host, char *service, int port, + int verbose) { int i; BSOCK *bsock; int fatal = 0; for (i = 0; (bsock = bnet_open(jcr, name, host, service, port, &fatal)) == NULL; - i -= retry_interval) { + i -= retry_interval) { berrno be; if (fatal || (jcr && job_canceled(jcr))) { - return NULL; + return NULL; } Dmsg4(100, "Unable to connect to %s on %s:%d. ERR=%s\n", - name, host, port, be.strerror()); + name, host, port, be.strerror()); if (i < 0) { - i = 60 * 5; /* complain again in 5 minutes */ - if (verbose) + i = 60 * 5; /* complain again in 5 minutes */ + if (verbose) Qmsg4(jcr, M_WARNING, 0, "Could not connect to %s on %s:%d. ERR=%s\n" "Retrying ...\n", name, host, port, be.strerror()); } @@ -834,8 +845,8 @@ BSOCK *bnet_connect(JCR * jcr, int retry_interval, int max_retry_time, max_retry_time -= retry_interval; if (max_retry_time <= 0) { Qmsg4(jcr, M_FATAL, 0, _("Unable to connect to %s on %s:%d. ERR=%s\n"), - name, host, port, be.strerror()); - return NULL; + name, host, port, be.strerror()); + return NULL; } } return bsock; @@ -859,7 +870,7 @@ const char *bnet_strerror(BSOCK * bsock) /* * Format and send a message * Returns: false on error - * true on success + * true on success */ bool bnet_fsend(BSOCK * bs, const char *fmt, ...) { @@ -880,7 +891,7 @@ bool bnet_fsend(BSOCK * bs, const char *fmt, ...) bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (bs->msglen > 0 && bs->msglen < (maxlen - 5)) { - break; + break; } bs->msg = realloc_pool_memory(bs->msg, maxlen + maxlen / 2); } @@ -892,7 +903,7 @@ bool bnet_fsend(BSOCK * bs, const char *fmt, ...) * Actual size obtained is returned in bs->msglen * * Returns: 0 on failure - * 1 on success + * 1 on success */ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) { @@ -916,20 +927,20 @@ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) } if (rw & BNET_SETBUF_READ) { while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET, - SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { - berrno be; + SO_RCVBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { + berrno be; Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); - dbuf_size -= TAPE_BSIZE; + dbuf_size -= TAPE_BSIZE; } Dmsg1(200, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { - Qmsg1(bs->jcr, M_WARNING, 0, + Qmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } if (dbuf_size % TAPE_BSIZE != 0) { - Qmsg1(bs->jcr, M_ABORT, 0, + Qmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"), - dbuf_size); + dbuf_size); } } if (size != 0) { @@ -940,20 +951,20 @@ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw) start_size = dbuf_size; if (rw & BNET_SETBUF_WRITE) { while ((dbuf_size > TAPE_BSIZE) && (setsockopt(bs->fd, SOL_SOCKET, - SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { - berrno be; + SO_SNDBUF, (sockopt_val_t) & dbuf_size, sizeof(dbuf_size)) < 0)) { + berrno be; Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror()); - dbuf_size -= TAPE_BSIZE; + dbuf_size -= TAPE_BSIZE; } Dmsg1(200, "set network buffer size=%d\n", dbuf_size); if (dbuf_size != start_size) { - Qmsg1(bs->jcr, M_WARNING, 0, + Qmsg1(bs->jcr, M_WARNING, 0, _("Warning network buffer = %d bytes not max size.\n"), dbuf_size); } if (dbuf_size % TAPE_BSIZE != 0) { - Qmsg1(bs->jcr, M_ABORT, 0, + Qmsg1(bs->jcr, M_ABORT, 0, _("Network buffer size %d not multiple of tape block size.\n"), - dbuf_size); + dbuf_size); } } @@ -1053,7 +1064,7 @@ void bnet_restore_blocking (BSOCK *bsock, int flags) { * This consists of sending a negative packet length * * Returns: false on failure - * true on success + * true on success */ bool bnet_sig(BSOCK * bs, int sig) { @@ -1099,7 +1110,7 @@ const char *bnet_sig_to_ascii(BSOCK * bs) * This probably should be done in net_open */ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port, - struct sockaddr *client_addr) + struct sockaddr *client_addr) { Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port); BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK)); @@ -1116,9 +1127,9 @@ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr)); /* * ****FIXME**** reduce this to a few hours once - * heartbeats are implemented + * heartbeats are implemented */ - bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */ + bsock->timeout = 60 * 60 * 6 * 24; /* 6 days timeout */ bsock->jcr = jcr; return bsock; } @@ -1148,17 +1159,17 @@ void bnet_close(BSOCK * bsock) next = bsock->next; if (!bsock->duped) { #ifdef HAVE_TLS - /* Shutdown tls cleanly. */ - if (bsock->tls) { - tls_bsock_shutdown(bsock); - free_tls_connection(bsock->tls); - bsock->tls = NULL; - } + /* Shutdown tls cleanly. */ + if (bsock->tls) { + tls_bsock_shutdown(bsock); + free_tls_connection(bsock->tls); + bsock->tls = NULL; + } #endif /* HAVE_TLS */ - if (bsock->timed_out) { - shutdown(bsock->fd, 2); /* discard any pending I/O */ - } - socketClose(bsock->fd); /* normal close */ + if (bsock->timed_out) { + shutdown(bsock->fd, 2); /* discard any pending I/O */ + } + socketClose(bsock->fd); /* normal close */ } term_bsock(bsock); } @@ -1171,7 +1182,7 @@ void term_bsock(BSOCK * bsock) free_pool_memory(bsock->msg); bsock->msg = NULL; } else { - ASSERT(1 == 0); /* double close */ + ASSERT(1 == 0); /* double close */ } if (bsock->errmsg) { free_pool_memory(bsock->errmsg); diff --git a/bacula/src/lib/dlist.c b/bacula/src/lib/dlist.c index 2c71698431..bd8efb4409 100644 --- a/bacula/src/lib/dlist.c +++ b/bacula/src/lib/dlist.c @@ -10,7 +10,7 @@ * */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2003-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -105,7 +105,7 @@ void dlist::insert_after(void *item, void *where) * Returns: item if item inserted * other_item if same value already exists (item not inserted) */ -void *dlist::unique_binary_insert(void *item, int compare(void *item1, void *item2)) +void *dlist::binary_insert(void *item, int compare(void *item1, void *item2)) { int comp; int low, high, cur; @@ -195,20 +195,84 @@ void *dlist::unique_binary_insert(void *item, int compare(void *item1, void *ite return item; } - /* * Insert an item in the list, regardless if it is unique * or not. */ -void dlist::binary_insert(void *item, int compare(void *item1, void *item2)) +void dlist::binary_insert_multiple(void *item, int compare(void *item1, void *item2)) { - void *ins_item = unique_binary_insert(item, compare); + void *ins_item = binary_insert(item, compare); /* If identical, insert after the one found */ if (ins_item != item) { insert_after(item, ins_item); } } +/* + * Search for item + */ +void *dlist::binary_search(void *item, int compare(void *item1, void *item2)) +{ + int comp; + int low, high, cur; + void *cur_item; + + + if (num_items == 0) { + return NULL; + } + cur_item = first(); + if (num_items == 1) { + comp = compare(item, cur_item); + if (comp == 0) { + return cur_item; + } else { + return NULL; + } + } + low = 1; + high = num_items; + cur = 1; + cur_item = first(); + while (low < high) { + int nxt; + nxt = (low + high) / 2; + /* Now get cur pointing to nxt */ + while (nxt > cur) { + cur_item = next(cur_item); + cur++; + } + while (nxt < cur) { + cur_item = prev(cur_item); + cur--; + } + comp = compare(item, cur_item); + //Dmsg2(000, "Compare item to %d = %d\n", cur, comp); + if (comp < 0) { + high = cur; + //Dmsg2(000, "set high; low=%d high=%d\n", low, high); + } else if (comp > 0) { + low = cur + 1; + //Dmsg2(000, "set low; low=%d high=%d\n", low, high); + } else { + return cur_item; + } + } + /* + * low == high can only happen if low just + * got incremented from cur, and we have + * not yet tested cur+1 + */ + if (low == high) { + cur_item = next(cur_item); + comp = compare(item, cur_item); + if (comp == 0) { + return cur_item; + } + } + return NULL; +} + void dlist::remove(void *item) { @@ -313,15 +377,16 @@ int main() next_jcr = (MYJCR *)jcr_chain->next(save_jcr); printf("11th item=%s\n", next_jcr->buf); - jcr = (MYJCR *)malloc(sizeof(MYJCR)); - jcr->buf = save_jcr->buf; + jcr1 = (MYJCR *)malloc(sizeof(MYJCR)); + jcr1->buf = save_jcr->buf; printf("Remove 10th item\n"); jcr_chain->remove(save_jcr); + free(save_jcr); printf("Re-insert 10th item\n"); - jcr_chain->insert_before(jcr, next_jcr); + jcr_chain->insert_before(jcr1, next_jcr); printf("Print remaining list.\n"); - foreach_dlist (jcr, jcr_chain) { + foreach_dlist(jcr, jcr_chain) { printf("Dlist item = %s\n", jcr->buf); free(jcr->buf); } @@ -346,6 +411,7 @@ int main() jcr->buf = save_jcr->buf; printf("Remove 10th item\n"); jcr_chain->remove(save_jcr); + free(save_jcr); printf("Re-insert 10th item\n"); jcr_chain->insert_before(jcr, next_jcr); @@ -386,12 +452,37 @@ int main() buf[0]--; } - printf("Print sorted list.\n"); + jcr = (MYJCR *)malloc(sizeof(MYJCR)); + strcpy(buf, "a"); + jcr->buf = bstrdup(buf); + if (jcr_chain->binary_search(jcr, my_compare)) { + printf("One less failed!!!!\n"); + } else { + printf("One less: OK\n"); + } + free(jcr->buf); + strcpy(buf, "ZZZZZZZZZZZZZZZZ"); + jcr->buf = bstrdup(buf); + if (jcr_chain->binary_search(jcr, my_compare)) { + printf("One greater failed!!!!\n"); + } else { + printf("One greater: OK\n"); + } + free(jcr->buf); + free(jcr); + + + printf("Find each of %d items in list.\n", count); + foreach_dlist (jcr, jcr_chain) { + if (!jcr_chain->binary_search(jcr, my_compare)) { + printf("Dlist binary_search item not found = %s\n", jcr->buf); + } + } + printf("Free each of %d items in list.\n", count); foreach_dlist (jcr, jcr_chain) { - printf("Dlist item = %s\n", jcr->buf); free(jcr->buf); + jcr->buf = NULL; } - delete jcr_chain; diff --git a/bacula/src/lib/dlist.h b/bacula/src/lib/dlist.h index 7dd1b17562..ec5b631c31 100644 --- a/bacula/src/lib/dlist.h +++ b/bacula/src/lib/dlist.h @@ -28,7 +28,7 @@ #define M_ABORT 1 /* In case you want to specifically specify the offset to the link */ -#define OFFSET(item, link) ((char *)(link) - (char *)(item)) +#define OFFSET(item, link) (int)((char *)(link) - (char *)(item)) /* * There is a lot of extra casting here to work around the fact * that some compilers (Sun and Visual C++) do not accept @@ -64,8 +64,9 @@ public: void append(void *item); void insert_before(void *item, void *where); void insert_after(void *item, void *where); - void *unique_binary_insert(void *item, int compare(void *item1, void *item2)); - void binary_insert(void *item, int compare(void *item1, void *item2)); + void *binary_insert(void *item, int compare(void *item1, void *item2)); + void *binary_search(void *item, int compare(void *item1, void *item2)); + void binary_insert_multiple(void *item, int compare(void *item1, void *item2)); void remove(void *item); bool empty() const; int size() const; @@ -85,7 +86,7 @@ public: inline void dlist::init(void *item, dlink *link) { head = tail = NULL; - loffset = (char *)link - (char *)item; + loffset = (int)((char *)link - (char *)item); if (loffset < 0 || loffset > 5000) { Emsg0(M_ABORT, 0, "Improper dlist initialization.\n"); } diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 8151ccd28d..514d8860bb 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -32,24 +32,24 @@ #endif #endif -#define FULL_LOCATION 1 /* set for file:line in Debug messages */ +#define FULL_LOCATION 1 /* set for file:line in Debug messages */ /* * This is where we define "Globals" because all the * daemons include this file. */ -const char *working_directory = NULL; /* working directory path stored here */ -int verbose = 0; /* increase User messages */ -int debug_level = 0; /* debug level */ -time_t daemon_start_time = 0; /* Daemon start time */ +const char *working_directory = NULL; /* working directory path stored here */ +int verbose = 0; /* increase User messages */ +int debug_level = 0; /* debug level */ +time_t daemon_start_time = 0; /* Daemon start time */ const char *version = VERSION " (" BDATE ")"; -char my_name[30]; /* daemon name is stored here */ +char my_name[30]; /* daemon name is stored here */ char *exepath = (char *)NULL; char *exename = (char *)NULL; int console_msg_pending = 0; -char con_fname[500]; /* Console filename */ -FILE *con_fd = NULL; /* Console file descriptor */ -brwlock_t con_lock; /* Console lock structure */ +char con_fname[500]; /* Console filename */ +FILE *con_fd = NULL; /* Console file descriptor */ +brwlock_t con_lock; /* Console lock structure */ #ifdef HAVE_POSTGRESQL char catalog_db[] = "PostgreSQL"; @@ -84,7 +84,7 @@ static bool trace = false; /* Used to allow only one thread close the daemon messages at a time */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static MSGS *daemon_msgs; /* global messages */ +static MSGS *daemon_msgs; /* global messages */ /* @@ -109,41 +109,41 @@ void my_name_is(int argc, char *argv[], const char *name) /* strip trailing filename and save exepath */ for (l=p=argv[0]; *p; p++) { if (*p == '/') { - l = p; /* set pos of last slash */ - } + l = p; /* set pos of last slash */ + } } if (*l == '/') { - l++; + l++; } else { - l = argv[0]; + l = argv[0]; #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32) - /* On Windows allow c: junk */ + /* On Windows allow c: junk */ if (l[1] == ':') { - l += 2; - } + l += 2; + } #endif } len = strlen(l) + 1; if (exename) { - free(exename); + free(exename); } exename = (char *)malloc(len); strcpy(exename, l); if (exepath) { - free(exepath); + free(exepath); } exepath = (char *)malloc(strlen(argv[0]) + 1 + len); for (p=argv[0],q=exepath; p < l; ) { - *q++ = *p++; + *q++ = *p++; } *q = 0; if (strchr(exepath, '.') || exepath[0] != '/') { - if (getcwd(cpath, sizeof(cpath))) { - free(exepath); - exepath = (char *)malloc(strlen(cpath) + 1 + len); - strcpy(exepath, cpath); - } + if (getcwd(cpath, sizeof(cpath))) { + free(exepath); + exepath = (char *)malloc(strlen(cpath) + 1 + len); + strcpy(exepath, cpath); + } } Dmsg2(500, "exepath=%s\nexename=%s\n", exepath, exename); } @@ -155,7 +155,7 @@ void my_name_is(int argc, char *argv[], const char *name) * to the job or daemon and thus can be modified. * * NULL for jcr -> initialize global messages for daemon - * non-NULL -> initialize jcr using Message resource + * non-NULL -> initialize jcr using Message resource */ void init_msg(JCR *jcr, MSGS *msg) @@ -181,7 +181,7 @@ init_msg(JCR *jcr, MSGS *msg) close(fd); } else { for(i=1; fd + i <= 2; i++) { - dup2(fd, fd+i); + dup2(fd, fd+i); } } @@ -194,9 +194,9 @@ init_msg(JCR *jcr, MSGS *msg) memset(daemon_msgs, 0, sizeof(MSGS)); for (i=1; i<=M_MAX; i++) { #ifndef WIN32 - add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL); + add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL); #endif - add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL); + add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL); } Dmsg1(050, "Create daemon global message resource 0x%x\n", daemon_msgs); return; @@ -213,10 +213,10 @@ init_msg(JCR *jcr, MSGS *msg) dnew->fd = NULL; dnew->mail_filename = NULL; if (d->mail_cmd) { - dnew->mail_cmd = bstrdup(d->mail_cmd); + dnew->mail_cmd = bstrdup(d->mail_cmd); } if (d->where) { - dnew->where = bstrdup(d->where); + dnew->where = bstrdup(d->where); } temp_chain = dnew; } @@ -229,7 +229,7 @@ init_msg(JCR *jcr, MSGS *msg) } else { /* If we have default values, release them now */ if (daemon_msgs) { - free_msgs_res(daemon_msgs); + free_msgs_res(daemon_msgs); } daemon_msgs = (MSGS *)malloc(sizeof(MSGS)); memset(daemon_msgs, 0, sizeof(MSGS)); @@ -252,7 +252,7 @@ void init_console_msg(const char *wd) if (fd == -1) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Could not open console message file %s: ERR=%s\n"), - con_fname, be.strerror()); + con_fname, be.strerror()); } if (lseek(fd, 0, SEEK_END) > 0) { console_msg_pending = 1; @@ -262,12 +262,12 @@ void init_console_msg(const char *wd) if (!con_fd) { berrno be; Emsg2(M_ERROR, 0, _("Could not open console message file %s: ERR=%s\n"), - con_fname, be.strerror()); + con_fname, be.strerror()); } if (rwl_init(&con_lock) != 0) { berrno be; Emsg1(M_ERROR_TERM, 0, _("Could not get con mutex: ERR=%s\n"), - be.strerror()); + be.strerror()); } } @@ -289,12 +289,12 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai */ for (d=msg->dest_chain; d; d=d->next) { if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) || - (strcmp(where, d->where) == 0))) { + (strcmp(where, d->where) == 0))) { Dmsg4(850, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n", - d, msg_type, dest_code, NPRT(where)); - set_bit(msg_type, d->msg_types); - set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */ - return; + d, msg_type, dest_code, NPRT(where)); + set_bit(msg_type, d->msg_types); + set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */ + return; } } /* Not found, create a new entry */ @@ -302,8 +302,8 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai memset(d, 0, sizeof(DEST)); d->next = msg->dest_chain; d->dest_code = dest_code; - set_bit(msg_type, d->msg_types); /* set type bit in structure */ - set_bit(msg_type, msg->send_msg); /* set type bit in our local */ + set_bit(msg_type, d->msg_types); /* set type bit in structure */ + set_bit(msg_type, msg->send_msg); /* set type bit in our local */ if (where) { d->where = bstrdup(where); } @@ -311,7 +311,7 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai d->mail_cmd = bstrdup(mail_cmd); } Dmsg5(850, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n", - d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd)); + d, msg_type, dest_code, NPRT(where), NPRT(d->mail_cmd)); msg->dest_chain = d; } @@ -327,13 +327,13 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where) for (d=msg->dest_chain; d; d=d->next) { Dmsg2(850, "Remove_msg_dest d=%x where=%s\n", d, NPRT(d->where)); if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) && - ((where == NULL && d->where == NULL) || - (strcmp(where, d->where) == 0))) { + ((where == NULL && d->where == NULL) || + (strcmp(where, d->where) == 0))) { Dmsg3(850, "Found for remove d=%x msgtype=%d destcode=%d\n", - d, msg_type, dest_code); - clear_bit(msg_type, d->msg_types); + d, msg_type, dest_code); + clear_bit(msg_type, d->msg_types); Dmsg0(850, "Return rem_msg_dest\n"); - return; + return; } } } @@ -346,10 +346,10 @@ static void make_unique_mail_filename(JCR *jcr, POOLMEM *&name, DEST *d) { if (jcr) { Mmsg(name, "%s/%s.mail.%s.%d", working_directory, my_name, - jcr->Job, (int)(long)d); + jcr->Job, (int)(long)d); } else { Mmsg(name, "%s/%s.mail.%s.%d", working_directory, my_name, - my_name, (int)(long)d); + my_name, (int)(long)d); } Dmsg1(850, "mailname=%s\n", name); } @@ -371,7 +371,7 @@ static BPIPE *open_mail_pipe(JCR *jcr, POOLMEM *&cmd, DEST *d) if (!(bpipe = open_bpipe(cmd, 120, "rw"))) { berrno be; Jmsg(jcr, M_ERROR, 0, "open mail pipe %s failed: ERR=%s\n", - cmd, be.strerror()); + cmd, be.strerror()); } /* If we had to use sendmail, add subject */ @@ -396,9 +396,9 @@ void close_msg(JCR *jcr) Dmsg1(850, "Close_msg jcr=0x%x\n", jcr); - if (jcr == NULL) { /* NULL -> global chain */ + if (jcr == NULL) { /* NULL -> global chain */ msgs = daemon_msgs; - P(mutex); /* only one thread walking the chain */ + P(mutex); /* only one thread walking the chain */ } else { msgs = jcr->jcr_msgs; jcr->jcr_msgs = NULL; @@ -410,76 +410,76 @@ void close_msg(JCR *jcr) cmd = get_pool_memory(PM_MESSAGE); for (d=msgs->dest_chain; d; ) { if (d->fd) { - switch (d->dest_code) { - case MD_FILE: - case MD_APPEND: - if (d->fd) { - fclose(d->fd); /* close open file descriptor */ - } - break; - case MD_MAIL: - case MD_MAIL_ON_ERROR: + switch (d->dest_code) { + case MD_FILE: + case MD_APPEND: + if (d->fd) { + fclose(d->fd); /* close open file descriptor */ + } + break; + case MD_MAIL: + case MD_MAIL_ON_ERROR: Dmsg0(850, "Got MD_MAIL or MD_MAIL_ON_ERROR\n"); - if (!d->fd) { - break; - } - if (d->dest_code == MD_MAIL_ON_ERROR && jcr && - jcr->JobStatus == JS_Terminated) { - goto rem_temp_file; - } - - if (!(bpipe=open_mail_pipe(jcr, cmd, d))) { + if (!d->fd) { + break; + } + if (d->dest_code == MD_MAIL_ON_ERROR && jcr && + jcr->JobStatus == JS_Terminated) { + goto rem_temp_file; + } + + if (!(bpipe=open_mail_pipe(jcr, cmd, d))) { Pmsg0(000, "open mail pipe failed.\n"); - goto rem_temp_file; - } + goto rem_temp_file; + } Dmsg0(850, "Opened mail pipe\n"); - len = d->max_len+10; - line = get_memory(len); - rewind(d->fd); - while (fgets(line, len, d->fd)) { - fputs(line, bpipe->wfd); - } - if (!close_wpipe(bpipe)) { /* close write pipe sending mail */ - berrno be; + len = d->max_len+10; + line = get_memory(len); + rewind(d->fd); + while (fgets(line, len, d->fd)) { + fputs(line, bpipe->wfd); + } + if (!close_wpipe(bpipe)) { /* close write pipe sending mail */ + berrno be; Pmsg1(000, "close error: ERR=%s\n", be.strerror()); - } + } - /* + /* * Since we are closing all messages, before "recursing" - * make sure we are not closing the daemon messages, otherwise - * kaboom. - */ - if (msgs != daemon_msgs) { - /* read what mail prog returned -- should be nothing */ - while (fgets(line, len, bpipe->rfd)) { + * make sure we are not closing the daemon messages, otherwise + * kaboom. + */ + if (msgs != daemon_msgs) { + /* read what mail prog returned -- should be nothing */ + while (fgets(line, len, bpipe->rfd)) { Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line); - } - } + } + } - stat = close_bpipe(bpipe); - if (stat != 0 && msgs != daemon_msgs) { - berrno be; - be.set_errno(stat); + stat = close_bpipe(bpipe); + if (stat != 0 && msgs != daemon_msgs) { + berrno be; + be.set_errno(stat); Dmsg1(850, "Calling emsg. CMD=%s\n", cmd); Jmsg2(jcr, M_ERROR, 0, _("Mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n"), cmd, be.strerror()); - } - free_memory(line); + } + free_memory(line); rem_temp_file: - /* Remove temp file */ - fclose(d->fd); - unlink(d->mail_filename); - free_pool_memory(d->mail_filename); - d->mail_filename = NULL; + /* Remove temp file */ + fclose(d->fd); + unlink(d->mail_filename); + free_pool_memory(d->mail_filename); + d->mail_filename = NULL; Dmsg0(850, "end mail or mail on error\n"); - break; - default: - break; - } - d->fd = NULL; + break; + default: + break; + } + d->fd = NULL; } - d = d->next; /* point to next buffer */ + d = d->next; /* point to next buffer */ } free_pool_memory(cmd); Dmsg0(850, "Done walking message chain.\n"); @@ -502,17 +502,17 @@ void free_msgs_res(MSGS *msgs) /* Walk down the message chain releasing allocated buffers */ for (d=msgs->dest_chain; d; ) { if (d->where) { - free(d->where); + free(d->where); } if (d->mail_cmd) { - free(d->mail_cmd); + free(d->mail_cmd); } - old = d; /* save pointer to release */ - d = d->next; /* point to next buffer */ - free(old); /* free the destination item */ + old = d; /* save pointer to release */ + d = d->next; /* point to next buffer */ + free(old); /* free the destination item */ } msgs->dest_chain = NULL; - free(msgs); /* free the head */ + free(msgs); /* free the head */ } @@ -526,8 +526,8 @@ void free_msgs_res(MSGS *msgs) void term_msg() { Dmsg0(850, "Enter term_msg\n"); - close_msg(NULL); /* close global chain */ - free_msgs_res(daemon_msgs); /* free the resources */ + close_msg(NULL); /* close global chain */ + free_msgs_res(daemon_msgs); /* free the resources */ daemon_msgs = NULL; if (con_fd) { fflush(con_fd); @@ -567,9 +567,9 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg) /* * Most messages are prefixed by a date and time. If mtime is - * zero, then we use the current time. If mtime is 1 (special - * kludge), we do not prefix the date and time. Otherwise, - * we assume mtime is a time_t and use it. + * zero, then we use the current time. If mtime is 1 (special + * kludge), we do not prefix the date and time. Otherwise, + * we assume mtime is a time_t and use it. */ if (mtime == 0) { mtime = time(NULL); @@ -587,7 +587,7 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg) if (type == M_ABORT || type == M_ERROR_TERM) { #ifndef HAVE_WIN32 fputs(dt, stdout); - fputs(msg, stdout); /* print this here to INSURE that it is printed */ + fputs(msg, stdout); /* print this here to INSURE that it is printed */ fflush(stdout); #endif } @@ -602,138 +602,138 @@ void dispatch_message(JCR *jcr, int type, time_t mtime, char *msg) } for (d=msgs->dest_chain; d; d=d->next) { if (bit_is_set(type, d->msg_types)) { - switch (d->dest_code) { - case MD_CONSOLE: + switch (d->dest_code) { + case MD_CONSOLE: Dmsg1(850, "CONSOLE for following msg: %s", msg); - if (!con_fd) { + if (!con_fd) { con_fd = fopen(con_fname, "a+"); Dmsg0(850, "Console file not open.\n"); - } - if (con_fd) { - Pw(con_lock); /* get write lock on console message file */ - errno = 0; - if (dtlen) { - fwrite(dt, dtlen, 1, con_fd); - } - len = strlen(msg); - if (len > 0) { - fwrite(msg, len, 1, con_fd); + } + if (con_fd) { + Pw(con_lock); /* get write lock on console message file */ + errno = 0; + if (dtlen) { + fwrite(dt, dtlen, 1, con_fd); + } + len = strlen(msg); + if (len > 0) { + fwrite(msg, len, 1, con_fd); if (msg[len-1] != '\n') { fwrite("\n", 2, 1, con_fd); - } - } else { + } + } else { fwrite("\n", 2, 1, con_fd); - } - fflush(con_fd); - console_msg_pending = TRUE; - Vw(con_lock); - } - break; - case MD_SYSLOG: + } + fflush(con_fd); + console_msg_pending = TRUE; + Vw(con_lock); + } + break; + case MD_SYSLOG: Dmsg1(850, "SYSLOG for collowing msg: %s\n", msg); - /* - * We really should do an openlog() here. - */ + /* + * We really should do an openlog() here. + */ syslog(LOG_DAEMON|LOG_ERR, "%s", msg); - break; - case MD_OPERATOR: + break; + case MD_OPERATOR: Dmsg1(850, "OPERATOR for following msg: %s\n", msg); - mcmd = get_pool_memory(PM_MESSAGE); - if ((bpipe=open_mail_pipe(jcr, mcmd, d))) { - int stat; - fputs(dt, bpipe->wfd); - fputs(msg, bpipe->wfd); - /* Messages to the operator go one at a time */ - stat = close_bpipe(bpipe); - if (stat != 0) { - berrno be; - be.set_errno(stat); + mcmd = get_pool_memory(PM_MESSAGE); + if ((bpipe=open_mail_pipe(jcr, mcmd, d))) { + int stat; + fputs(dt, bpipe->wfd); + fputs(msg, bpipe->wfd); + /* Messages to the operator go one at a time */ + stat = close_bpipe(bpipe); + if (stat != 0) { + berrno be; + be.set_errno(stat); Qmsg2(jcr, M_ERROR, 0, _("Operator mail program terminated in error.\n" "CMD=%s\n" "ERR=%s\n"), mcmd, be.strerror()); - } - } - free_pool_memory(mcmd); - break; - case MD_MAIL: - case MD_MAIL_ON_ERROR: + } + } + free_pool_memory(mcmd); + break; + case MD_MAIL: + case MD_MAIL_ON_ERROR: Dmsg1(850, "MAIL for following msg: %s", msg); - if (!d->fd) { - POOLMEM *name = get_pool_memory(PM_MESSAGE); - make_unique_mail_filename(jcr, name, d); + if (!d->fd) { + POOLMEM *name = get_pool_memory(PM_MESSAGE); + make_unique_mail_filename(jcr, name, d); d->fd = fopen(name, "w+"); - if (!d->fd) { - berrno be; - d->fd = stdout; + if (!d->fd) { + berrno be; + d->fd = stdout; Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", name, - be.strerror()); - d->fd = NULL; - free_pool_memory(name); - break; - } - d->mail_filename = name; - } - fputs(dt, d->fd); - len = strlen(msg) + dtlen;; - if (len > d->max_len) { - d->max_len = len; /* keep max line length */ - } - fputs(msg, d->fd); - break; - case MD_FILE: + be.strerror()); + d->fd = NULL; + free_pool_memory(name); + break; + } + d->mail_filename = name; + } + fputs(dt, d->fd); + len = strlen(msg) + dtlen;; + if (len > d->max_len) { + d->max_len = len; /* keep max line length */ + } + fputs(msg, d->fd); + break; + case MD_FILE: Dmsg1(850, "FILE for following msg: %s", msg); - if (!d->fd) { + if (!d->fd) { d->fd = fopen(d->where, "w+"); - if (!d->fd) { - berrno be; - d->fd = stdout; + if (!d->fd) { + berrno be; + d->fd = stdout; Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, - be.strerror()); - d->fd = NULL; - break; - } - } - fputs(dt, d->fd); - fputs(msg, d->fd); - break; - case MD_APPEND: + be.strerror()); + d->fd = NULL; + break; + } + } + fputs(dt, d->fd); + fputs(msg, d->fd); + break; + case MD_APPEND: Dmsg1(850, "APPEND for following msg: %s", msg); - if (!d->fd) { + if (!d->fd) { d->fd = fopen(d->where, "a"); - if (!d->fd) { - berrno be; - d->fd = stdout; + if (!d->fd) { + berrno be; + d->fd = stdout; Qmsg2(jcr, M_ERROR, 0, "fopen %s failed: ERR=%s\n", d->where, - be.strerror()); - d->fd = NULL; - break; - } - } - fputs(dt, d->fd); - fputs(msg, d->fd); - break; - case MD_DIRECTOR: + be.strerror()); + d->fd = NULL; + break; + } + } + fputs(dt, d->fd); + fputs(msg, d->fd); + break; + case MD_DIRECTOR: Dmsg1(850, "DIRECTOR for following msg: %s", msg); - if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) { + if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) { bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s", - jcr->Job, type, mtime, msg); - } - break; - case MD_STDOUT: + jcr->Job, type, mtime, msg); + } + break; + case MD_STDOUT: Dmsg1(850, "STDOUT for following msg: %s", msg); - if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */ - fputs(dt, stdout); - fputs(msg, stdout); - } - break; - case MD_STDERR: + if (type != M_ABORT && type != M_ERROR_TERM) { /* already printed */ + fputs(dt, stdout); + fputs(msg, stdout); + } + break; + case MD_STDERR: Dmsg1(850, "STDERR for following msg: %s", msg); - fputs(dt, stderr); - fputs(msg, stderr); - break; - default: - break; - } + fputs(dt, stderr); + fputs(msg, stderr); + break; + default: + break; + } } } } @@ -765,14 +765,14 @@ d_msg(const char *file, int line, int level, const char *fmt,...) if (level <= debug_level) { #ifdef FULL_LOCATION if (details) { - /* visual studio passes the whole path to the file as well - * which makes for very long lines - */ + /* visual studio passes the whole path to the file as well + * which makes for very long lines + */ const char *f = strrchr(file, '\\'); - if (f) file = f + 1; + if (f) file = f + 1; len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line); } else { - len = 0; + len = 0; } #else len = 0; @@ -784,18 +784,22 @@ d_msg(const char *file, int line, int level, const char *fmt,...) /* * Used the "trace on" command in the console to turn on * output to the trace file. "trace off" will close the file. - */ + */ if (trace) { - if (!trace_fd) { - bsnprintf(buf, sizeof(buf), "%s/bacula.trace", working_directory ? working_directory : "."); - trace_fd = fopen(buf, "a+"); - } - if (trace_fd) { - fputs(buf, trace_fd); - fflush(trace_fd); - } + if (!trace_fd) { + char fn[200]; + bsnprintf(fn, sizeof(fn), "%s/bacula.trace", working_directory ? working_directory : "."); + trace_fd = fopen(fn, "a+"); + } + if (trace_fd) { + fputs(buf, trace_fd); + fflush(trace_fd); + } else { + /* Some problem, turn off tracing */ + trace = false; + } } else { /* not tracing */ - fputs(buf, stdout); + fputs(buf, stdout); } } } @@ -815,7 +819,7 @@ void set_trace(int trace_flag) if (!trace && trace_fd) { FILE *ltrace_fd = trace_fd; trace_fd = NULL; - bmicrosleep(0, 100000); /* yield to prevent seg faults */ + bmicrosleep(0, 100000); /* yield to prevent seg faults */ fclose(ltrace_fd); } } @@ -888,7 +892,7 @@ t_msg(const char *file, int line, int level, const char *fmt,...) if (details) { len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line); } else { - len = 0; + len = 0; } #else len = 0; @@ -897,8 +901,8 @@ t_msg(const char *file, int line, int level, const char *fmt,...) bvsnprintf(buf+len, sizeof(buf)-len, (char *)fmt, arg_ptr); va_end(arg_ptr); if (trace_fd != NULL) { - fputs(buf, trace_fd); - fflush(trace_fd); + fputs(buf, trace_fd); + fflush(trace_fd); } } } @@ -922,26 +926,26 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...) * We always report M_ABORT and M_ERROR_TERM */ if (!daemon_msgs || ((type != M_ABORT && type != M_ERROR_TERM) && - !bit_is_set(type, daemon_msgs->send_msg))) { - return; /* no destination */ + !bit_is_set(type, daemon_msgs->send_msg))) { + return; /* no destination */ } switch (type) { case M_ABORT: len = bsnprintf(buf, sizeof(buf), "%s: ABORTING due to ERROR in %s:%d\n", - my_name, file, line); + my_name, file, line); break; case M_ERROR_TERM: len = bsnprintf(buf, sizeof(buf), "%s: ERROR TERMINATION at %s:%d\n", - my_name, file, line); + my_name, file, line); break; case M_FATAL: - if (level == -1) /* skip details */ + if (level == -1) /* skip details */ len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error because: ", my_name); else len = bsnprintf(buf, sizeof(buf), "%s: Fatal Error at %s:%d because:\n", my_name, file, line); break; case M_ERROR: - if (level == -1) /* skip details */ + if (level == -1) /* skip details */ len = bsnprintf(buf, sizeof(buf), "%s: ERROR: ", my_name); else len = bsnprintf(buf, sizeof(buf), "%s: ERROR in %s:%d ", my_name, file, line); @@ -965,7 +969,7 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...) if (type == M_ABORT) { char *p = 0; - p[0] = 0; /* generate segmentation violation */ + p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { exit(1); @@ -990,14 +994,14 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) Dmsg1(850, "Enter Jmsg type=%d\n", type); /* Special case for the console, which has a dir_bsock and JobId==0, - * in that case, we send the message directly back to the - * dir_bsock. + * in that case, we send the message directly back to the + * dir_bsock. */ if (jcr && jcr->JobId == 0 && jcr->dir_bsock) { BSOCK *dir = jcr->dir_bsock; va_start(arg_ptr, fmt); dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg), - fmt, arg_ptr); + fmt, arg_ptr); va_end(arg_ptr); bnet_send(jcr->dir_bsock); return; @@ -1010,7 +1014,7 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) job = jcr->Job; } if (!msgs) { - msgs = daemon_msgs; /* if no jcr, we use daemon handler */ + msgs = daemon_msgs; /* if no jcr, we use daemon handler */ } if (!job) { job = ""; /* Set null job name if none */ @@ -1021,8 +1025,8 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) * We always report M_ABORT and M_ERROR_TERM */ if (msgs && (type != M_ABORT && type != M_ERROR_TERM) && - !bit_is_set(type, msgs->send_msg)) { - return; /* no destination */ + !bit_is_set(type, msgs->send_msg)) { + return; /* no destination */ } switch (type) { case M_ABORT: @@ -1034,13 +1038,13 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) case M_FATAL: len = bsnprintf(rbuf, sizeof(rbuf), "%s: %s Fatal error: ", my_name, job); if (jcr) { - set_jcr_job_status(jcr, JS_FatalError); + set_jcr_job_status(jcr, JS_FatalError); } break; case M_ERROR: len = bsnprintf(rbuf, sizeof(rbuf), "%s: %s Error: ", my_name, job); if (jcr) { - jcr->Errors++; + jcr->Errors++; } break; case M_WARNING: @@ -1062,7 +1066,7 @@ Jmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) if (type == M_ABORT){ char *p = 0; - p[0] = 0; /* generate segmentation violation */ + p[0] = 0; /* generate segmentation violation */ } if (type == M_ERROR_TERM) { exit(1); @@ -1088,8 +1092,8 @@ void j_msg(const char *file, int line, JCR *jcr, int type, time_t mtime, const c len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); - continue; + pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); + continue; } break; } @@ -1115,8 +1119,8 @@ int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...) len = bvsnprintf(*pool_buf+i, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2); - continue; + *pool_buf = realloc_pool_memory(*pool_buf, maxlen + i + maxlen/2); + continue; } break; } @@ -1136,8 +1140,8 @@ int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...) len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); - continue; + pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); + continue; } break; } @@ -1160,8 +1164,8 @@ int Mmsg(POOLMEM **pool_buf, const char *fmt, ...) len = bvsnprintf(*pool_buf, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2); - continue; + *pool_buf = realloc_pool_memory(*pool_buf, maxlen + maxlen/2); + continue; } break; } @@ -1179,8 +1183,8 @@ int Mmsg(POOLMEM *&pool_buf, const char *fmt, ...) len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2); - continue; + pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2); + continue; } break; } @@ -1198,8 +1202,8 @@ int Mmsg(POOL_MEM &pool_buf, const char *fmt, ...) len = bvsnprintf(pool_buf.c_str(), maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf.realloc_pm(maxlen + maxlen/2); - continue; + pool_buf.realloc_pm(maxlen + maxlen/2); + continue; } break; } @@ -1231,8 +1235,8 @@ void Qmsg(JCR *jcr, int type, time_t mtime, const char *fmt,...) len = bvsnprintf(pool_buf, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2); - continue; + pool_buf = realloc_pool_memory(pool_buf, maxlen + maxlen/2); + continue; } break; } @@ -1292,8 +1296,8 @@ void q_msg(const char *file, int line, JCR *jcr, int type, time_t mtime, const c len = bvsnprintf(pool_buf+i, maxlen, fmt, arg_ptr); va_end(arg_ptr); if (len < 0 || len >= (maxlen-5)) { - pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); - continue; + pool_buf = realloc_pool_memory(pool_buf, maxlen + i + maxlen/2); + continue; } break; } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 5addbd397b..75e140ae5f 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -71,11 +71,9 @@ bool bnet_send (BSOCK *bsock); bool bnet_fsend (BSOCK *bs, const char *fmt, ...); bool bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); bool bnet_sig (BSOCK *bs, int sig); -#ifdef HAVE_TLS int bnet_tls_server (TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list); int bnet_tls_client (TLS_CONTEXT *ctx, BSOCK *bsock); -#endif /* HAVE_TLS */ BSOCK * bnet_connect (JCR *jcr, int retry_interval, int max_retry_time, const char *name, char *host, char *service, int port, int verbose); diff --git a/bacula/src/lib/tree.c b/bacula/src/lib/tree.c index d094e4c473..6f34e3d7bb 100755 --- a/bacula/src/lib/tree.c +++ b/bacula/src/lib/tree.c @@ -26,7 +26,7 @@ /* Forward referenced subroutines */ static TREE_NODE *search_and_insert_tree_node(char *fname, int type, - TREE_ROOT *root, TREE_NODE *parent); + TREE_ROOT *root, TREE_NODE *parent); static char *tree_alloc(TREE_ROOT *root, int size); /* @@ -70,7 +70,7 @@ TREE_ROOT *new_tree(int count) TREE_ROOT *root; uint32_t size; - if (count < 1000) { /* minimum tree size */ + if (count < 1000) { /* minimum tree size */ count = 1000; } root = (TREE_ROOT *)malloc(sizeof(TREE_ROOT)); @@ -101,7 +101,6 @@ static TREE_NODE *new_tree_node(TREE_ROOT *root) return node; } -#ifdef USE_DLIST /* * This routine can be called to release the * previously allocated tree node. @@ -112,7 +111,6 @@ static void free_tree_node(TREE_ROOT *root) root->mem->rem += asize; root->mem->mem -= asize; } -#endif @@ -129,9 +127,9 @@ static char *tree_alloc(TREE_ROOT *root, int size) if (root->mem->rem < asize) { uint32_t mb_size; if (root->total_size >= 1000000) { - mb_size = 1000000; + mb_size = 1000000; } else { - mb_size = 100000; + mb_size = 100000; } malloc_buf(root, mb_size); } @@ -168,7 +166,7 @@ void free_tree(TREE_ROOT *root) * */ TREE_NODE *insert_tree_node(char *path, char *fname, int type, - TREE_ROOT *root, TREE_NODE *parent) + TREE_ROOT *root, TREE_NODE *parent) { char *p, *q; int path_len = strlen(path); @@ -181,52 +179,52 @@ TREE_NODE *insert_tree_node(char *path, char *fname, int type, if (path_len > 0) { q = path + path_len - 1; if (*q == '/') { - *q = 0; /* strip trailing slash */ + *q = 0; /* strip trailing slash */ } else { - q = NULL; /* no trailing slash */ + q = NULL; /* no trailing slash */ } } else { - q = NULL; /* no trailing slash */ + q = NULL; /* no trailing slash */ } /* If no filename, strip last component of path as "filename" */ if (*fname == 0) { p = strrchr(path, '/'); /* separate path and filename */ if (p) { - fname = p + 1; /* set new filename */ - *p = 0; /* terminate new path */ + fname = p + 1; /* set new filename */ + *p = 0; /* terminate new path */ } } else { p = NULL; } if (*fname) { - if (!parent) { /* if no parent, we need to make one */ + if (!parent) { /* if no parent, we need to make one */ Dmsg1(100, "make_tree_path for %s\n", path); - path_len = strlen(path); /* get new length */ - if (path_len == root->cached_path_len && - strcmp(path, root->cached_path) == 0) { - parent = root->cached_parent; - } else { - root->cached_path_len = path_len; - pm_strcpy(&root->cached_path, path); - parent = make_tree_path(path, root); - root->cached_parent = parent; - } + path_len = strlen(path); /* get new length */ + if (path_len == root->cached_path_len && + strcmp(path, root->cached_path) == 0) { + parent = root->cached_parent; + } else { + root->cached_path_len = path_len; + pm_strcpy(&root->cached_path, path); + parent = make_tree_path(path, root); + root->cached_parent = parent; + } Dmsg1(100, "parent=%s\n", parent->fname); } } else { fname = path; if (!parent) { - parent = (TREE_NODE *)root; - type = TN_DIR_NLS; + parent = (TREE_NODE *)root; + type = TN_DIR_NLS; } Dmsg1(100, "No / found: %s\n", path); } node = search_and_insert_tree_node(fname, 0, root, parent); - if (q) { /* if trailing slash on entry */ + if (q) { /* if trailing slash on entry */ *q = '/'; /* restore it */ } - if (p) { /* if slash in path trashed */ + if (p) { /* if slash in path trashed */ *p = '/'; /* restore full path */ } return node; @@ -250,7 +248,7 @@ TREE_NODE *make_tree_path(char *path, TREE_ROOT *root) p = strrchr(path, '/'); /* get last dir component of path */ if (p) { fname = p + 1; - *p = 0; /* terminate path */ + *p = 0; /* terminate path */ parent = make_tree_path(path, root); *p = '/'; /* restore full name */ } else { @@ -262,7 +260,6 @@ TREE_NODE *make_tree_path(char *path, TREE_ROOT *root) return node; } -#ifdef USE_DLIST static int node_compare(void *item1, void *item2) { TREE_NODE *tn1 = (TREE_NODE *)item1; @@ -274,21 +271,19 @@ static int node_compare(void *item1, void *item2) } return strcmp(tn1->fname, tn2->fname); } -#endif /* * See if the fname already exists. If not insert a new node for it. */ static TREE_NODE *search_and_insert_tree_node(char *fname, int type, - TREE_ROOT *root, TREE_NODE *parent) + TREE_ROOT *root, TREE_NODE *parent) { -#ifdef USE_DLIST TREE_NODE *node, *found_node; node = new_tree_node(root); node->fname = fname; - found_node = (TREE_NODE *)parent->child.unique_binary_insert(node, node_compare); - if (found_node != node) { /* already in list */ - free_tree_node(root); /* free node allocated above */ + found_node = (TREE_NODE *)parent->child.binary_insert(node, node_compare); + if (found_node != node) { /* already in list */ + free_tree_node(root); /* free node allocated above */ found_node->inserted = false; return found_node; } @@ -307,85 +302,11 @@ static TREE_NODE *search_and_insert_tree_node(char *fname, int type, root->last->next = node; root->last = node; } - node->inserted = true; /* inserted into tree */ - return node; - -#else - TREE_NODE *sibling, *last_sibling = NULL; - uint16_t fname_len = strlen(fname); - int cmp; - - /* Is it already a sibling? */ - foreach_child(sibling, parent) { - Dmsg2(000, "sibling->fname=%s fname=%s\n", sibling->fname, fname); - if (fname[0] > sibling->fname[0] || (cmp=strcmp(fname, sibling->fname)) > 0) { - last_sibling = sibling; - continue; - } - if (cmp < 0) { - /* Insert before current sibling */ - if (!node) { - node = new_tree_node(root); - } - node->sibling_ = sibling; - if (sibling == first_child(parent)) { /* if sibling was at head of list */ - parent->child_ = NULL; /* force parent to be updated below */ - } - Dmsg2(000, "insert before sibling->fname=%s fname=%s\n", sibling->fname, fname); - break; - } - /* Found it */ - sibling->inserted = false; /* already in tree */ - return sibling; - } - - - /* - * At this point, the fname is not found. We must add it - */ - if (!node) { - node = new_tree_node(root); - } - Dmsg1(000, "append_tree_node: %s\n", fname); - node->fname_len = fname_len; - node->fname = tree_alloc(root, node->fname_len + 1); - strcpy(node->fname, fname); - node->parent = parent; - node->type = type; - if (!tree_node_has_child(parent)) { - parent->child_ = node; - } else { - last_sibling->sibling_ = node; - } - - /* Maintain a linear chain of nodes */ - if (!root->first) { - root->first = node; - root->last = node; - } else { - root->last->next = node; - root->last = node; - } - node->inserted = true; /* inserted into tree */ + node->inserted = true; /* inserted into tree */ return node; -#endif -} -#ifdef SLOW_WAY -/* Moved to tree.h to eliminate subroutine call */ -TREE_NODE *first_tree_node(TREE_ROOT *root) -{ - return root->first; } -TREE_NODE *next_tree_node(TREE_NODE *node) -{ - return node->next; -} -#endif - - - int tree_getpath(TREE_NODE *node, char *buf, int buf_size) { if (!node) { @@ -395,7 +316,7 @@ int tree_getpath(TREE_NODE *node, char *buf, int buf_size) tree_getpath(node->parent, buf, buf_size); /* * Fixup for Win32. If we have a Win32 directory and - * there is only a / in the buffer, remove it since + * there is only a / in the buffer, remove it since * win32 names don't generally start with / */ if (node->type == TN_DIR_NLS && buf[0] == '/' && buf[1] == 0) { @@ -423,9 +344,9 @@ TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node) } if (strcmp(path, "..") == 0) { if (node->parent) { - return node->parent; + return node->parent; } else { - return node; + return node; } } if (path[0] == '/') { @@ -460,8 +381,8 @@ TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node) foreach_child(cd, node) { Dmsg1(100, "tree_relcwd: test cd=%s\n", cd->fname); if (cd->fname[0] == path[0] && len == (int)strlen(cd->fname) - && strncmp(cd->fname, path, len) == 0) { - break; + && strncmp(cd->fname, path, len) == 0) { + break; } } if (!cd || (cd->type == TN_FILE && !tree_node_has_child(cd))) { @@ -545,32 +466,32 @@ void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent) } while ((dir = readdir(dp))) { if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) { - continue; + continue; } bstrncpy(file, dir->d_name, sizeof(file)); snprintf(pathbuf, MAXPATHLEN-1, "%s/%s", path, file); if (lstat(pathbuf, &statbuf) < 0) { printf("lstat() failed. ERR=%s\n", strerror(errno)); - continue; + continue; } // printf("got file=%s, pathbuf=%s\n", file, pathbuf); type = TN_FILE; if (S_ISLNK(statbuf.st_mode)) - type = TN_FILE; /* link */ + type = TN_FILE; /* link */ else if (S_ISREG(statbuf.st_mode)) - type = TN_FILE; + type = TN_FILE; else if (S_ISDIR(statbuf.st_mode)) { - type = TN_DIR; + type = TN_DIR; } else if (S_ISCHR(statbuf.st_mode)) - type = TN_FILE; /* char dev */ + type = TN_FILE; /* char dev */ else if (S_ISBLK(statbuf.st_mode)) - type = TN_FILE; /* block dev */ + type = TN_FILE; /* block dev */ else if (S_ISFIFO(statbuf.st_mode)) - type = TN_FILE; /* fifo */ + type = TN_FILE; /* fifo */ else if (S_ISSOCK(statbuf.st_mode)) - type = TN_FILE; /* sock */ + type = TN_FILE; /* sock */ else { - type = TN_FILE; + type = TN_FILE; printf("Unknown file type: 0x%x\n", statbuf.st_mode); } @@ -580,7 +501,7 @@ void FillDirectoryTree(char *path, TREE_ROOT *root, TREE_NODE *parent) parent = insert_tree_node(pathbuf, node, root, parent); if (S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) { Dmsg2(100, "calling fill. pathbuf=%s, file=%s\n", pathbuf, file); - FillDirectoryTree(pathbuf, root, node); + FillDirectoryTree(pathbuf, root, node); } } closedir(dp); diff --git a/bacula/src/lib/tree.h b/bacula/src/lib/tree.h index 5c7f39e978..2108f6ab51 100644 --- a/bacula/src/lib/tree.h +++ b/bacula/src/lib/tree.h @@ -5,42 +5,37 @@ * */ /* - Copyright (C) 2002-2004 Kern Sibbald and John Walker + Copyright (C) 2002-2005 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 ammended 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. */ struct s_mem { - struct s_mem *next; /* next buffer */ - int rem; /* remaining bytes */ - char *mem; /* memory pointer */ - char first[1]; /* first byte */ + struct s_mem *next; /* next buffer */ + int rem; /* remaining bytes */ + char *mem; /* memory pointer */ + char first[1]; /* first byte */ }; #define USE_DLIST -#ifdef USE_DLIST + #define foreach_child(var, list) \ for((var)=NULL; (*((TREE_NODE **)&(var))=(TREE_NODE*)(list->child.next(var))); ) #define tree_node_has_child(node) \ - ((node)->child.size() > 0) + ((node)->child.size() > 0) #define first_child(node) \ - ((TREE_NODE *)(node->child.first()) + ((TREE_NODE *)(node->child.first()) /* @@ -52,18 +47,18 @@ struct s_tree_node { * do initialization of child */ dlink sibling; dlist child; - char *fname; /* file name */ - int32_t FileIndex; /* file index */ - uint32_t JobId; /* JobId */ - uint16_t fname_len; /* filename length */ - int type: 8; /* node type */ - unsigned int extract: 1; /* extract item */ + char *fname; /* file name */ + int32_t FileIndex; /* file index */ + uint32_t JobId; /* JobId */ + uint16_t fname_len; /* filename length */ + int type: 8; /* node type */ + unsigned int extract: 1; /* extract item */ unsigned int extract_dir: 1; /* extract dir entry only */ - unsigned int hard_link: 1; /* set if have hard link */ - unsigned int soft_link: 1; /* set if is soft link */ - unsigned int inserted: 1; /* set when newly inserted */ + unsigned int hard_link: 1; /* set if have hard link */ + unsigned int soft_link: 1; /* set if is soft link */ + unsigned int inserted: 1; /* set when newly inserted */ struct s_tree_node *parent; - struct s_tree_node *next; /* next hash of FileIndex */ + struct s_tree_node *next; /* next hash of FileIndex */ }; typedef struct s_tree_node TREE_NODE; @@ -72,102 +67,42 @@ struct s_tree_root { * do initialization of child */ dlink sibling; dlist child; - const char *fname; /* file name */ - int32_t FileIndex; /* file index */ - uint32_t JobId; /* JobId */ - uint16_t fname_len; /* filename length */ - unsigned int type: 8; /* node type */ - unsigned int extract: 1; /* extract item */ + const char *fname; /* file name */ + int32_t FileIndex; /* file index */ + uint32_t JobId; /* JobId */ + uint16_t fname_len; /* filename length */ + unsigned int type: 8; /* node type */ + unsigned int extract: 1; /* extract item */ unsigned int extract_dir: 1; /* extract dir entry only */ - unsigned int have_link: 1; /* set if have hard link */ - unsigned int inserted: 1; /* set when newly inserted */ + unsigned int have_link: 1; /* set if have hard link */ + unsigned int inserted: 1; /* set when newly inserted */ struct s_tree_node *parent; - struct s_tree_node *next; /* next hash of FileIndex */ + struct s_tree_node *next; /* next hash of FileIndex */ /* The above ^^^ must be identical to a TREE_NODE structure */ - struct s_tree_node *first; /* first entry in the tree */ - struct s_tree_node *last; /* last entry in tree */ - struct s_mem *mem; /* tree memory */ - uint32_t total_size; /* total bytes allocated */ - uint32_t blocks; /* total mallocs */ - int cached_path_len; /* length of cached path */ - char *cached_path; /* cached current path */ - TREE_NODE *cached_parent; /* cached parent for above path */ + struct s_tree_node *first; /* first entry in the tree */ + struct s_tree_node *last; /* last entry in tree */ + struct s_mem *mem; /* tree memory */ + uint32_t total_size; /* total bytes allocated */ + uint32_t blocks; /* total mallocs */ + int cached_path_len; /* length of cached path */ + char *cached_path; /* cached current path */ + TREE_NODE *cached_parent; /* cached parent for above path */ }; typedef struct s_tree_root TREE_ROOT; -#else -#define foreach_child(cld, node) \ - for(cld=(node)->child_; cld; cld=cld->sibling_) - -#define tree_node_has_child(node) \ - ((node)->child_ != NULL) - -#define first_child(node) \ - ((node)->child_) - - -/* - * Keep this node as small as possible because - * there is one for each file. - */ -struct s_tree_node { - char *fname; /* file name */ - int32_t FileIndex; /* file index */ - uint32_t JobId; /* JobId */ - uint16_t fname_len; /* filename length */ - int type: 8; /* node type */ - unsigned int extract: 1; /* extract item */ - unsigned int extract_dir: 1; /* extract dir entry only */ - unsigned int hard_link: 1; /* set if have hard link */ - unsigned int soft_link: 1; /* set if is soft link */ - unsigned int inserted: 1; /* set when newly inserted */ - struct s_tree_node *parent; - struct s_tree_node *sibling_; - struct s_tree_node *next; /* next hash of FileIndex */ - struct s_tree_node *child_; -}; -typedef struct s_tree_node TREE_NODE; - -struct s_tree_root { - char *fname; /* file name */ - int32_t FileIndex; /* file index */ - uint32_t JobId; /* JobId */ - uint16_t fname_len; /* filename length */ - unsigned int type: 8; /* node type */ - unsigned int extract: 1; /* extract item */ - unsigned int extract_dir: 1; /* extract dir entry only */ - unsigned int have_link: 1; /* set if have hard link */ - unsigned int inserted: 1; /* set when newly inserted */ - struct s_tree_node *parent; - struct s_tree_node *sibling_; - struct s_tree_node *next; /* next hash of FileIndex */ - struct s_tree_node *child_; - - /* The above ^^^ must be identical to a TREE_NODE structure */ - struct s_tree_node *first; /* first entry in the tree */ - struct s_tree_node *last; /* last entry in tree */ - struct s_mem *mem; /* tree memory */ - uint32_t total_size; /* total bytes allocated */ - uint32_t blocks; /* total mallocs */ - int cached_path_len; /* length of cached path */ - char *cached_path; /* cached current path */ - TREE_NODE *cached_parent; /* cached parent for above path */ -}; -typedef struct s_tree_root TREE_ROOT; -#endif /* type values */ -#define TN_ROOT 1 /* root node */ -#define TN_NEWDIR 2 /* created directory to fill path */ -#define TN_DIR 3 /* directory entry */ -#define TN_DIR_NLS 4 /* directory -- no leading slash -- win32 */ -#define TN_FILE 5 /* file entry */ +#define TN_ROOT 1 /* root node */ +#define TN_NEWDIR 2 /* created directory to fill path */ +#define TN_DIR 3 /* directory entry */ +#define TN_DIR_NLS 4 /* directory -- no leading slash -- win32 */ +#define TN_FILE 5 /* file entry */ /* External interface */ TREE_ROOT *new_tree(int count); TREE_NODE *insert_tree_node(char *path, char *fname, int type, - TREE_ROOT *root, TREE_NODE *parent); + TREE_ROOT *root, TREE_NODE *parent); TREE_NODE *make_tree_path(char *path, TREE_ROOT *root); TREE_NODE *tree_cwd(char *path, TREE_ROOT *root, TREE_NODE *node); TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node); @@ -179,10 +114,5 @@ int tree_getpath(TREE_NODE *node, char *buf, int buf_size); * traversed in the order the entries were inserted into the * tree. */ -#ifdef SLOW_WAY -TREE_NODE *first_tree_node(TREE_ROOT *root); -TREE_NODE *next_tree_node(TREE_NODE *node); -#else - #define first_tree_node(r) (r)->first - #define next_tree_node(n) (n)->next -#endif +#define first_tree_node(r) (r)->first +#define next_tree_node(n) (n)->next diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 4b9122644c..8529b29f6c 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -247,7 +247,7 @@ default_path: /* If the device requires mount, close it, so the device can be ejected. * FIXME: This should perhaps be done for all devices. */ if (dev_cap(dev, CAP_REQMOUNT)) { - force_close_dev(dev); + force_close_device(dev); } /* Call autochanger only once unless ask_sysop called */ @@ -477,7 +477,7 @@ bool release_device(DCR *dcr) /* If no writers, close if file or !CAP_ALWAYS_OPEN */ if (dev->num_writers == 0 && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) { offline_or_rewind_dev(dev); - close_dev(dev); + close_device(dev); } /* Fire off Alert command and include any output */ diff --git a/bacula/src/stored/ansi_label.c b/bacula/src/stored/ansi_label.c index 46bb03f05a..09370935d8 100644 --- a/bacula/src/stored/ansi_label.c +++ b/bacula/src/stored/ansi_label.c @@ -13,19 +13,14 @@ Copyright (C) 2005 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 ammended 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. */ @@ -48,18 +43,18 @@ static bool same_label_names(char *bacula_name, char *ansi_name); * point, all is good. * * Returns: - * VOL_OK Volume name OK - * VOL_NO_LABEL No ANSI label on Volume - * VOL_IO_ERROR I/O error on read - * VOL_NAME_ERROR Wrong name in VOL1 record - * VOL_LABEL_ERROR Probably an ANSI label, but something wrong - * + * VOL_OK Volume name OK + * VOL_NO_LABEL No ANSI label on Volume + * VOL_IO_ERROR I/O error on read + * VOL_NAME_ERROR Wrong name in VOL1 record + * VOL_LABEL_ERROR Probably an ANSI label, but something wrong + * */ int read_ansi_ibm_label(DCR *dcr) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; - char label[80]; /* tape label */ + char label[80]; /* tape label */ int stat, i; char *VolName = dcr->VolumeName; bool ok = false; @@ -79,106 +74,107 @@ int read_ansi_ibm_label(DCR *dcr) /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */ for (i=0; i < 6; i++) { do { - stat = read(dev->fd, label, sizeof(label)); + stat = read(dev->fd, label, sizeof(label)); } while (stat == -1 && errno == EINTR); if (stat < 0) { - berrno be; - clrerror_dev(dev, -1); + berrno be; + clrerror_dev(dev, -1); Dmsg1(100, "Read device got: ERR=%s\n", be.strerror()); Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"), - dev->dev_name, be.strerror()); + dev->dev_name, be.strerror()); Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); - dev->VolCatInfo.VolCatErrors++; - return VOL_IO_ERROR; + dev->VolCatInfo.VolCatErrors++; + return VOL_IO_ERROR; } if (stat == 0) { - if (dev->at_eof()) { - dev->state |= ST_EOT; + if (dev->at_eof()) { + dev->state |= ST_EOT; Dmsg0(100, "EOM on ANSI label\n"); Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n")); return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */ - } else { - dev->set_eof(); - } + } else { + dev->set_eof(); + } } switch (i) { - case 0: /* Want VOL1 label */ - if (stat == 80) { + case 0: /* Want VOL1 label */ + if (stat == 80) { if (strncmp("VOL1", label, 4) == 0) { - ok = true; - dev->label_type = B_ANSI_LABEL; - } else { - /* Try EBCDIC */ - ebcdic_to_ascii(label, label, sizeof(label)); + ok = true; + dev->label_type = B_ANSI_LABEL; + } else { + /* Try EBCDIC */ + ebcdic_to_ascii(label, label, sizeof(label)); if (strncmp("VOL1", label, 4) == 0) { - ok = true;; - dev->label_type = B_IBM_LABEL; - } - } - } - if (!ok) { + ok = true;; + dev->label_type = B_IBM_LABEL; + } + } + } + if (!ok) { Dmsg0(100, "No VOL1 label\n"); Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n")); - return VOL_NO_LABEL; /* No ANSI label */ - } + return VOL_NO_LABEL; /* No ANSI label */ + } - /* Compare Volume Names allow special wild card */ + /* Compare Volume Names allow special wild card */ if (VolName && *VolName && *VolName != '*') { - if (!same_label_names(VolName, &label[4])) { - char *p = &label[4]; - char *q = dev->VolHdr.VolName; + if (!same_label_names(VolName, &label[4])) { + char *p = &label[4]; + char *q = dev->VolHdr.VolName; for (int i=0; *p != ' ' && i < 6; i++) { - *q++ = *p++; - } - *q = 0; + *q++ = *p++; + } + *q = 0; + new_volume(dev->VolHdr.VolName, dev); Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName); Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolName); - return VOL_NAME_ERROR; - } - } - break; + return VOL_NAME_ERROR; + } + } + break; case 1: - if (dev->label_type == B_IBM_LABEL) { - ebcdic_to_ascii(label, label, sizeof(label)); - } + if (dev->label_type == B_IBM_LABEL) { + ebcdic_to_ascii(label, label, sizeof(label)); + } if (stat != 80 || strncmp("HDR1", label, 4) != 0) { Dmsg0(100, "No HDR1 label\n"); Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n")); - return VOL_LABEL_ERROR; - } + return VOL_LABEL_ERROR; + } if (strncmp("BACULA.DATA", &label[4], 11) != 0) { Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n", - &label[4]); + &label[4]); Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"), - dev->VolHdr.VolName); - return VOL_NAME_ERROR; /* Not a Bacula label */ - } - break; + dev->VolHdr.VolName); + return VOL_NAME_ERROR; /* Not a Bacula label */ + } + break; case 2: - if (dev->label_type == B_IBM_LABEL) { - ebcdic_to_ascii(label, label, sizeof(label)); - } + if (dev->label_type == B_IBM_LABEL) { + ebcdic_to_ascii(label, label, sizeof(label)); + } if (stat != 80 || strncmp("HDR2", label, 4) != 0) { Dmsg0(100, "No HDR2 label\n"); Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n")); - return VOL_LABEL_ERROR; - } - break; + return VOL_LABEL_ERROR; + } + break; default: - if (stat == 0) { + if (stat == 0) { Dmsg0(100, "ANSI label OK\n"); - return VOL_OK; - } - if (dev->label_type == B_IBM_LABEL) { - ebcdic_to_ascii(label, label, sizeof(label)); - } + return VOL_OK; + } + if (dev->label_type == B_IBM_LABEL) { + ebcdic_to_ascii(label, label, sizeof(label)); + } if (stat != 80 || strncmp("HDR", label, 3) != 0) { Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n"); Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n")); - return VOL_LABEL_ERROR; - } - break; + return VOL_LABEL_ERROR; + } + break; } } Dmsg0(100, "Too many records in ANSI/IBM label.\n"); @@ -189,58 +185,58 @@ int read_ansi_ibm_label(DCR *dcr) /* * ANSI/IBM VOL1 label * 80 characters blank filled - * Pos count Function What Bacula puts + * Pos count Function What Bacula puts * 0-3 4 "VOL1" VOL1 - * 4-9 6 Volume name Volume name - * 10-10 1 Access code - * 11-36 26 Unused + * 4-9 6 Volume name Volume name + * 10-10 1 Access code + * 11-36 26 Unused * * ANSI - * 37-50 14 Owner - * 51-78 28 reserved - * 79 1 ANSI level 3 + * 37-50 14 Owner + * 51-78 28 reserved + * 79 1 ANSI level 3 * * IBM - * 37-40 4 reserved - * 41-50 10 Owner - * 51-79 29 reserved + * 37-40 4 reserved + * 41-50 10 Owner + * 51-79 29 reserved * * * ANSI/IBM HDR1 label * 80 characters blank filled - * Pos count Function What Bacula puts + * Pos count Function What Bacula puts * 0-3 4 "HDR1" HDR1 - * 4-20 17 File name BACULA.DATA - * 21-26 6 Volume name Volume name - * 27-30 4 Vol seq num 0001 - * 31-34 4 file num 0001 - * 35-38 4 Generation 0001 - * 39-40 2 Gen version 00 - * 41-46 6 Create date bYYDDD yesterday - * 47-52 6 Expire date bYYDDD today - * 53-53 1 Access - * 54-59 6 Block count 000000 - * 60-72 13 Software name Bacula - * 73-79 7 Reserved + * 4-20 17 File name BACULA.DATA + * 21-26 6 Volume name Volume name + * 27-30 4 Vol seq num 0001 + * 31-34 4 file num 0001 + * 35-38 4 Generation 0001 + * 39-40 2 Gen version 00 + * 41-46 6 Create date bYYDDD yesterday + * 47-52 6 Expire date bYYDDD today + * 53-53 1 Access + * 54-59 6 Block count 000000 + * 60-72 13 Software name Bacula + * 73-79 7 Reserved * ANSI/IBM HDR2 label * 80 characters blank filled - * Pos count Function What Bacula puts + * Pos count Function What Bacula puts * 0-3 4 "HDR2" HDR2 - * 4-4 1 Record format D (V if IBM) => variable - * 5-9 5 Block length 32000 - * 10-14 5 Rec length 32000 - * 15-15 1 Density - * 16-16 1 Continued - * 17-33 17 Job - * 34-35 2 Recording - * 36-36 1 cr/lf ctl - * 37-37 1 reserved - * 38-38 1 Blocked flag - * 39-49 11 reserved - * 50-51 2 offset - * 52-79 28 reserved + * 4-4 1 Record format D (V if IBM) => variable + * 5-9 5 Block length 32000 + * 10-14 5 Rec length 32000 + * 15-15 1 Density + * 16-16 1 Continued + * 17-33 17 Job + * 34-35 2 Recording + * 36-36 1 cr/lf ctl + * 37-37 1 reserved + * 38-38 1 Blocked flag + * 39-49 11 reserved + * 50-51 2 offset + * 52-79 28 reserved */ @@ -251,14 +247,14 @@ static const char *labels[] = {"HDR", "EOF", "EOV"}; * Type determines whether we are writing HDR, EOF, or EOV labels * Assume we are positioned to write the labels * Returns: true of OK - * false if error + * false if error */ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; - char label[80]; /* tape label */ - char date[20]; /* ansi date buffer */ + char label[80]; /* tape label */ + char date[20]; /* ansi date buffer */ time_t now; int len, stat, label_type; @@ -282,26 +278,26 @@ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) len = strlen(VolName); if (len > 6) { Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"), - VolName); - return false; + VolName); + return false; } if (type == ANSI_VOL_LABEL) { - ser_begin(label, sizeof(label)); + ser_begin(label, sizeof(label)); ser_bytes("VOL1", 4); - ser_bytes(VolName, len); - /* Write VOL1 label */ - if (label_type == B_IBM_LABEL) { - ascii_to_ebcdic(label, label, sizeof(label)); - } else { + ser_bytes(VolName, len); + /* Write VOL1 label */ + if (label_type == B_IBM_LABEL) { + ascii_to_ebcdic(label, label, sizeof(label)); + } else { label[79] = '3'; /* ANSI label flag */ - } - stat = write(dev->fd, label, sizeof(label)); - if (stat != sizeof(label)) { - berrno be; + } + stat = write(dev->fd, label, sizeof(label)); + if (stat != sizeof(label)) { + berrno be; Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"), - be.strerror()); - return false; - } + be.strerror()); + return false; + } } /* Now construct HDR1 label */ @@ -311,7 +307,7 @@ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) ser_bytes("1", 1); ser_bytes("BACULA.DATA", 11); /* Filename field */ ser_begin(&label[21], sizeof(label)-21); /* fileset field */ - ser_bytes(VolName, len); /* write Vol Ser No. */ + ser_bytes(VolName, len); /* write Vol Ser No. */ ser_begin(&label[27], sizeof(label)-27); ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */ now = time(NULL); @@ -320,14 +316,14 @@ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) ser_bytes(" 000000Bacula ", 27); /* Write HDR1 label */ if (label_type == B_IBM_LABEL) { - ascii_to_ebcdic(label, label, sizeof(label)); + ascii_to_ebcdic(label, label, sizeof(label)); } stat = write(dev->fd, label, sizeof(label)); if (stat != sizeof(label)) { - berrno be; + berrno be; Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"), - be.strerror()); - return false; + be.strerror()); + return false; } @@ -339,18 +335,18 @@ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName) /* Write HDR2 label */ if (label_type == B_IBM_LABEL) { label[4] = 'V'; - ascii_to_ebcdic(label, label, sizeof(label)); + ascii_to_ebcdic(label, label, sizeof(label)); } stat = write(dev->fd, label, sizeof(label)); if (stat != sizeof(label)) { - berrno be; + berrno be; Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"), - be.strerror()); - return false; + be.strerror()); + return false; } if (weof_dev(dev, 1) < 0) { Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg); - return false; + return false; } return true; default: @@ -367,13 +363,13 @@ static bool same_label_names(char *bacula_name, char *ansi_name) /* Six characters max */ for (int i=0; i < 6; i++) { if (*a == *b) { - a++; - b++; - continue; + a++; + b++; + continue; } /* ANSI labels are blank filled, Bacula's are zero terminated */ if (*a == ' ' && *b == 0) { - return true; + return true; } return false; } diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 675f17b1f2..a3c9fef854 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -212,39 +212,6 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) return do_get_volume_info(dcr); } -/* - * Rewrite this to use a list, but need something to add - * and remove volumes from the list. - */ -static bool is_volume_in_use(JCR *jcr, const char *VolumeName) { - bool in_use = false; - JCR *njcr; - Dmsg2(300, "JobId=%d got possible Vol=%s\n", jcr->JobId, VolumeName); - /* - * Walk through all jobs and see if the volume is - * already mounted. If so, try a different one. - * This would be better done by walking through - * all the devices. - */ - foreach_jcr(njcr) { - if (jcr == njcr) { - free_jcr(njcr); - continue; /* us */ - } - Dmsg2(300, "Compare to JobId=%d using Vol=%s\n", njcr->JobId, njcr->dcr->VolumeName); - if (njcr->dcr && strcmp(VolumeName, njcr->dcr->VolumeName) == 0) { - in_use = true; - Dmsg1(400, "Vol in use by JobId=%u\n", njcr->JobId); - free_jcr(njcr); - break; - } - free_jcr(njcr); - } - return in_use; - } - - - /* * Get info on the next appendable volume in the Director's database * Returns: true on success @@ -257,6 +224,7 @@ bool dir_find_next_appendable_volume(DCR *dcr) { JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; + bool found = false; Dmsg0(200, "dir_find_next_appendable_volume\n"); /* @@ -272,9 +240,10 @@ bool dir_find_next_appendable_volume(DCR *dcr) unbash_spaces(dcr->pool_name); Dmsg1(100, ">dird: %s", dir->msg); if (do_get_volume_info(dcr)) { - if (is_volume_in_use(jcr, dcr->VolumeName)) { + if (is_volume_in_use(dcr->VolumeName)) { continue; } else { + found = true; break; } } else { @@ -282,8 +251,12 @@ bool dir_find_next_appendable_volume(DCR *dcr) return false; } } - Dmsg0(400, "dir_find_next_appendable_volume return true\n"); - return true; + if (found) { + Dmsg0(400, "dir_find_next_appendable_volume return true\n"); + new_volume(dcr->VolumeName, NULL); /* reserve volume */ + return true; + } + return false; } diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 6c8472fe75..28c7efc08f 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -80,7 +80,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) if (loaded != slot) { offline_or_rewind_dev(dev); /* We are going to load a new tape, so close the device */ - force_close_dev(dev); + force_close_device(dev); lock_changer(dcr); if (loaded != 0 && loaded != -1) { /* must unload drive */ Dmsg0(400, "Doing changer unload.\n"); @@ -241,7 +241,7 @@ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd) /* Yes, to get a good listing, we unload any volumes */ offline_or_rewind_dev(dev); /* We are going to load a new tape, so close the device */ - force_close_dev(dev); + force_close_device(dev); /* First unload any tape */ loaded = get_autochanger_loaded_slot(dcr); diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index 0ab339851f..d0e71c597c 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -275,6 +275,8 @@ bool dir_create_jobmedia_record(DCR *dcr) { return 1; } bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; } +bool free_volume(DEVICE *dev) { return true; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 1896397065..6e6c9d8817 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -458,6 +458,8 @@ bool dir_create_jobmedia_record(DCR *dcr) { return 1; } bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; } +bool free_volume(DEVICE *dev) { return true; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index e9ca15b5a4..9a72866e4c 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -429,6 +429,9 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} int generate_job_event(JCR *jcr, const char *event) { return 1; } +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; } +bool free_volume(DEVICE *dev) { return true; } + bool dir_ask_sysop_to_mount_volume(DCR *dcr) { diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 1adb1d2769..00a04fc9d7 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -1200,6 +1200,8 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} int generate_job_event(JCR *jcr, const char *event) { return 1; } +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; } +bool free_volume(DEVICE *dev) { return true; } bool dir_ask_sysop_to_mount_volume(DCR *dcr) { @@ -1209,7 +1211,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } - force_close_dev(dev); + force_close_device(dev); fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ", dcr->VolumeName, dev->print_name()); getchar(); diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 3d29100c0c..9af3ad2cf0 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -1046,7 +1046,7 @@ static int append_test() if (dev_cap(dev, CAP_TWOEOF)) { weofcmd(); } - force_close_dev(dev); /* release device */ + force_close_device(dev); /* release device */ if (!open_the_device()) { return -1; } @@ -1142,7 +1142,7 @@ try_again: dcr->VolCatInfo.Slot = loaded; offline_or_rewind_dev(dev); /* We are going to load a new tape, so close the device */ - force_close_dev(dev); + force_close_device(dev); Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"), loaded, dev->drive_index); changer = edit_device_codes(dcr, changer, @@ -1167,7 +1167,7 @@ try_again: changer = edit_device_codes(dcr, changer, dcr->device->changer_command, "load"); Dmsg1(100, "Changer=%s\n", changer); - force_close_dev(dev); + force_close_device(dev); status = run_program(changer, timeout, results); if (status == 0) { Pmsg2(-1, _("3303 Autochanger \"load slot %d %d\" status is OK.\n"), @@ -2048,15 +2048,15 @@ static void do_unfill() } autochanger = autoload_device(dcr, 1, NULL); if (!autochanger) { - force_close_dev(dev); + force_close_device(dev); get_cmd(_("Mount first tape. Press enter when ready: ")); } - free_vol_list(jcr); + free_restore_volume_list(jcr); jcr->dcr = new_dcr(jcr, dev); set_volume_name("TestVolume1", 1); jcr->bsr = NULL; - create_vol_list(jcr); - close_dev(dev); + create_restore_volume_list(jcr); + close_device(dev); dev->state &= ~(ST_READ|ST_APPEND); dev->num_writers = 0; if (!acquire_device_for_read(dcr)) { @@ -2109,13 +2109,13 @@ static void do_unfill() offline_dev(dev); } - free_vol_list(jcr); + free_restore_volume_list(jcr); set_volume_name("TestVolume2", 2); jcr->bsr = NULL; - create_vol_list(jcr); + create_restore_volume_list(jcr); autochanger = autoload_device(dcr, 1, NULL); if (!autochanger) { - force_close_dev(dev); + force_close_device(dev); get_cmd(_("Mount second tape. Press enter when ready: ")); } @@ -2625,7 +2625,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr) if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { offline_dev(dev); } - force_close_dev(dev); + force_close_device(dev); Pmsg1(-1, "%s", dev->errmsg); /* print reason */ if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) { fprintf(stderr, "Mount second Volume on device %s and press return when ready: ", @@ -2654,7 +2654,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) } autochanger = autoload_device(dcr, 1, NULL); if (!autochanger) { - force_close_dev(dev); + force_close_device(dev); fprintf(stderr, "Mount blank Volume on device %s and press return when ready: ", dev->print_name()); getchar(); @@ -2693,11 +2693,11 @@ static bool my_mount_next_read_volume(DCR *dcr) return false; } - free_vol_list(jcr); + free_restore_volume_list(jcr); set_volume_name("TestVolume2", 2); jcr->bsr = NULL; - create_vol_list(jcr); - close_dev(dev); + create_restore_volume_list(jcr); + close_device(dev); dev->clear_read(); if (!acquire_device_for_read(dcr)) { Pmsg2(0, "Cannot open Dev=%s, Vol=%s\n", dev->print_name(), dcr->VolumeName); @@ -2716,3 +2716,6 @@ static void set_volume_name(const char *VolName, int volnum) bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName)); dcr->VolCatInfo.Slot = volnum; } + +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; } +bool free_volume(DEVICE *dev) { return true; } diff --git a/bacula/src/stored/butil.c b/bacula/src/stored/butil.c index d1205ca27f..786b6bdad1 100644 --- a/bacula/src/stored/butil.c +++ b/bacula/src/stored/butil.c @@ -159,7 +159,7 @@ static DCR *setup_to_access_device(JCR *jcr, char *dev_name, } bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name)); - create_vol_list(jcr); + create_restore_volume_list(jcr); if (mode) { /* read only access? */ if (!acquire_device_for_read(dcr)) { @@ -198,7 +198,7 @@ static void my_free_jcr(JCR *jcr) jcr->fileset_md5 = NULL; } if (jcr->VolList) { - free_vol_list(jcr); + free_restore_volume_list(jcr); } if (jcr->dcr) { free_dcr(jcr->dcr); diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 48efb12346..227d11f717 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -2,18 +2,18 @@ * * dev.c -- low level operations on device (storage device) * - * Kern Sibbald, MM + * Kern Sibbald, MM * * NOTE!!!! None of these routines are reentrant. You must - * use lock_device() and unlock_device() at a higher level, - * or use the xxx_device() equivalents. By moving the - * thread synchronization to a higher level, we permit + * use lock_device() and unlock_device() at a higher level, + * or use the xxx_device() equivalents. By moving the + * thread synchronization to a higher level, we permit * the higher level routines to "seize" the device and - * to carry out operations without worrying about who - * set what lock (i.e. race conditions). + * to carry out operations without worrying about who + * set what lock (i.e. race conditions). * * Note, this is the device dependent code, and my have - * to be modified for each system, but is meant to + * to be modified for each system, but is meant to * be as "generic" as possible. * * The purpose of this code is to develop a SIMPLE Storage @@ -120,10 +120,10 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device) if (stat(device->device_name, &statp) < 0) { berrno be; if (dev) { - dev->dev_errno = errno; + dev->dev_errno = errno; } Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"), - device->device_name, be.strerror()); + device->device_name, be.strerror()); return NULL; } @@ -138,10 +138,10 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device) fifo = true; } else if (!(device->cap_bits & CAP_REQMOUNT)) { if (dev) { - dev->dev_errno = ENODEV; + dev->dev_errno = ENODEV; } Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory. st_mode=%x\n"), - device->device_name, statp.st_mode); + device->device_name, statp.st_mode); return NULL; } if (!dev) { @@ -198,11 +198,11 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device) */ if (dev->is_file() && device->cap_bits & CAP_REQMOUNT) { if (stat(device->mount_point, &statp) < 0) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Jmsg2(jcr, M_ERROR, 0, _("Unable to stat mount point %s: ERR=%s\n"), - device->mount_point, be.strerror()); - return NULL; + device->mount_point, be.strerror()); + return NULL; } if (!device->mount_command || !device->unmount_command) { Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n")); @@ -215,12 +215,12 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device) if (dev->max_block_size > 1000000) { Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"), - dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE); + dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE); dev->max_block_size = 0; } if (dev->max_block_size % TAPE_BSIZE != 0) { Jmsg2(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size.\n"), - dev->max_block_size, dev->print_name()); + dev->max_block_size, dev->print_name()); } dev->errmsg = get_pool_memory(PM_EMSG); @@ -269,7 +269,7 @@ init_dev(JCR *jcr, DEVICE *dev, DEVRES *device) * initialize buffer pointers. * * Returns: -1 on error - * fd on success + * fd on success * * Note, for a tape, the VolName is the name we give to the * volume (not really used here), but for a file, the @@ -282,9 +282,9 @@ open_dev(DEVICE *dev, char *VolName, int mode) { if (dev->is_open()) { if (dev->openmode == mode) { - return dev->fd; + return dev->fd; } else { - close(dev->fd); /* close so correct mode will be used */ + close(dev->fd); /* close so correct mode will be used */ } } if (VolName) { @@ -294,7 +294,7 @@ open_dev(DEVICE *dev, char *VolName, int mode) } Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev->is_tape(), - dev->dev_name, dev->VolCatInfo.VolCatName); + dev->dev_name, dev->VolCatInfo.VolCatName); dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF); dev->label_type = B_BACULA_LABEL; if (dev->is_tape() || dev->is_fifo()) { @@ -342,27 +342,27 @@ open_again: Dmsg2(500, "Open error errno=%d ERR=%s\n", errno, be.strerror()); if (errno == EINTR || errno == EAGAIN) { Dmsg0(500, "Continue open\n"); - continue; + continue; } /* Busy wait for specified time (default = 5 mins) */ if (errno == EBUSY && timeout-- > 0) { Dmsg2(100, "Device %s busy. ERR=%s\n", dev->print_name(), be.strerror()); - bmicrosleep(1, 0); - continue; + bmicrosleep(1, 0); + continue; } /* IO error (no volume) try 10 times every 6 seconds */ if (errno == EIO && ioerrcnt-- > 0) { - bmicrosleep(5, 0); + bmicrosleep(5, 0); Dmsg0(500, "Continue open\n"); - continue; + continue; } dev->dev_errno = errno; Mmsg2(dev->errmsg, _("Unable to open device %s: ERR=%s\n"), - dev->print_name(), be.strerror(dev->dev_errno)); + dev->print_name(), be.strerror(dev->dev_errno)); /* Stop any open timer we set */ if (dev->tid) { - stop_thread_timer(dev->tid); - dev->tid = 0; + stop_thread_timer(dev->tid); + dev->tid = 0; } Emsg0(M_FATAL, 0, dev->errmsg); break; @@ -370,16 +370,16 @@ open_again: if (dev->fd >= 0) { /* If opened in non-block mode, close it an open it normally */ if (nonblocking) { - nonblocking = 0; - close(dev->fd); - goto open_again; + nonblocking = 0; + close(dev->fd); + goto open_again; } - dev->openmode = mode; /* save open mode */ + dev->openmode = mode; /* save open mode */ dev->dev_errno = 0; dev->state |= ST_OPENED; dev->use_count = 1; - update_pos_dev(dev); /* update position */ - set_os_device_parameters(dev); /* do system dependent stuff */ + update_pos_dev(dev); /* update position */ + set_os_device_parameters(dev); /* do system dependent stuff */ Dmsg0(500, "Open OK\n"); } /* Stop any open() timer we started */ @@ -399,7 +399,7 @@ static void open_file_device(DEVICE *dev, int mode) struct stat filestat; /* * Handle opening of File Archive (not a tape) - */ + */ if (dev->part == 0) { dev->file_size = 0; } @@ -413,7 +413,7 @@ static void open_file_device(DEVICE *dev, int mode) if (dev->VolCatInfo.VolCatName[0] == 0) { Mmsg(dev->errmsg, _("Could not open file device %s. No Volume name given.\n"), - dev->print_name()); + dev->print_name()); dev->fd = -1; return; } @@ -421,18 +421,18 @@ static void open_file_device(DEVICE *dev, int mode) if (mount_dev(dev, 1) < 0) { Mmsg(dev->errmsg, _("Could not mount device %s.\n"), - dev->print_name()); + dev->print_name()); Emsg0(M_FATAL, 0, dev->errmsg); dev->fd = -1; return; } - + Dmsg2(29, "open_dev: device is disk %s (mode:%d)\n", archive_name.c_str(), mode); dev->openmode = mode; /* * If we are not trying to access the last part, set mode to - * OPEN_READ_ONLY as writing would be an error. + * OPEN_READ_ONLY as writing would be an error. */ if (dev->part < dev->num_parts) { mode = OPEN_READ_ONLY; @@ -452,21 +452,21 @@ static void open_file_device(DEVICE *dev, int mode) berrno be; dev->dev_errno = errno; Mmsg2(dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), - be.strerror()); + be.strerror()); Emsg0(M_FATAL, 0, dev->errmsg); } else { dev->dev_errno = 0; dev->state |= ST_OPENED; dev->use_count = 1; - update_pos_dev(dev); /* update position */ + update_pos_dev(dev); /* update position */ if (fstat(dev->fd, &filestat) < 0) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Mmsg2(dev->errmsg, _("Could not fstat: %s, ERR=%s\n"), archive_name.c_str(), - be.strerror()); - Emsg0(M_FATAL, 0, dev->errmsg); + be.strerror()); + Emsg0(M_FATAL, 0, dev->errmsg); } else { - dev->part_size = filestat.st_size; + dev->part_size = filestat.st_size; } } Dmsg4(29, "open_dev: disk fd=%d opened, part=%d/%d, part_size=%u\n", dev->fd, dev->part, dev->num_parts, dev->part_size); @@ -488,7 +488,7 @@ bool _rewind_dev(char *file, int line, DEVICE *dev) /* * Rewind the device. * Returns: true on success - * false on failure + * false on failure */ bool rewind_dev(DEVICE *dev) { @@ -499,7 +499,7 @@ bool rewind_dev(DEVICE *dev) if (dev->fd < 0) { dev->dev_errno = EBADF; Mmsg1(dev->errmsg, _("Bad call to rewind_dev. Device %s not open\n"), - dev->print_name()); + dev->print_name()); Emsg0(M_ABORT, 0, dev->errmsg); return false; } @@ -515,30 +515,30 @@ bool rewind_dev(DEVICE *dev) * retrying every 5 seconds. */ for (i=dev->max_rewind_wait; ; i -= 5) { - if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - berrno be; - clrerror_dev(dev, MTREW); - if (i == dev->max_rewind_wait) { + if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { + berrno be; + clrerror_dev(dev, MTREW); + if (i == dev->max_rewind_wait) { Dmsg1(200, "Rewind error, %s. retrying ...\n", be.strerror()); - } - if (dev->dev_errno == EIO && i > 0) { + } + if (dev->dev_errno == EIO && i > 0) { Dmsg0(200, "Sleeping 5 seconds.\n"); - bmicrosleep(5, 0); - continue; - } + bmicrosleep(5, 0); + continue; + } Mmsg2(dev->errmsg, _("Rewind error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return false; - } - break; + dev->print_name(), be.strerror()); + return false; + } + break; } } else if (dev->is_file()) { if (lseek_dev(dev, (off_t)0, SEEK_SET) < 0) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return false; + dev->print_name(), be.strerror()); + return false; } } return true; @@ -578,13 +578,13 @@ void DEVICE::set_eof() void DEVICE::set_eot() { state |= (ST_EOF|ST_EOT|ST_WEOT); - state &= ~ST_APPEND; /* make tape read-only */ + state &= ~ST_APPEND; /* make tape read-only */ } /* * Position device to end of medium (end of data) * Returns: true on succes - * false on error + * false on error */ bool eod_dev(DEVICE *dev) @@ -597,9 +597,14 @@ eod_dev(DEVICE *dev) if (dev->fd < 0) { dev->dev_errno = EBADF; Mmsg1(dev->errmsg, _("Bad call to eod_dev. Device %s not open\n"), - dev->print_name()); + dev->print_name()); return false; } + +#if defined (__digital__) && defined (__unix__) + return fsf_dev(dev, dev->VolCatInfo.VolCatFiles); +#endif + Dmsg0(29, "eod_dev\n"); if (dev->at_eot()) { return true; @@ -615,14 +620,14 @@ eod_dev(DEVICE *dev) pos = lseek_dev(dev, (off_t)0, SEEK_END); // Dmsg1(100, "====== Seek to %lld\n", pos); if (pos >= 0) { - update_pos_dev(dev); - dev->state |= ST_EOT; - return true; + update_pos_dev(dev); + dev->state |= ST_EOT; + return true; } dev->dev_errno = errno; berrno be; Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); return false; } #ifdef MTEOM @@ -630,9 +635,9 @@ eod_dev(DEVICE *dev) Dmsg0(100,"Using FAST FSF for EOM\n"); /* If unknown position, rewind */ if (!dev_get_os_pos(dev, &mt_stat)) { - if (!rewind_dev(dev)) { - return false; - } + if (!rewind_dev(dev)) { + return false; + } } mt_com.mt_op = MTFSF; /* @@ -641,33 +646,33 @@ eod_dev(DEVICE *dev) */ mt_com.mt_count = INT16_MAX; /* use big positive number */ if (mt_com.mt_count < 0) { - mt_com.mt_count = INT16_MAX; /* brain damaged system */ + mt_com.mt_count = INT16_MAX; /* brain damaged system */ } } if (dev_cap(dev, CAP_MTIOCGET) && (dev_cap(dev, CAP_FASTFSF) || dev_cap(dev, CAP_EOM))) { if (dev_cap(dev, CAP_EOM)) { Dmsg0(100,"Using EOM for EOM\n"); - mt_com.mt_op = MTEOM; - mt_com.mt_count = 1; + mt_com.mt_op = MTEOM; + mt_com.mt_count = 1; } if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - berrno be; - clrerror_dev(dev, mt_com.mt_op); + berrno be; + clrerror_dev(dev, mt_com.mt_op); Dmsg1(50, "ioctl error: %s\n", be.strerror()); - update_pos_dev(dev); + update_pos_dev(dev); Mmsg2(dev->errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return false; + dev->print_name(), be.strerror()); + return false; } if (!dev_get_os_pos(dev, &mt_stat)) { - berrno be; - clrerror_dev(dev, -1); + berrno be; + clrerror_dev(dev, -1); Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return false; + dev->print_name(), be.strerror()); + return false; } Dmsg2(100, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno); dev->set_eof(); @@ -680,7 +685,7 @@ eod_dev(DEVICE *dev) * Rewind then use FSF until EOT reached */ if (!rewind_dev(dev)) { - return false; + return false; } /* * Move file by file to the end of the tape @@ -688,24 +693,24 @@ eod_dev(DEVICE *dev) int file_num; for (file_num=dev->file; !dev->at_eot(); file_num++) { Dmsg0(200, "eod_dev: doing fsf 1\n"); - if (!fsf_dev(dev, 1)) { + if (!fsf_dev(dev, 1)) { Dmsg0(200, "fsf_dev error.\n"); - return false; - } - /* - * Avoid infinite loop. ***FIXME*** possibly add code - * to set EOD or to turn off CAP_FASTFSF if on. - */ - if (file_num == (int)dev->file) { - struct mtget mt_stat; + return false; + } + /* + * Avoid infinite loop. ***FIXME*** possibly add code + * to set EOD or to turn off CAP_FASTFSF if on. + */ + if (file_num == (int)dev->file) { + struct mtget mt_stat; Dmsg1(100, "fsf_dev did not advance from file %d\n", file_num); - if (dev_get_os_pos(dev, &mt_stat)) { + if (dev_get_os_pos(dev, &mt_stat)) { Dmsg2(100, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno); - dev->set_eof(); - dev->file = mt_stat.mt_fileno; - } - return false; - } + dev->set_eof(); + dev->file = mt_stat.mt_fileno; + } + return false; + } } } /* @@ -720,12 +725,12 @@ eod_dev(DEVICE *dev) /* If BSF worked and fileno is known (not -1), set file */ if (dev_get_os_pos(dev, &mt_stat)) { Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno); - dev->file = mt_stat.mt_fileno; + dev->file = mt_stat.mt_fileno; } else { - dev->file++; /* wing it -- not correct on all OSes */ + dev->file++; /* wing it -- not correct on all OSes */ } } else { - update_pos_dev(dev); /* update position */ + update_pos_dev(dev); /* update position */ } Dmsg1(200, "EOD dev->file=%d\n", dev->file); return ok; @@ -735,7 +740,7 @@ eod_dev(DEVICE *dev) * Set the position of the device -- only for files * For other devices, there is no generic way to do it. * Returns: true on succes - * false on error + * false on error */ bool update_pos_dev(DEVICE *dev) { @@ -755,14 +760,14 @@ bool update_pos_dev(DEVICE *dev) dev->file_addr = 0; pos = lseek_dev(dev, (off_t)0, SEEK_CUR); if (pos < 0) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Pmsg1(000, "Seek error: ERR=%s\n", be.strerror()); Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - ok = false; + dev->print_name(), be.strerror()); + ok = false; } else { - dev->file_addr = pos; + dev->file_addr = pos; } } return ok; @@ -796,49 +801,49 @@ uint32_t status_dev(DEVICE *dev) Pmsg0(-20," Bacula status:"); Pmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num); if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return 0; + dev->print_name(), be.strerror()); + return 0; } Pmsg0(-20, " Device status:"); #if defined(HAVE_LINUX_OS) if (GMT_EOF(mt_stat.mt_gstat)) { - stat |= BMT_EOF; + stat |= BMT_EOF; Pmsg0(-20, " EOF"); } if (GMT_BOT(mt_stat.mt_gstat)) { - stat |= BMT_BOT; + stat |= BMT_BOT; Pmsg0(-20, " BOT"); } if (GMT_EOT(mt_stat.mt_gstat)) { - stat |= BMT_EOT; + stat |= BMT_EOT; Pmsg0(-20, " EOT"); } if (GMT_SM(mt_stat.mt_gstat)) { - stat |= BMT_SM; + stat |= BMT_SM; Pmsg0(-20, " SM"); } if (GMT_EOD(mt_stat.mt_gstat)) { - stat |= BMT_EOD; + stat |= BMT_EOD; Pmsg0(-20, " EOD"); } if (GMT_WR_PROT(mt_stat.mt_gstat)) { - stat |= BMT_WR_PROT; + stat |= BMT_WR_PROT; Pmsg0(-20, " WR_PROT"); } if (GMT_ONLINE(mt_stat.mt_gstat)) { - stat |= BMT_ONLINE; + stat |= BMT_ONLINE; Pmsg0(-20, " ONLINE"); } if (GMT_DR_OPEN(mt_stat.mt_gstat)) { - stat |= BMT_DR_OPEN; + stat |= BMT_DR_OPEN; Pmsg0(-20, " DR_OPEN"); } if (GMT_IM_REP_EN(mt_stat.mt_gstat)) { - stat |= BMT_IM_REP_EN; + stat |= BMT_IM_REP_EN; Pmsg0(-20, " IM_REP_EN"); } #endif /* !SunOS && !OSF */ @@ -857,7 +862,7 @@ uint32_t status_dev(DEVICE *dev) /* * Load medium in device * Returns: true on success - * false on failure + * false on failure */ bool load_dev(DEVICE *dev) { @@ -877,9 +882,9 @@ bool load_dev(DEVICE *dev) #ifndef MTLOAD Dmsg0(200, "stored: MTLOAD command not available\n"); berrno be; - dev->dev_errno = ENOTTY; /* function not available */ + dev->dev_errno = ENOTTY; /* function not available */ Mmsg2(dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); return false; #else @@ -892,7 +897,7 @@ bool load_dev(DEVICE *dev) berrno be; dev->dev_errno = errno; Mmsg2(dev->errmsg, _("ioctl MTLOAD error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); return false; } return true; @@ -902,7 +907,7 @@ bool load_dev(DEVICE *dev) /* * Rewind device and put it offline * Returns: true on success - * false on failure + * false on failure */ bool offline_dev(DEVICE *dev) { @@ -934,7 +939,7 @@ bool offline_dev(DEVICE *dev) berrno be; dev->dev_errno = errno; Mmsg2(dev->errmsg, _("ioctl MTOFFL error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); return false; } Dmsg1(100, "Offlined device %s\n", dev->print_name()); @@ -964,7 +969,7 @@ bool offline_or_rewind_dev(DEVICE *dev) /* * Foward space a file * Returns: true on success - * false on failure + * false on failure */ bool fsf_dev(DEVICE *dev, int num) @@ -1006,14 +1011,14 @@ fsf_dev(DEVICE *dev, int num) mt_com.mt_count = num; stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com); if (stat < 0 || !dev_get_os_pos(dev, &mt_stat)) { - berrno be; - dev->state |= ST_EOT; + berrno be; + dev->state |= ST_EOT; Dmsg0(200, "Set ST_EOT\n"); - clrerror_dev(dev, MTFSF); + clrerror_dev(dev, MTFSF); Mmsg2(dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); Dmsg1(200, "%s", dev->errmsg); - return false; + return false; } Dmsg2(200, "fsf file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno); dev->set_eof(); @@ -1032,60 +1037,60 @@ fsf_dev(DEVICE *dev, int num) int rbuf_len; Dmsg0(200, "FSF has cap_fsf\n"); if (dev->max_block_size == 0) { - rbuf_len = DEFAULT_BLOCK_SIZE; + rbuf_len = DEFAULT_BLOCK_SIZE; } else { - rbuf_len = dev->max_block_size; + rbuf_len = dev->max_block_size; } rbuf = get_memory(rbuf_len); mt_com.mt_op = MTFSF; mt_com.mt_count = 1; while (num-- && !(dev->state & ST_EOT)) { Dmsg0(100, "Doing read before fsf\n"); - if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) { - if (errno == ENOMEM) { /* tape record exceeds buf len */ - stat = rbuf_len; /* This is OK */ - } else { - berrno be; - dev->state |= ST_EOT; - clrerror_dev(dev, -1); + if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) { + if (errno == ENOMEM) { /* tape record exceeds buf len */ + stat = rbuf_len; /* This is OK */ + } else { + berrno be; + dev->state |= ST_EOT; + clrerror_dev(dev, -1); Dmsg2(100, "Set ST_EOT read errno=%d. ERR=%s\n", dev->dev_errno, - be.strerror()); + be.strerror()); Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); Dmsg1(100, "%s", dev->errmsg); - break; - } - } - if (stat == 0) { /* EOF */ - update_pos_dev(dev); + break; + } + } + if (stat == 0) { /* EOF */ + update_pos_dev(dev); Dmsg1(100, "End of File mark from read. File=%d\n", dev->file+1); - /* Two reads of zero means end of tape */ - if (dev->state & ST_EOF) { - dev->state |= ST_EOT; + /* Two reads of zero means end of tape */ + if (dev->state & ST_EOF) { + dev->state |= ST_EOT; Dmsg0(100, "Set ST_EOT\n"); - break; - } else { - dev->set_eof(); - continue; - } - } else { /* Got data */ - dev->state &= ~(ST_EOF|ST_EOT); - } + break; + } else { + dev->set_eof(); + continue; + } + } else { /* Got data */ + dev->state &= ~(ST_EOF|ST_EOT); + } Dmsg0(100, "Doing MTFSF\n"); - stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com); - if (stat < 0) { /* error => EOT */ - berrno be; - dev->state |= ST_EOT; + stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com); + if (stat < 0) { /* error => EOT */ + berrno be; + dev->state |= ST_EOT; Dmsg0(100, "Set ST_EOT\n"); - clrerror_dev(dev, MTFSF); + clrerror_dev(dev, MTFSF); Mmsg2(dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); Dmsg0(100, "Got < 0 for MTFSF\n"); Dmsg1(100, "%s", dev->errmsg); - } else { - dev->set_eof(); - } + } else { + dev->set_eof(); + } } free_memory(rbuf); @@ -1095,14 +1100,14 @@ fsf_dev(DEVICE *dev, int num) } else { Dmsg0(200, "Doing FSR for FSF\n"); while (num-- && !(dev->state & ST_EOT)) { - dev->fsr(INT32_MAX); /* returns -1 on EOF or EOT */ + dev->fsr(INT32_MAX); /* returns -1 on EOF or EOT */ } if (dev->state & ST_EOT) { - dev->dev_errno = 0; + dev->dev_errno = 0; Mmsg1(dev->errmsg, _("Device %s at End of Tape.\n"), dev->print_name()); - stat = -1; + stat = -1; } else { - stat = 0; + stat = 0; } } update_pos_dev(dev); @@ -1118,7 +1123,7 @@ fsf_dev(DEVICE *dev, int num) /* * Backward space a file * Returns: false on failure - * true on success + * true on success */ bool bsf_dev(DEVICE *dev, int num) @@ -1135,7 +1140,7 @@ bsf_dev(DEVICE *dev, int num) if (!dev->is_tape()) { Mmsg1(dev->errmsg, _("Device %s cannot BSF because it is not a tape.\n"), - dev->print_name()); + dev->print_name()); return false; } Dmsg0(29, "bsf_dev\n"); @@ -1150,7 +1155,7 @@ bsf_dev(DEVICE *dev, int num) berrno be; clrerror_dev(dev, MTBSF); Mmsg2(dev->errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); } update_pos_dev(dev); return stat == 0; @@ -1160,7 +1165,7 @@ bsf_dev(DEVICE *dev, int num) /* * Foward space num records * Returns: false on failure - * true on success + * true on success */ bool DEVICE::fsr(int num) { @@ -1196,18 +1201,18 @@ bool DEVICE::fsr(int num) Dmsg1(100, "FSF fail: ERR=%s\n", be.strerror()); if (dev_get_os_pos(this, &mt_stat)) { Dmsg4(100, "Adjust from %d:%d to %d:%d\n", file, - block_num, mt_stat.mt_fileno, mt_stat.mt_blkno); - file = mt_stat.mt_fileno; - block_num = mt_stat.mt_blkno; + block_num, mt_stat.mt_fileno, mt_stat.mt_blkno); + file = mt_stat.mt_fileno; + block_num = mt_stat.mt_blkno; } else { - if (at_eof()) { - state |= ST_EOT; - } else { - set_eof(); - } + if (at_eof()) { + state |= ST_EOT; + } else { + set_eof(); + } } Mmsg3(errmsg, _("ioctl MTFSR %d error on %s. ERR=%s.\n"), - num, print_name(), be.strerror()); + num, print_name(), be.strerror()); } update_pos_dev(this); return stat == 0; @@ -1216,7 +1221,7 @@ bool DEVICE::fsr(int num) /* * Backward space a record * Returns: false on failure - * true on success + * true on success */ bool bsr_dev(DEVICE *dev, int num) @@ -1250,7 +1255,7 @@ bsr_dev(DEVICE *dev, int num) berrno be; clrerror_dev(dev, MTBSR); Mmsg2(dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); } update_pos_dev(dev); return stat == 0; @@ -1259,7 +1264,7 @@ bsr_dev(DEVICE *dev, int num) /* * Reposition the device to file, block * Returns: false on failure - * true on success + * true on success */ bool reposition_dev(DEVICE *dev, uint32_t file, uint32_t block) @@ -1275,11 +1280,11 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block) off_t pos = (((off_t)file)<<32) + block; Dmsg1(100, "===== lseek_dev to %d\n", (int)pos); if (lseek_dev(dev, pos, SEEK_SET) == (off_t)-1) { - berrno be; - dev->dev_errno = errno; + berrno be; + dev->dev_errno = errno; Mmsg2(dev->errmsg, _("lseek_dev error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); - return false; + dev->print_name(), be.strerror()); + return false; } dev->file = file; dev->block_num = block; @@ -1291,14 +1296,14 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block) if (file < dev->file) { Dmsg0(100, "Rewind_dev\n"); if (!rewind_dev(dev)) { - return false; + return false; } } if (file > dev->file) { Dmsg1(100, "fsf %d\n", file-dev->file); if (!fsf_dev(dev, file-dev->file)) { Dmsg1(100, "fsf failed! ERR=%s\n", strerror_dev(dev)); - return false; + return false; } Dmsg2(100, "wanted_file=%d at_file=%d\n", file, dev->file); } @@ -1323,7 +1328,7 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block) /* * Write an end of file on the device * Returns: 0 on success - * non-zero on failure + * non-zero on failure */ int weof_dev(DEVICE *dev, int num) @@ -1362,7 +1367,7 @@ weof_dev(DEVICE *dev, int num) clrerror_dev(dev, MTWEOF); if (stat == -1) { Mmsg2(dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); } } return stat; @@ -1392,7 +1397,7 @@ clrerror_dev(DEVICE *dev, int func) struct mtget mt_stat; char buf[100]; - dev->dev_errno = errno; /* save errno */ + dev->dev_errno = errno; /* save errno */ if (errno == EIO) { dev->VolCatInfo.VolCatErrors++; } @@ -1404,60 +1409,60 @@ clrerror_dev(DEVICE *dev, int func) switch (func) { case -1: Emsg0(M_ABORT, 0, "Got ENOTTY on read/write!\n"); - break; + break; case MTWEOF: msg = "WTWEOF"; - dev->capabilities &= ~CAP_EOF; /* turn off feature */ - break; + dev->capabilities &= ~CAP_EOF; /* turn off feature */ + break; #ifdef MTEOM case MTEOM: msg = "WTEOM"; - dev->capabilities &= ~CAP_EOM; /* turn off feature */ - break; + dev->capabilities &= ~CAP_EOM; /* turn off feature */ + break; #endif case MTFSF: msg = "MTFSF"; - dev->capabilities &= ~CAP_FSF; /* turn off feature */ - break; + dev->capabilities &= ~CAP_FSF; /* turn off feature */ + break; case MTBSF: msg = "MTBSF"; - dev->capabilities &= ~CAP_BSF; /* turn off feature */ - break; + dev->capabilities &= ~CAP_BSF; /* turn off feature */ + break; case MTFSR: msg = "MTFSR"; - dev->capabilities &= ~CAP_FSR; /* turn off feature */ - break; + dev->capabilities &= ~CAP_FSR; /* turn off feature */ + break; case MTBSR: msg = "MTBSR"; - dev->capabilities &= ~CAP_BSR; /* turn off feature */ - break; + dev->capabilities &= ~CAP_BSR; /* turn off feature */ + break; case MTREW: msg = "MTREW"; - break; + break; #ifdef MTSETBLK case MTSETBLK: msg = "MTSETBLK"; - break; + break; #endif #ifdef MTSETBSIZ case MTSETBSIZ: msg = "MTSETBSIZ"; - break; + break; #endif #ifdef MTSRSZ case MTSRSZ: msg = "MTSRSZ"; - break; + break; #endif default: bsnprintf(buf, sizeof(buf), "unknown func code %d", func); - msg = buf; - break; + msg = buf; + break; } if (msg != NULL) { - dev->dev_errno = ENOSYS; + dev->dev_errno = ENOSYS; Mmsg1(dev->errmsg, _("I/O function \"%s\" not supported on this device.\n"), msg); - Emsg0(M_ERROR, 0, dev->errmsg); + Emsg0(M_ERROR, 0, dev->errmsg); } } /* On some systems such as NetBSD, this clears all errors */ @@ -1528,7 +1533,7 @@ static void do_close(DEVICE *dev) get_filename(dev, dev->VolCatInfo.VolCatName, archive_name); /* Check that the part file is empty */ if ((stat(archive_name.c_str(), &statp) == 0) && (statp.st_size == 0)) { - unlink(archive_name.c_str()); + unlink(archive_name.c_str()); } } @@ -1556,46 +1561,23 @@ static void do_close(DEVICE *dev) /* * Close the device */ -void -close_dev(DEVICE *dev) +void DEVICE::close() { - if (!dev) { - Mmsg0(dev->errmsg, _("Bad call to close_dev. Device not open\n")); - Emsg0(M_FATAL, 0, dev->errmsg); - return; - } - /*if (dev->fd >= 0 && dev->use_count == 1) {*/ - /* No need to check if dev->fd >= 0: it is checked again + /*if (fd >= 0 && use_count == 1) {*/ + /* No need to check if fd >= 0: it is checked again * in do_close, and do_close MUST be called for volumes - * splitted in parts, even if dev->fd == -1. */ - if (dev->use_count == 1) { - do_close(dev); - } else if (dev->use_count > 0) { - dev->use_count--; + * splitted in parts, even if fd == -1. */ + if (use_count == 1) { + do_close(this); + } else if (use_count > 0) { + use_count--; } #ifdef FULL_DEBUG - ASSERT(dev->use_count >= 0); + ASSERT(use_count >= 0); #endif } -/* - * Used when unmounting the device, ignore use_count - */ -void force_close_dev(DEVICE *dev) -{ - if (!dev) { - Mmsg0(dev->errmsg, _("Bad call to force_close_dev. Device not open\n")); - Emsg0(M_FATAL, 0, dev->errmsg); - return; - } - Dmsg1(29, "Force close_dev %s\n", dev->print_name()); - do_close(dev); - -#ifdef FULL_DEBUG - ASSERT(dev->use_count >= 0); -#endif -} bool truncate_dev(DEVICE *dev) { @@ -1610,7 +1592,7 @@ bool truncate_dev(DEVICE *dev) dev->num_parts = 0; dev->VolCatInfo.VolCatParts = 0; if (open_first_part(dev) < 0) { - berrno be; + berrno be; Mmsg1(dev->errmsg, "Unable to truncate device, because I'm unable to open the first part. ERR=%s\n", be.strerror()); } } @@ -1698,7 +1680,7 @@ void init_device_wait_timers(DCR *dcr) /* ******FIXME******* put these on config variables */ dev->min_wait = 60 * 60; dev->max_wait = 24 * 60 * 60; - dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ + dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ dev->wait_sec = dev->min_wait; dev->rem_wait_sec = dev->wait_sec; dev->num_wait = 0; @@ -1707,7 +1689,7 @@ void init_device_wait_timers(DCR *dcr) jcr->min_wait = 60 * 60; jcr->max_wait = 24 * 60 * 60; - jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ + jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ jcr->wait_sec = jcr->min_wait; jcr->rem_wait_sec = jcr->wait_sec; jcr->num_wait = 0; @@ -1719,7 +1701,7 @@ void init_jcr_device_wait_timers(JCR *jcr) /* ******FIXME******* put these on config variables */ jcr->min_wait = 60 * 60; jcr->max_wait = 24 * 60 * 60; - jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ + jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */ jcr->wait_sec = jcr->min_wait; jcr->rem_wait_sec = jcr->wait_sec; jcr->num_wait = 0; @@ -1730,11 +1712,11 @@ void init_jcr_device_wait_timers(JCR *jcr) * The dev timers are used for waiting on a particular device * * Returns: true if time doubled - * false if max time expired + * false if max time expired */ bool double_dev_wait_time(DEVICE *dev) { - dev->wait_sec *= 2; /* double wait time */ + dev->wait_sec *= 2; /* double wait time */ if (dev->wait_sec > dev->max_wait) { /* but not longer than maxtime */ dev->wait_sec = dev->max_wait; } @@ -1756,18 +1738,18 @@ void set_os_device_parameters(DEVICE *dev) mt_com.mt_op = MTSETBLK; mt_com.mt_count = 0; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTSETBLK); + clrerror_dev(dev, MTSETBLK); } mt_com.mt_op = MTSETDRVBUFFER; mt_com.mt_count = MT_ST_CLEARBOOLEANS; if (!dev_cap(dev, CAP_TWOEOF)) { - mt_com.mt_count |= MT_ST_TWO_FM; + mt_com.mt_count |= MT_ST_TWO_FM; } if (dev_cap(dev, CAP_EOM)) { - mt_com.mt_count |= MT_ST_FAST_MTEOM; + mt_com.mt_count |= MT_ST_FAST_MTEOM; } if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTSETBLK); + clrerror_dev(dev, MTSETBLK); } } return; @@ -1780,13 +1762,13 @@ void set_os_device_parameters(DEVICE *dev) mt_com.mt_op = MTSETBSIZ; mt_com.mt_count = 0; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTSETBSIZ); + clrerror_dev(dev, MTSETBSIZ); } /* Get notified at logical end of tape */ mt_com.mt_op = MTEWARN; mt_com.mt_count = 1; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTEWARN); + clrerror_dev(dev, MTEWARN); } } return; @@ -1799,7 +1781,7 @@ void set_os_device_parameters(DEVICE *dev) mt_com.mt_op = MTSETBSIZ; mt_com.mt_count = 0; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTSETBSIZ); + clrerror_dev(dev, MTSETBSIZ); } } return; @@ -1812,7 +1794,7 @@ void set_os_device_parameters(DEVICE *dev) mt_com.mt_op = MTSRSZ; mt_com.mt_count = 0; if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) { - clrerror_dev(dev, MTSRSZ); + clrerror_dev(dev, MTSRSZ); } } return; @@ -1822,6 +1804,6 @@ void set_os_device_parameters(DEVICE *dev) static bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat) { return dev_cap(dev, CAP_MTIOCGET) && - ioctl(dev->fd, MTIOCGET, (char *)mt_stat) == 0 && - mt_stat->mt_fileno >= 0; + ioctl(dev->fd, MTIOCGET, (char *)mt_stat) == 0 && + mt_stat->mt_fileno >= 0; } diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 11c5bb9890..2988caf884 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -296,6 +296,7 @@ public: void clear_eof() { state &= ~ST_EOF; }; void block(int why); /* in dev.c */ void unblock(); /* in dev.c */ + void close(); /* in dev.c */ }; /* Note, these return int not bool! */ @@ -345,6 +346,16 @@ public: VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */ }; +/* + * Volume reservation class -- see reserve.c + */ +class VOLRES { +public: + dlink link; + char *vol_name; + DEVICE *dev; +}; + /* Get some definition of function to position * to the end of the medium in MTEOM. System diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 939ac7e9ff..097c353d44 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -32,19 +32,14 @@ Copyright (C) 2000-2005 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 ammended 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. */ @@ -310,6 +305,36 @@ bool open_device(DCR *dcr) return true; } +/* + * Release any Volume attached to this device + * then close the device. + */ +void close_device(DEVICE *dev) +{ + free_volume(dev); + dev->close(); +} + +/* + * Used when unmounting the device, ignore use_count + */ +void force_close_device(DEVICE *dev) +{ + if (!dev) { + Mmsg0(dev->errmsg, _("Bad call to force_close_dev. Device not open\n")); + Emsg0(M_FATAL, 0, dev->errmsg); + return; + } + Dmsg1(29, "Force close_dev %s\n", dev->print_name()); + dev->use_count = 1; + dev->close(); + +#ifdef FULL_DEBUG + ASSERT(dev->use_count >= 0); +#endif +} + + void dev_lock(DEVICE *dev) { int errstat; diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 1e4b3b4c1d..258773ed20 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -22,19 +22,14 @@ Copyright (C) 2001-2005 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 ammended 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. */ @@ -335,7 +330,7 @@ static bool do_label(JCR *jcr, int relabel) P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel); - force_close_dev(dev); + force_close_device(dev); /* Under certain "safe" conditions, we can steal the lock */ } else if (dev->can_steal_lock()) { label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel); @@ -669,7 +664,7 @@ static bool unmount_cmd(JCR *jcr) Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->dev_blocked); offline_or_rewind_dev(dev); - force_close_dev(dev); + force_close_device(dev); dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP; bnet_fsend(dir, _("3001 Device %s unmounted.\n"), dev->print_name()); @@ -695,7 +690,7 @@ static bool unmount_cmd(JCR *jcr) dev->dev_blocked = BST_UNMOUNTED; dev->no_wait_id = 0; offline_or_rewind_dev(dev); - force_close_dev(dev); + force_close_device(dev); bnet_fsend(dir, _("3002 Device %s unmounted.\n"), dev->print_name()); } @@ -838,7 +833,7 @@ static bool readlabel_cmd(JCR *jcr) P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { read_volume_label(jcr, dev, Slot); - force_close_dev(dev); + force_close_device(dev); /* Under certain "safe" conditions, we can steal the lock */ } else if (dev->can_steal_lock()) { read_volume_label(jcr, dev, Slot); diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 9e7e762891..c296e39ff7 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -11,19 +11,14 @@ Copyright (C) 2000-2005 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 ammended 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,14 +42,14 @@ extern int debug_level; * * Returns VOL_ code as defined in record.h * VOL_NOT_READ - * VOL_OK good label found - * VOL_NO_LABEL volume not labeled - * VOL_IO_ERROR I/O error reading tape - * VOL_NAME_ERROR label has wrong name - * VOL_CREATE_ERROR Error creating label - * VOL_VERSION_ERROR label has wrong version - * VOL_LABEL_ERROR bad label type - * VOL_NO_MEDIA no media in drive + * VOL_OK good label found + * VOL_NO_LABEL volume not labeled + * VOL_IO_ERROR I/O error reading tape + * VOL_NAME_ERROR label has wrong name + * VOL_CREATE_ERROR Error creating label + * VOL_VERSION_ERROR label has wrong version + * VOL_LABEL_ERROR bad label type + * VOL_NO_MEDIA no media in drive * * The dcr block is emptied on return, and the Volume is * rewound. @@ -76,22 +71,22 @@ int read_dev_volume_label(DCR *dcr) if (!dev->is_open()) { Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n")); } - if (dev->is_labeled()) { /* did we already read label? */ + if (dev->is_labeled()) { /* did we already read label? */ /* Compare Volume Names allow special wild card */ if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) { Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"), - dev->print_name(), VolName, dev->VolHdr.VolName); - /* - * Cancel Job if too many label errors - * => we are in a loop - */ - if (!dev->poll && jcr->label_errors++ > 100) { + dev->print_name(), VolName, dev->VolHdr.VolName); + /* + * Cancel Job if too many label errors + * => we are in a loop + */ + if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg); - } - return VOL_NAME_ERROR; + } + return VOL_NAME_ERROR; } Dmsg0(30, "Leave read_volume_label() VOL_OK\n"); - return VOL_OK; /* label already read */ + return VOL_OK; /* label already read */ } dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ); /* set no label, no append */ @@ -99,7 +94,7 @@ int read_dev_volume_label(DCR *dcr) if (!rewind_dev(dev)) { Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"), - dev->print_name(), strerror_dev(dev)); + dev->print_name(), strerror_dev(dev)); Dmsg1(30, "%s", jcr->errmsg); return VOL_NO_MEDIA; } @@ -108,27 +103,27 @@ int read_dev_volume_label(DCR *dcr) /* Read ANSI/IBM label if so requested */ want_ansi_label = dcr->VolCatInfo.LabelType != B_BACULA_LABEL || - dcr->device->label_type != B_BACULA_LABEL; + dcr->device->label_type != B_BACULA_LABEL; if (want_ansi_label || dev_cap(dev, CAP_CHECKLABELS)) { - stat = read_ansi_ibm_label(dcr); + stat = read_ansi_ibm_label(dcr); /* If we want a label and didn't find it, return error */ if (want_ansi_label && stat != VOL_OK) { - empty_block(block); - rewind_dev(dev); - return stat; + empty_block(block); + rewind_dev(dev); + return stat; } if (stat == VOL_NAME_ERROR || stat == VOL_LABEL_ERROR) { Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"), - dev->print_name(), VolName, dev->VolHdr.VolName); - if (!dev->poll && jcr->label_errors++ > 100) { + dev->print_name(), VolName, dev->VolHdr.VolName); + if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg); - } - empty_block(block); - rewind_dev(dev); - return stat; + } + empty_block(block); + rewind_dev(dev); + return stat; } - if (stat != VOL_OK) { /* Not an ANSI/IBM label, so re-read */ - rewind_dev(dev); + if (stat != VOL_OK) { /* Not an ANSI/IBM label, so re-read */ + rewind_dev(dev); } } @@ -140,30 +135,30 @@ int read_dev_volume_label(DCR *dcr) if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) { Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula " "labeled Volume, because: ERR=%s"), NPRT(VolName), - dev->print_name(), strerror_dev(dev)); + dev->print_name(), strerror_dev(dev)); Dmsg1(30, "%s", jcr->errmsg); } else if (!read_record_from_block(block, record)) { Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n")); Dmsg1(30, "%s", jcr->errmsg); } else if (!unser_volume_label(dev, record)) { Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"), - strerror_dev(dev)); + strerror_dev(dev)); Dmsg1(30, "%s", jcr->errmsg); } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0 && - strcmp(dev->VolHdr.Id, OldBaculaId) != 0) { + strcmp(dev->VolHdr.Id, OldBaculaId) != 0) { Mmsg(jcr->errmsg, _("Volume Header Id bad: %s\n"), dev->VolHdr.Id); Dmsg1(30, "%s", jcr->errmsg); } else { ok = true; } - free_record(record); /* finished reading Volume record */ - empty_block(block); /* done with block */ + free_record(record); /* finished reading Volume record */ + empty_block(block); /* done with block */ if (!ok) { if (forge_on || jcr->ignore_label_errors) { - dev->set_labeled(); /* set has Bacula label */ + dev->set_labeled(); /* set has Bacula label */ Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg); - return VOL_OK; + return VOL_OK; } rewind_dev(dev); return VOL_NO_LABEL; @@ -183,7 +178,7 @@ int read_dev_volume_label(DCR *dcr) dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion1 && dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion2) { Mmsg(jcr->errmsg, _("Volume on %s has wrong Bacula version. Wanted %d got %d\n"), - dev->print_name(), BaculaTapeVersion, dev->VolHdr.VerNum); + dev->print_name(), BaculaTapeVersion, dev->VolHdr.VerNum); Dmsg1(30, "%s", jcr->errmsg); return VOL_VERSION_ERROR; } @@ -193,7 +188,7 @@ int read_dev_volume_label(DCR *dcr) */ if (dev->VolHdr.LabelType != PRE_LABEL && dev->VolHdr.LabelType != VOL_LABEL) { Mmsg(jcr->errmsg, _("Volume on %s has bad Bacula label type: %x\n"), - dev->print_name(), dev->VolHdr.LabelType); + dev->print_name(), dev->VolHdr.LabelType); Dmsg1(30, "%s", jcr->errmsg); if (!dev->poll && jcr->label_errors++ > 100) { Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg); @@ -201,13 +196,14 @@ int read_dev_volume_label(DCR *dcr) return VOL_LABEL_ERROR; } - dev->set_labeled(); /* set has Bacula label */ + dev->set_labeled(); /* set has Bacula label */ + new_volume(dev->VolHdr.VolName, dev); /* Compare Volume Names */ Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolName); if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) { Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"), - dev->print_name(), VolName, dev->VolHdr.VolName); + dev->print_name(), VolName, dev->VolHdr.VolName); Dmsg1(30, "%s", jcr->errmsg); /* * Cancel Job if too many label errors @@ -240,7 +236,7 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; Dmsg3(100, "Enter read_dev_volume_label_guess device=%s vol=%s dev_Vol=%s\n", - dev->print_name(), dcr->VolumeName, dev->VolHdr.VolName); + dev->print_name(), dcr->VolumeName, dev->VolHdr.VolName); if (!dev->is_dvd()) { Dmsg0(100, "Leave read_dev_volume_label_guess !CAP_REQMOUNT\n"); @@ -254,28 +250,28 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) /* For mounted devices, tries to guess the volume name, and read the label if possible. */ - if (open_guess_name_dev(dev) < 0) { + if (open_guess_name_dev(dev) < 0) { if (!write || dcr->VolCatInfo.VolCatParts > 0) { Mmsg2(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."), - dev->print_name(), dcr->VolumeName); + dev->print_name(), dcr->VolumeName); Dmsg0(100, "Leave read_dev_volume_label_guess VOL_NO_LABEL (!open_guess_name_dev)\n"); - return VOL_NO_LABEL; + return VOL_NO_LABEL; } if (write && dev->free_space_errno < 0) { Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n"); Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"), - dev->print_name(), dev->errmsg); - return VOL_NO_MEDIA; + dev->print_name(), dev->errmsg); + return VOL_NO_MEDIA; } /* If we can't guess the name, and we are writing, just reopen the right file with open_first_part. */ if (open_first_part(dev) < 0) { - berrno be; + berrno be; Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev && !open_first_part)\n"); - return VOL_IO_ERROR; + return VOL_IO_ERROR; } Dmsg0(100, "Leave read_dev_volume_label_guess !open_guess_name_dev\n"); @@ -284,23 +280,23 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) if (write && dcr->dev->free_space_errno < 0) { Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n"); Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"), - dev->print_name(), dev->errmsg); - return VOL_NO_MEDIA; + dev->print_name(), dev->errmsg); + return VOL_NO_MEDIA; } vol_label_status = read_dev_volume_label(dcr); if (!write || dcr->VolCatInfo.VolCatParts > 0) { Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && (!write || dcr->VolCatInfo.VolCatParts > 0))\n"); - return vol_label_status; + return vol_label_status; } if (open_first_part(dcr->dev) < 0) { - berrno be; + berrno be; Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"), - dev->print_name(), be.strerror()); + dev->print_name(), be.strerror()); Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (open_guess_name_dev && !open_first_part)\n"); - return VOL_IO_ERROR; + return VOL_IO_ERROR; } /* When writing, if the guessed volume name is no the right volume name, @@ -308,11 +304,11 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) */ if (vol_label_status != VOL_NAME_ERROR) { Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && !VOL_NAME_ERROR)\n"); - dev->clear_labeled(); - return read_dev_volume_label(dcr); + dev->clear_labeled(); + return read_dev_volume_label(dcr); } else { Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && VOL_NAME_ERROR)\n"); - return vol_label_status; + return vol_label_status; } } } @@ -321,7 +317,7 @@ int read_dev_volume_label_guess(DCR *dcr, bool write) * Put a volume label into the block * * Returns: false on failure - * true on success + * true on success */ bool write_volume_label_to_block(DCR *dcr) { @@ -333,7 +329,7 @@ bool write_volume_label_to_block(DCR *dcr) Dmsg0(20, "write Label in write_volume_label_to_block()\n"); memset(&rec, 0, sizeof(rec)); rec.data = get_memory(SER_LENGTH_Volume_Label); - empty_block(block); /* Volume label always at beginning */ + empty_block(block); /* Volume label always at beginning */ create_volume_label_record(dcr, &rec); @@ -341,7 +337,7 @@ bool write_volume_label_to_block(DCR *dcr) if (!write_record_to_block(block, &rec)) { free_pool_memory(rec.data); Jmsg1(jcr, M_FATAL, 0, _("Cannot write Volume label to block for device %s\n"), - dev->print_name()); + dev->print_name()); return false; } else { Dmsg1(90, "Wrote label of %d bytes to block\n", rec.data_len); @@ -354,9 +350,9 @@ bool write_volume_label_to_block(DCR *dcr) /* * Write a Volume Label * !!! Note, this is ONLY used for writing - * a fresh volume label. Any data - * after the label will be destroyed, - * in fact, we write the label 5 times !!!! + * a fresh volume label. Any data + * after the label will be destroyed, + * in fact, we write the label 5 times !!!! * * This routine expects that open_device() was previously called. * @@ -375,7 +371,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); Dmsg2(30, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), strerror_dev(dev)); if (!forge_on) { - goto bail_out; + goto bail_out; } } @@ -384,13 +380,13 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po /* * If we have already detected an ANSI label, re-read it - * to skip past it. Otherwise, we write a new one if - * so requested. + * to skip past it. Otherwise, we write a new one if + * so requested. */ if (dev->label_type != B_BACULA_LABEL) { if (read_ansi_ibm_label(dcr) != VOL_OK) { - rewind_dev(dev); - goto bail_out; + rewind_dev(dev); + goto bail_out; } } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) { goto bail_out; @@ -423,12 +419,12 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po if (debug_level >= 20) { dump_volume_label(dev); } - dev->clear_append(); /* remove append since this is PRE_LABEL */ + dev->clear_append(); /* remove append since this is PRE_LABEL */ return true; bail_out: memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); - dev->clear_append(); /* remove append since this is PRE_LABEL */ + dev->clear_append(); /* remove append since this is PRE_LABEL */ return false; } @@ -436,7 +432,7 @@ bail_out: * Write a volume label. This is ONLY called if we have a valid Bacula * label of type PRE_LABEL; * Returns: true if OK - * false if unable to write it + * false if unable to write it */ bool rewrite_volume_label(DCR *dcr, bool recycle) { @@ -460,13 +456,13 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) if (!dev_cap(dev, CAP_STREAM)) { if (!rewind_dev(dev)) { Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s: ERR=%s\n"), - dev->print_name(), strerror_dev(dev)); + dev->print_name(), strerror_dev(dev)); } if (recycle) { - if (!truncate_dev(dev)) { + if (!truncate_dev(dev)) { Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s: ERR=%s\n"), - dev->print_name(), strerror_dev(dev)); - } + dev->print_name(), strerror_dev(dev)); + } } /* @@ -475,21 +471,21 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) * so requested. */ if (dev->label_type != B_BACULA_LABEL) { - if (read_ansi_ibm_label(dcr) != VOL_OK) { - rewind_dev(dev); - return false; - } + if (read_ansi_ibm_label(dcr) != VOL_OK) { + rewind_dev(dev); + return false; + } } else if (!write_ansi_ibm_labels (dcr, ANSI_VOL_LABEL, dev->VolHdr.VolName)) { - return false; + return false; } /* Attempt write to check write permission */ Dmsg0(200, "Attempt to write to device.\n"); if (!write_block_to_dev(dcr)) { Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"), - dev->print_name(), strerror_dev(dev)); + dev->print_name(), strerror_dev(dev)); Dmsg0(200, "===ERROR write block to dev\n"); - return false; + return false; } } /* Set or reset Volume statistics */ @@ -515,10 +511,10 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) } if (recycle) { Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\" on device %s, all previous data lost.\n"), - dcr->VolumeName, dev->print_name()); + dcr->VolumeName, dev->print_name()); } else { Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume \"%s\" on device %s\n"), - dcr->VolumeName, dev->print_name()); + dcr->VolumeName, dev->print_name()); } /* * End writing real Volume label (from pre-labeled tape), or recycling @@ -565,7 +561,7 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec) dev->VolHdr.write_time = dt.julian_day_fraction; } ser_float64(dev->VolHdr.write_date); /* 0 if VerNum >= 11 */ - ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */ + ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */ ser_string(dev->VolHdr.VolName); ser_string(dev->VolHdr.PrevVolName); @@ -621,7 +617,7 @@ void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName) bstrncpy(dev->VolHdr.LabelProg, my_name, sizeof(dev->VolHdr.LabelProg)); sprintf(dev->VolHdr.ProgVersion, "Ver. %s %s", VERSION, BDATE); sprintf(dev->VolHdr.ProgDate, "Build %s %s", __DATE__, __TIME__); - dev->set_labeled(); /* set has Bacula label */ + dev->set_labeled(); /* set has Bacula label */ if (debug_level >= 90) { dump_volume_label(dev); } @@ -638,7 +634,7 @@ void create_session_label(DCR *dcr, DEV_RECORD *rec, int label) rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; - rec->Stream = jcr->JobId; + rec->Stream = jcr->JobId; rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Session_Label); ser_begin(rec->data, SER_LENGTH_Session_Label); @@ -653,11 +649,11 @@ void create_session_label(DCR *dcr, DEV_RECORD *rec, int label) ser_string(dcr->pool_name); ser_string(dcr->pool_type); - ser_string(jcr->job_name); /* base Job name */ + ser_string(jcr->job_name); /* base Job name */ ser_string(jcr->client_name); /* Added in VerNum 10 */ - ser_string(jcr->Job); /* Unique name of this Job */ + ser_string(jcr->Job); /* Unique name of this Job */ ser_string(jcr->fileset_name); ser_uint32(jcr->JobType); ser_uint32(jcr->JobLevel); @@ -682,7 +678,7 @@ void create_session_label(DCR *dcr, DEV_RECORD *rec, int label) /* Write session label * Returns: false on failure - * true on success + * true on success */ bool write_session_label(DCR *dcr, int label) { @@ -696,20 +692,20 @@ bool write_session_label(DCR *dcr, int label) switch (label) { case SOS_LABEL: if (dev->is_tape()) { - dcr->StartBlock = dev->block_num; - dcr->StartFile = dev->file; + dcr->StartBlock = dev->block_num; + dcr->StartFile = dev->file; } else { - dcr->StartBlock = (uint32_t)dev->file_addr; - dcr->StartFile = (uint32_t)(dev->file_addr >> 32); + dcr->StartBlock = (uint32_t)dev->file_addr; + dcr->StartFile = (uint32_t)(dev->file_addr >> 32); } break; case EOS_LABEL: if (dev->is_tape()) { - dcr->EndBlock = dev->EndBlock; - dcr->EndFile = dev->EndFile; + dcr->EndBlock = dev->EndBlock; + dcr->EndFile = dev->EndFile; } else { - dcr->EndBlock = (uint32_t)dev->file_addr; - dcr->EndFile = (uint32_t)(dev->file_addr >> 32); + dcr->EndBlock = (uint32_t)dev->file_addr; + dcr->EndFile = (uint32_t)(dev->file_addr >> 32); } break; default: @@ -730,16 +726,16 @@ bool write_session_label(DCR *dcr, int label) Dmsg0(100, "Cannot write session label to block.\n"); if (!write_block_to_device(dcr)) { Dmsg0(90, "Got session label write_block_to_dev error.\n"); - /* ****FIXME***** errno is not set here */ + /* ****FIXME***** errno is not set here */ Jmsg(jcr, M_FATAL, 0, _("Error writing Session label to %s: %s\n"), - dev_vol_name(dev), strerror(errno)); - free_record(rec); - return false; + dev_vol_name(dev), strerror(errno)); + free_record(rec); + return false; } } if (!write_record_to_block(block, rec)) { Jmsg(jcr, M_FATAL, 0, _("Error writing Session label to %s: %s\n"), - dev_vol_name(dev), strerror(errno)); + dev_vol_name(dev), strerror(errno)); free_record(rec); return false; } @@ -764,7 +760,7 @@ bool write_session_label(DCR *dcr, int label) * Assumes that the record is already read. * * Returns: false on error - * true on success + * true on success */ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec) @@ -773,11 +769,11 @@ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec) if (rec->FileIndex != VOL_LABEL && rec->FileIndex != PRE_LABEL) { Mmsg3(dev->errmsg, _("Expecting Volume Label, got FI=%s Stream=%s len=%d\n"), - FI_to_ascii(rec->FileIndex), - stream_to_ascii(rec->Stream, rec->FileIndex), - rec->data_len); + FI_to_ascii(rec->FileIndex), + stream_to_ascii(rec->Stream, rec->FileIndex), + rec->data_len); if (!forge_on) { - return false; + return false; } } @@ -841,7 +837,7 @@ bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec) unser_string(label->JobName); unser_string(label->ClientName); if (label->VerNum >= 10) { - unser_string(label->Job); /* Unique name of this Job */ + unser_string(label->Job); /* Unique name of this Job */ unser_string(label->FileSetName); unser_uint32(label->JobType); unser_uint32(label->JobLevel); @@ -860,9 +856,9 @@ bool unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec) unser_uint32(label->EndFile); unser_uint32(label->JobErrors); if (label->VerNum >= 11) { - unser_uint32(label->JobStatus); + unser_uint32(label->JobStatus); } else { - label->JobStatus = JS_Terminated; /* kludge */ + label->JobStatus = JS_Terminated; /* kludge */ } } return true; @@ -916,11 +912,11 @@ void dump_volume_label(DEVICE *dev) "PoolType : %s\n" "HostName : %s\n" "", - dev->VolHdr.Id, dev->VolHdr.VerNum, - dev->VolHdr.VolName, dev->VolHdr.PrevVolName, - File, LabelType, dev->VolHdr.LabelSize, - dev->VolHdr.PoolName, dev->VolHdr.MediaType, - dev->VolHdr.PoolType, dev->VolHdr.HostName); + dev->VolHdr.Id, dev->VolHdr.VerNum, + dev->VolHdr.VolName, dev->VolHdr.PrevVolName, + File, LabelType, dev->VolHdr.LabelSize, + dev->VolHdr.PoolName, dev->VolHdr.MediaType, + dev->VolHdr.PoolType, dev->VolHdr.HostName); if (dev->VolHdr.VerNum >= 11) { char dt[50]; @@ -982,14 +978,14 @@ static void dump_session_label(DEV_RECORD *rec, const char *type) "JobErrors : %s\n" "JobStatus : %c\n" "", - edit_uint64_with_commas(label.JobFiles, ec1), - edit_uint64_with_commas(label.JobBytes, ec2), - edit_uint64_with_commas(label.StartBlock, ec3), - edit_uint64_with_commas(label.EndBlock, ec4), - edit_uint64_with_commas(label.StartFile, ec5), - edit_uint64_with_commas(label.EndFile, ec6), - edit_uint64_with_commas(label.JobErrors, ec7), - label.JobStatus); + edit_uint64_with_commas(label.JobFiles, ec1), + edit_uint64_with_commas(label.JobBytes, ec2), + edit_uint64_with_commas(label.StartBlock, ec3), + edit_uint64_with_commas(label.EndBlock, ec4), + edit_uint64_with_commas(label.StartFile, ec5), + edit_uint64_with_commas(label.EndFile, ec6), + edit_uint64_with_commas(label.JobErrors, ec7), + label.JobStatus); } if (label.VerNum >= 11) { char dt[50]; @@ -1041,56 +1037,56 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose) switch (rec->FileIndex) { case PRE_LABEL: case VOL_LABEL: - unser_volume_label(dev, rec); - dump_volume_label(dev); - break; + unser_volume_label(dev, rec); + dump_volume_label(dev); + break; case SOS_LABEL: - dump_session_label(rec, type); - break; + dump_session_label(rec, type); + break; case EOS_LABEL: - dump_session_label(rec, type); - break; + dump_session_label(rec, type); + break; case EOM_LABEL: Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n", - type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); - break; + type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + break; case EOT_LABEL: Pmsg0(-1, _("End of physical tape.\n")); - break; + break; default: Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n", - type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); - break; + type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); + break; } } else { SESSION_LABEL label; switch (rec->FileIndex) { case SOS_LABEL: - unser_session_label(&label, rec); + unser_session_label(&label, rec); Pmsg6(-1, "%s Record: SessId=%d SessTime=%d JobId=%d Level=%c Type=%c\n", - type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, - label.JobLevel, label.JobType); - break; + type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, + label.JobLevel, label.JobType); + break; case EOS_LABEL: - char ed1[30], ed2[30]; - unser_session_label(&label, rec); + char ed1[30], ed2[30]; + unser_session_label(&label, rec); Pmsg6(-1, "%s Record: SessId=%d SessTime=%d JobId=%d Level=%c Type=%c\n", - type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, - label.JobLevel, label.JobType); + type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, + label.JobLevel, label.JobType); Pmsg4(-1, " Files=%s Bytes=%s Errors=%d Status=%c\n", - edit_uint64_with_commas(label.JobFiles, ed1), - edit_uint64_with_commas(label.JobBytes, ed2), - label.JobErrors, (char)label.JobStatus); - break; + edit_uint64_with_commas(label.JobFiles, ed1), + edit_uint64_with_commas(label.JobBytes, ed2), + label.JobErrors, (char)label.JobStatus); + break; case EOM_LABEL: case PRE_LABEL: case VOL_LABEL: default: Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n", type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len); - break; + break; case EOT_LABEL: - break; + break; } } debug_level = dbl; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 70f959259c..499335829c 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -8,22 +8,17 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2002-2005 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 ammended 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. */ @@ -150,7 +145,7 @@ mount_next_vol: Dmsg1(100, "want vol=%s\n", dcr->VolumeName); if (dev->poll && dev_cap(dev, CAP_CLOSEONPOLL)) { - force_close_dev(dev); + force_close_device(dev); } /* Ensure the device is open */ @@ -316,7 +311,7 @@ read_volume: ask = true; /* Needed, so the medium can be changed */ if (dev_cap(dev, CAP_REQMOUNT)) { - close_dev(dev); + close_device(dev); } goto mount_next_vol; } @@ -348,11 +343,7 @@ read_volume: Dmsg0(200, "Device previously written, moving to end of data\n"); Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"), dcr->VolumeName); -#if defined (__digital__) && defined (__unix__) - if (!fsf_dev(dev,dev->VolCatInfo.VolCatFiles)) { -#else if (!eod_dev(dev)) { -#endif Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"), dev->print_name(), strerror_dev(dev)); mark_volume_in_error(dcr); @@ -422,33 +413,6 @@ static void mark_volume_not_inchanger(DCR *dcr) dir_update_volume_info(dcr, true); /* set new status */ } - -/* - * If we are reading, we come here at the end of the tape - * and see if there are more volumes to be mounted. - */ -bool mount_next_read_volume(DCR *dcr) -{ - DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; - Dmsg2(90, "NumVolumes=%d CurVolume=%d\n", jcr->NumVolumes, jcr->CurVolume); - /* - * End Of Tape -- mount next Volume (if another specified) - */ - if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) { - close_dev(dev); - dev->clear_read(); - if (!acquire_device_for_read(dcr)) { - Jmsg2(jcr, M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", dev->print_name(), - dcr->VolumeName); - return false; - } - return true; /* next volume mounted */ - } - Dmsg0(90, "End of Device reached.\n"); - return false; -} - /* * Either because we are going to hang a new volume, or because * of explicit user request, we release the current volume. @@ -468,6 +432,7 @@ void release_volume(DCR *dcr) dev->EndBlock = dev->EndFile = 0; memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); memset(&dcr->VolCatInfo, 0, sizeof(dcr->VolCatInfo)); + free_volume(dev); memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); /* Force re-read of label */ dev->state &= ~(ST_LABEL|ST_READ|ST_APPEND); @@ -476,7 +441,7 @@ void release_volume(DCR *dcr) if (dev->is_open() && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) { offline_or_rewind_dev(dev); - close_dev(dev); + close_device(dev); } /* If we have not closed the device, then at least rewind the tape */ @@ -485,3 +450,29 @@ void release_volume(DCR *dcr) } Dmsg0(190, "===== release_volume ---"); } + +/* + * If we are reading, we come here at the end of the tape + * and see if there are more volumes to be mounted. + */ +bool mount_next_read_volume(DCR *dcr) +{ + DEVICE *dev = dcr->dev; + JCR *jcr = dcr->jcr; + Dmsg2(90, "NumVolumes=%d CurVolume=%d\n", jcr->NumVolumes, jcr->CurVolume); + /* + * End Of Tape -- mount next Volume (if another specified) + */ + if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) { + close_device(dev); + dev->clear_read(); + if (!acquire_device_for_read(dcr)) { + Jmsg2(jcr, M_FATAL, 0, "Cannot open Dev=%s, Vol=%s\n", dev->print_name(), + dcr->VolumeName); + return false; + } + return true; /* next volume mounted */ + } + Dmsg0(90, "End of Device reached.\n"); + return false; +} diff --git a/bacula/src/stored/parse_bsr.c b/bacula/src/stored/parse_bsr.c index 2a9034bc78..9c26e0672f 100755 --- a/bacula/src/stored/parse_bsr.c +++ b/bacula/src/stored/parse_bsr.c @@ -103,18 +103,18 @@ static void s_err(const char *file, int line, LEX *lc, const char *msg, ...) if (jcr) { Jmsg(jcr, M_FATAL, 0, _("Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), - buf, lc->line_no, lc->col_no, lc->fname, lc->line); + buf, lc->line_no, lc->col_no, lc->fname, lc->line); } else { e_msg(file, line, M_FATAL, 0, _("Bootstrap file error: %s\n" " : Line %d, col %d of file %s\n%s\n"), - buf, lc->line_no, lc->col_no, lc->fname, lc->line); + buf, lc->line_no, lc->col_no, lc->fname, lc->line); } } /********************************************************************* * - * Parse Bootstrap file + * Parse Bootstrap file * */ BSR *parse_bsr(JCR *jcr, char *fname) @@ -128,38 +128,38 @@ BSR *parse_bsr(JCR *jcr, char *fname) if ((lc = lex_open_file(lc, fname, s_err)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"), - fname, be.strerror()); + fname, be.strerror()); } lc->caller_ctx = (void *)jcr; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(200, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { - continue; + continue; } for (i=0; items[i].name; i++) { - if (strcasecmp(items[i].name, lc->str) == 0) { - token = lex_get_token(lc, T_ALL); + if (strcasecmp(items[i].name, lc->str) == 0) { + token = lex_get_token(lc, T_ALL); Dmsg1 (200, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); - if (token != T_EQUALS) { + if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); - bsr = NULL; - break; - } + bsr = NULL; + break; + } Dmsg1(200, "calling handler for %s\n", items[i].name); - /* Call item handler */ - bsr = items[i].handler(lc, bsr); - i = -1; - break; - } + /* Call item handler */ + bsr = items[i].handler(lc, bsr); + i = -1; + break; + } } if (i >= 0) { Dmsg1(200, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); - bsr = NULL; - break; + bsr = NULL; + break; } if (!bsr) { - break; + break; } } lc = lex_close_file(lc); @@ -187,7 +187,7 @@ static bool is_fast_rejection_ok(BSR *bsr) */ for ( ; bsr; bsr=bsr->next) { if (!(bsr->sesstime && bsr->sessid)) { - return false; + return false; } } return true; @@ -197,11 +197,11 @@ static bool is_positioning_ok(BSR *bsr) { /* * Every bsr should have a volfile entry and a volblock entry - * if we are going to use positioning + * if we are going to use positioning */ for ( ; bsr; bsr=bsr->next) { if (!bsr->volfile || !bsr->volblock) { - return false; + return false; } } return true; @@ -228,19 +228,19 @@ static BSR *store_vol(LEX *lc, BSR *bsr) for (p=lc->str; p && *p; ) { n = strchr(p, '|'); if (n) { - *n++ = 0; + *n++ = 0; } volume = (BSR_VOLUME *)malloc(sizeof(BSR_VOLUME)); memset(volume, 0, sizeof(BSR_VOLUME)); bstrncpy(volume->VolumeName, p, sizeof(volume->VolumeName)); /* Add it to the end of the volume chain */ if (!bsr->volume) { - bsr->volume = volume; + bsr->volume = volume; } else { - BSR_VOLUME *bc = bsr->volume; - for ( ;bc->next; bc=bc->next) - { } - bc->next = volume; + BSR_VOLUME *bc = bsr->volume; + for ( ;bc->next; bc=bc->next) + { } + bc->next = volume; } p = n; } @@ -258,7 +258,7 @@ static BSR *store_mediatype(LEX *lc, BSR *bsr) } if (!bsr->volume) { Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"), - lc->str); + lc->str); return bsr; } BSR_VOLUME *bv; @@ -277,23 +277,23 @@ static BSR *store_client(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { - return NULL; + return NULL; } client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT)); memset(client, 0, sizeof(BSR_CLIENT)); bstrncpy(client->ClientName, lc->str, sizeof(client->ClientName)); /* Add it to the end of the client chain */ if (!bsr->client) { - bsr->client = client; + bsr->client = client; } else { - BSR_CLIENT *bc = bsr->client; - for ( ;bc->next; bc=bc->next) - { } - bc->next = client; + BSR_CLIENT *bc = bsr->client; + for ( ;bc->next; bc=bc->next) + { } + bc->next = client; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -307,24 +307,24 @@ static BSR *store_job(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { - return NULL; + return NULL; } job = (BSR_JOB *)malloc(sizeof(BSR_JOB)); memset(job, 0, sizeof(BSR_JOB)); bstrncpy(job->Job, lc->str, sizeof(job->Job)); /* Add it to the end of the client chain */ if (!bsr->job) { - bsr->job = job; + bsr->job = job; } else { - /* Add to end of chain */ - BSR_JOB *bc = bsr->job; - for ( ;bc->next; bc=bc->next) - { } - bc->next = job; + /* Add to end of chain */ + BSR_JOB *bc = bsr->job; + for ( ;bc->next; bc=bc->next) + { } + bc->next = job; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -338,7 +338,7 @@ static BSR *store_findex(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { - return NULL; + return NULL; } findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX)); memset(findex, 0, sizeof(BSR_FINDEX)); @@ -346,17 +346,17 @@ static BSR *store_findex(LEX *lc, BSR *bsr) findex->findex2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->FileIndex) { - bsr->FileIndex = findex; + bsr->FileIndex = findex; } else { - /* Add to end of chain */ - BSR_FINDEX *bs = bsr->FileIndex; - for ( ;bs->next; bs=bs->next) - { } - bs->next = findex; + /* Add to end of chain */ + BSR_FINDEX *bs = bsr->FileIndex; + for ( ;bs->next; bs=bs->next) + { } + bs->next = findex; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -371,7 +371,7 @@ static BSR *store_jobid(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { - return NULL; + return NULL; } jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID)); memset(jobid, 0, sizeof(BSR_JOBID)); @@ -379,17 +379,17 @@ static BSR *store_jobid(LEX *lc, BSR *bsr) jobid->JobId2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->JobId) { - bsr->JobId = jobid; + bsr->JobId = jobid; } else { - /* Add to end of chain */ - BSR_JOBID *bs = bsr->JobId; - for ( ;bs->next; bs=bs->next) - { } - bs->next = jobid; + /* Add to end of chain */ + BSR_JOBID *bs = bsr->JobId; + for ( ;bs->next; bs=bs->next) + { } + bs->next = jobid; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -439,7 +439,7 @@ static BSR *store_volfile(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { - return NULL; + return NULL; } volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE)); memset(volfile, 0, sizeof(BSR_VOLFILE)); @@ -447,17 +447,17 @@ static BSR *store_volfile(LEX *lc, BSR *bsr) volfile->efile = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->volfile) { - bsr->volfile = volfile; + bsr->volfile = volfile; } else { - /* Add to end of chain */ - BSR_VOLFILE *bs = bsr->volfile; - for ( ;bs->next; bs=bs->next) - { } - bs->next = volfile; + /* Add to end of chain */ + BSR_VOLFILE *bs = bsr->volfile; + for ( ;bs->next; bs=bs->next) + { } + bs->next = volfile; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -475,7 +475,7 @@ static BSR *store_volblock(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { - return NULL; + return NULL; } volblock = (BSR_VOLBLOCK *)malloc(sizeof(BSR_VOLBLOCK)); memset(volblock, 0, sizeof(BSR_VOLBLOCK)); @@ -483,17 +483,17 @@ static BSR *store_volblock(LEX *lc, BSR *bsr) volblock->eblock = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->volblock) { - bsr->volblock = volblock; + bsr->volblock = volblock; } else { - /* Add to end of chain */ - BSR_VOLBLOCK *bs = bsr->volblock; - for ( ;bs->next; bs=bs->next) - { } - bs->next = volblock; + /* Add to end of chain */ + BSR_VOLBLOCK *bs = bsr->volblock; + for ( ;bs->next; bs=bs->next) + { } + bs->next = volblock; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -508,7 +508,7 @@ static BSR *store_sessid(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { - return NULL; + return NULL; } sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID)); memset(sid, 0, sizeof(BSR_SESSID)); @@ -516,17 +516,17 @@ static BSR *store_sessid(LEX *lc, BSR *bsr) sid->sessid2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->sessid) { - bsr->sessid = sid; + bsr->sessid = sid; } else { - /* Add to end of chain */ - BSR_SESSID *bs = bsr->sessid; - for ( ;bs->next; bs=bs->next) - { } - bs->next = sid; + /* Add to end of chain */ + BSR_SESSID *bs = bsr->sessid; + for ( ;bs->next; bs=bs->next) + { } + bs->next = sid; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -540,24 +540,24 @@ static BSR *store_sesstime(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_PINT32); if (token == T_ERROR) { - return NULL; + return NULL; } stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME)); memset(stime, 0, sizeof(BSR_SESSTIME)); stime->sesstime = lc->pint32_val; /* Add it to the end of the chain */ if (!bsr->sesstime) { - bsr->sesstime = stime; + bsr->sesstime = stime; } else { - /* Add to end of chain */ - BSR_SESSTIME *bs = bsr->sesstime; - for ( ;bs->next; bs=bs->next) - { } - bs->next = stime; + /* Add to end of chain */ + BSR_SESSTIME *bs = bsr->sesstime; + for ( ;bs->next; bs=bs->next) + { } + bs->next = stime; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -572,24 +572,24 @@ static BSR *store_stream(LEX *lc, BSR *bsr) for (;;) { token = lex_get_token(lc, T_INT32); if (token == T_ERROR) { - return NULL; + return NULL; } stream = (BSR_STREAM *)malloc(sizeof(BSR_STREAM)); memset(stream, 0, sizeof(BSR_STREAM)); stream->stream = lc->int32_val; /* Add it to the end of the chain */ if (!bsr->stream) { - bsr->stream = stream; + bsr->stream = stream; } else { - /* Add to end of chain */ - BSR_STREAM *bs = bsr->stream; - for ( ;bs->next; bs=bs->next) - { } - bs->next = stream; + /* Add to end of chain */ + BSR_STREAM *bs = bsr->stream; + for ( ;bs->next; bs=bs->next) + { } + bs->next = stream; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { - break; + break; } } return bsr; @@ -752,7 +752,7 @@ void dump_bsr(BSR *bsr, bool recurse) /********************************************************************* * - * Free bsr resources + * Free bsr resources */ static void free_bsr_item(BSR *bsr) @@ -786,7 +786,7 @@ void free_bsr(BSR *bsr) /***************************************************************** * Routines for handling volumes */ -VOL_LIST *new_vol() +VOL_LIST *new_restore_volume() { VOL_LIST *vol; vol = (VOL_LIST *)malloc(sizeof(VOL_LIST)); @@ -799,35 +799,35 @@ VOL_LIST *new_vol() * is not already in the list. * * returns: 1 if volume added - * 0 if volume already in list + * 0 if volume already in list */ -int add_vol(JCR *jcr, VOL_LIST *vol) +int add_restore_volume(JCR *jcr, VOL_LIST *vol) { VOL_LIST *next = jcr->VolList; - if (!next) { /* list empty ? */ - jcr->VolList = vol; /* yes, add volume */ + if (!next) { /* list empty ? */ + jcr->VolList = vol; /* yes, add volume */ } else { for ( ; next->next; next=next->next) { - if (strcmp(vol->VolumeName, next->VolumeName) == 0) { - if (vol->start_file < next->start_file) { - next->start_file = vol->start_file; - } - return 0; /* already in list */ - } + if (strcmp(vol->VolumeName, next->VolumeName) == 0) { + if (vol->start_file < next->start_file) { + next->start_file = vol->start_file; + } + return 0; /* already in list */ + } } if (strcmp(vol->VolumeName, next->VolumeName) == 0) { - if (vol->start_file < next->start_file) { - next->start_file = vol->start_file; - } - return 0; /* already in list */ + if (vol->start_file < next->start_file) { + next->start_file = vol->start_file; + } + return 0; /* already in list */ } - next->next = vol; /* add volume */ + next->next = vol; /* add volume */ } return 1; } -void free_vol_list(JCR *jcr) +void free_restore_volume_list(JCR *jcr) { VOL_LIST *next = jcr->VolList; VOL_LIST *tmp; @@ -844,7 +844,7 @@ void free_vol_list(JCR *jcr) * Create a list of Volumes (and Slots and Start positions) to be * used in the current restore job. */ -void create_vol_list(JCR *jcr) +void create_restore_volume_list(JCR *jcr) { char *p, *n; VOL_LIST *vol; @@ -857,52 +857,52 @@ void create_vol_list(JCR *jcr) if (jcr->bsr) { BSR *bsr = jcr->bsr; if (!bsr->volume || !bsr->volume->VolumeName) { - return; + return; } for ( ; bsr; bsr=bsr->next) { - BSR_VOLUME *bsrvol; - BSR_VOLFILE *volfile; - uint32_t sfile = UINT32_MAX; - - /* Find minimum start file so that we can forward space to it */ - for (volfile = bsr->volfile; volfile; volfile=volfile->next) { - if (volfile->sfile < sfile) { - sfile = volfile->sfile; - } - } - /* Now add volumes for this bsr */ - for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) { - vol = new_vol(); - bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName)); - bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType)); - vol->start_file = sfile; - if (add_vol(jcr, vol)) { - jcr->NumVolumes++; + BSR_VOLUME *bsrvol; + BSR_VOLFILE *volfile; + uint32_t sfile = UINT32_MAX; + + /* Find minimum start file so that we can forward space to it */ + for (volfile = bsr->volfile; volfile; volfile=volfile->next) { + if (volfile->sfile < sfile) { + sfile = volfile->sfile; + } + } + /* Now add volumes for this bsr */ + for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) { + vol = new_restore_volume(); + bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName)); + bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType)); + vol->start_file = sfile; + if (add_restore_volume(jcr, vol)) { + jcr->NumVolumes++; Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName, - vol->MediaType); - } else { + vol->MediaType); + } else { Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName); - free((char *)vol); - } - sfile = 0; /* start at beginning of second volume */ - } + free((char *)vol); + } + sfile = 0; /* start at beginning of second volume */ + } } } else { /* This is the old way -- deprecated */ for (p = jcr->dcr->VolumeName; p && *p; ) { n = strchr(p, '|'); /* volume name separator */ - if (n) { - *n++ = 0; /* Terminate name */ - } - vol = new_vol(); - bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName)); - bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType)); - if (add_vol(jcr, vol)) { - jcr->NumVolumes++; - } else { - free((char *)vol); - } - p = n; + if (n) { + *n++ = 0; /* Terminate name */ + } + vol = new_restore_volume(); + bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName)); + bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType)); + if (add_restore_volume(jcr, vol)) { + jcr->NumVolumes++; + } else { + free((char *)vol); + } + p = n; } } } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index c20da23fe8..445d947e93 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -3,24 +3,18 @@ * * Version $Id$ */ - /* Copyright (C) 2000-2005 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 ammended 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. */ @@ -90,8 +84,6 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence); int open_first_part(DEVICE *dev); int open_next_part(DEVICE *dev); int open_guess_name_dev(DEVICE *dev); -void close_dev(DEVICE *dev); -void force_close_dev(DEVICE *dev); bool truncate_dev(DEVICE *dev); void term_dev(DEVICE *dev); char * strerror_dev(DEVICE *dev); @@ -128,6 +120,8 @@ bool dvd_close_job(DCR *dcr); /* From device.c */ bool open_device(DCR *dcr); +void close_device(DEVICE *dev); +void force_close_device(DEVICE *dev); bool first_open_device(DEVICE *dev); bool fixup_device_block_write_error(DCR *dcr); void _lock_device(const char *file, int line, DEVICE *dev); @@ -186,17 +180,16 @@ bool match_set_eof(BSR *bsr, DEV_RECORD *rec); /* From mount.c */ bool mount_next_write_volume(DCR *dcr, bool release); bool mount_next_read_volume(DCR *dcr); -void release_volume(DCR *ddr); void mark_volume_in_error(DCR *dcr); /* From parse_bsr.c */ BSR *parse_bsr(JCR *jcr, char *lf); void dump_bsr(BSR *bsr, bool recurse); void free_bsr(BSR *bsr); -VOL_LIST *new_vol(); -int add_vol(JCR *jcr, VOL_LIST *vol); -void free_vol_list(JCR *jcr); -void create_vol_list(JCR *jcr); +VOL_LIST *new_restore_volume(); +int add_restore_volume(JCR *jcr, VOL_LIST *vol); +void free_restore_volume_list(JCR *jcr); +void create_restore_volume_list(JCR *jcr); /* From record.c */ const char *FI_to_ascii(int fi); @@ -213,6 +206,17 @@ bool read_records(DCR *dcr, bool record_cb(DCR *dcr, DEV_RECORD *rec), bool mount_cb(DCR *dcr)); +/* From reserve.c */ +void release_volume(DCR *dcr); +VOLRES *new_volume(const char *VolumeName, DEVICE *dev); +VOLRES *find_volume(const char *VolumeName); +bool free_volume(DEVICE *dev); +void create_volume_list(); +void free_volume_list(); +void list_volumes(BSOCK *user); +bool is_volume_in_use(const char *VolumeName); + + /* From spool.c */ bool begin_data_spool (DCR *dcr); bool discard_data_spool (DCR *dcr); diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index cf490ce490..a02c70d757 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -35,7 +35,7 @@ static char rec_header[] = "rechdr %ld %ld %ld %ld %ld"; /* * Read Data and send to File Daemon * Returns: false on failure - * true on success + * true on success */ bool do_read_data(JCR *jcr) { @@ -50,10 +50,10 @@ bool do_read_data(JCR *jcr) } - create_vol_list(jcr); + create_restore_volume_list(jcr); if (jcr->NumVolumes == 0) { Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n")); - free_vol_list(jcr); + free_restore_volume_list(jcr); bnet_fsend(fd, FD_error); return false; } @@ -63,7 +63,7 @@ bool do_read_data(JCR *jcr) /* Ready device for reading */ if (!acquire_device_for_read(dcr)) { - free_vol_list(jcr); + free_restore_volume_list(jcr); bnet_fsend(fd, FD_error); return false; } @@ -79,7 +79,7 @@ bool do_read_data(JCR *jcr) ok = false; } - free_vol_list(jcr); + free_restore_volume_list(jcr); Dmsg0(30, "Done reading.\n"); return ok; } @@ -87,7 +87,7 @@ bool do_read_data(JCR *jcr) /* * Called here for each record from read_records() * Returns: true if OK - * false if error + * false if error */ static bool record_cb(DCR *dcr, DEV_RECORD *rec) { @@ -105,10 +105,10 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) /* Send record header to File daemon */ if (!bnet_fsend(fd, rec_header, rec->VolSessionId, rec->VolSessionTime, - rec->FileIndex, rec->Stream, rec->data_len)) { + rec->FileIndex, rec->Stream, rec->data_len)) { Dmsg1(30, ">filed: Error Hdr=%s\n", fd->msg); Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), - bnet_strerror(fd)); + bnet_strerror(fd)); return false; } else { Dmsg1(31, ">filed: Hdr=%s\n", fd->msg); @@ -116,17 +116,17 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) /* Send data record to File daemon */ - save_msg = fd->msg; /* save fd message pointer */ - fd->msg = rec->data; /* pass data directly to bnet_send */ + save_msg = fd->msg; /* save fd message pointer */ + fd->msg = rec->data; /* pass data directly to bnet_send */ fd->msglen = rec->data_len; Dmsg1(31, ">filed: send %d bytes data.\n", fd->msglen); if (!bnet_send(fd)) { Pmsg1(000, "Error sending to FD. ERR=%s\n", bnet_strerror(fd)); Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), - bnet_strerror(fd)); + bnet_strerror(fd)); ok = false; } - fd->msg = save_msg; /* restore fd message pointer */ + fd->msg = save_msg; /* restore fd message pointer */ return ok; } diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index ed970300f5..c4ca08d802 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -55,6 +55,8 @@ public: DEVRES *device; }; +static dlist *vol_list = NULL; +static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER; /* Forward referenced functions */ static int can_reserve_drive(DCR *dcr); @@ -74,7 +76,6 @@ static char OK_device[] = "3000 OK use device device=%s\n"; static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n"; static char BAD_use[] = "3913 Bad use command: %s\n"; - bool use_cmd(JCR *jcr) { /* @@ -88,6 +89,132 @@ bool use_cmd(JCR *jcr) return true; } +static int my_compare(void *item1, void *item2) +{ + return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name); +} + + +/* + * Put a new Volume entry in the Volume list. This + * effectively reserves the volume so that it will + * not be mounted again. + * + * Return: VOLRES entry on success + * NULL if the Volume is already in the list + */ +VOLRES *new_volume(const char *VolumeName, DEVICE *dev) +{ + VOLRES *vol, *nvol; + vol = (VOLRES *)malloc(sizeof(VOLRES)); + memset(vol, 0, sizeof(VOLRES)); + vol->vol_name = bstrdup(VolumeName); + vol->dev = dev; + P(vol_list_lock); + nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare); + V(vol_list_lock); + if (nvol != vol) { + free(vol->vol_name); + free(vol); + if (dev) { + nvol->dev = dev; + } + return NULL; + } + return vol; +} + +/* + * Search for a Volume name in the Volume list. + * + * Returns: VOLRES entry on success + * NULL if the Volume is not in the list + */ +VOLRES *find_volume(const char *VolumeName) +{ + VOLRES vol, *fvol; + vol.vol_name = bstrdup(VolumeName); + P(vol_list_lock); + fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare); + V(vol_list_lock); + free(vol.vol_name); + return fvol; +} + +/* + * Free a Volume from the Volume list + * + * Returns: true if the Volume found and removed from the list + * false if the Volume is not in the list + */ +bool free_volume(DEVICE *dev) +{ + VOLRES vol, *fvol; + + if (dev->VolHdr.VolName[0] == 0) { + return false; + } + vol.vol_name = bstrdup(dev->VolHdr.VolName); + P(vol_list_lock); + fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare); + if (fvol) { + vol_list->remove(fvol); + free(fvol->vol_name); + free(fvol); + } + V(vol_list_lock); + free(vol.vol_name); + dev->VolHdr.VolName[0] = 0; + return fvol != NULL; +} + +/* + * List Volumes -- this should be moved to status.c + */ +void list_volumes(BSOCK *user) +{ + VOLRES *vol; + for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) { + bnet_fsend(user, "%s\n", vol->vol_name); + } +} + +/* Create the Volume list */ +void create_volume_list() +{ + VOLRES *dummy; + if (vol_list == NULL) { + vol_list = New(dlist(dummy, &dummy->link)); + } +} + +/* Release all Volumes from the list */ +void free_volume_list() +{ + VOLRES *vol; + for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) { + Dmsg1(000, "Unreleased Volume=%s\n", vol->vol_name); + } + delete vol_list; + vol_list = NULL; +} + +bool is_volume_in_use(const char *VolumeName) +{ + VOLRES *vol = find_volume(VolumeName); + if (!vol) { + return false; /* vol not in list */ + } + if (!vol->dev) { /* vol not attached to device */ + return false; + } + if (!vol->dev->is_busy()) { + return false; + } + return true; +} + + static bool use_storage_cmd(JCR *jcr) { POOL_MEM store_name, dev_name, media_type, pool_name, pool_type; @@ -242,6 +369,9 @@ done: return ok; } + + + /* * Search for a particular storage device with particular storage * characteristics (MediaType). diff --git a/bacula/src/stored/status.c b/bacula/src/stored/status.c index 0e281357ac..32e6fd7057 100644 --- a/bacula/src/stored/status.c +++ b/bacula/src/stored/status.c @@ -7,22 +7,17 @@ * */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2003-2005 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 ammended 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. */ @@ -154,6 +149,10 @@ bool status_cmd(JCR *jcr) } } // UnlockRes(); + bnet_fsend(user, "====\n\n"); + bnet_fsend(user, "Volume status:\n"); + list_volumes(user); + #ifdef xxx if (debug_level > 0) { diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index cca3248ffc..cd21d9cd10 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -217,6 +217,7 @@ int main (int argc, char *argv[]) /* Make sure on Solaris we can run concurrent, watch dog + servers + misc */ set_thread_concurrency(me->max_concurrent_jobs * 2 + 4); + create_volume_list(); /* * Start the device allocation thread */ @@ -307,13 +308,13 @@ static int check_resources() foreach_res(store, R_STORAGE) { /* tls_require implies tls_enable */ if (store->tls_require) { -#ifndef HAVE_TLS - Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); - OK = false; - continue; -#else - store->tls_enable = true; -#endif + if (have_tls) { + store->tls_enable = true; + } else { + Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n")); + OK = false; + continue; + } } if (!store->tls_certfile && store->tls_enable) { @@ -557,12 +558,15 @@ void terminate_stored(int sig) foreach_res(device, R_DEVICE) { if (device->dev) { + free_volume(device->dev); term_dev(device->dev); } } - if (configfile) - free(configfile); + if (configfile) { + free(configfile); + configfile = NULL; + } free_config_resources(); if (debug_level > 10) { @@ -571,6 +575,7 @@ void terminate_stored(int sig) term_msg(); stop_watchdog(); cleanup_tls(); + free_volume_list(); close_memory_pool(); sm_dump(false); /* dump orphaned buffers */ diff --git a/bacula/src/version.h b/bacula/src/version.h index 8ab1cb03eb..a9182f5c2a 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION -#define VERSION "1.37.21" -#define BDATE "05 June 2005" -#define LSMDATE "05Jun05" +#define VERSION "1.37.22" +#define BDATE "10 June 2005" +#define LSMDATE "10Jun05" /* Debug flags */ #undef DEBUG diff --git a/bacula/src/wx-console/authenticate.c b/bacula/src/wx-console/authenticate.c index 0ae446869b..d8d53a564d 100644 --- a/bacula/src/wx-console/authenticate.c +++ b/bacula/src/wx-console/authenticate.c @@ -11,21 +11,18 @@ * */ /* - Copyright (C) 2001-2004 Kern Sibbald and John Walker + Copyright (C) 2001-2005 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. + version 2 as ammended 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional 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" @@ -55,6 +52,7 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) int tls_remote_need = BNET_TLS_NONE; char bashed_name[MAX_NAME_LENGTH]; char *password; + TLS_CONTEXT *tls_ctx = NULL; /* * Send my name to the Director then do authentication @@ -63,38 +61,89 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons) bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name)); bash_spaces(bashed_name); password = cons->password; + /* TLS Requirement */ + if (cons->tls_enable) { + if (cons->tls_require) { + tls_local_need = BNET_TLS_REQUIRED; + } else { + tls_local_need = BNET_TLS_OK; + } + } + + tls_ctx = cons->tls_ctx; } else { bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); password = director->password; + /* TLS Requirement */ + if (director->tls_enable) { + if (director->tls_require) { + tls_local_need = BNET_TLS_REQUIRED; + } else { + tls_local_need = BNET_TLS_OK; + } + } + + tls_ctx = director->tls_ctx; } + + /* Timeout Hello after 5 mins */ btimer_t *tid = start_bsock_timer(dir, 60 * 5); bnet_fsend(dir, hello, bashed_name); if (!cram_md5_get_auth(dir, password, &tls_remote_need) || !cram_md5_auth(dir, password, tls_local_need)) { - stop_bsock_timer(tid); - csprint("Director authorization problem.\nMost likely the passwords do not agree.\n", CS_DATA); - csprint( - "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n", CS_DATA); - return 0; + goto bail_out; + } + + /* Verify that the remote host is willing to meet our TLS requirements */ + if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { + csprint(_("Authorization problem:" + " Remote server did not advertise required TLS support.\n")); + goto bail_out; + } + + /* Verify that we are willing to meet the remote host's requirements */ + if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) { + csprint(_("Authorization problem:" + " Remote server requires TLS.\n")); + goto bail_out; + } + + /* Is TLS Enabled? */ + if (have_tls) { + if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { + /* Engage TLS! Full Speed Ahead! */ + if (!bnet_tls_client(tls_ctx, dir)) { + csprint(_("TLS negotiation failed\n")); + goto bail_out; + } + } } Dmsg1(6, ">dird: %s", dir->msg); if (bnet_recv(dir) <= 0) { - stop_bsock_timer(tid); csprint("Bad response to Hello command: ERR=", CS_DATA); csprint(bnet_strerror(dir), CS_DATA); csprint("\n", CS_DATA); - return 0; + goto bail_out; } Dmsg1(10, "msg); - stop_bsock_timer(tid); if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) { csprint("Director rejected Hello command\n", CS_DATA); - return 0; + goto bail_out; } else { csprint(dir->msg, CS_DATA); } + stop_bsock_timer(tid); return 1; + +bail_out: + stop_bsock_timer(tid); + csprint( _("Director authorization problem.\n" + "Most likely the passwords do not agree.\n" + "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n" + "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n")); + return 0; + } diff --git a/bacula/src/wx-console/console_conf.c b/bacula/src/wx-console/console_conf.c index 440987cbcf..7e33ca6531 100644 --- a/bacula/src/wx-console/console_conf.c +++ b/bacula/src/wx-console/console_conf.c @@ -19,25 +19,22 @@ * * Kern Sibbald, January MM, September MM */ - /* - Copyright (C) 2000, 2001 Kern Sibbald and John Walker + Copyright (C) 2000-2005 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. + version 2 as ammended 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional 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 "console_conf.h" @@ -79,8 +76,13 @@ static RES_ITEM cons_items[] = { {"description", store_str, ITEM(res_cons.hdr.desc), 0, 0, 0}, {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0}, {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0}, - {"requiressl", store_yesno, ITEM(res_cons.require_ssl), 1, ITEM_DEFAULT, 0}, {"password", store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0}, + {"tlsenable", store_yesno, ITEM(res_cons.tls_enable), 1, ITEM_DEFAULT, 0}, + {"tlsrequire", store_yesno, ITEM(res_cons.tls_require), 1, ITEM_DEFAULT, 0}, + {"tlscacertificatefile", store_dir, ITEM(res_cons.tls_ca_certfile), 0, 0, 0}, + {"tlscacertificatedir", store_dir, ITEM(res_cons.tls_ca_certdir), 0, 0, 0}, + {"tlscertificate", store_dir, ITEM(res_cons.tls_certfile), 0, 0, 0}, + {"tlskey", store_dir, ITEM(res_cons.tls_keyfile), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -92,7 +94,12 @@ static RES_ITEM dir_items[] = { {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101}, {"address", store_str, ITEM(res_dir.address), 0, 0, 0}, {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0}, - {"enablessl", store_yesno, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0}, + {"tlsenable", store_yesno, ITEM(res_dir.tls_enable), 1, ITEM_DEFAULT, 0}, + {"tlsrequire", store_yesno, ITEM(res_dir.tls_require), 1, ITEM_DEFAULT, 0}, + {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0}, + {"tlscacertificatedir", store_dir, ITEM(res_dir.tls_ca_certdir), 0, 0, 0}, + {"tlscertificate", store_dir, ITEM(res_dir.tls_certfile), 0, 0, 0}, + {"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -103,7 +110,7 @@ static RES_ITEM dir_items[] = { RES_TABLE resources[] = { {"console", cons_items, R_CONSOLE}, {"director", dir_items, R_DIRECTOR}, - {NULL, NULL, 0} + {NULL, NULL, 0} }; @@ -117,21 +124,21 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm printf("No record for %d %s\n", type, res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_CONSOLE: - printf("Console: name=%s rcfile=%s histfile=%s\n", reshdr->name, + printf("Console: name=%s rcfile=%s histfile=%s\n", reshdr->name, res->res_cons.rc_file, res->res_cons.hist_file); break; case R_DIRECTOR: - printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, + printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, res->res_dir.address, res->res_dir.DIRport); break; default: - printf("Unknown resource type %d\n", type); + printf("Unknown resource type %d\n", type); } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock); @@ -163,20 +170,51 @@ void free_resource(RES *sres, int type) } switch (type) { - case R_CONSOLE: - if (res->res_cons.rc_file) { - free(res->res_cons.rc_file); - } - if (res->res_cons.hist_file) { - free(res->res_cons.hist_file); - } - case R_DIRECTOR: - if (res->res_dir.address) - free(res->res_dir.address); - break; - default: - printf("Unknown resource type %d\n", type); - } + case R_CONSOLE: + if (res->res_cons.rc_file) { + free(res->res_cons.rc_file); + } + if (res->res_cons.hist_file) { + free(res->res_cons.hist_file); + } + if (res->res_cons.tls_ctx) { + free_tls_context(res->res_cons.tls_ctx); + } + if (res->res_cons.tls_ca_certfile) { + free(res->res_cons.tls_ca_certfile); + } + if (res->res_cons.tls_ca_certdir) { + free(res->res_cons.tls_ca_certdir); + } + if (res->res_cons.tls_certfile) { + free(res->res_cons.tls_certfile); + } + if (res->res_cons.tls_keyfile) { + free(res->res_cons.tls_keyfile); + } + case R_DIRECTOR: + if (res->res_dir.address) { + free(res->res_dir.address); + } + if (res->res_dir.tls_ctx) { + free_tls_context(res->res_dir.tls_ctx); + } + if (res->res_dir.tls_ca_certfile) { + free(res->res_dir.tls_ca_certfile); + } + if (res->res_dir.tls_ca_certdir) { + free(res->res_dir.tls_ca_certdir); + } + if (res->res_dir.tls_certfile) { + free(res->res_dir.tls_certfile); + } + if (res->res_dir.tls_keyfile) { + free(res->res_dir.tls_keyfile); + } + break; + default: + printf("Unknown resource type %d\n", type); + } /* Common stuff again -- free the resource, recurse to next one */ free(res); if (nres) { @@ -201,9 +239,9 @@ void save_resource(int type, RES_ITEM *items, int pass) for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { - Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n", + Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n", items[i].name, resources[rindex]); - } + } } } @@ -220,7 +258,7 @@ void save_resource(int type, RES_ITEM *items, int pass) break; default: - Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); + Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type); error = 1; break; } @@ -247,7 +285,7 @@ void save_resource(int type, RES_ITEM *items, int pass) size = sizeof(DIRRES); break; default: - printf("Unknown resource type %d\n", type); + printf("Unknown resource type %d\n", type); error = 1; size = 1; break; @@ -262,14 +300,14 @@ void save_resource(int type, RES_ITEM *items, int pass) RES *next; for (next=res_head[rindex]; next->next; next=next->next) { if (strcmp(next->name, res->res_dir.hdr.name) == 0) { - Emsg2(M_ERROR_TERM, 0, - _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), - resources[rindex].name, res->res_dir.hdr.name); + Emsg2(M_ERROR_TERM, 0, + _("Attempt to define second %s resource named \"%s\" is not permitted.\n"), + resources[rindex].name, res->res_dir.hdr.name); } } next->next = (RES *)res; - Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), + res->res_dir.hdr.name); } } } diff --git a/bacula/src/wx-console/console_conf.h b/bacula/src/wx-console/console_conf.h index d7e70c2a1a..2cc1314677 100644 --- a/bacula/src/wx-console/console_conf.h +++ b/bacula/src/wx-console/console_conf.h @@ -1,22 +1,19 @@ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + * Version $Id$ + */ +/* + Copyright (C) 2000-2005 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. + version 2 as ammended 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional 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. - */ -/* - * Version $Id$ */ #ifndef CONSOLECONF_H @@ -52,8 +49,15 @@ struct s_res_con { RES hdr; char *rc_file; /* startup file */ char *hist_file; /* command history file */ - int require_ssl; /* Require SSL on all connections */ char *password; /* UA server password */ + int tls_enable; /* Enable TLS on all connections */ + int tls_require; /* Require TLS on all connections */ + char *tls_ca_certfile; /* TLS CA Certificate File */ + char *tls_ca_certdir; /* TLS CA Certificate Directory */ + char *tls_certfile; /* TLS Client Certificate File */ + char *tls_keyfile; /* TLS Client Key File */ + + TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; typedef struct s_res_con CONRES; @@ -63,7 +67,14 @@ struct s_res_dir { int DIRport; /* UA server port */ char *address; /* UA server address */ char *password; /* UA server password */ - int enable_ssl; /* Use SSL */ + int tls_enable; /* Enable TLS on all connections */ + int tls_require; /* Require TLS on all connections */ + char *tls_ca_certfile; /* TLS CA Certificate File */ + char *tls_ca_certdir; /* TLS CA Certificate Directory */ + char *tls_certfile; /* TLS Client Certificate File */ + char *tls_keyfile; /* TLS Client Key File */ + + TLS_CONTEXT *tls_ctx; /* Shared TLS Context */ }; typedef struct s_res_dir DIRRES; -- 2.39.5