#include "event.h"
#include "security.h"
-#define amrecover_debug(i,x) do { \
+#define amrecover_debug(i, ...) do { \
if ((i) <= debug_amrecover) { \
- dbprintf(x); \
+ dbprintf(__VA_ARGS__); \
} \
} while (0)
void sigint_handler(int signum);
int main(int argc, char **argv);
-#define USAGE "Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n"
+#define USAGE _("Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n")
-char *config = NULL;
char *server_name = NULL;
int server_socket;
char *server_line = NULL;
char *dump_datestamp = NULL; /* date we are restoring */
char *dump_hostname; /* which machine we are restoring */
char *disk_name = NULL; /* disk we are restoring */
+dle_t *dump_dle = NULL;
char *mount_point = NULL; /* where disk was mounted */
char *disk_path = NULL; /* path relative to mount point */
char dump_date[STR_SIZE]; /* date on which we are restoring */
buf = NULL;
size = security_stream_read_sync(streams[MESGFD].fd, &buf);
if(size < 0) {
- amrecover_debug(1, ("%s: amrecover: get_line size < 0 (%zd)\n", debug_prefix_time(NULL), size));
+ amrecover_debug(1, "amrecover: get_line size < 0 (%zd)\n", size);
return -1;
}
else if(size == 0) {
- amrecover_debug(1, ("%s: amrecover: get_line size == 0 (%zd)\n", debug_prefix_time(NULL), size));
+ amrecover_debug(1, "amrecover: get_line size == 0 (%zd)\n", size);
return -1;
}
else if (buf == NULL) {
- amrecover_debug(1, ("%s: amrecover: get_line buf == NULL\n", debug_prefix_time(NULL)));
+ amrecover_debug(1, "amrecover: get_line buf == NULL\n");
return -1;
}
- amrecover_debug(1, ("%s: amrecover: get_line size = %zd\n", debug_prefix_time(NULL), size));
+ amrecover_debug(1, "amrecover: get_line size = %zd\n", size);
newbuf = alloc(strlen(mesg_buffer)+size+1);
strncpy(newbuf, mesg_buffer, (size_t)(strlen(mesg_buffer) + size));
memcpy(newbuf+strlen(mesg_buffer), buf, (size_t)size);
server_line = newstralloc(server_line, mesg_buffer);
amfree(mesg_buffer);
mesg_buffer = newbuf;
+ amrecover_debug(1, "get: %s\n", mesg_buffer);
return 0;
}
extern char *optarg;
extern int optind;
char *line = NULL;
- char *conffile;
const security_driver_t *secdrv;
char *req = NULL;
int response_error;
- int new_argc;
- char **new_argv;
struct tm *tm;
+ config_overwrites_t *cfg_ovr;
+
+ /*
+ * Configure program for internationalization:
+ * 1) Only set the message locale for now.
+ * 2) Set textdomain for all amanda related programs to "amanda"
+ * We don't want to be forced to support dozens of message catalogs.
+ */
+ setlocale(LC_MESSAGES, "C");
+ textdomain("amanda");
safe_fd(-1, 0);
dbopen(DBG_SUBDIR_CLIENT);
-#ifndef IGNORE_UID_CHECK
- if (geteuid() != 0) {
- erroutput_type |= ERR_SYSLOG;
- error("amrecover must be run by root");
- /*NOTREACHED*/
- }
-#endif
-
localhost = alloc(MAX_HOSTNAME_LENGTH+1);
if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
- error("cannot determine local host name\n");
+ error(_("cannot determine local host name\n"));
/*NOTREACHED*/
}
localhost[MAX_HOSTNAME_LENGTH] = '\0';
- parse_conf(argc, argv, &new_argc, &new_argv);
+ /* load the base client configuration */
+ config_init(CONFIG_INIT_CLIENT, NULL);
- if (new_argc > 1 && new_argv[1][0] != '-') {
- /*
- * If the first argument is not an option flag, then we assume
- * it is a configuration name to match the syntax of the other
- * Amanda utilities.
- */
- char **new_argv1;
-
- new_argv1 = (char **) alloc((size_t)((new_argc + 1 + 1) * sizeof(*new_argv1)));
- new_argv1[0] = new_argv[0];
- new_argv1[1] = "-C";
- for (i = 1; i < new_argc; i++) {
- new_argv1[i + 1] = new_argv[i];
+ if (config_errors(NULL) >= CFGERR_WARNINGS) {
+ config_print_errors();
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
}
- new_argv1[i + 1] = NULL;
- new_argc++;
- amfree(new_argv);
- new_argv = new_argv1;
}
- while ((i = getopt(new_argc, new_argv, "C:s:t:d:U")) != EOF) {
+
+ /* treat amrecover-specific command line options as the equivalent
+ * -o command-line options to set configuration values */
+ cfg_ovr = new_config_overwrites(argc/2);
+
+ /* If the first argument is not an option flag, then we assume
+ * it is a configuration name to match the syntax of the other
+ * Amanda utilities. */
+ if (argc > 1 && argv[1][0] != '-') {
+ add_config_overwrite(cfg_ovr, "conf", argv[1]);
+
+ /* remove that option from the command line */
+ argv[1] = argv[0];
+ argv++; argc--;
+ }
+
+ /* now parse regular command-line '-' options */
+ while ((i = getopt(argc, argv, "o:C:s:t:d:U")) != EOF) {
switch (i) {
case 'C':
- add_client_conf(CNF_CONF, optarg);
+ add_config_overwrite(cfg_ovr, "conf", optarg);
break;
case 's':
- add_client_conf(CNF_INDEX_SERVER, optarg);
+ add_config_overwrite(cfg_ovr, "index_server", optarg);
break;
case 't':
- add_client_conf(CNF_TAPE_SERVER, optarg);
+ add_config_overwrite(cfg_ovr, "tape_server", optarg);
break;
case 'd':
- add_client_conf(CNF_TAPEDEV, optarg);
+ add_config_overwrite(cfg_ovr, "tapedev", optarg);
+ break;
+
+ case 'o':
+ add_config_overwrite_opt(cfg_ovr, optarg);
break;
case 'U':
case '?':
- (void)printf(USAGE);
+ (void)g_printf(USAGE);
return 0;
}
}
- if (optind != new_argc) {
- (void)fprintf(stderr, USAGE);
+ if (optind != argc) {
+ (void)g_fprintf(stderr, USAGE);
exit(1);
}
- our_features = am_init_feature_set();
- our_features_string = am_feature_to_string(our_features);
+ /* and now try to load the configuration named in that file */
+ apply_config_overwrites(cfg_ovr);
+ config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
+ getconf_str(CNF_CONF));
- conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
- if (read_clientconf(conffile) > 0) {
- error("error reading conffile: %s", conffile);
- /*NOTREACHED*/
- }
- amfree(conffile);
+ check_running_as(RUNNING_AS_ROOT);
- config = stralloc(getconf_str(CNF_CONF));
+ dbrename(get_config_name(), DBG_SUBDIR_CLIENT);
- conffile = vstralloc(CONFIG_DIR, "/", config, "/", "amanda-client.conf",
- NULL);
- if (read_clientconf(conffile) > 0) {
- error("error reading conffile: %s", conffile);
- /*NOTREACHED*/
- }
- amfree(conffile);
-
- dbrename(config, DBG_SUBDIR_CLIENT);
-
- report_bad_conf_arg();
+ our_features = am_init_feature_set();
+ our_features_string = am_feature_to_string(our_features);
server_name = NULL;
if (getconf_seen(CNF_INDEX_SERVER) == -2) { /* command line argument */
if (!server_name) {
server_name = getenv("AMANDA_SERVER");
if (server_name) {
- printf("Using index server from environment AMANDA_SERVER (%s)\n", server_name);
+ g_printf(_("Using index server from environment AMANDA_SERVER (%s)\n"), server_name);
}
}
if (!server_name) {
server_name = getconf_str(CNF_INDEX_SERVER);
}
if (!server_name) {
- error("No index server set");
+ error(_("No index server set"));
/*NOTREACHED*/
}
server_name = stralloc(server_name);
if (!tape_server_name) {
tape_server_name = getenv("AMANDA_TAPESERVER");
if (tape_server_name) {
- printf("Using tape server from environment AMANDA_TAPESERVER (%s)\n", tape_server_name);
+ g_printf(_("Using tape server from environment AMANDA_TAPESERVER (%s)\n"), tape_server_name);
}
} else {
- printf("Using tape server from environment AMANDA_TAPE_SERVER (%s)\n", tape_server_name);
+ g_printf(_("Using tape server from environment AMANDA_TAPE_SERVER (%s)\n"), tape_server_name);
}
}
if (!tape_server_name) {
tape_server_name = getconf_str(CNF_TAPE_SERVER);
}
if (!tape_server_name) {
- error("No tape server set");
+ error(_("No tape server set"));
/*NOTREACHED*/
}
tape_server_name = stralloc(tape_server_name);
amfree(tape_device_name);
tape_device_name = getconf_str(CNF_TAPEDEV);
- if (tape_device_name)
+ if (!tape_device_name ||
+ strlen(tape_device_name) == 0 ||
+ !getconf_seen(CNF_TAPEDEV)) {
+ tape_device_name = NULL;
+ } else {
tape_device_name = stralloc(tape_device_name);
+ }
authopt = stralloc(getconf_str(CNF_AUTH));
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGINT, &act, &oact) != 0) {
- error("error setting signal handler: %s", strerror(errno));
+ error(_("error setting signal handler: %s"), strerror(errno));
/*NOTREACHED*/
}
/* We assume that amindexd support fe_amindexd_options_features */
/* and fe_amindexd_options_auth */
/* We should send a noop to really know */
- req = vstralloc("SERVICE amindexd\n",
- "OPTIONS ", "features=", our_features_string, ";",
- "auth=", authopt, ";",
- "\n", NULL);
+ req = vstrallocf("SERVICE amindexd\n"
+ "OPTIONS features=%s;auth=%s;\n",
+ our_features_string, authopt);
secdrv = security_getdriver(authopt);
if (secdrv == NULL) {
- error("no '%s' security driver available for host '%s'",
+ error(_("no '%s' security driver available for host '%s'"),
authopt, server_name);
/*NOTREACHED*/
}
amfree(req);
protocol_run();
- printf("AMRECOVER Version %s. Contacting server on %s ...\n",
+ g_printf(_("AMRECOVER Version %s. Contacting server on %s ...\n"),
version(), server_name);
if(response_error != 0) {
- fprintf(stderr,"%s\n",errstr);
+ g_fprintf(stderr,"%s\n",errstr);
exit(1);
}
-#if 0
- /*
- * We may need root privilege again later for a reserved port to
- * the tape server, so we will drop down now but might have to
- * come back later.
- */
- setegid(getgid());
- seteuid(getuid());
-#endif
-
/* get server's banner */
if (grab_reply(1) == -1) {
aclose(server_socket);
{
char *their_feature_string = NULL;
- line = stralloc2("FEATURES ", our_features_string);
+ indexsrv_features = NULL;
+
+ line = vstrallocf("FEATURES %s", our_features_string);
if(exchange(line) == 0) {
their_feature_string = stralloc(server_line+13);
indexsrv_features = am_string_to_feature(their_feature_string);
+ if (!indexsrv_features)
+ g_printf(_("Bad feature string from server: %s"), their_feature_string);
}
- else {
+ if (!indexsrv_features)
indexsrv_features = am_set_default_feature_set();
- }
+
amfree(their_feature_string);
amfree(line);
}
if (tm)
strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm);
else
- error("BAD DATE");
+ error(_("BAD DATE"));
- printf("Setting restore date to today (%s)\n", dump_date);
- line = stralloc2("DATE ", dump_date);
+ g_printf(_("Setting restore date to today (%s)\n"), dump_date);
+ line = vstrallocf("DATE %s", dump_date);
if (converse(line) == -1) {
aclose(server_socket);
exit(1);
}
amfree(line);
- line = stralloc2("SCNF ", config);
+ line = vstrallocf("SCNF %s", get_config_name());
if (converse(line) == -1) {
aclose(server_socket);
exit(1);
amfree(dump_hostname);
set_host(localhost);
if (dump_hostname)
- printf("Use the setdisk command to choose dump disk to recover\n");
+ g_printf(_("Use the setdisk command to choose dump disk to recover\n"));
else
- printf("Use the sethost command to choose a host to recover\n");
+ g_printf(_("Use the sethost command to choose a host to recover\n"));
}
if (lineread[0] != '\0')
{
add_history(lineread);
+ dbprintf(_("user command: '%s'\n"), lineread);
process_line(lineread); /* act on line's content */
}
amfree(lineread);
assert(sech != NULL);
if (pkt == NULL) {
- errstr = newvstralloc(errstr, "[request failed: ",
- security_geterror(sech), "]", NULL);
+ errstr = newvstrallocf(errstr, _("[request failed: %s]"),
+ security_geterror(sech));
*response_error = 1;
return;
}
if (pkt->type == P_NAK) {
#if defined(PACKET_DEBUG)
- fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
+ dbprintf(_("got nak response:\n----\n%s\n----\n\n"), pkt->body);
#endif
tok = strtok(pkt->body, " ");
tok = strtok(NULL, "\n");
if (tok != NULL) {
- errstr = newvstralloc(errstr, "NAK: ", tok, NULL);
+ errstr = newvstrallocf(errstr, "NAK: %s", tok);
*response_error = 1;
} else {
bad_nak:
- errstr = newstralloc(errstr, "request NAK");
+ errstr = newvstrallocf(errstr, _("request NAK"));
*response_error = 2;
}
return;
}
if (pkt->type != P_REP) {
- errstr = newvstralloc(errstr, "received strange packet type ",
- pkt_type2str(pkt->type), ": ", pkt->body, NULL);
+ errstr = newvstrallocf(errstr, _("received strange packet type %s: %s"),
+ pkt_type2str(pkt->type), pkt->body);
*response_error = 1;
return;
}
#if defined(PACKET_DEBUG)
- fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
+ g_fprintf(stderr, _("got response:\n----\n%s\n----\n\n"), pkt->body);
#endif
for(i = 0; i < NSTREAMS; i++) {
*/
if (strcmp(tok, "ERROR") == 0) {
tok = strtok(NULL, "\n");
- if (tok == NULL)
- tok = "[bogus error packet]";
- errstr = newstralloc(errstr, tok);
+ if (tok == NULL) {
+ errstr = newvstrallocf(errstr, _("[bogus error packet]"));
+ } else {
+ errstr = newvstrallocf(errstr, "%s", tok);
+ }
*response_error = 2;
return;
}
for (i = 0; i < NSTREAMS; i++) {
tok = strtok(NULL, " ");
if (tok == NULL || strcmp(tok, streams[i].name) != 0) {
- extra = vstralloc("CONNECT token is \"",
- tok ? tok : "(null)",
- "\": expected \"",
- streams[i].name,
- "\"",
- NULL);
+ extra = vstrallocf(
+ _("CONNECT token is \"%s\": expected \"%s\""),
+ tok ? tok : _("(null)"), streams[i].name);
goto parse_error;
}
tok = strtok(NULL, " \n");
if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {
- extra = vstralloc("CONNECT ",
- streams[i].name,
- " token is \"",
- tok ? tok : "(null)",
- "\": expected a port number",
- NULL);
+ extra = vstrallocf(
+ _("CONNECT %s token is \"%s\" expected a port number"),
+ streams[i].name, tok ? tok : _("(null)"));
goto parse_error;
}
}
if (strcmp(tok, "OPTIONS") == 0) {
tok = strtok(NULL, "\n");
if (tok == NULL) {
- extra = stralloc("OPTIONS token is missing");
+ extra = vstrallocf(_("OPTIONS token is missing"));
goto parse_error;
}
-/*
+#if 0
tok_end = tok + strlen(tok);
while((p = strchr(tok, ';')) != NULL) {
*p++ = '\0';
tok += SIZEOF("features=") - 1;
am_release_feature_set(their_features);
if((their_features = am_string_to_feature(tok)) == NULL) {
- errstr = newvstralloc(errstr,
- "OPTIONS: bad features value: ",
- tok,
- NULL);
+ errstr = newvstrallocf(errstr,
+ _("OPTIONS: bad features value: %s"),
+ tok);
goto parse_error;
}
}
tok = p;
}
-*/
+#endif
continue;
}
-/*
- extra = vstralloc("next token is \"",
- tok ? tok : "(null)",
- "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"",
- NULL);
+#if 0
+ extra = vstrallocf(_("next token is \"%s\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\""), tok ? tok : _("(null)"));
goto parse_error;
-*/
+#endif
}
/*
continue;
streams[i].fd = security_stream_client(sech, ports[i]);
if (streams[i].fd == NULL) {
- errstr = newvstralloc(errstr,
- "[could not connect ", streams[i].name, " stream: ",
- security_geterror(sech), "]", NULL);
+ errstr = newvstrallocf(errstr,
+ _("[could not connect %s stream: %s]"),
+ streams[i].name, security_geterror(sech));
goto connect_error;
}
}
if (streams[i].fd == NULL)
continue;
if (security_stream_auth(streams[i].fd) < 0) {
- errstr = newvstralloc(errstr,
- "[could not authenticate ", streams[i].name, " stream: ",
- security_stream_geterror(streams[i].fd), "]", NULL);
+ errstr = newvstrallocf(errstr,
+ _("[could not authenticate %s stream: %s]"),
+ streams[i].name, security_stream_geterror(streams[i].fd));
goto connect_error;
}
}
* them, complain.
*/
if (streams[MESGFD].fd == NULL) {
- errstr = newstralloc(errstr, "[couldn't open MESG streams]");
+ errstr = newvstrallocf(errstr, _("[couldn't open MESG streams]"));
goto connect_error;
}
return;
parse_error:
- errstr = newvstralloc(errstr,
- "[parse of reply message failed: ",
- extra ? extra : "(no additional information)",
- "]",
- NULL);
+ errstr = newvstrallocf(errstr,
+ _("[parse of reply message failed: %s]"),
+ extra ? extra : _("(no additional information)"));
amfree(extra);
*response_error = 2;
return;