X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=client-src%2Fsendsize.c;h=e99071c24f9747a25d079fd2ee4374e9c2463656;hb=34197d9f46a5f4e944378cbb65fca32ee0eec7b9;hp=dc8a67dd9e6b2e978a8edffaf737e2f128285b1c;hpb=1194fb66aa28d9929c3f2bef3cc6c1c3f40a60a4;p=debian%2Famanda diff --git a/client-src/sendsize.c b/client-src/sendsize.c index dc8a67d..e99071c 100644 --- a/client-src/sendsize.c +++ b/client-src/sendsize.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: sendsize.c,v 1.152 2006/03/09 16:51:41 martinea Exp $ + * $Id: sendsize.c,v 1.171.2.4 2006/12/22 14:42:42 martinea Exp $ * * send estimated backup sizes using dump */ @@ -38,6 +38,8 @@ #include "getfsent.h" #include "version.h" #include "client_util.h" +#include "clientconf.h" +#include "amandad.h" #ifdef SAMBA_CLIENT #include "findpass.h" @@ -76,8 +78,11 @@ typedef struct level_estimates_s { typedef struct disk_estimates_s { struct disk_estimates_s *next; char *amname; + char *qamname; char *amdevice; + char *qamdevice; char *dirname; + char *qdirname; char *program; char *calcprog; int program_is_wrapper; @@ -95,25 +100,27 @@ static char *our_feature_string = NULL; static g_option_t *g_options = NULL; /* local functions */ -int main P((int argc, char **argv)); -void add_diskest P((char *disk, char *amdevice, int level, int spindle, +int main(int argc, char **argv); +void add_diskest(char *disk, char *amdevice, int level, int spindle, int program_is_wrapper, char *prog, char *calcprog, - option_t *options)); -void calc_estimates P((disk_estimates_t *est)); -void free_estimates P((disk_estimates_t *est)); -void dump_calc_estimates P((disk_estimates_t *)); -void smbtar_calc_estimates P((disk_estimates_t *)); -void gnutar_calc_estimates P((disk_estimates_t *)); -void wrapper_calc_estimates P((disk_estimates_t *)); -void generic_calc_estimates P((disk_estimates_t *)); - - -int main(argc, argv) -int argc; -char **argv; + option_t *options); +void calc_estimates(disk_estimates_t *est); +void free_estimates(disk_estimates_t *est); +void dump_calc_estimates(disk_estimates_t *); +void star_calc_estimates(disk_estimates_t *); +void smbtar_calc_estimates(disk_estimates_t *); +void gnutar_calc_estimates(disk_estimates_t *); +void wrapper_calc_estimates(disk_estimates_t *); +void generic_calc_estimates(disk_estimates_t *); + + +int +main( + int argc, + char ** argv) { int level, spindle; - char *prog, *calcprog, *disk, *amdevice, *dumpdate; + char *prog, *calcprog, *dumpdate; option_t *options = NULL; int program_is_wrapper; disk_estimates_t *est; @@ -123,12 +130,24 @@ char **argv; char *s, *fp; int ch; char *err_extra = NULL; - unsigned long malloc_hist_1, malloc_size_1; - unsigned long malloc_hist_2, malloc_size_2; int done; int need_wait; int dumpsrunning; + char *disk = NULL; + char *qdisk = NULL; + char *qlist = NULL; + char *amdevice = NULL; + char *qamdevice = NULL; + char *conffile; + char *amandates_file; + int amandates_read = 0; +#if defined(USE_DBMALLOC) + unsigned long malloc_hist_1, malloc_size_1; + unsigned long malloc_hist_2, malloc_size_2; +#endif + (void)argc; /* Quiet unused parameter warning */ + (void)argv; /* Quiet unused parameter warning */ /* initialize */ @@ -140,10 +159,12 @@ char **argv; /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); +#if defined(USE_DBMALLOC) malloc_size_1 = malloc_inuse(&malloc_hist_1); +#endif erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG); - dbopen(); + dbopen(DBG_SUBDIR_CLIENT); startclock(); dbprintf(("%s: version %s\n", get_pname(), version())); @@ -152,13 +173,20 @@ char **argv; set_debug_prefix_pid(getpid()); - /* handle all service requests */ + conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL); + if (read_clientconf(conffile) > 0) { + error("error reading conffile: %s", conffile); + /*NOTREACHED*/ + } + amfree(conffile); - start_amandates(0); + /* handle all service requests */ for(; (line = agets(stdin)) != NULL; free(line)) { + if (line[0] == '\0') + continue; #define sc "OPTIONS " - if(strncmp(line, sc, sizeof(sc)-1) == 0) { + if(strncmp(line, sc, SIZEOF(sc)-1) == 0) { #undef sc g_options = parse_g_options(line+8, 1); if(!g_options->hostname) { @@ -179,15 +207,36 @@ char **argv; } printf("\n"); fflush(stdout); + + if (g_options->config) { + conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/", + "amanda-client.conf", NULL); + if (read_clientconf(conffile) > 0) { + error("error reading conffile: %s", conffile); + /*NOTREACHED*/ + } + amfree(conffile); + + dbrename(g_options->config, DBG_SUBDIR_CLIENT); + } + continue; } + if (amandates_read == 0) { + amandates_file = client_getconf_str(CLN_AMANDATES); + if(!start_amandates(amandates_file, 0)) + error("error [opening %s: %s]", amandates_file, + strerror(errno)); + amandates_read = 1; + } + s = line; ch = *s++; skip_whitespace(s, ch); /* find the program name */ if(ch == '\0') { - err_extra = "no program name"; + err_extra = stralloc("no program name"); goto err; /* no program name */ } prog = s - 1; @@ -209,7 +258,7 @@ char **argv; if(strncmp(prog, "CALCSIZE", 8) == 0) { skip_whitespace(s, ch); /* find the program name */ if(ch == '\0') { - err_extra = "no program name"; + err_extra = stralloc("no program name"); goto err; } calcprog = s - 1; @@ -222,56 +271,71 @@ char **argv; skip_whitespace(s, ch); /* find the disk name */ if(ch == '\0') { - err_extra = "no disk name"; + err_extra = stralloc("no disk name"); goto err; /* no disk name */ } - disk = s - 1; - skip_non_whitespace(s, ch); - s[-1] = '\0'; + + if (qdisk != NULL) + amfree(qdisk); + if (disk != NULL) + amfree(disk); + + fp = s - 1; + skip_quoted_string(s, ch); + s[-1] = '\0'; /* terminate the disk name */ + qdisk = stralloc(fp); + disk = unquote_string(qdisk); skip_whitespace(s, ch); /* find the device or level */ if (ch == '\0') { - err_extra = "bad level"; + err_extra = stralloc("bad level"); goto err; } if(!isdigit((int)s[-1])) { fp = s - 1; - skip_non_whitespace(s, ch); + skip_quoted_string(s, ch); s[-1] = '\0'; - amdevice = stralloc(fp); + qamdevice = stralloc(fp); + amdevice = unquote_string(qamdevice); skip_whitespace(s, ch); /* find level number */ } else { amdevice = stralloc(disk); + qamdevice = stralloc(qdisk); } /* find the level number */ if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { - err_extra = "bad level"; + err_extra = stralloc("bad level"); goto err; /* bad level */ } + if (level < 0 || level >= DUMP_LEVELS) { + err_extra = stralloc("bad level"); + goto err; + } skip_integer(s, ch); skip_whitespace(s, ch); /* find the dump date */ if(ch == '\0') { - err_extra = "no dumpdate"; + err_extra = stralloc("no dumpdate"); goto err; /* no dumpdate */ } dumpdate = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; + (void)dumpdate; /* XXX: Set but not used */ spindle = 0; /* default spindle */ skip_whitespace(s, ch); /* find the spindle */ if(ch != '\0') { if(sscanf(s - 1, "%d", &spindle) != 1) { - err_extra = "bad spindle"; + err_extra = stralloc("bad spindle"); goto err; /* bad spindle */ } skip_integer(s, ch); - skip_whitespace(s, ch); /* find the exclusion list */ + skip_whitespace(s, ch); /* find the parameters */ if(ch != '\0') { if(strncmp(s-1, "OPTIONS |;",10) == 0) { options = parse_options(s + 8, @@ -281,32 +345,61 @@ char **argv; 0); } else { - options = alloc(sizeof(option_t)); + options = alloc(SIZEOF(option_t)); init_options(options); - if(strncmp(s-1, "exclude-file=", 13) == 0) { - options->exclude_file = - append_sl(options->exclude_file, s+12); - } - if(strncmp(s-1, "exclude-list=", 13) == 0) { - options->exclude_list = - append_sl(options->exclude_list, s+12); - } - - skip_non_whitespace(s, ch); - if(ch) { - err_extra = "extra text at end"; - goto err; /* should have gotten to end */ + while (ch != '\0') { + if(strncmp(s-1, "exclude-file=", 13) == 0) { + qlist = unquote_string(s+12); + options->exclude_file = + append_sl(options->exclude_file, qlist); + amfree(qlist); + } else if(strncmp(s-1, "exclude-list=", 13) == 0) { + options->exclude_list = + append_sl(options->exclude_list, qlist); + qlist = unquote_string(s+12); + amfree(qlist); + } else if(strncmp(s-1, "include-file=", 13) == 0) { + options->include_file = + append_sl(options->include_file, qlist); + qlist = unquote_string(s+12); + amfree(qlist); + } else if(strncmp(s-1, "include-list=", 13) == 0) { + options->include_list = + append_sl(options->include_list, qlist); + qlist = unquote_string(s+12); + amfree(qlist); + } else { + err_extra = vstralloc("Invalid parameter (", + s-1, ")", NULL); + goto err; /* should have gotten to end */ + } + skip_quoted_string(s, ch); + skip_whitespace(s, ch); /* find the inclusion list */ + amfree(qlist); } } } else { - options = alloc(sizeof(option_t)); + options = alloc(SIZEOF(option_t)); init_options(options); } } + else { + options = alloc(SIZEOF(option_t)); + init_options(options); + } + /*@ignore@*/ add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options); + /*@end@*/ + amfree(disk); + amfree(qdisk); amfree(amdevice); + amfree(qamdevice); + } + if (g_options == NULL) { + error("Missing OPTIONS line in sendsize input\n"); + /*NOTREACHED*/ } amfree(line); @@ -333,6 +426,7 @@ char **argv; child_pid = wait(&child_status); if(child_pid == -1) { error("wait failed: %s", strerror(errno)); + /*NOTREACHED*/ } if(WIFSIGNALED(child_status)) { dbprintf(("%s: child %ld terminated with signal %d\n", @@ -419,6 +513,7 @@ char **argv; exit(0); } else if(est->child == -1) { error("calc_estimates fork failed: %s", strerror(errno)); + /*NOTREACHED*/ } dumpsrunning++; /* parent */ } @@ -440,13 +535,13 @@ char **argv; amfree(g_options->str); amfree(g_options); +#if defined(USE_DBMALLOC) malloc_size_2 = malloc_inuse(&malloc_hist_2); if(malloc_size_1 != malloc_size_2) { -#if defined(USE_DBMALLOC) malloc_list(dbfd(), malloc_hist_1, malloc_hist_2); -#endif } +#endif dbclose(); return 0; @@ -456,21 +551,33 @@ char **argv; debug_prefix_time(NULL), err_extra ? ": " : "", err_extra ? err_extra : "")); + amfree(err_extra); dbclose(); return 1; } -void add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options) -char *disk, *amdevice, *prog, *calcprog; -int level, spindle, program_is_wrapper; -option_t *options; +void +add_diskest( + char * disk, + char * amdevice, + int level, + int spindle, + int program_is_wrapper, + char * prog, + char * calcprog, + option_t * options) { disk_estimates_t *newp, *curp; amandates_t *amdp; int dumplev, estlev; time_t dumpdate; + if (level < 0) + level = 0; + if (level >= DUMP_LEVELS) + level = DUMP_LEVELS - 1; + for(curp = est_list; curp != NULL; curp = curp->next) { if(strcmp(curp->amname, disk) == 0) { /* already have disk info, just note the level request */ @@ -488,13 +595,16 @@ option_t *options; } } - newp = (disk_estimates_t *) alloc(sizeof(disk_estimates_t)); - memset(newp, 0, sizeof(*newp)); + newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t)); + memset(newp, 0, SIZEOF(*newp)); newp->next = est_list; est_list = newp; newp->amname = stralloc(disk); + newp->qamname = quote_string(disk); newp->amdevice = stralloc(amdevice); + newp->qamdevice = quote_string(amdevice); newp->dirname = amname_to_dirname(newp->amdevice); + newp->qdirname = quote_string(newp->dirname); newp->program = stralloc(prog); if(calcprog != NULL) newp->calcprog = stralloc(calcprog); @@ -520,12 +630,16 @@ option_t *options; } -void free_estimates(est) -disk_estimates_t *est; +void +free_estimates( + disk_estimates_t * est) { amfree(est->amname); + amfree(est->qamname); amfree(est->amdevice); + amfree(est->qamdevice); amfree(est->dirname); + amfree(est->qdirname); amfree(est->program); if(est->options) { free_sl(est->options->exclude_file); @@ -543,13 +657,14 @@ disk_estimates_t *est; * */ -void calc_estimates(est) -disk_estimates_t *est; +void +calc_estimates( + disk_estimates_t * est) { - dbprintf(("%s: calculating for amname '%s', dirname '%s', spindle %d\n", + dbprintf(("%s: calculating for amname %s, dirname %s, spindle %d\n", debug_prefix_time(NULL), - est->amname, est->dirname, est->spindle)); - + est->qamname, est->qdirname, est->spindle)); + if(est->program_is_wrapper == 1) wrapper_calc_estimates(est); else @@ -573,14 +688,14 @@ disk_estimates_t *est; if (est->amdevice[0] == '/' && est->amdevice[1] == '/') dbprintf(("%s: Can't use CALCSIZE for samba estimate: %s %s\n", debug_prefix_time(NULL), - est->amname, est->dirname)); + est->qamname, est->qdirname)); else #endif generic_calc_estimates(est); - dbprintf(("%s: done with amname '%s', dirname '%s', spindle %d\n", + dbprintf(("%s: done with amname %s dirname %s spindle %d\n", debug_prefix_time(NULL), - est->amname, est->dirname, est->spindle)); + est->qamname, est->qdirname, est->spindle)); } /* @@ -589,33 +704,40 @@ disk_estimates_t *est; */ /* local functions */ -long getsize_dump P((char *disk, char *amdevice, int level, option_t *options)); -long getsize_smbtar P((char *disk, char *amdevice, int level, option_t *options)); -long getsize_gnutar P((char *disk, char *amdevice, int level, - option_t *options, time_t dumpsince)); -long getsize_wrapper P((char *program, char *disk, char *amdevice, int level, - option_t *options, time_t dumpsince)); -long handle_dumpline P((char *str)); -double first_num P((char *str)); - -void wrapper_calc_estimates(est) -disk_estimates_t *est; +off_t getsize_dump(char *disk, char *amdevice, int level, option_t *options); +off_t getsize_star(char *disk, char *amdevice, int level, + option_t *options, time_t dumpsince); +off_t getsize_smbtar(char *disk, char *amdevice, int level, option_t *options); +off_t getsize_gnutar(char *disk, char *amdevice, int level, + option_t *options, time_t dumpsince); +off_t getsize_wrapper(char *program, char *disk, char *amdevice, int level, + option_t *options, time_t dumpsince); +off_t handle_dumpline(char *str); +double first_num(char *str); + +void +wrapper_calc_estimates( + disk_estimates_t * est) { int level; - long size; + off_t size; for(level = 0; level < DUMP_LEVELS; level++) { if (est->est[level].needestimate) { dbprintf(("%s: getting size via wrapper for %s level %d\n", - debug_prefix_time(NULL), est->amname, level)); - size = getsize_wrapper(est->program, est->amname, est->amdevice, level, est->options, - est->est[level].dumpsince); + debug_prefix_time(NULL), est->qamname, level)); + size = getsize_wrapper(est->program, est->amname, est->amdevice, + level, est->options, est->est[level].dumpsince); amflock(1, "size"); - fseek(stdout, (off_t)0, SEEK_SET); + if (fseek(stdout, 0L, SEEK_END) < 0) { + dbprintf(("wrapper_calc_estimates: warning - seek failed: %s\n", + strerror(errno))); + } - printf("%s %d SIZE %ld\n", est->amname, level, size); + printf("%s %d SIZE " OFF_T_FMT "\n", est->qamname, level, + (OFF_T_FMT_TYPE)size); fflush(stdout); amfunlock(1, "size"); @@ -624,28 +746,36 @@ disk_estimates_t *est; } -void generic_calc_estimates(est) -disk_estimates_t *est; +void +generic_calc_estimates( + disk_estimates_t * est) { int pipefd = -1, nullfd = -1; char *cmd; - char *my_argv[DUMP_LEVELS*2+20]; + char *my_argv[DUMP_LEVELS*2+22]; char number[NUM_STR_SIZE]; - int i, level, my_argc, calcpid; + int i, level, my_argc, status; + pid_t calcpid; int nb_exclude = 0; int nb_include = 0; char *file_exclude = NULL; char *file_include = NULL; times_t start_time; FILE *dumpout = NULL; - long size = 1; + off_t size = (off_t)1; char *line = NULL; char *match_expr; cmd = vstralloc(libexecdir, "/", "calcsize", versionsuffix(), NULL); my_argc = 0; + my_argv[my_argc++] = stralloc("calcsize"); + if (g_options->config) + my_argv[my_argc++] = stralloc(g_options->config); + else + my_argv[my_argc++] = stralloc("NOCONFIG"); + my_argv[my_argc++] = stralloc(est->calcprog); my_argv[my_argc++] = stralloc(est->amname); @@ -662,9 +792,11 @@ disk_estimates_t *est; nb_include += est->options->include_list->nb_element; if(nb_exclude > 0) - file_exclude = build_exclude(est->amname, est->amdevice,est->options,0); + file_exclude = build_exclude(est->amname, + est->amdevice, est->options, 0); if(nb_include > 0) - file_include = build_include(est->amname, est->amdevice,est->options,0); + file_include = build_include(est->amname, + est->amdevice, est->options, 0); if(file_exclude) { my_argv[my_argc++] = stralloc("-X"); @@ -683,10 +815,10 @@ disk_estimates_t *est; for(level = 0; level < DUMP_LEVELS; level++) { if(est->est[level].needestimate) { - snprintf(number, sizeof(number), "%d", level); + snprintf(number, SIZEOF(number), "%d", level); my_argv[my_argc++] = stralloc(number); dbprintf((" %s", number)); - snprintf(number, sizeof(number), + snprintf(number, SIZEOF(number), "%ld", (long)est->est[level].dumpsince); my_argv[my_argc++] = stralloc(number); dbprintf((" %s", number)); @@ -706,29 +838,36 @@ disk_estimates_t *est; amfree(cmd); dumpout = fdopen(pipefd,"r"); - match_expr = vstralloc(est->amname," %d SIZE %ld", NULL); - for(size = -1; (line = agets(dumpout)) != NULL; free(line)) { + if (!dumpout) { + error("Can't fdopen: %s", strerror(errno)); + /*NOTREACHED*/ + } + match_expr = vstralloc(est->qamname," %d SIZE " OFF_T_FMT, NULL); + for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { + if (line[0] == '\0') + continue; if(sscanf(line, match_expr, &level, &size) == 2) { printf("%s\n", line); /* write to amandad */ - dbprintf(("%s: estimate size for %s level %d: %ld KB\n", + dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n", debug_prefix(NULL), - est->amname, + est->qamname, level, size)); } } amfree(match_expr); - dbprintf(("%s: waiting for %s \"%s\" child\n", - debug_prefix_time(NULL), my_argv[0], est->amdevice)); - wait(NULL); - dbprintf(("%s: after %s \"%s\" wait\n", - debug_prefix_time(NULL), my_argv[0], est->amdevice)); + dbprintf(("%s: waiting for %s %s child (pid=%d)\n", + debug_prefix_time(NULL), my_argv[0], est->qamdevice, calcpid)); + wait(&status); + dbprintf(("%s: after %s %s wait: child pid=%d status=%d\n", + debug_prefix_time(NULL), my_argv[0], est->qamdevice, + calcpid, WEXITSTATUS(status))); dbprintf(("%s: .....\n", debug_prefix_time(NULL))); dbprintf(("%s: estimate time for %s: %s\n", debug_prefix(NULL), - est->amname, + est->qamname, walltime_str(timessub(curclock(), start_time)))); common_exit: @@ -739,23 +878,29 @@ common_exit: } -void dump_calc_estimates(est) -disk_estimates_t *est; +void +dump_calc_estimates( + disk_estimates_t * est) { int level; - long size; + off_t size; for(level = 0; level < DUMP_LEVELS; level++) { if(est->est[level].needestimate) { dbprintf(("%s: getting size via dump for %s level %d\n", - debug_prefix_time(NULL), est->amname, level)); - size = getsize_dump(est->amname, est->amdevice,level, est->options); + debug_prefix_time(NULL), est->qamname, level)); + size = getsize_dump(est->amname, est->amdevice, + level, est->options); amflock(1, "size"); - fseek(stdout, (off_t)0, SEEK_SET); + if (fseek(stdout, 0L, SEEK_END) < 0) { + dbprintf(("dump_calc_estimates: warning - seek failed: %s\n", + strerror(errno))); + } - printf("%s %d SIZE %ld\n", est->amname, level, size); + printf("%s %d SIZE " OFF_T_FMT "\n", + est->qamname, level, (OFF_T_FMT_TYPE)size); fflush(stdout); amfunlock(1, "size"); @@ -764,23 +909,28 @@ disk_estimates_t *est; } #ifdef SAMBA_CLIENT -void smbtar_calc_estimates(est) -disk_estimates_t *est; +void +smbtar_calc_estimates( + disk_estimates_t * est) { int level; - long size; + off_t size; for(level = 0; level < DUMP_LEVELS; level++) { if(est->est[level].needestimate) { dbprintf(("%s: getting size via smbclient for %s level %d\n", - debug_prefix_time(NULL), est->amname, level)); + debug_prefix_time(NULL), est->qamname, level)); size = getsize_smbtar(est->amname, est->amdevice, level, est->options); amflock(1, "size"); - fseek(stdout, (off_t)0, SEEK_SET); + if (fseek(stdout, 0L, SEEK_END) < 0) { + dbprintf(("smbtar_calc_estimates: warning - seek failed: %s\n", + strerror(errno))); + } - printf("%s %d SIZE %ld\n", est->amname, level, size); + printf("%s %d SIZE " OFF_T_FMT "\n", + est->qamname, level, (OFF_T_FMT_TYPE)size); fflush(stdout); amfunlock(1, "size"); @@ -790,24 +940,29 @@ disk_estimates_t *est; #endif #ifdef GNUTAR -void gnutar_calc_estimates(est) -disk_estimates_t *est; +void +gnutar_calc_estimates( + disk_estimates_t * est) { int level; - long size; + off_t size; for(level = 0; level < DUMP_LEVELS; level++) { if (est->est[level].needestimate) { dbprintf(("%s: getting size via gnutar for %s level %d\n", - debug_prefix_time(NULL), est->amname, level)); + debug_prefix_time(NULL), est->qamname, level)); size = getsize_gnutar(est->amname, est->amdevice, level, est->options, est->est[level].dumpsince); amflock(1, "size"); - fseek(stdout, (off_t)0, SEEK_SET); + if (fseek(stdout, 0L, SEEK_END) < 0) { + dbprintf(("gnutar_calc_estimates: warning - seek failed: %s\n", + strerror(errno))); + } - printf("%s %d SIZE %ld\n", est->amname, level, size); + printf("%s %d SIZE " OFF_T_FMT "\n", + est->qamname, level, (OFF_T_FMT_TYPE)size); fflush(stdout); amfunlock(1, "size"); @@ -821,12 +976,13 @@ typedef struct regex_s { int scale; } regex_t; +/*@ignore@*/ regex_t re_size[] = { #ifdef DUMP {" DUMP: estimated -*[0-9][0-9]* tape blocks", 1024}, {" DUMP: [Ee]stimated [0-9][0-9]* blocks", 512}, - {" DUMP: [Ee]stimated [0-9][0-9]* bytes", 1}, /* Ultrix 4.4 */ - {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* NEC EWS-UX */ + {" DUMP: [Ee]stimated [0-9][0-9]* bytes", 1}, /* Ultrix 4.4 */ + {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* NEC EWS-UX */ {"dump: Estimate: [0-9][0-9]* tape blocks", 1024}, /* OSF/1 */ {"backup: There are an estimated [0-9][0-9]* tape blocks.",1024}, /* AIX */ {"backup: estimated [0-9][0-9]* 1k blocks", 1024}, /* AIX */ @@ -834,27 +990,27 @@ regex_t re_size[] = { {"backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024}, /* AIX */ {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024}, /* AIX */ {"dump: Estimate: [0-9][0-9]* blocks being output to pipe",1024}, - /* DU 4.0 dump */ - {"dump: Dumping [0-9][0-9]* bytes, ", 1}, /* DU 4.0 vdump */ - {"DUMP: estimated [0-9][0-9]* KB output", 1024}, /* HPUX */ - {"DUMP: estimated [0-9][0-9]* KB\\.", 1024}, /* NetApp */ - {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */ + /* DU 4.0 dump */ + {"dump: Dumping [0-9][0-9]* bytes, ", 1}, /* DU 4.0 vdump */ + {"DUMP: estimated [0-9][0-9]* KB output", 1024}, /* HPUX */ + {"DUMP: estimated [0-9][0-9]* KB\\.", 1024}, /* NetApp */ + {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */ #ifdef HAVE_DUMP_ESTIMATE {"[0-9][0-9]* blocks, [0-9][0-9]*.[0-9][0-9]* volumes", 1024}, - /* DU 3.2g dump -E */ - {"^[0-9][0-9]* blocks$", 1024}, /* DU 4.0 dump -E */ - {"^[0-9][0-9]*$", 1}, /* Solaris ufsdump -S */ + /* DU 3.2g dump -E */ + {"^[0-9][0-9]* blocks$", 1024}, /* DU 4.0 dump -E */ + {"^[0-9][0-9]*$", 1}, /* Solaris ufsdump -S */ #endif #endif #ifdef VDUMP - {"vdump: Dumping [0-9][0-9]* bytes, ", 1}, /* OSF/1 vdump */ + {"vdump: Dumping [0-9][0-9]* bytes, ", 1}, /* OSF/1 vdump */ #endif #ifdef VXDUMP - {"vxdump: estimated [0-9][0-9]* blocks", 512}, /* HPUX's vxdump */ - {" VXDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */ + {"vxdump: estimated [0-9][0-9]* blocks", 512}, /* HPUX's vxdump */ + {" VXDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */ #endif #ifdef XFSDUMP @@ -877,16 +1033,18 @@ regex_t re_size[] = { { NULL, 0 } }; - - -long getsize_dump(disk, amdevice, level, options) - char *disk, *amdevice; - int level; - option_t *options; +/*@end@*/ + +off_t +getsize_dump( + char *disk, + char *amdevice, + int level, + option_t * options) { int pipefd[2], nullfd, stdoutfd, killctl[2]; pid_t dumppid; - long size; + off_t size; FILE *dumpout; char *dumpkeys = NULL; char *device = NULL; @@ -898,29 +1056,55 @@ long getsize_dump(disk, amdevice, level, options) char level_str[NUM_STR_SIZE]; int s; times_t start_time; + char *qdisk = quote_string(disk); + char *qdevice; + char *config; +#if defined(DUMP) || defined(VDUMP) || defined(VXDUMP) || defined(XFSDUMP) + int is_rundump = 1; +#endif + + (void)options; /* Quiet unused parameter warning */ - snprintf(level_str, sizeof(level_str), "%d", level); + (void)getsize_smbtar; /* Quiet unused parameter warning */ + + snprintf(level_str, SIZEOF(level_str), "%d", level); device = amname_to_devname(amdevice); + qdevice = quote_string(device); fstype = amname_to_fstype(amdevice); - dbprintf(("%s: calculating for device '%s' with '%s'\n", - debug_prefix_time(NULL), device, fstype)); + dbprintf(("%s: calculating for device %s with %s\n", + debug_prefix_time(NULL), qdevice, fstype)); cmd = vstralloc(libexecdir, "/rundump", versionsuffix(), NULL); rundump_cmd = stralloc(cmd); - + if (g_options->config) + config = g_options->config; + else + config = "NOCONFIG"; if ((stdoutfd = nullfd = open("/dev/null", O_RDWR)) == -1) { dbprintf(("getsize_dump could not open /dev/null: %s\n", - strerror(errno))); + strerror(errno))); amfree(cmd); amfree(rundump_cmd); amfree(fstype); amfree(device); + amfree(qdevice); + amfree(qdisk); return(-1); } pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1; - pipe(pipefd); + if (pipe(pipefd) < 0) { + dbprintf(("getsize_dump could create data pipes: %s\n", + strerror(errno))); + amfree(cmd); + amfree(rundump_cmd); + amfree(fstype); + amfree(device); + amfree(qdevice); + amfree(qdisk); + return(-1); + } #ifdef XFSDUMP /* { */ #ifdef DUMP /* { */ @@ -929,9 +1113,9 @@ long getsize_dump(disk, amdevice, level, options) if (1) #endif /* } */ { - name = stralloc(" (xfsdump)"); + name = stralloc(" (xfsdump)"); dbprintf(("%s: running \"%s%s -F -J -l %s - %s\"\n", - debug_prefix_time(NULL), cmd, name, level_str, device)); + debug_prefix_time(NULL), cmd, name, level_str, qdevice)); } else #endif /* } */ @@ -943,14 +1127,16 @@ long getsize_dump(disk, amdevice, level, options) #endif /* } */ { #ifdef USE_RUNDUMP - name = stralloc(" (vxdump)"); + name = stralloc(" (vxdump)"); #else name = stralloc(""); cmd = newstralloc(cmd, VXDUMP); + config = skip_argument; + is_rundump = 0; #endif dumpkeys = vstralloc(level_str, "s", "f", NULL); - dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n", - debug_prefix_time(NULL), cmd, name, dumpkeys, device)); + dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n", + debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice)); } else #endif /* } */ @@ -963,10 +1149,12 @@ long getsize_dump(disk, amdevice, level, options) { name = stralloc(" (vdump)"); amfree(device); + amfree(qdevice); device = amname_to_dirname(amdevice); + qdevice = quote_string(device); dumpkeys = vstralloc(level_str, "b", "f", NULL); dbprintf(("%s: running \"%s%s %s 60 - %s\"\n", - debug_prefix_time(NULL), cmd, name, dumpkeys, device)); + debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice)); } else #endif /* } */ @@ -981,20 +1169,28 @@ long getsize_dump(disk, amdevice, level, options) # else /* } { */ name = stralloc(""); cmd = newstralloc(cmd, DUMP); + config = skip_argument; + is_rundump = 0; # endif /* } */ # ifdef AIX_BACKUP /* { */ dumpkeys = vstralloc("-", level_str, "f", NULL); dbprintf(("%s: running \"%s%s %s - %s\"\n", - debug_prefix_time(NULL), cmd, name, dumpkeys, device)); + debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice)); # else /* } { */ +# ifdef HAVE_DUMP_ESTIMATE +# define PARAM_DUMP_ESTIMATE HAVE_DUMP_ESTIMATE +# else +# define PARAM_DUMP_ESTIMATE "" +# endif +# ifdef HAVE_HONOR_NODUMP +# define PARAM_HONOR_NODUMP "h" +# else +# define PARAM_HONOR_NODUMP "" +# endif dumpkeys = vstralloc(level_str, -# ifdef HAVE_DUMP_ESTIMATE /* { */ - HAVE_DUMP_ESTIMATE, -# endif /* } */ -# ifdef HAVE_HONOR_NODUMP /* { */ - "h", -# endif /* } */ + PARAM_DUMP_ESTIMATE, + PARAM_DUMP_ESTIMATE, "s", "f", NULL); # ifdef HAVE_DUMP_ESTIMATE @@ -1003,10 +1199,10 @@ long getsize_dump(disk, amdevice, level, options) # ifdef HAVE_HONOR_NODUMP /* { */ dbprintf(("%s: running \"%s%s %s 0 1048576 - %s\"\n", - debug_prefix_time(NULL), cmd, name, dumpkeys, device)); + debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice)); # else /* } { */ dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n", - debug_prefix_time(NULL), cmd, name, dumpkeys, device)); + debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice)); # endif /* } */ # endif /* } */ } @@ -1014,9 +1210,15 @@ long getsize_dump(disk, amdevice, level, options) #endif /* } */ { error("no dump program available"); + /*NOTREACHED*/ } - pipe(killctl); + if (pipe(killctl) < 0) { + dbprintf(("%s: Could not create pipe: %s\n", + debug_prefix(NULL), strerror(errno))); + /* Message will be printed later... */ + killctl[0] = killctl[1] = -1; + } start_time = curclock(); switch(dumppid = fork()) { @@ -1027,6 +1229,8 @@ long getsize_dump(disk, amdevice, level, options) amfree(cmd); amfree(rundump_cmd); amfree(device); + amfree(qdevice); + amfree(qdisk); amfree(name); amfree(fstype); return -1; @@ -1036,8 +1240,7 @@ long getsize_dump(disk, amdevice, level, options) if(SETPGRP == -1) SETPGRP_FAILED(); else if (killctl[0] == -1 || killctl[1] == -1) - dbprintf(("%s: pipe for killpgrp failed, trying without killpgrp\n", - debug_prefix(NULL))); + dbprintf(("%s: Trying without killpgrp\n", debug_prefix(NULL))); else { switch(fork()) { case -1: @@ -1047,6 +1250,7 @@ long getsize_dump(disk, amdevice, level, options) default: { + char *config; char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp", versionsuffix(), NULL); dbprintf(("%s: running %s\n", @@ -1058,7 +1262,12 @@ long getsize_dump(disk, amdevice, level, options) close(pipefd[1]); close(killctl[1]); close(nullfd); - execle(killpgrp_cmd, killpgrp_cmd, (char *)0, safe_env()); + if (g_options->config) + config = g_options->config; + else + config = "NOCONFIG"; + execle(killpgrp_cmd, killpgrp_cmd, config, (char *)0, + safe_env()); dbprintf(("%s: cannot execute %s: %s\n", debug_prefix(NULL), killpgrp_cmd, strerror(errno))); exit(-1); @@ -1084,8 +1293,12 @@ long getsize_dump(disk, amdevice, level, options) #else if (1) #endif - execle(cmd, "xfsdump", "-F", "-J", "-l", level_str, "-", device, - (char *)0, safe_env()); + if (is_rundump) + execle(cmd, "rundump", config, "xfsdump", "-F", "-J", "-l", + level_str, "-", device, (char *)0, safe_env()); + else + execle(cmd, "xfsdump", "-F", "-J", "-l", + level_str, "-", device, (char *)0, safe_env()); else #endif #ifdef VXDUMP @@ -1094,8 +1307,12 @@ long getsize_dump(disk, amdevice, level, options) #else if (1) #endif - execle(cmd, "vxdump", dumpkeys, "1048576", "-", device, (char *)0, - safe_env()); + if (is_rundump) + execle(cmd, "rundump", config, "vxdump", dumpkeys, "1048576", + "-", device, (char *)0, safe_env()); + else + execle(cmd, "vxdump", dumpkeys, "1048576", "-", + device, (char *)0, safe_env()); else #endif #ifdef VDUMP @@ -1104,24 +1321,42 @@ long getsize_dump(disk, amdevice, level, options) #else if (1) #endif - execle(cmd, "vdump", dumpkeys, "60", "-", device, (char *)0, - safe_env()); + if (is_rundump) + execle(cmd, "rundump", config, "vdump", dumpkeys, "60", "-", + device, (char *)0, safe_env()); + else + execle(cmd, "vdump", dumpkeys, "60", "-", + device, (char *)0, safe_env()); else #endif #ifdef DUMP # ifdef AIX_BACKUP - execle(cmd, "backup", dumpkeys, "-", device, (char *)0, safe_env()); + if (is_rundump) + execle(cmd, "rundump", config, "backup", dumpkeys, "-", + device, (char *)0, safe_env()); + else + execle(cmd, "backup", dumpkeys, "-", + device, (char *)0, safe_env()); # else - execle(cmd, "dump", dumpkeys, + if (is_rundump) { + execle(cmd, "rundump", config, "dump", dumpkeys, #ifdef HAVE_HONOR_NODUMP - "0", + "0", #endif - "1048576", "-", device, (char *)0, safe_env()); + "1048576", "-", device, (char *)0, safe_env()); + } else { + execle(cmd, "dump", dumpkeys, +#ifdef HAVE_HONOR_NODUMP + "0", +#endif + "1048576", "-", device, (char *)0, safe_env()); + } # endif #endif { error("exec %s failed or no dump program available: %s", cmd, strerror(errno)); + /*NOTREACHED*/ } } @@ -1132,13 +1367,24 @@ long getsize_dump(disk, amdevice, level, options) if (killctl[0] != -1) aclose(killctl[0]); dumpout = fdopen(pipefd[0],"r"); + if (!dumpout) { + error("Can't fdopen: %s", strerror(errno)); + /*NOTREACHED*/ + } - for(size = -1; (line = agets(dumpout)) != NULL; free(line)) { + for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { + if (line[0] == '\0') + continue; dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); size = handle_dumpline(line); - if(size > -1) { + if(size > (off_t)-1) { amfree(line); - if((line = agets(dumpout)) != NULL) { + while ((line = agets(dumpout)) != NULL) { + if (line[0] != '\0') + break; + amfree(line); + } + if (line != NULL) { dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); } break; @@ -1149,23 +1395,23 @@ long getsize_dump(disk, amdevice, level, options) dbprintf(("%s: .....\n", debug_prefix_time(NULL))); dbprintf(("%s: estimate time for %s level %d: %s\n", debug_prefix(NULL), - disk, + qdisk, level, walltime_str(timessub(curclock(), start_time)))); - if(size == -1) { + if(size == (off_t)-1) { dbprintf(("%s: no size line match in %s%s output for \"%s\"\n", debug_prefix(NULL), cmd, name, disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); dbprintf(("%s: Run %s%s manually to check for errors\n", debug_prefix(NULL), cmd, name)); - } else if(size == 0 && level == 0) { + } else if(size == (off_t)0 && level == 0) { dbprintf(("%s: possible %s%s problem -- is \"%s\" really empty?\n", debug_prefix(NULL), cmd, name, disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); } else { dbprintf(("%s: estimate size for %s level %d: %ld KB\n", debug_prefix(NULL), - disk, + qdisk, level, size)); } @@ -1211,10 +1457,10 @@ long getsize_dump(disk, amdevice, level, options) } dbprintf(("%s: waiting for %s%s \"%s\" child\n", - debug_prefix_time(NULL), cmd, name, disk)); + debug_prefix_time(NULL), cmd, name, qdisk)); wait(NULL); - dbprintf(("%s: after %s%s \"%s\" wait\n", - debug_prefix_time(NULL), cmd, name, disk)); + dbprintf(("%s: after %s%s %s wait\n", + debug_prefix_time(NULL), cmd, name, qdisk)); terminated: @@ -1222,6 +1468,8 @@ long getsize_dump(disk, amdevice, level, options) afclose(dumpout); amfree(device); + amfree(qdevice); + amfree(qdisk); amfree(fstype); amfree(cmd); @@ -1231,24 +1479,29 @@ long getsize_dump(disk, amdevice, level, options) } #ifdef SAMBA_CLIENT -long getsize_smbtar(disk, amdevice, level, optionns) - char *disk, *amdevice; - int level; - option_t *optionns; +off_t +getsize_smbtar( + char *disk, + char *amdevice, + int level, + option_t * options) { int pipefd = -1, nullfd = -1, passwdfd = -1; - int dumppid; - long size; + pid_t dumppid; + off_t size; FILE *dumpout; char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL; char *share = NULL, *subdir = NULL; - int lpass; + size_t lpass; char *pwtext; - int pwtext_len; + size_t pwtext_len; char *line; char *pw_fd_env; times_t start_time; char *error_pn = NULL; + char *qdisk = quote_string(disk); + + (void)options; /* Quiet unused parameter warning */ error_pn = stralloc2(get_pname(), "-smbclient"); @@ -1258,14 +1511,16 @@ long getsize_smbtar(disk, amdevice, level, optionns) amfree(subdir); set_pname(error_pn); amfree(error_pn); - error("cannot parse disk entry '%s' for share/subdir", disk); + error("cannot parse disk entry %s for share/subdir", qdisk); + /*NOTREACHED*/ } if ((subdir) && (SAMBA_VERSION < 2)) { amfree(share); amfree(subdir); set_pname(error_pn); amfree(error_pn); - error("subdirectory specified for share '%s' but samba not v2 or better", disk); + error("subdirectory specified for share %s but samba not v2 or better", qdisk); + /*NOTREACHED*/ } if ((user_and_password = findpass(share, &domain)) == NULL) { @@ -1276,10 +1531,11 @@ long getsize_smbtar(disk, amdevice, level, optionns) set_pname(error_pn); amfree(error_pn); error("cannot find password for %s", disk); + /*NOTREACHED*/ } lpass = strlen(user_and_password); if ((pwtext = strchr(user_and_password, '%')) == NULL) { - memset(user_and_password, '\0', lpass); + memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); @@ -1288,11 +1544,12 @@ long getsize_smbtar(disk, amdevice, level, optionns) set_pname(error_pn); amfree(error_pn); error("password field not \'user%%pass\' for %s", disk); + /*NOTREACHED*/ } *pwtext++ = '\0'; pwtext_len = strlen(pwtext); if ((sharename = makesharename(share, 0)) == NULL) { - memset(user_and_password, '\0', lpass); + memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); @@ -1301,9 +1558,10 @@ long getsize_smbtar(disk, amdevice, level, optionns) set_pname(error_pn); amfree(error_pn); error("cannot make share name of %s", share); + /*NOTREACHED*/ } if ((nullfd = open("/dev/null", O_RDWR)) == -1) { - memset(user_and_password, '\0', lpass); + memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); @@ -1314,6 +1572,7 @@ long getsize_smbtar(disk, amdevice, level, optionns) amfree(sharename); error("could not open /dev/null: %s\n", strerror(errno)); + /*NOTREACHED*/ } #if SAMBA_VERSION >= 2 @@ -1357,17 +1616,18 @@ long getsize_smbtar(disk, amdevice, level, optionns) amfree(domain); } aclose(nullfd); - if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) { + if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) { int save_errno = errno; - memset(user_and_password, '\0', lpass); + memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); aclose(passwdfd); set_pname(error_pn); amfree(error_pn); error("password write failed: %s", strerror(save_errno)); + /*NOTREACHED*/ } - memset(user_and_password, '\0', lpass); + memset(user_and_password, '\0', (size_t)lpass); amfree(user_and_password); aclose(passwdfd); amfree(sharename); @@ -1375,13 +1635,24 @@ long getsize_smbtar(disk, amdevice, level, optionns) amfree(subdir); amfree(error_pn); dumpout = fdopen(pipefd,"r"); + if (!dumpout) { + error("Can't fdopen: %s", strerror(errno)); + /*NOTREACHED*/ + } - for(size = -1; (line = agets(dumpout)) != NULL; free(line)) { + for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { + if (line[0] == '\0') + continue; dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); size = handle_dumpline(line); if(size > -1) { amfree(line); - if((line = agets(dumpout)) != NULL) { + while ((line = agets(dumpout)) != NULL) { + if (line[0] != '\0') + break; + amfree(line); + } + if(line != NULL) { dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); } break; @@ -1392,50 +1663,54 @@ long getsize_smbtar(disk, amdevice, level, optionns) dbprintf(("%s: .....\n", debug_prefix_time(NULL))); dbprintf(("%s: estimate time for %s level %d: %s\n", debug_prefix(NULL), - disk, + qdisk, level, walltime_str(timessub(curclock(), start_time)))); - if(size == -1) { + if(size == (off_t)-1) { dbprintf(("%s: no size line match in %s output for \"%s\"\n", debug_prefix(NULL), SAMBA_CLIENT, disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); - } else if(size == 0 && level == 0) { + } else if(size == (off_t)0 && level == 0) { dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n", debug_prefix(NULL), SAMBA_CLIENT, disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); } dbprintf(("%s: estimate size for %s level %d: %ld KB\n", debug_prefix(NULL), - disk, + qdisk, level, size)); kill(-dumppid, SIGTERM); dbprintf(("%s: waiting for %s \"%s\" child\n", - debug_prefix_time(NULL), SAMBA_CLIENT, disk)); + debug_prefix_time(NULL), SAMBA_CLIENT, qdisk)); wait(NULL); - dbprintf(("%s: after %s \"%s\" wait\n", - debug_prefix_time(NULL), SAMBA_CLIENT, disk)); + dbprintf(("%s: after %s %s wait\n", + debug_prefix_time(NULL), SAMBA_CLIENT, qdisk)); afclose(dumpout); pipefd = -1; amfree(error_pn); + amfree(qdisk); return size; } #endif #ifdef GNUTAR -long getsize_gnutar(disk, amdevice, level, options, dumpsince) -char *disk, *amdevice; -int level; -option_t *options; -time_t dumpsince; +off_t +getsize_gnutar( + char *disk, + char *amdevice, + int level, + option_t * options, + time_t dumpsince) { - int pipefd = -1, nullfd = -1, dumppid; - long size = -1; + int pipefd = -1, nullfd = -1; + pid_t dumppid; + off_t size = (off_t)-1; FILE *dumpout = NULL; char *incrname = NULL; char *basename = NULL; @@ -1454,6 +1729,11 @@ time_t dumpsince; char *file_exclude = NULL; char *file_include = NULL; times_t start_time; + int infd, outfd; + ssize_t nb; + char buf[32768]; + char *qdisk = quote_string(disk); + char *gnutar_list_dir; if(options->exclude_file) nb_exclude += options->exclude_file->nb_element; if(options->exclude_list) nb_exclude += options->exclude_list->nb_element; @@ -1463,17 +1743,19 @@ time_t dumpsince; if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0); if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0); - my_argv = alloc(sizeof(char *) * 21); + my_argv = alloc(SIZEOF(char *) * 22); i = 0; -#ifdef GNUTAR_LISTED_INCREMENTAL_DIR - { + gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR); + if (strlen(gnutar_list_dir) == 0) + gnutar_list_dir = NULL; + if (gnutar_list_dir) { char number[NUM_STR_SIZE]; char *s; int ch; int baselevel; - basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR, + basename = vstralloc(gnutar_list_dir, "/", g_options->hostname, disk, @@ -1482,12 +1764,12 @@ time_t dumpsince; * The loop starts at the first character of the host name, * not the '/'. */ - s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR); + s = basename + strlen(gnutar_list_dir) + 1; while((ch = *s++) != '\0') { if(ch == '/' || isspace(ch)) s[-1] = '_'; } - snprintf(number, sizeof(number), "%d", level); + snprintf(number, SIZEOF(number), "%d", level); incrname = vstralloc(basename, "_", number, ".new", NULL); unlink(incrname); @@ -1497,15 +1779,16 @@ time_t dumpsince; * be true for a level 0), arrange to read from /dev/null. */ baselevel = level; - while (in == NULL) { + infd = -1; + while (infd == -1) { if (--baselevel >= 0) { - snprintf(number, sizeof(number), "%d", baselevel); + snprintf(number, SIZEOF(number), "%d", baselevel); inputname = newvstralloc(inputname, basename, "_", number, NULL); } else { inputname = newstralloc(inputname, "/dev/null"); } - if ((in = fopen(inputname, "r")) == NULL) { + if ((infd = open(inputname, O_RDONLY)) == -1) { int save_errno = errno; dbprintf(("%s: gnutar: error opening %s: %s\n", @@ -1519,59 +1802,57 @@ time_t dumpsince; /* * Copy the previous listed incremental file to the new one. */ - if ((out = fopen(incrname, "w")) == NULL) { + if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) { dbprintf(("%s: opening %s: %s\n", debug_prefix(NULL), incrname, strerror(errno))); goto common_exit; } - for (; (line = agets(in)) != NULL; free(line)) { - if (fputs(line, out) == EOF || putc('\n', out) == EOF) { + while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) { + if (fullwrite(outfd, &buf, (size_t)nb) < nb) { dbprintf(("%s: writing to %s: %s\n", debug_prefix(NULL), incrname, strerror(errno))); goto common_exit; } } - amfree(line); - if (ferror(in)) { + if (nb < 0) { dbprintf(("%s: reading from %s: %s\n", debug_prefix(NULL), inputname, strerror(errno))); goto common_exit; } - if (fclose(in) == EOF) { + + if (close(infd) != 0) { dbprintf(("%s: closing %s: %s\n", debug_prefix(NULL), inputname, strerror(errno))); - in = NULL; goto common_exit; } - in = NULL; - if (fclose(out) == EOF) { + if (close(outfd) != 0) { dbprintf(("%s: closing %s: %s\n", debug_prefix(NULL), incrname, strerror(errno))); - out = NULL; goto common_exit; } - out = NULL; amfree(inputname); amfree(basename); } -#endif gmtm = gmtime(&dumpsince); - snprintf(dumptimestr, sizeof(dumptimestr), + snprintf(dumptimestr, SIZEOF(dumptimestr), "%04d-%02d-%02d %2d:%02d:%02d GMT", gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); dirname = amname_to_dirname(amdevice); - - -#ifdef GNUTAR cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL); + my_argv[i++] = "runtar"; + if (g_options->config) + my_argv[i++] = g_options->config; + else + my_argv[i++] = "NOCONFIG"; +#ifdef GNUTAR my_argv[i++] = GNUTAR; #else my_argv[i++] = "tar"; @@ -1582,14 +1863,14 @@ time_t dumpsince; my_argv[i++] = "--directory"; my_argv[i++] = dirname; my_argv[i++] = "--one-file-system"; -#ifdef GNUTAR_LISTED_INCREMENTAL_DIR - my_argv[i++] = "--listed-incremental"; - my_argv[i++] = incrname; -#else - my_argv[i++] = "--incremental"; - my_argv[i++] = "--newer"; - my_argv[i++] = dumptimestr; -#endif + if (gnutar_list_dir) { + my_argv[i++] = "--listed-incremental"; + my_argv[i++] = incrname; + } else { + my_argv[i++] = "--incremental"; + my_argv[i++] = "--newer"; + my_argv[i++] = dumptimestr; + } #ifdef ENABLE_GNUTAR_ATIME_PRESERVE /* --atime-preserve causes gnutar to call * utime() after reading files in order to @@ -1618,21 +1899,35 @@ time_t dumpsince; start_time = curclock(); - nullfd = open("/dev/null", O_RDWR); + if ((nullfd = open("/dev/null", O_RDWR)) == -1) { + dbprintf(("Cannot access /dev/null : %s\n", strerror(errno))); + goto common_exit; + } + dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv); - amfree(cmd); - amfree(file_exclude); - amfree(file_include); dumpout = fdopen(pipefd,"r"); + if (!dumpout) { + error("Can't fdopen: %s", strerror(errno)); + /*NOTREACHED*/ + } - for(size = -1; (line = agets(dumpout)) != NULL; free(line)) { + for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { + if (line[0] == '\0') + continue; dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); size = handle_dumpline(line); - if(size > -1) { + if(size > (off_t)-1) { amfree(line); - if((line = agets(dumpout)) != NULL) { + while ((line = agets(dumpout)) != NULL) { + if (line[0] != '\0') { + break; + } + amfree(line); + } + if (line != NULL) { dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); + break; } break; } @@ -1642,31 +1937,31 @@ time_t dumpsince; dbprintf(("%s: .....\n", debug_prefix_time(NULL))); dbprintf(("%s: estimate time for %s level %d: %s\n", debug_prefix(NULL), - disk, + qdisk, level, walltime_str(timessub(curclock(), start_time)))); - if(size == -1) { + if(size == (off_t)-1) { dbprintf(("%s: no size line match in %s output for \"%s\"\n", debug_prefix(NULL), my_argv[0], disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); - } else if(size == 0 && level == 0) { + } else if(size == (off_t)0 && level == 0) { dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n", debug_prefix(NULL), my_argv[0], disk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); } dbprintf(("%s: estimate size for %s level %d: %ld KB\n", debug_prefix(NULL), - disk, + qdisk, level, size)); kill(-dumppid, SIGTERM); dbprintf(("%s: waiting for %s \"%s\" child\n", - debug_prefix_time(NULL), my_argv[0], disk)); + debug_prefix_time(NULL), my_argv[0], qdisk)); wait(NULL); - dbprintf(("%s: after %s \"%s\" wait\n", - debug_prefix_time(NULL), my_argv[0], disk)); + dbprintf(("%s: after %s %s wait\n", + debug_prefix_time(NULL), my_argv[0], qdisk)); common_exit: @@ -1678,6 +1973,10 @@ common_exit: amfree(dirname); amfree(inputname); amfree(my_argv); + amfree(qdisk); + amfree(cmd); + amfree(file_exclude); + amfree(file_include); aclose(nullfd); afclose(dumpout); @@ -1688,14 +1987,18 @@ common_exit: } #endif -long getsize_wrapper(program, disk, amdevice, level, options, dumpsince) -char *program, *disk, *amdevice; -int level; -option_t *options; -time_t dumpsince; +off_t +getsize_wrapper( + char *program, + char *disk, + char *amdevice, + int level, + option_t * options, + time_t dumpsince) { - int pipefd[2], nullfd, dumppid; - long size; + int pipefd[2], nullfd; + pid_t dumppid; + off_t size = (off_t)-1; FILE *dumpout; char *line = NULL; char *cmd = NULL; @@ -1704,11 +2007,13 @@ time_t dumpsince; int i, j; char *argvchild[10]; char *newoptstr = NULL; - long size1, size2; + off_t size1, size2; times_t start_time; + char *qdisk = quote_string(disk); + char *qamdevice = quote_string(amdevice); gmtm = gmtime(&dumpsince); - snprintf(dumptimestr, sizeof(dumptimestr), + snprintf(dumptimestr, SIZEOF(dumptimestr), "%04d-%02d-%02d %2d:%02d:%02d GMT", gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); @@ -1722,7 +2027,7 @@ time_t dumpsince; argvchild[i++] = "full"; else { char levelstr[NUM_STR_SIZE]; - snprintf(levelstr,sizeof(levelstr),"%d",level); + snprintf(levelstr,SIZEOF(levelstr),"%d",level); argvchild[i++] = "level"; argvchild[i++] = levelstr; } @@ -1736,14 +2041,23 @@ time_t dumpsince; dbprintf((" %s", argvchild[j])); } dbprintf(("\n")); - nullfd = open("/dev/null", O_RDWR); - pipe(pipefd); + + if ((nullfd = open("/dev/null", O_RDWR)) == -1) { + dbprintf(("Cannot access /dev/null : %s\n", strerror(errno))); + goto common_exit; + } + + if (pipe(pipefd) < 0) { + dbprintf(("getsize_wrapper could create data pipes: %s\n", + strerror(errno))); + goto common_exit; + } start_time = curclock(); switch(dumppid = fork()) { case -1: - size = -1; + size = (off_t)-1; goto common_exit; default: break; /* parent */ @@ -1755,21 +2069,35 @@ time_t dumpsince; execve(cmd, argvchild, safe_env()); error("exec %s failed: %s", cmd, strerror(errno)); + /*NOTREACHED*/ } amfree(newoptstr); aclose(pipefd[1]); dumpout = fdopen(pipefd[0],"r"); + if (!dumpout) { + error("Can't fdopen: %s", strerror(errno)); + /*NOTREACHED*/ + } - for(size = -1; (line = agets(dumpout)) != NULL; free(line)) { + for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { + if (line[0] == '\0') + continue; dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); - i = sscanf(line,"%ld %ld",&size1, &size2); + i = sscanf(line, OFF_T_FMT " " OFF_T_FMT, + (OFF_T_FMT_TYPE *)&size1, + (OFF_T_FMT_TYPE *)&size2); if(i == 2) { size = size1 * size2; } if(size > -1) { amfree(line); - if((line = agets(dumpout)) != NULL) { + while ((line = agets(dumpout)) != NULL) { + if (line[0] != '\0') + break; + amfree(line); + } + if(line != NULL) { dbprintf(("%s: %s\n", debug_prefix_time(NULL), line)); } break; @@ -1780,31 +2108,31 @@ time_t dumpsince; dbprintf(("%s: .....\n", debug_prefix_time(NULL))); dbprintf(("%s: estimate time for %s level %d: %s\n", debug_prefix(NULL), - amdevice, + qamdevice, level, walltime_str(timessub(curclock(), start_time)))); - if(size == -1) { + if(size == (off_t)-1) { dbprintf(("%s: no size line match in %s output for \"%s\"\n", - debug_prefix(NULL), cmd, disk)); + debug_prefix(NULL), cmd, qdisk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); - } else if(size == 0 && level == 0) { + } else if(size == (off_t)0 && level == 0) { dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n", - debug_prefix(NULL), cmd, disk)); + debug_prefix(NULL), cmd, qdisk)); dbprintf(("%s: .....\n", debug_prefix(NULL))); } - dbprintf(("%s: estimate size for %s level %d: %ld KB\n", + dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n", debug_prefix(NULL), - amdevice, + qamdevice, level, size)); kill(-dumppid, SIGTERM); dbprintf(("%s: waiting for %s \"%s\" child\n", - debug_prefix_time(NULL), cmd, disk)); + debug_prefix_time(NULL), cmd, qdisk)); wait(NULL); - dbprintf(("%s: after %s \"%s\" wait\n", - debug_prefix_time(NULL), cmd, disk)); + dbprintf(("%s: after %s %s wait\n", + debug_prefix_time(NULL), cmd, qdisk)); aclose(nullfd); afclose(dumpout); @@ -1813,15 +2141,19 @@ common_exit: amfree(cmd); amfree(newoptstr); + amfree(qdisk); + amfree(qamdevice); return size; } -double first_num(str) -char *str; /* * Returns the value of the first integer in a string. */ + +double +first_num( + char * str) { char *start; int ch; @@ -1833,27 +2165,32 @@ char *str; while(isdigit(ch) || (ch == '.')) ch = *str++; str[-1] = '\0'; d = atof(start); - str[-1] = ch; + str[-1] = (char)ch; return d; } -long handle_dumpline(str) -char *str; /* * Checks the dump output line against the error and size regex tables. */ + +off_t +handle_dumpline( + char * str) { regex_t *rp; double size; /* check for size match */ + /*@ignore@*/ for(rp = re_size; rp->regex != NULL; rp++) { if(match(rp->regex, str)) { size = ((first_num(str)*rp->scale+1023.0)/1024.0); - if(size < 0) size = 1; /* found on NeXT -- sigh */ - return (long) size; + if(size < 0.0) + size = 1.0; /* found on NeXT -- sigh */ + return (off_t)size; } } - return -1; + /*@end@*/ + return (off_t)-1; }