X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famflush.c;h=4d28e44755118821311cffa1a934d9a8234fa689;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=f6a5df5d79315905ccc0d9fa73aec2481e9df0ea;hpb=0de2ad0a86685398621fb8ffa6990c029681bb3a;p=debian%2Famanda diff --git a/server-src/amflush.c b/server-src/amflush.c index f6a5df5..4d28e44 100644 --- a/server-src/amflush.c +++ b/server-src/amflush.c @@ -24,21 +24,22 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: amflush.c,v 1.41.2.13.4.6.2.9.2.2 2004/10/20 21:49:26 martinea Exp $ + * $Id: amflush.c,v 1.95 2006/07/25 21:41:24 martinea Exp $ * * write files from work directory onto tape */ #include "amanda.h" +#include "match.h" +#include "find.h" #include "conffile.h" #include "diskfile.h" #include "tapefile.h" #include "logfile.h" #include "clock.h" -#include "version.h" #include "holding.h" -#include "driverio.h" #include "server_util.h" +#include "timestamp.h" static char *conf_logdir; FILE *driver_stream; @@ -46,69 +47,82 @@ char *driver_program; char *reporter_program; char *logroll_program; char *datestamp; -sl_t *datestamp_list; +char *amflush_timestamp; +char *amflush_datestamp; /* local functions */ -int main P((int main_argc, char **main_argv)); -void flush_holdingdisk P((char *diskdir, char *datestamp)); -void confirm P((void)); -void redirect_stderr P((void)); -void detach P((void)); -void run_dumps P((void)); - - -int main(main_argc, main_argv) -int main_argc; -char **main_argv; +void flush_holdingdisk(char *diskdir, char *datestamp); +static GSList * pick_datestamp(void); +void confirm(GSList *datestamp_list); +void redirect_stderr(void); +void detach(void); +void run_dumps(void); +static int get_letter_from_user(void); + +int +main( + int argc, + char ** argv) { int foreground; int batch; int redirect; - struct passwd *pw; - char *dumpuser; char **datearg = NULL; int nb_datearg = 0; - int fd; - char *conffile; char *conf_diskfile; char *conf_tapelist; char *conf_logfile; - disklist_t *diskqp; + int conf_usetimestamps; + disklist_t diskq; disk_t *dp; - pid_t pid, driver_pid, reporter_pid; + pid_t pid; + pid_t driver_pid, reporter_pid; amwait_t exitcode; int opt; - dumpfile_t file; - sl_t *holding_list=NULL; - sle_t *holding_file; + GSList *holding_list=NULL, *holding_file; int driver_pipe[2]; char date_string[100]; + char date_string_standard[100]; time_t today; + char *errstr; + struct tm *tm; + char *tapedev; + char *tpchanger; + char *qdisk, *qhname; + GSList *datestamp_list = NULL; + config_overrides_t *cfg_ovr; + char **config_options; + find_result_t *holding_files; + disklist_t holding_disklist = { NULL, NULL }; - for(fd = 3; fd < FD_SETSIZE; fd++) { - /* - * Make sure nobody spoofs us with a lot of extra open files - * that would cause an open we do to get a very high file - * descriptor, which in turn might be used as an index into - * an array (e.g. an fd_set). - */ - close(fd); - } - + /* + * 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); safe_cd(); set_pname("amflush"); + /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); - erroutput_type = ERR_INTERACTIVE; + dbopen(DBG_SUBDIR_SERVER); + + add_amanda_log_handler(amanda_log_stderr); foreground = 0; batch = 0; redirect = 1; /* process arguments */ - while((opt = getopt(main_argc, main_argv, "bfsD:")) != EOF) { + cfg_ovr = new_config_overrides(argc/2); + while((opt = getopt(argc, argv, "bfso:D:")) != EOF) { switch(opt) { case 'b': batch = 1; break; @@ -116,10 +130,12 @@ char **main_argv; break; case 's': redirect = 0; break; + case 'o': add_config_override_opt(cfg_ovr, optarg); + break; case 'D': if (datearg == NULL) - datearg = alloc(21*sizeof(char *)); + datearg = alloc(21*SIZEOF(char *)); if(nb_datearg == 20) { - fprintf(stderr,"maximum of 20 -D arguments.\n"); + g_fprintf(stderr,_("maximum of 20 -D arguments.\n")); exit(1); } datearg[nb_datearg++] = stralloc(optarg); @@ -127,138 +143,180 @@ char **main_argv; break; } } + argc -= optind, argv += optind; + if(!foreground && !redirect) { - fprintf(stderr,"Can't redirect to stdout/stderr if not in forground.\n"); + g_fprintf(stderr,_("Can't redirect to stdout/stderr if not in forground.\n")); exit(1); } - main_argc -= optind, main_argv += optind; - - if(main_argc < 1) { - error("Usage: amflush%s [-b] [-f] [-s] [-D date]* [host [disk]* ]*", versionsuffix()); + if(argc < 1) { + error(_("Usage: amflush [-b] [-f] [-s] [-D date]* [-o configoption]* [host [disk]* ]*")); + /*NOTREACHED*/ } - config_name = main_argv[0]; + set_config_overrides(cfg_ovr); + config_init(CONFIG_INIT_EXPLICIT_NAME, + argv[0]); - config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL); - conffile = stralloc2(config_dir, CONFFILE_NAME); - if(read_conffile(conffile)) { - error("errors processing config file \"%s\"", conffile); - } - amfree(conffile); - conf_diskfile = getconf_str(CNF_DISKFILE); - if (*conf_diskfile == '/') { - conf_diskfile = stralloc(conf_diskfile); - } else { - conf_diskfile = stralloc2(config_dir, conf_diskfile); - } - if((diskqp = read_diskfile(conf_diskfile)) == NULL) { - error("could not read disklist file \"%s\"", conf_diskfile); - } - match_disklist(diskqp, main_argc-1, main_argv+1); + conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); + read_diskfile(conf_diskfile, &diskq); amfree(conf_diskfile); - conf_tapelist = getconf_str(CNF_TAPELIST); - if (*conf_tapelist == '/') { - conf_tapelist = stralloc(conf_tapelist); - } else { - conf_tapelist = stralloc2(config_dir, conf_tapelist); + + if (config_errors(NULL) >= CFGERR_WARNINGS) { + config_print_errors(); + if (config_errors(NULL) >= CFGERR_ERRORS) { + g_critical(_("errors processing config file")); + } } + + check_running_as(RUNNING_AS_DUMPUSER); + + dbrename(get_config_name(), DBG_SUBDIR_SERVER); + + /* load DLEs from the holding disk, in case there's anything to flush there */ + search_holding_disk(&holding_files, &holding_disklist); + /* note that the dumps are added to the global disklist, so we need not + * consult holding_files or holding_disklist after this. The holding-only + * dumps will be filtered properly by match_disklist, setting the dp->todo + * flag appropriately. */ + + errstr = match_disklist(&diskq, argc-1, argv+1); + if (errstr) { + g_printf(_("%s"),errstr); + amfree(errstr); + } + + conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST)); if(read_tapelist(conf_tapelist)) { - error("could not load tapelist \"%s\"", conf_tapelist); + error(_("could not load tapelist \"%s\""), conf_tapelist); + /*NOTREACHED*/ } amfree(conf_tapelist); - datestamp = construct_datestamp(NULL); + conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS); - dumpuser = getconf_str(CNF_DUMPUSER); - if((pw = getpwnam(dumpuser)) == NULL) - error("dumpuser %s not found in password file", dumpuser); - if(pw->pw_uid != getuid()) - error("must run amflush as user %s", dumpuser); - - conf_logdir = getconf_str(CNF_LOGDIR); - if (*conf_logdir == '/') { - conf_logdir = stralloc(conf_logdir); - } else { - conf_logdir = stralloc2(config_dir, conf_logdir); + amflush_datestamp = get_datestamp_from_time(0); + if(conf_usetimestamps == 0) { + amflush_timestamp = stralloc(amflush_datestamp); } + else { + amflush_timestamp = get_timestamp_from_time(0); + } + + conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); conf_logfile = vstralloc(conf_logdir, "/log", NULL); if (access(conf_logfile, F_OK) == 0) { - error("%s exists: amdump or amflush is already running, or you must run amcleanup", conf_logfile); + run_amcleanup(get_config_name()); + } + if (access(conf_logfile, F_OK) == 0) { + char *process_name = get_master_process(conf_logfile); + error(_("%s exists: %s is already running, or you must run amcleanup"), conf_logfile, process_name); + /*NOTREACHED*/ + } + + driver_program = vstralloc(amlibexecdir, "/", "driver", NULL); + reporter_program = vstralloc(sbindir, "/", "amreport", NULL); + logroll_program = vstralloc(amlibexecdir, "/", "amlogroll", NULL); + + tapedev = getconf_str(CNF_TAPEDEV); + tpchanger = getconf_str(CNF_TPCHANGER); + if (tapedev == NULL && tpchanger == NULL) { + error(_("No tapedev or tpchanger specified")); } - amfree(conf_logfile); - - driver_program = vstralloc(libexecdir, "/", "driver", versionsuffix(), - NULL); - reporter_program = vstralloc(sbindir, "/", "amreport", versionsuffix(), - NULL); - logroll_program = vstralloc(libexecdir, "/", "amlogroll", versionsuffix(), - NULL); + /* if dates were specified (-D), then use match_datestamp + * against the list of all datestamps to turn that list + * into a set of existing datestamps (basically, evaluate the + * expressions into actual datestamps) */ if(datearg) { - sle_t *dir, *next_dir; + GSList *all_datestamps; + GSList *datestamp; int i, ok; - datestamp_list = pick_all_datestamp(1); - for(dir = datestamp_list->first; dir != NULL;) { - next_dir = dir->next; + all_datestamps = holding_get_all_datestamps(); + for(datestamp = all_datestamps; datestamp != NULL; datestamp = datestamp->next) { ok = 0; for(i=0; iname); - } - if(ok == 0) { /* remove dir */ - remove_sl(datestamp_list, dir); + ok = match_datestamp(datearg[i], (char *)datestamp->data); } - dir = next_dir; + if (ok) + datestamp_list = g_slist_insert_sorted(datestamp_list, + stralloc((char *)datestamp->data), + g_compare_strings); } + g_slist_free_full(all_datestamps); } else { + /* otherwise, in batch mode, use all datestamps */ if(batch) { - datestamp_list = pick_all_datestamp(1); + datestamp_list = holding_get_all_datestamps(); } + /* or allow the user to pick datestamps */ else { - datestamp_list = pick_datestamp(1); + datestamp_list = pick_datestamp(); } } - if(is_empty_sl(datestamp_list)) { - printf("Could not find any Amanda directories to flush.\n"); + if(!datestamp_list) { + g_printf(_("Could not find any Amanda directories to flush.\n")); exit(1); } - holding_list = get_flush(datestamp_list, NULL, 1, 0); - if(holding_list->first == NULL) { - printf("Could not find any valid dump image, check directory.\n"); + holding_list = holding_get_files_for_flush(datestamp_list); + if (holding_list == NULL) { + g_printf(_("Could not find any valid dump image, check directory.\n")); exit(1); } - if(!batch) confirm(); + if (access(conf_logfile, F_OK) == 0) { + char *process_name = get_master_process(conf_logfile); + error(_("%s exists: someone started %s"), conf_logfile, process_name); + /*NOTREACHED*/ + } + log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid()); + + if(!batch) confirm(datestamp_list); - for(dp = diskqp->head; dp != NULL; dp = dp->next) { - if(dp->todo) - log_add(L_DISK, "%s %s", dp->host->hostname, dp->name); + for(dp = diskq.head; dp != NULL; dp = dp->next) { + if(dp->todo) { + char *qname; + qname = quote_string(dp->name); + log_add(L_DISK, "%s %s", dp->host->hostname, qname); + amfree(qname); + } } if(!foreground) { /* write it before redirecting stdout */ - puts("Running in background, you can log off now."); - puts("You'll get mail when amflush is finished."); + puts(_("Running in background, you can log off now.")); + puts(_("You'll get mail when amflush is finished.")); } if(redirect) redirect_stderr(); if(!foreground) detach(); - erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE); - set_logerror(logerror); + add_amanda_log_handler(amanda_log_stderr); + add_amanda_log_handler(amanda_log_trace_log); today = time(NULL); - strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", localtime (&today)); - fprintf(stderr, "amflush: start at %s\n", date_string); - fprintf(stderr, "amflush: datestamp %s\n", datestamp); - log_add(L_START, "date %s", datestamp); + tm = localtime(&today); + if (tm) { + strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", tm); + strftime(date_string_standard, 100, "%Y-%m-%d %H:%M:%S %Z", tm); + } else { + error(_("BAD DATE")); /* should never happen */ + } + g_fprintf(stderr, _("amflush: start at %s\n"), date_string); + g_fprintf(stderr, _("amflush: datestamp %s\n"), amflush_timestamp); + g_fprintf(stderr, _("amflush: starttime %s\n"), amflush_timestamp); + g_fprintf(stderr, _("amflush: starttime-locale-independent %s\n"), + date_string_standard); + log_add(L_START, _("date %s"), amflush_timestamp); /* START DRIVER */ if(pipe(driver_pipe) == -1) { - error("error [opening pipe to driver: %s]", strerror(errno)); + error(_("error [opening pipe to driver: %s]"), strerror(errno)); + /*NOTREACHED*/ } if((driver_pid = fork()) == 0) { /* @@ -266,39 +324,71 @@ char **main_argv; */ dup2(driver_pipe[0], 0); close(driver_pipe[1]); - execle(driver_program, - "driver", config_name, "nodump", (char *)0, - safe_env()); - error("cannot exec %s: %s", driver_program, strerror(errno)); + config_options = get_config_options(3); + config_options[0] = "driver"; + config_options[1] = get_config_name(); + config_options[2] = "nodump"; + safe_fd(-1, 0); + execve(driver_program, config_options, safe_env()); + error(_("cannot exec %s: %s"), driver_program, strerror(errno)); + /*NOTREACHED*/ } else if(driver_pid == -1) { - error("cannot fork for %s: %s", driver_program, strerror(errno)); + error(_("cannot fork for %s: %s"), driver_program, strerror(errno)); + /*NOTREACHED*/ } driver_stream = fdopen(driver_pipe[1], "w"); + if (!driver_stream) { + error(_("Can't fdopen: %s"), strerror(errno)); + /*NOTREACHED*/ + } - for(holding_file=holding_list->first; holding_file != NULL; + g_fprintf(driver_stream, "DATE %s\n", amflush_timestamp); + for(holding_file=holding_list; holding_file != NULL; holding_file = holding_file->next) { - get_dumpfile(holding_file->name, &file); + dumpfile_t file; + holding_file_get_dumpfile((char *)holding_file->data, &file); + + if (holding_file_size((char *)holding_file->data, 1) <= 0) { + g_debug("%s is empty - ignoring", (char *)holding_file->data); + log_add(L_INFO, "%s: removing file with no data.", + (char *)holding_file->data); + holding_file_unlink((char *)holding_file->data); + dumpfile_free_data(&file); + continue; + } + /* search_holding_disk should have already ensured that every + * holding dumpfile has an entry in the dynamic disklist */ dp = lookup_disk(file.name, file.disk); + assert(dp != NULL); + + /* but match_disklist may have indicated we should not flush it */ if (dp->todo == 0) continue; - fprintf(stderr, + qdisk = quote_string(file.disk); + qhname = quote_string((char *)holding_file->data); + g_fprintf(stderr, "FLUSH %s %s %s %d %s\n", file.name, - file.disk, + qdisk, file.datestamp, file.dumplevel, - holding_file->name); - fprintf(driver_stream, + qhname); + + g_debug("flushing '%s'", (char *)holding_file->data); + g_fprintf(driver_stream, "FLUSH %s %s %s %d %s\n", file.name, - file.disk, + qdisk, file.datestamp, file.dumplevel, - holding_file->name); + qhname); + amfree(qdisk); + amfree(qhname); + dumpfile_free_data(&file); } - fprintf(stderr, "ENDFLUSH\n"); fflush(stderr); - fprintf(driver_stream, "ENDFLUSH\n"); fflush(driver_stream); + g_fprintf(stderr, "ENDFLUSH\n"); fflush(stderr); + g_fprintf(driver_stream, "ENDFLUSH\n"); fflush(driver_stream); fclose(driver_stream); /* WAIT DRIVER */ @@ -307,16 +397,17 @@ char **main_argv; if(errno == EINTR) { continue; } else { - error("wait for %s: %s", driver_program, strerror(errno)); + error(_("wait for %s: %s"), driver_program, strerror(errno)); + /*NOTREACHED*/ } } else if (pid == driver_pid) { break; } } - free_sl(datestamp_list); + g_slist_free_full(datestamp_list); datestamp_list = NULL; - free_sl(holding_list); + g_slist_free_full(holding_list); holding_list = NULL; if(redirect) { /* rename errfile */ @@ -335,31 +426,33 @@ char **main_argv; /* First, find out the last existing errfile, */ /* to avoid ``infinite'' loops if tapecycle is infinite */ - ap_snprintf(number,100,"%d",days); + g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); while ( days < maxdays && stat(errfilex,&stat_buf)==0) { days++; - ap_snprintf(number,100,"%d",days); + g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); } - ap_snprintf(number,100,"%d",days); + g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); nerrfilex = NULL; while (days > 1) { amfree(nerrfilex); nerrfilex = errfilex; days--; - ap_snprintf(number,100,"%d",days); + g_snprintf(number,100,"%d",days); errfilex = vstralloc(errfile, ".", number, NULL); if (rename(errfilex, nerrfilex) != 0) { - error("cannot rename \"%s\" to \"%s\": %s", + error(_("cannot rename \"%s\" to \"%s\": %s"), errfilex, nerrfilex, strerror(errno)); + /*NOTREACHED*/ } } errfilex = newvstralloc(errfilex, errfile, ".1", NULL); if (rename(errfile,errfilex) != 0) { - error("cannot rename \"%s\" to \"%s\": %s", + error(_("cannot rename \"%s\" to \"%s\": %s"), errfilex, nerrfilex, strerror(errno)); + /*NOTREACHED*/ } amfree(errfile); amfree(errfilex); @@ -376,51 +469,65 @@ char **main_argv; /* * This is the child process. */ - execle(reporter_program, - "amreport", config_name, (char *)0, - safe_env()); - error("cannot exec %s: %s", reporter_program, strerror(errno)); + config_options = get_config_options(3); + config_options[0] = "amreport"; + config_options[1] = get_config_name(); + config_options[2] = "--from-amdump"; + safe_fd(-1, 0); + execve(reporter_program, config_options, safe_env()); + error(_("cannot exec %s: %s"), reporter_program, strerror(errno)); + /*NOTREACHED*/ } else if(reporter_pid == -1) { - error("cannot fork for %s: %s", reporter_program, strerror(errno)); + error(_("cannot fork for %s: %s"), reporter_program, strerror(errno)); + /*NOTREACHED*/ } while(1) { if((pid = wait(&exitcode)) == -1) { if(errno == EINTR) { continue; } else { - error("wait for %s: %s", reporter_program, strerror(errno)); + error(_("wait for %s: %s"), reporter_program, strerror(errno)); + /*NOTREACHED*/ } } else if (pid == reporter_pid) { break; } } + log_add(L_INFO, "pid-done %ld", (long)getpid()); + /* * Call amlogroll to rename the log file to its datestamped version. * Since we exec at this point, our exit code will be that of amlogroll. */ - - execle(logroll_program, - "amlogroll", config_name, (char *)0, - safe_env()); - error("cannot exec %s: %s", logroll_program, strerror(errno)); + config_options = get_config_options(2); + config_options[0] = "amlogroll"; + config_options[1] = get_config_name(); + safe_fd(-1, 0); + execve(logroll_program, config_options, safe_env()); + error(_("cannot exec %s: %s"), logroll_program, strerror(errno)); + /*NOTREACHED*/ return 0; /* keep the compiler happy */ } -int get_letter_from_user() +static int +get_letter_from_user(void) { - int r = '\0'; - int ch; + int r, ch; fflush(stdout); fflush(stderr); - while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {} + while((ch = getchar()) != EOF && ch != '\n' && g_ascii_isspace(ch)) { + (void)ch; /* Quite lint */ + } if(ch == '\n') { r = '\0'; } else if (ch != EOF) { r = ch; if(islower(r)) r = toupper(r); - while((ch = getchar()) != EOF && ch != '\n') {} + while((ch = getchar()) != EOF && ch != '\n') { + (void)ch; /* Quite lint */ + } } else { r = ch; clearerr(stdin); @@ -428,39 +535,129 @@ int get_letter_from_user() return r; } +/* Allow the user to select a set of datestamps from those in + * holding disks. The result can be passed to + * holding_get_files_for_flush. If less than two dates are + * available, then no user interaction takes place. + * + * @returns: a new GSList listing the selected datestamps + */ +static GSList * +pick_datestamp(void) +{ + GSList *datestamp_list; + GSList *r_datestamp_list = NULL; + GSList *ds; + char **datestamps = NULL; + int i; + char *answer = NULL; + char *a = NULL; + int ch = 0; + char max_char = '\0', chupper = '\0'; + + datestamp_list = holding_get_all_datestamps(); + + if(g_slist_length(datestamp_list) < 2) { + return datestamp_list; + } else { + datestamps = alloc(g_slist_length(datestamp_list) * SIZEOF(char *)); + for(ds = datestamp_list, i=0; ds != NULL; ds = ds->next,i++) { + datestamps[i] = (char *)ds->data; /* borrowing reference */ + } + + while(1) { + puts(_("\nMultiple Amanda runs in holding disks; please pick one by letter:")); + for(ds = datestamp_list, max_char = 'A'; + ds != NULL && max_char <= 'Z'; + ds = ds->next, max_char++) { + g_printf(" %c. %s\n", max_char, (char *)ds->data); + } + max_char--; + g_printf(_("Select datestamps to flush [A..%c or for all]: "), max_char); + fflush(stdout); fflush(stderr); + amfree(answer); + if ((answer = agets(stdin)) == NULL) { + clearerr(stdin); + continue; + } + + if (*answer == '\0' || strncasecmp(answer, "ALL", 3) == 0) { + break; + } + + a = answer; + while ((ch = *a++) != '\0') { + if (!g_ascii_isspace(ch)) + break; + } + + /* rewrite the selected list into r_datestamp_list, then copy it over + * to datestamp_list */ + do { + if (g_ascii_isspace(ch) || ch == ',') { + continue; + } + chupper = (char)toupper(ch); + if (chupper < 'A' || chupper > max_char) { + g_slist_free_full(r_datestamp_list); + r_datestamp_list = NULL; + break; + } + r_datestamp_list = g_slist_append(r_datestamp_list, + stralloc(datestamps[chupper - 'A'])); + } while ((ch = *a++) != '\0'); + if (r_datestamp_list && ch == '\0') { + g_slist_free_full(datestamp_list); + datestamp_list = r_datestamp_list; + break; + } + } + } + amfree(datestamps); /* references in this array are borrowed */ + amfree(answer); + + return datestamp_list; +} + + +/* + * confirm before detaching and running + */ -void confirm() -/* confirm before detaching and running */ +void +confirm(GSList *datestamp_list) { tape_t *tp; char *tpchanger; - sle_t *dir; + GSList *datestamp; int ch; char *extra; - printf("\nToday is: %s\n",datestamp); - printf("Flushing dumps in"); + g_printf(_("\nToday is: %s\n"),amflush_datestamp); + g_printf(_("Flushing dumps from")); extra = ""; - for(dir = datestamp_list->first; dir != NULL; dir = dir->next) { - printf("%s %s", extra, dir->name); + for(datestamp = datestamp_list; datestamp != NULL; datestamp = datestamp->next) { + g_printf("%s %s", extra, (char *)datestamp->data); extra = ","; } tpchanger = getconf_str(CNF_TPCHANGER); if(*tpchanger != '\0') { - printf(" using tape changer \"%s\".\n", tpchanger); + g_printf(_(" using tape changer \"%s\".\n"), tpchanger); } else { - printf(" to tape drive \"%s\".\n", getconf_str(CNF_TAPEDEV)); + g_printf(_(" to tape drive \"%s\".\n"), getconf_str(CNF_TAPEDEV)); } - printf("Expecting "); + g_printf(_("Expecting ")); tp = lookup_last_reusable_tape(0); - if(tp != NULL) printf("tape %s or ", tp->label); - printf("a new tape."); + if(tp != NULL) + g_printf(_("tape %s or "), tp->label); + g_printf(_("a new tape.")); tp = lookup_tapepos(1); - if(tp != NULL) printf(" (The last dumps were to tape %s)", tp->label); + if(tp != NULL) + g_printf(_(" (The last dumps were to tape %s)"), tp->label); while (1) { - printf("\nAre you sure you want to do this [yN]? "); + g_printf(_("\nAre you sure you want to do this [yN]? ")); if((ch = get_letter_from_user()) == 'Y') { return; } else if (ch == 'N' || ch == '\0' || ch == EOF) { @@ -471,38 +668,48 @@ void confirm() } } - printf("Ok, quitting. Run amflush again when you are ready.\n"); + g_printf(_("Ok, quitting. Run amflush again when you are ready.\n")); + log_add(L_INFO, "pid-done %ld", (long)getpid()); exit(1); } -void redirect_stderr() +void +redirect_stderr(void) { int fderr; char *errfile; fflush(stdout); fflush(stderr); errfile = vstralloc(conf_logdir, "/amflush", NULL); - if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1) - error("could not open %s: %s", errfile, strerror(errno)); + if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1) { + error(_("could not open %s: %s"), errfile, strerror(errno)); + /*NOTREACHED*/ + } dup2(fderr,1); dup2(fderr,2); aclose(fderr); amfree(errfile); } -void detach() +void +detach(void) { int fd; fflush(stdout); fflush(stderr); - if((fd = open("/dev/null", O_RDWR, 0666)) == -1) - error("could not open /dev/null: %s", strerror(errno)); + if((fd = open("/dev/null", O_RDWR, 0666)) == -1) { + error(_("could not open /dev/null: %s"), strerror(errno)); + /*NOTREACHED*/ + } dup2(fd,0); aclose(fd); switch(fork()) { - case -1: error("could not fork: %s", strerror(errno)); + case -1: + error(_("could not fork: %s"), strerror(errno)); + /*NOTREACHED*/ + case 0: setsid(); return; @@ -510,5 +717,3 @@ void detach() exit(0); } - -