- 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
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).
#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
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
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) {
}
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) {
}
tls_ctx = director->tls_ctx;
-#endif /* HAVE_TLS */
}
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;
}
/*
*/
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, "<dird: %s", dir->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;
}
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.
*/
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) {
*
* 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.
*/
}
}
-#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.
return (strlen(buf));
}
-#endif
/*********************************************************************
#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);
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)) {
return 1;
}
}
-#endif /* HAVE_TLS */
UA_sock = bnet_connect(NULL, 5, 15, "Director daemon", dir->address,
NULL, dir->DIRport, 0);
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) {
director->hdr.name, configfile);
OK = false;
}
-#endif /* HAVE_TLS */
}
if (numdir == 0) {
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) {
OK = false;
}
}
-#endif /* HAVE_TLS */
UnlockRes();
* 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"
{"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}
};
{"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}
};
RES_TABLE resources[] = {
{"console", cons_items, R_CONSOLE},
{"director", dir_items, R_DIRECTOR},
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
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);
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);
*/
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]);
+ }
}
}
*/
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;
}
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);
}
}
}
*
* 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
R_CONSOLE = 1001,
R_DIRECTOR,
R_FIRST = R_CONSOLE,
- R_LAST = R_DIRECTOR /* Keep this updated */
+ R_LAST = R_DIRECTOR /* Keep this updated */
};
/*
/* 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 */
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 */
char *tls_keyfile; /* TLS Client Key File */
TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-#endif /* HAVE_TLS */
};
*
*/
/*
- 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.
*/
return 0;
}
-#ifdef HAVE_TLS
/* TLS Requirement */
if (store->tls_enable) {
if (store->tls_require) {
tls_local_need = BNET_TLS_OK;
}
}
-#endif
auth_success = cram_md5_get_auth(sd, store->password, &tls_remote_need);
if (auth_success) {
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) {
OK = false;
}
}
-#endif /* HAVE_TLS */
}
if (!job) {
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) {
OK = false;
}
}
-#endif /* HAVE_TLS */
}
/* Loop over all counters, defining them in each database */
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) {
}
}
-#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) {
}
}
}
-#endif /* HAVE_TLS */
UnlockRes();
if (OK) {
{"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},
{"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}
};
{"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},
{"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}
};
{"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}
};
{"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}
};
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);
}
if (res->res_dir.tls_allowed_cns) {
delete res->res_dir.tls_allowed_cns;
}
-#endif /* HAVE_TLS */
break;
case R_DEVICE:
case R_COUNTER:
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);
}
if (res->res_con.tls_allowed_cns) {
delete res->res_con.tls_allowed_cns;
}
-#endif /* HAVE_TLS */
for (int i=0; i<Num_ACL; i++) {
if (res->res_con.ACL_lists[i]) {
delete res->res_con.ACL_lists[i];
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);
}
if (res->res_client.tls_keyfile) {
free(res->res_client.tls_keyfile);
}
-#endif /* HAVE_TLS */
break;
case R_STORAGE:
if (res->res_store.address) {
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);
}
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) {
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) {
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.
*/
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 */
{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;
{"priority", 'p'},
{"spooldata", 's'},
{"writepartafterjob", 'W'},
- {NULL, 0}
+ {NULL, 0}
};
/*
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 */
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;
}
}
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);
}
*
* 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.
*/
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);
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
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);
}
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);
/* 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;
}
}
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;
if (pr.PoolId == 0) {
memset(&pr, 0, sizeof(pr));
if (!select_pool_dbr(ua, &pr)) {
- return 1;
+ return 1;
}
}
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) {
"==============\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);
}
/* 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;
* 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));
/* 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);
* 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];
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);
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);
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;
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);
/* 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 */
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);
for (vl=vol_list; vl; ) {
vol_list_t *ovl;
if (vl->VolName) {
- free(vl->VolName);
+ free(vl->VolName);
}
ovl = vl;
vl = vl->next;
while (bnet_recv(sd) >= 0) {
if (sscanf(sd->msg, "slots=%d\n", &slots) == 1) {
- break;
+ break;
} else {
bsendmsg(ua, "%s", sd->msg);
}
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;
}
*
* 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.
*/
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
}
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) {
i = -1;
while (fgets(line, sizeof(line), fd) != NULL) {
if (line[0] == ':') {
- i++;
+ i++;
}
if (i == item) {
- break;
+ break;
}
}
if (i != item) {
}
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 */
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:
}
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;
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':
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;
*o = 0;
for (i=0; i<9; i++) {
if (subst[i]) {
- free(subst[i]);
+ free(subst[i]);
}
}
free_pool_memory(query);
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) {
}
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: ");
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 */
/*
*
* 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.
*/
{ 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))
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;
}
* 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)
{
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;
/*
* - 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.
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) {
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++;
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];
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;
}
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) {
}
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) {
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;
}
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;
}
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)?"/":"");
}
}
}
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);
+ }
}
}
}
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;
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);
}
}
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;
}
}
/*
- * 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.
*/
/* 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;
}
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) {
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++;
+ }
+ }
}
}
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);
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);
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);
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.
*/
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) {
OK = false;
}
}
-
-#endif /* HAVE_TLS */
}
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) {
}
}
}
-#endif /* HAVE_TLS */
UnlockRes();
{"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}
};
{"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},
{"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}
};
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) {
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)
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);
* 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.
*/
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 */
alist *tls_allowed_cns; /* TLS Allowed Clients */
TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-#endif /* HAVE_TLS */
};
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 */
};
/*
- * Bacula File Daemon restore.c Restorefiles.
+ * Bacula File Daemon restore.c Restorefiles.
*
* Kern Sibbald, November MM
*
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.
*/
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.
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;
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;
/* 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));
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);
/*
* 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);
/* 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 */
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:
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() */
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);
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;
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;
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;
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;
}
*
*/
/*
- 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.
*/
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.
*/
for (j=0; j<incexe->name_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 */
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.
*/
/*
* 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.
*/
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;
} 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;
}
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)
{
* 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) {
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);
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++ = ' ';
*p++ = ' ';
/* Copy link name */
for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
- *p++ = *f++;
+ *p++ = *f++;
}
}
*p++ = '\n';
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;
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 */
}
/*
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;
}
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
* 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;
* 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:
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 */
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
*/
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 */
}
* 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;
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);
}
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;
* the length of the data packet which follows.
*
* Returns: false on failure
- * true on success
+ * true on success
*/
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;
}
/*
* 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)
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;
}
}
/*
* 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;
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 */
/*
* 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)
{
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;
}
}
}
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;
}
}
#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
/*
} 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);
}
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 */
#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;
*
*/
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;
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;
}
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;
}
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);
* 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());
}
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;
/*
* Format and send a message
* Returns: false on error
- * true on success
+ * true on success
*/
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);
}
* 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)
{
}
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) {
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);
}
}
* 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)
{
* 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));
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;
}
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);
}
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);
*
*/
/*
- 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
* 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;
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)
{
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);
}
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);
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;
#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
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;
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");
}
#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";
/* 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 */
/*
/* 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);
}
* 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)
close(fd);
} else {
for(i=1; fd + i <= 2; i++) {
- dup2(fd, fd+i);
+ dup2(fd, fd+i);
}
}
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;
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;
}
} 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));
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;
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());
}
}
*/
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 */
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);
}
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;
}
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;
}
}
}
{
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);
}
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 */
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;
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");
/* 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 */
}
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);
/*
* 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);
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
}
}
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;
+ }
}
}
}
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;
/*
* 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);
}
}
}
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);
}
}
if (details) {
len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
} else {
- len = 0;
+ len = 0;
}
#else
len = 0;
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);
}
}
}
* 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);
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);
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;
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 */
* 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:
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:
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);
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
/* 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);
/*
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));
return node;
}
-#ifdef USE_DLIST
/*
* This routine can be called to release the
* previously allocated tree node.
root->mem->rem += asize;
root->mem->mem -= asize;
}
-#endif
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);
}
*
*/
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);
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;
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 {
return node;
}
-#ifdef USE_DLIST
static int node_compare(void *item1, void *item2)
{
TREE_NODE *tn1 = (TREE_NODE *)item1;
}
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;
}
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) {
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) {
}
if (strcmp(path, "..") == 0) {
if (node->parent) {
- return node->parent;
+ return node->parent;
} else {
- return node;
+ return node;
}
}
if (path[0] == '/') {
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))) {
}
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);
}
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);
*
*/
/*
- 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())
/*
* 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;
* 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);
* 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
/* 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 */
/* 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 */
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.
*/
* 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;
/* 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");
/*
* 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
*/
* 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;
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 */
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);
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;
}
/* 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:
/* 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;
}
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
{
JCR *jcr = dcr->jcr;
BSOCK *dir = jcr->dir_bsock;
+ bool found = false;
Dmsg0(200, "dir_find_next_appendable_volume\n");
/*
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 {
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;
}
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");
/* 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);
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)
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)
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)
{
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)
{
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();
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;
}
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,
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"),
}
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)) {
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: "));
}
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: ",
}
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();
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);
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; }
}
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)) {
jcr->fileset_md5 = NULL;
}
if (jcr->VolList) {
- free_vol_list(jcr);
+ free_restore_volume_list(jcr);
}
if (jcr->dcr) {
free_dcr(jcr->dcr);
*
* 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
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;
}
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) {
*/
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"));
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);
* 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
{
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) {
}
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()) {
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;
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 */
struct stat filestat;
/*
* Handle opening of File Archive (not a tape)
- */
+ */
if (dev->part == 0) {
dev->file_size = 0;
}
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;
}
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;
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);
/*
* Rewind the device.
* Returns: true on success
- * false on failure
+ * false on failure
*/
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;
}
* 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;
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)
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;
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
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;
/*
*/
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();
* 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
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;
+ }
}
}
/*
/* 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;
* 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)
{
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;
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 */
/*
* Load medium in device
* Returns: true on success
- * false on failure
+ * false on failure
*/
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
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;
/*
* Rewind device and put it offline
* Returns: true on success
- * false on failure
+ * false on failure
*/
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());
/*
* Foward space a file
* Returns: true on success
- * false on failure
+ * false on failure
*/
bool
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();
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);
} 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);
/*
* Backward space a file
* Returns: false on failure
- * true on success
+ * true on success
*/
bool
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");
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;
/*
* Foward space num records
* Returns: false on failure
- * true on success
+ * true on success
*/
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;
/*
* Backward space a record
* Returns: false on failure
- * true on success
+ * true on success
*/
bool
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;
/*
* 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)
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;
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);
}
/*
* 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)
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;
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++;
}
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 */
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());
}
}
/*
* 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)
{
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());
}
}
/* ******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;
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;
/* ******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;
* 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;
}
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;
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;
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;
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;
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;
}
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! */
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
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.
*/
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;
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.
*/
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);
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());
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());
}
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);
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.
*/
*
* 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.
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 */
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;
}
/* 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);
}
}
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;
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;
}
*/
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);
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
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");
/* 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");
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,
*/
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;
}
}
}
* 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)
{
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);
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);
/*
* 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.
*
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;
}
}
/*
* 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;
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;
}
* 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)
{
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));
+ }
}
/*
* 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 */
}
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
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);
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);
}
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);
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);
/* Write session label
* Returns: false on failure
- * true on success
+ * true on success
*/
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:
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;
}
* 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)
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;
}
}
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);
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;
"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];
"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];
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;
* 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.
*/
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 */
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;
}
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);
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.
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);
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 */
}
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;
+}
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)
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);
*/
for ( ; bsr; bsr=bsr->next) {
if (!(bsr->sesstime && bsr->sessid)) {
- return false;
+ return false;
}
}
return true;
{
/*
* 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;
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;
}
}
if (!bsr->volume) {
Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"),
- lc->str);
+ lc->str);
return bsr;
}
BSR_VOLUME *bv;
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;
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;
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));
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;
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));
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;
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));
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;
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));
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;
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));
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;
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;
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;
/*********************************************************************
*
- * Free bsr resources
+ * Free bsr resources
*/
static void free_bsr_item(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));
* 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;
* 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;
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;
}
}
}
*
* 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.
*/
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);
/* 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);
/* 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);
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);
/*
* Read Data and send to File Daemon
* Returns: false on failure
- * true on success
+ * true on success
*/
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;
}
/* 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;
}
ok = false;
}
- free_vol_list(jcr);
+ free_restore_volume_list(jcr);
Dmsg0(30, "Done reading.\n");
return ok;
}
/*
* 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)
{
/* 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);
/* 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;
}
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);
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)
{
/*
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;
return ok;
}
+
+
+
/*
* Search for a particular storage device with particular storage
* characteristics (MediaType).
*
*/
/*
- 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.
*/
}
}
// UnlockRes();
+ bnet_fsend(user, "====\n\n");
+ bnet_fsend(user, "Volume status:\n");
+ list_volumes(user);
+
#ifdef xxx
if (debug_level > 0) {
/* 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
*/
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) {
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) {
term_msg();
stop_watchdog();
cleanup_tls();
+ free_volume_list();
close_memory_pool();
sm_dump(false); /* dump orphaned buffers */
/* */
#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
*
*/
/*
- 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"
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
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, "<dird: %s", dir->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;
+
}
*
* 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"
{"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}
};
{"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}
};
RES_TABLE resources[] = {
{"console", cons_items, R_CONSOLE},
{"director", dir_items, R_DIRECTOR},
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
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);
}
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) {
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]);
- }
+ }
}
}
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;
}
size = sizeof(DIRRES);
break;
default:
- printf("Unknown resource type %d\n", type);
+ printf("Unknown resource type %d\n", type);
error = 1;
size = 1;
break;
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);
}
}
}
/*
- 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
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;
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;