X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=restore-src%2Famidxtaped.c;h=78abffd899205913c3c9f093df66928b2c36e4bc;hb=b6ea83cedbf3e034fa91d66a7f180f788f34f907;hp=93d93506577a6b55531aba9b60122906e4ad545b;hpb=71325c297e0436e9930a3e129a26696e78c27f62;p=debian%2Famanda diff --git a/restore-src/amidxtaped.c b/restore-src/amidxtaped.c index 93d9350..78abffd 100644 --- a/restore-src/amidxtaped.c +++ b/restore-src/amidxtaped.c @@ -23,7 +23,7 @@ * Authors: the Amanda Development Team. Its members are listed in a * file named AUTHORS, in the root directory of this distribution. */ -/* $Id: amidxtaped.c,v 1.73.2.1 2006/09/27 12:04:09 martinea Exp $ +/* $Id: amidxtaped.c,v 1.73 2006/07/25 19:06:46 martinea Exp $ * * This daemon extracts a dump image off a tape for amrecover and * returns it over the network. It basically, reads a number of @@ -36,21 +36,27 @@ #include "version.h" #include "clock.h" #include "restore.h" +#include "cmdline.h" #include "changer.h" -#include "tapeio.h" #include "conffile.h" #include "logfile.h" #include "amfeatures.h" #include "stream.h" #include "amandad.h" +#include "server_util.h" + +#define amidxtaped_debug(i,x) do { \ + if ((i) <= debug_amidxtaped) { \ + dbprintf(x); \ + } \ +} while (0) #define TIMEOUT 30 static char *pgm = "amidxtaped"; /* in case argv[0] is not set */ extern char *rst_conf_logfile; -extern char *config_dir; static int get_lock = 0; static int from_amandad; @@ -84,16 +90,15 @@ get_client_line(FILE *in) while(1) { if((part = agets(in)) == NULL) { if(errno != 0) { - dbprintf(("%s: read error: %s\n", - debug_prefix_time(NULL), strerror(errno))); + dbprintf(_("read error: %s\n"), strerror(errno)); } else { - dbprintf(("%s: EOF reached\n", debug_prefix_time(NULL))); + dbprintf(_("EOF reached\n")); } if(line) { - dbprintf(("%s: unprocessed input:\n", debug_prefix_time(NULL))); - dbprintf(("-----\n")); - dbprintf(("%s\n", line)); - dbprintf(("-----\n")); + dbprintf(_("s: unprocessed input:\n")); + dbprintf("-----\n"); + dbprintf("%s\n", line); + dbprintf("-----\n"); } amfree(line); amfree(part); @@ -119,7 +124,7 @@ get_client_line(FILE *in) */ strappend(line, "\n"); } - dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line)); + dbprintf("> %s\n", line); return line; } @@ -147,8 +152,8 @@ get_client_line_fd( /* Keep looping if failure is temporary */ continue; } - dbprintf(("%s: Control pipe read error - %s\n", - pgm, strerror(errno))); + dbprintf(_("%s: Control pipe read error - %s\n"), + pgm, strerror(errno)); break; } @@ -156,7 +161,7 @@ get_client_line_fd( line_size *= 2; line = realloc(line, line_size); if (line == NULL) { - error("Memory reallocation failure"); + error(_("Memory reallocation failure")); /*NOTREACHED*/ } s = &line[len]; @@ -182,22 +187,21 @@ void check_security_buffer( char * buffer) { - socklen_t i; + socklen_t_equiv i; struct sockaddr_in addr; char *s, *fp, ch; char *errstr = NULL; - dbprintf(("%s: check_security_buffer(buffer='%s')\n", - debug_prefix(NULL), buffer)); + dbprintf(_("check_security_buffer(buffer='%s')\n"), buffer); i = SIZEOF(addr); if (getpeername(0, (struct sockaddr *)&addr, &i) == -1) { - error("getpeername: %s", strerror(errno)); + error(_("getpeername: %s"), strerror(errno)); /*NOTREACHED*/ } if ((addr.sin_family != (sa_family_t)AF_INET) || (ntohs(addr.sin_port) == 20)) { - error("connection rejected from %s family %d port %d", + error(_("connection rejected from %s family %d port %d"), inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port)); /*NOTREACHED*/ } @@ -208,19 +212,19 @@ check_security_buffer( skip_whitespace(s, ch); if (ch == '\0') { - error("cannot parse SECURITY line"); + error(_("cannot parse SECURITY line")); /*NOTREACHED*/ } fp = s-1; skip_non_whitespace(s, ch); s[-1] = '\0'; if (strcmp(fp, "SECURITY") != 0) { - error("cannot parse SECURITY line"); + error(_("cannot parse SECURITY line")); /*NOTREACHED*/ } skip_whitespace(s, ch); - if (!check_security(&addr, s-1, 0, &errstr)) { - error("security check failed: %s", errstr); + if (!check_security((sockaddr_union *)&addr, s-1, 0, &errstr)) { + error(_("security check failed: %s"), errstr); /*NOTREACHED*/ } } @@ -233,9 +237,9 @@ main( char *buf = NULL; int data_sock = -1; in_port_t data_port = (in_port_t)-1; - socklen_t socklen; + socklen_t_equiv socklen; struct sockaddr_in addr; - match_list_t *match_list; + GSList *dumpspecs; tapelist_t *tapes = NULL; char *their_feature_string = NULL; rst_flags_t *rst_flags; @@ -245,6 +249,17 @@ main( char *conf_tapetype; tapetype_t *tape; char *line; + char *tapedev; + dumpspec_t *ds; + + /* + * 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(DATA_FD_OFFSET, 4); safe_cd(); @@ -284,25 +299,6 @@ main( safe_fd(-1, 0); } -#ifdef FORCE_USERID - - /* we'd rather not run as root */ - - if(geteuid() == 0) { - if(client_uid == (uid_t) -1) { - error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN); - /*NOTREACHED*/ - } - - /*@ignore@*/ - initgroups(CLIENT_LOGIN, client_gid); - /*@end@*/ - setgid(client_gid); - setuid(client_uid); - } - -#endif /* FORCE_USERID */ - /* initialize */ /* close stderr first so that debug file becomes it - amrestore chats to stderr, which we don't want going to client */ @@ -310,42 +306,22 @@ main( (void)close(STDERR_FILENO); dbopen(DBG_SUBDIR_SERVER); startclock(); - dbprintf(("%s: version %s\n", pgm, version())); -#ifdef DEBUG_CODE - if(dbfd() != -1 && dbfd() != STDERR_FILENO) - { - if(dup2(dbfd(),STDERR_FILENO) != STDERR_FILENO) - { - perror("amidxtaped can't redirect stderr to the debug file"); - dbprintf(("%s: can't redirect stderr to the debug file\n", - debug_prefix_time(NULL))); - return 1; - } - } -#else - if ((i = open("/dev/null", O_WRONLY)) == -1 || - (i != STDERR_FILENO && - (dup2(i, STDERR_FILENO) != STDERR_FILENO || - close(i) != 0))) { - perror("amidxtaped can't redirect stderr"); - return 1; - } -#endif + dbprintf(_("%s: version %s\n"), pgm, version()); + debug_dup_stderr_to_debug(); if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) { - dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n", - debug_prefix_time(NULL))); + dbprintf(_("WARNING: argv[0] not defined: check inetd.conf\n")); } if(from_amandad == 0) { socklen = SIZEOF(addr); if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1) { - error("getpeername: %s", strerror(errno)); + error(_("getpeername: %s"), strerror(errno)); /*NOTREACHED*/ } if ((addr.sin_family != (sa_family_t)AF_INET) || (ntohs(addr.sin_port) == 20)) { - error("connection rejected from %s family %d port %d", + error(_("connection rejected from %s family %d port %d"), inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port)); /*NOTREACHED*/ @@ -367,9 +343,9 @@ main( /* read the REQ packet */ for(; (line = agets(stdin)) != NULL; free(line)) { -#define sc "OPTIONS " - if(strncmp(line, sc, sizeof(sc)-1) == 0) { -#undef sc + if(strncmp_const(line, "OPTIONS ") == 0) { + if (g_options) + error(_("ERROR recover program sent multiple OPTIONS")); g_options = parse_g_options(line+8, 1); if(!g_options->hostname) { g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1); @@ -382,113 +358,111 @@ main( if(amandad_auth && g_options->auth) { if(strcasecmp(amandad_auth, g_options->auth) != 0) { - printf("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'\n", + g_printf(_("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'\n"), g_options->auth, amandad_auth); - error("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'", + error(_("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'"), g_options->auth, amandad_auth); /*NOTREACHED*/ } } /* send the REP packet */ - printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1); - printf("\n"); + g_printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1); + g_printf("\n"); fflush(stdout); fclose(stdin); fclose(stdout); cmdout = fdopen(ctlfdout, "a"); if (!cmdout) { - error("amidxtaped: Can't fdopen(ctlfdout): %s", strerror(errno)); + error(_("amidxtaped: Can't fdopen(ctlfdout): %s"), strerror(errno)); /*NOTREACHED*/ } cmdin = fdopen(ctlfdin, "r"); if (!cmdin) { - error("amidxtaped: Can't fdopen(ctlfdin): %s", strerror(errno)); + error(_("amidxtaped: Can't fdopen(ctlfdin): %s"), strerror(errno)); /*NOTREACHED*/ } } - /* get the number of arguments */ - match_list = alloc(SIZEOF(match_list_t)); - match_list->next = NULL; - match_list->hostname = ""; - match_list->datestamp = ""; - match_list->level = ""; - match_list->diskname = ""; - + ds = dumpspec_new(NULL, NULL, NULL, NULL); for (re_end = 0; re_end == 0; ) { + char *s, ch; amfree(buf); buf = stralloc(get_client_line(cmdin)); - if(strncmp(buf, "LABEL=", 6) == 0) { - tapes = unmarshal_tapelist_str(buf+6); + s = buf; + if(strncmp_const_skip(buf, "LABEL=", s, ch) == 0) { + tapes = unmarshal_tapelist_str(s); } - else if(strncmp(buf, "FSF=", 4) == 0) { - rst_flags->fsf = OFF_T_ATOI(buf + 4); + else if(strncmp_const_skip(buf, "FSF=", s, ch) == 0) { + rst_flags->fsf = OFF_T_ATOI(s); } - else if(strncmp(buf, "HEADER", 6) == 0) { + else if(strncmp_const_skip(buf, "HEADER", s, ch) == 0) { rst_flags->headers = 1; } - else if(strncmp(buf, "FEATURES=", 9) == 0) { + else if(strncmp_const_skip(buf, "FEATURES=", s, ch) == 0) { char *our_feature_string = NULL; - their_feature_string = stralloc(buf+9); + their_feature_string = stralloc(s); am_release_feature_set(their_features); their_features = am_string_to_feature(their_feature_string); amfree(their_feature_string); our_feature_string = am_feature_to_string(our_features); if(from_amandad == 1) - fprintf(cmdout,"FEATURES=%s\r\n", our_feature_string); + g_fprintf(cmdout,"FEATURES=%s\r\n", our_feature_string); else - fprintf(cmdout,"%s", our_feature_string); + g_fprintf(cmdout,"%s", our_feature_string); fflush(cmdout); amfree(our_feature_string); } - else if(strncmp(buf, "DEVICE=", 7) == 0) { - rst_flags->alt_tapedev= stralloc(buf+7); + else if(strncmp_const_skip(buf, "DEVICE=", s, ch) == 0) { + rst_flags->alt_tapedev= stralloc(s); } - else if(strncmp(buf, "HOST=", 5) == 0) { - match_list->hostname = stralloc(buf+5); + else if(strncmp_const_skip(buf, "HOST=", s, ch) == 0) { + if (ds->host) { + dbprintf(_("WARNING: HOST appeared twice in client request.\n")); + amfree(ds->host); + } + ds->host = stralloc(s); } - else if(strncmp(buf, "DISK=", 5) == 0) { - match_list->diskname = stralloc(buf+5); + else if(strncmp_const_skip(buf, "DISK=", s, ch) == 0) { + if (ds->disk) { + dbprintf(_("WARNING: DISK appeared twice in client request.\n")); + amfree(ds->disk); + } + ds->disk = stralloc(s); } - else if(strncmp(buf, "DATESTAMP=", 10) == 0) { - match_list->datestamp = stralloc(buf+10); + else if(strncmp_const_skip(buf, "DATESTAMP=", s, ch) == 0) { + if (ds->datestamp) { + dbprintf(_("WARNING: DATESTAMP appeared twice in client request.\n")); + amfree(ds->datestamp); + } + ds->datestamp = stralloc(s); } - else if(strncmp(buf, "END", 3) == 0) { + else if(strncmp_const(buf, "END") == 0) { re_end = 1; } - else if(strncmp(buf, "CONFIG=", 7) == 0) { - re_config = stralloc(buf+7); + else if(strncmp_const_skip(buf, "CONFIG=", s, ch) == 0) { + re_config = stralloc(s); + if(strlen(re_config) == 0) + amfree(re_config); } else if(buf[0] != '\0' && buf[0] >= '0' && buf[0] <= '9') { -/* XXX does nothing? amrestore_nargs = atoi(buf); */ re_end = 1; } } amfree(buf); - if(!tapes && rst_flags->alt_tapedev){ - dbprintf(("%s: Looks like we're restoring from a holding file...\n", debug_prefix_time(NULL))); - tapes = unmarshal_tapelist_str(rst_flags->alt_tapedev); - tapes->isafile = 1; - amfree(rst_flags->alt_tapedev); - rst_flags->alt_tapedev = NULL; - } - if(re_config) { - char *conffile; - config_dir = vstralloc(CONFIG_DIR, "/", re_config, "/", NULL); - conffile = stralloc2(config_dir, CONFFILE_NAME); - if (read_conffile(conffile)) { - dbprintf(("%s: config '%s' not found\n", - debug_prefix_time(NULL), re_config)); - amfree(re_config); - re_config = NULL; - } - amfree(conffile); + config_init(CONFIG_INIT_EXPLICIT_NAME, re_config); + dbrename(re_config, DBG_SUBDIR_SERVER); + } else { + config_init(0, NULL); + } - dbrename(config_name, DBG_SUBDIR_SERVER); + if (config_errors(NULL) >= CFGERR_ERRORS) { + g_critical(_("errors processing config file")); } + check_running_as(RUNNING_AS_DUMPUSER_PREFERRED); + if(tapes && (!rst_flags->alt_tapedev || (re_config && ( strcmp(rst_flags->alt_tapedev, @@ -497,28 +471,43 @@ main( getconf_str(CNF_TPCHANGER)) == 0 ) ) ) ) { /* We need certain options, if restoring from more than one tape */ if(tapes->next && !am_has_feature(their_features, fe_recover_splits)) { - error("%s: Client must support split dumps to restore requested data.", get_pname()); + error(_("Client must support split dumps to restore requested data.")); /*NOTREACHED*/ } - dbprintf(("%s: Restoring from changer, checking labels\n", get_pname())); + dbprintf(_("Restoring from changer, checking labels\n")); rst_flags->check_labels = 1; use_changer = 1; } + /* build the dumpspec list from our single dumpspec */ + dumpspecs = g_slist_append(NULL, (gpointer)ds); + ds = NULL; + + if(!tapes && rst_flags->alt_tapedev){ + dbprintf(_("Looks like we're restoring from a holding file...\n")); + tapes = unmarshal_tapelist_str(rst_flags->alt_tapedev); + tapes->isafile = 1; + amfree(rst_flags->alt_tapedev); + rst_flags->alt_tapedev = NULL; + use_changer = FALSE; + } + + tapedev = getconf_str(CNF_TAPEDEV); /* If we'll be stepping on the tape server's devices, lock them. */ if(re_config && - (use_changer || (rst_flags->alt_tapedev && - strcmp(rst_flags->alt_tapedev, - getconf_str(CNF_TAPEDEV)) == 0) ) ) { - dbprintf(("%s: Locking devices\n", get_pname())); + (use_changer || (rst_flags->alt_tapedev && tapedev && + strcmp(rst_flags->alt_tapedev, tapedev) == 0) ) ) { + dbprintf(_("Locking devices\n")); parent_pid = getpid(); atexit(cleanup); get_lock = lock_logfile(); } + if (get_lock) + log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid()); /* Init the tape changer */ if(tapes && use_changer && changer_init() == 0) { - dbprintf(("%s: No changer available\n", debug_prefix_time(NULL))); + dbprintf(_("No changer available\n")); } /* Read the default block size from the tape type */ @@ -546,23 +535,22 @@ main( int data_fd; char *buf; - dbprintf(("%s: Client understands split dumpfiles\n",get_pname())); + dbprintf(_("Client understands split dumpfiles\n")); - if((data_sock = stream_server(&data_port, STREAM_BUFSIZE, + if((data_sock = stream_server(AF_INET, &data_port, STREAM_BUFSIZE, STREAM_BUFSIZE, 0)) < 0){ - error("%s: could not create data socket: %s", get_pname(), - strerror(errno)); + error(_("could not create data socket: %s"), strerror(errno)); /*NOTREACHED*/ } - dbprintf(("%s: Local port %d set aside for data\n", get_pname(), data_port)); + dbprintf(_("Local port %d set aside for data\n"), data_port); /* tell client where to connect */ - printf("CONNECT %hu\n", (unsigned short)data_port); + g_printf(_("CONNECT %hu\n"), (unsigned short)data_port); fflush(stdout); if((data_fd = stream_accept(data_sock, TIMEOUT, STREAM_BUFSIZE, STREAM_BUFSIZE)) < 0){ - error("stream_accept failed for client data connection: %s\n", + error(_("stream_accept failed for client data connection: %s\n"), strerror(errno)); /*NOTREACHED*/ } @@ -577,22 +565,22 @@ main( rst_flags->pipe_to_fd = fileno(stdout); cmdout = stderr; } - dbprintf(("%s: Sending output to file descriptor %d\n", - get_pname(), rst_flags->pipe_to_fd)); + dbprintf(_("Sending output to file descriptor %d\n"), rst_flags->pipe_to_fd); + tapedev = getconf_str(CNF_TAPEDEV); if(get_lock == 0 && re_config && - (use_changer || (rst_flags->alt_tapedev && - strcmp(rst_flags->alt_tapedev, - getconf_str(CNF_TAPEDEV)) == 0) ) ) { + (use_changer || (rst_flags->alt_tapedev && tapedev && + strcmp(rst_flags->alt_tapedev, tapedev) == 0) ) ) { + char *process_name = get_master_process(rst_conf_logfile); send_message(cmdout, rst_flags, their_features, - "%s exists: amdump or amflush is already running, " - "or you must run amcleanup", - rst_conf_logfile); - error("%s exists: amdump or amflush is already running, " - "or you must run amcleanup", - rst_conf_logfile); + _("%s exists: %s is already running, " + "or you must run amcleanup"), + rst_conf_logfile, process_name); + error(_("%s exists: %s is already running, " + "or you must run amcleanup"), + rst_conf_logfile, process_name); } /* make sure our restore flags aren't crazy */ @@ -600,14 +588,14 @@ main( if (rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd); send_message(cmdout, rst_flags, their_features, - "restore flags are crazy"); + _("restore flags are crazy")); exit(1); } /* actual restoration */ - search_tapes(cmdout, cmdin, use_changer, tapes, match_list, rst_flags, + search_tapes(cmdout, cmdin, use_changer, tapes, dumpspecs, rst_flags, their_features); - dbprintf(("%s: Restoration finished\n", debug_prefix_time(NULL))); + dbprintf(_("Restoration finished\n")); /* cleanup */ if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd); @@ -617,11 +605,7 @@ main( amfree(rst_flags->alt_tapedev); amfree(rst_flags); - amfree(match_list->hostname); - amfree(match_list->diskname); - amfree(match_list->datestamp); - amfree(match_list); - amfree(config_dir); + dumpspec_list_free(dumpspecs); amfree(re_config); dbclose(); return 0; @@ -630,7 +614,10 @@ main( static void cleanup(void) { - if(parent_pid == getpid()) { - if(get_lock) unlink(rst_conf_logfile); + if (parent_pid == getpid()) { + if (get_lock) { + log_add(L_INFO, "pid-done %ld\n", (long)getpid()); + unlink(rst_conf_logfile); + } } }