* 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 2006/08/24 01:57:15 paddy_s Exp $
*
* send estimated backup sizes using dump
*/
#include "getfsent.h"
#include "version.h"
#include "client_util.h"
+#include "conffile.h"
+#include "amandad.h"
#ifdef SAMBA_CLIENT
#include "findpass.h"
#endif
+#define sendsize_debug(i,x) do { \
+ if ((i) <= debug_sebdsize) { \
+ dbprintf(x); \
+ } \
+} while (0)
+
#ifdef HAVE_SETPGID
# define SETPGRP setpgid(getpid(), getpid())
# define SETPGRP_FAILED() do { \
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;
+ int program_is_backup_api;
int spindle;
pid_t child;
int done;
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 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;
+int main(int argc, char **argv);
+void add_diskest(char *disk, char *amdevice, int level, int spindle,
+ int program_is_backup_api, char *prog, char *calcprog,
+ 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 backup_api_calc_estimate(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;
+ int program_is_backup_api;
disk_estimates_t *est;
disk_estimates_t *est1;
disk_estimates_t *est_prev;
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 */
/* 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()));
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)) {
-#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
-#undef sc
+ if (line[0] == '\0')
+ continue;
+ if(strncmp_const(line, "OPTIONS ") == 0) {
g_options = parse_g_options(line+8, 1);
if(!g_options->hostname) {
g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
}
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 = getconf_str(CNF_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;
skip_non_whitespace(s, ch);
s[-1] = '\0';
- program_is_wrapper=0;
- if(strcmp(prog,"DUMPER")==0) {
- program_is_wrapper=1;
- skip_whitespace(s, ch); /* find dumper name */
- if (ch == '\0') {
- goto err; /* no program */
- }
- prog = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- }
-
- if(strncmp(prog, "CALCSIZE", 8) == 0) {
+ program_is_backup_api=0;
+ if(strncmp_const(prog, "CALCSIZE") == 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;
skip_non_whitespace(s, ch);
s[-1] = '\0';
+ if (strcmp(calcprog,"BACKUP") == 0) {
+ program_is_backup_api=1;
+ skip_whitespace(s, ch); /* find dumper name */
+ if (ch == '\0') {
+ goto err; /* no program */
+ }
+ calcprog = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ }
}
else {
calcprog = NULL;
+ if (strcmp(prog,"BACKUP") == 0) {
+ program_is_backup_api=1;
+ skip_whitespace(s, ch); /* find dumper name */
+ if (ch == '\0') {
+ goto err; /* no program */
+ }
+ prog = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ }
}
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) {
+ if(strncmp_const(s-1, "OPTIONS |;") == 0) {
options = parse_options(s + 8,
disk,
amdevice,
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_const(s-1, "exclude-file=") == 0) {
+ qlist = unquote_string(s+12);
+ options->exclude_file =
+ append_sl(options->exclude_file, qlist);
+ amfree(qlist);
+ } else if(strncmp_const(s-1, "exclude-list=") == 0) {
+ qlist = unquote_string(s+12);
+ options->exclude_list =
+ append_sl(options->exclude_list, qlist);
+ amfree(qlist);
+ } else if(strncmp_const(s-1, "include-file=") == 0) {
+ qlist = unquote_string(s+12);
+ options->include_file =
+ append_sl(options->include_file, qlist);
+ amfree(qlist);
+ } else if(strncmp_const(s-1, "include-list=") == 0) {
+ qlist = unquote_string(s+12);
+ options->include_list =
+ append_sl(options->include_list, qlist);
+ 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);
+ }
- add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options);
+ /*@ignore@*/
+ add_diskest(disk, amdevice, level, spindle, program_is_backup_api, 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);
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",
exit(0);
} else if(est->child == -1) {
error("calc_estimates fork failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
dumpsrunning++; /* parent */
}
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;
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_backup_api,
+ 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 */
}
}
- 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);
else
newp->calcprog = NULL;
- newp->program_is_wrapper = program_is_wrapper;
+ newp->program_is_backup_api = program_is_backup_api;
newp->spindle = spindle;
newp->est[level].needestimate = 1;
newp->options = 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);
*
*/
-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));
-
- if(est->program_is_wrapper == 1)
- wrapper_calc_estimates(est);
+ est->qamname, est->qdirname, est->spindle));
+
+ if(est->program_is_backup_api == 1)
+ backup_api_calc_estimate(est);
else
#ifndef USE_GENERIC_CALCSIZE
if(strcmp(est->program, "DUMP") == 0)
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));
}
/*
*/
/* 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,
+ char **errmsg);
+off_t getsize_smbtar(char *disk, char *amdevice, int level, option_t *options,
+ char **errmsg);
+off_t getsize_gnutar(char *disk, char *amdevice, int level,
+ option_t *options, time_t dumpsince, char **errmsg);
+off_t getsize_backup_api(char *program, char *disk, char *amdevice, int level,
+ option_t *options, time_t dumpsince, char **errmsg);
+off_t handle_dumpline(char *str);
+double first_num(char *str);
+
+void
+backup_api_calc_estimate(
+ disk_estimates_t * est)
{
- int level;
- long size;
+ int level;
+ off_t size;
+ char *errmsg = NULL, *qerrmsg;
- 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);
-
- amflock(1, "size");
+ for(level = 0; level < DUMP_LEVELS; level++) {
+ if (est->est[level].needestimate) {
+ dbprintf(("%s: getting size via backup-api for %s %s level %d\n",
+ debug_prefix_time(NULL), est->qamname, est->qamdevice,
+ level));
+ size = getsize_backup_api(est->program, est->amname, est->amdevice,
+ level, est->options,
+ est->est[level].dumpsince, &errmsg);
- fseek(stdout, (off_t)0, SEEK_SET);
+ amflock(1, "size");
- printf("%s %d SIZE %ld\n", est->amname, level, size);
- fflush(stdout);
+ printf("%s %d SIZE " OFF_T_FMT "\n", est->qamname, level,
+ (OFF_T_FMT_TYPE)size);
+ if (errmsg && errmsg[0] != '\0') {
+ if(am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ qerrmsg = quote_string(errmsg);
+ dbprintf(("errmsg is %s\n", errmsg));
+ printf("%s %d ERROR %s\n",
+ est->qamname, level, qerrmsg);
+ amfree(qerrmsg);
+ }
+ }
+ amfree(errmsg);
+ fflush(stdout);
- amfunlock(1, "size");
- }
- }
+ amfunlock(1, "size");
+ }
+ }
}
-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;
+ 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;
+ amwait_t wait_status;
+ char *errmsg = NULL, *qerrmsg;
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);
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");
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));
fflush(stderr); fflush(stdout);
if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
- dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+ errmsg = vstrallocf("Cannot access /dev/null : %s",
+ strerror(errno));
+ dbprintf(("%s\n", errmsg));
goto common_exit;
}
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(sscanf(line, match_expr, &level, &size) == 2) {
+ 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)) {
+ OFF_T_FMT_TYPE size_ = (OFF_T_FMT_TYPE)0;
+ 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",
- debug_prefix(NULL),
- est->amname,
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
+ debug_prefix_time(NULL),
+ est->qamname,
level,
- size));
+ size_));
}
+ size = (off_t)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));
+ waitpid(calcpid, &wait_status, 0);
+ if (WIFSIGNALED(wait_status)) {
+ errmsg = vstrallocf("%s terminated with signal %d: see %s",
+ "calcsize", WTERMSIG(wait_status),
+ debug_fn());
+ } else if (WIFEXITED(wait_status)) {
+ if (WEXITSTATUS(wait_status) != 0) {
+ errmsg = vstrallocf("%s exited with status %d: see %s",
+ "calcsize", WEXITSTATUS(wait_status),
+ debug_fn());
+ } else {
+ /* Normal exit */
+ }
+ } else {
+ errmsg = vstrallocf("%s got bad exit: see %s",
+ "calcsize", debug_fn());
+ }
+ dbprintf(("%s: after %s %s wait: child pid=%d status=%d\n",
+ debug_prefix_time(NULL), my_argv[0], est->qamdevice,
+ calcpid, WEXITSTATUS(wait_status)));
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s: %s\n",
- debug_prefix(NULL),
- est->amname,
+ debug_prefix_time(NULL),
+ est->qamname,
walltime_str(timessub(curclock(), start_time))));
common_exit:
+ if (errmsg && errmsg[0] != '\0') {
+ if(am_has_feature(g_options->features, fe_rep_sendsize_quoted_error)) {
+ qerrmsg = quote_string(errmsg);
+ dbprintf(("errmsg is %s\n", errmsg));
+ printf("%s %d ERROR %s\n",
+ est->qamname, 0, qerrmsg);
+ amfree(qerrmsg);
+ }
+ }
+ amfree(errmsg);
for(i = 0; i < my_argc; i++) {
amfree(my_argv[i]);
}
}
-void dump_calc_estimates(est)
-disk_estimates_t *est;
+void
+dump_calc_estimates(
+ disk_estimates_t * est)
{
int level;
- long size;
+ off_t size;
+ char *errmsg=NULL, *qerrmsg;
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, &errmsg);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
-
- 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);
+ if (errmsg && errmsg[0] != '\0') {
+ if(am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ qerrmsg = quote_string(errmsg);
+ dbprintf(("errmsg is %s\n", errmsg));
+ printf("%s %d ERROR %s\n",
+ est->qamname, level, qerrmsg);
+ amfree(qerrmsg);
+ }
+ }
+ amfree(errmsg);
fflush(stdout);
amfunlock(1, "size");
}
#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;
+ char *errmsg = NULL, *qerrmsg;
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));
- size = getsize_smbtar(est->amname, est->amdevice, level, est->options);
+ debug_prefix_time(NULL), est->qamname, level));
+ size = getsize_smbtar(est->amname, est->amdevice, level,
+ est->options, &errmsg);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
-
- 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);
+ if (errmsg && errmsg[0] != '\0') {
+ if(am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ qerrmsg = quote_string(errmsg);
+ dbprintf(("errmsg is %s\n", errmsg));
+ printf("%s %d ERROR %s\n",
+ est->qamname, level, qerrmsg);
+ amfree(qerrmsg);
+ }
+ }
+ amfree(errmsg);
fflush(stdout);
amfunlock(1, "size");
#endif
#ifdef GNUTAR
-void gnutar_calc_estimates(est)
-disk_estimates_t *est;
+void
+gnutar_calc_estimates(
+ disk_estimates_t * est)
{
- int level;
- long 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));
- size = getsize_gnutar(est->amname, est->amdevice, level,
- est->options, est->est[level].dumpsince);
+ int level;
+ off_t size;
+ char *errmsg = NULL, *qerrmsg;
- amflock(1, "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->qamname, level));
+ size = getsize_gnutar(est->amname, est->amdevice, level,
+ est->options, est->est[level].dumpsince,
+ &errmsg);
- fseek(stdout, (off_t)0, SEEK_SET);
+ amflock(1, "size");
- printf("%s %d SIZE %ld\n", est->amname, level, size);
- fflush(stdout);
+ printf("%s %d SIZE " OFF_T_FMT "\n",
+ est->qamname, level, (OFF_T_FMT_TYPE)size);
+ if (errmsg && errmsg[0] != '\0') {
+ if(am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ qerrmsg = quote_string(errmsg);
+ dbprintf(("errmsg is %s\n", errmsg));
+ printf("%s %d ERROR %s\n",
+ est->qamname, level, qerrmsg);
+ amfree(qerrmsg);
+ }
+ }
+ amfree(errmsg);
+ fflush(stdout);
- amfunlock(1, "size");
- }
- }
+ amfunlock(1, "size");
+ }
+ }
}
#endif
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 */
{"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
{ 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,
+ char **errmsg)
{
int pipefd[2], nullfd, stdoutfd, killctl[2];
pid_t dumppid;
- long size;
+ off_t size;
FILE *dumpout;
char *dumpkeys = NULL;
char *device = NULL;
char level_str[NUM_STR_SIZE];
int s;
times_t start_time;
+ char *qdisk = quote_string(disk);
+ char *qdevice;
+ char *config;
+ amwait_t wait_status;
+#if defined(DUMP) || defined(VDUMP) || defined(VXDUMP) || defined(XFSDUMP)
+ int is_rundump = 1;
+#endif
+
+ (void)options; /* Quiet unused parameter warning */
+
+ (void)getsize_smbtar; /* Quiet unused parameter warning */
- snprintf(level_str, sizeof(level_str), "%d", level);
+ 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)));
+ *errmsg = vstrallocf("getsize_dump could not open /dev/null: %s",
+ strerror(errno));
+ dbprintf(("%s\n", *errmsg));
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) {
+ *errmsg = vstrallocf("getsize_dump could create data pipes: %s",
+ strerror(errno));
+ dbprintf(("%s\n", *errmsg));
+ amfree(cmd);
+ amfree(rundump_cmd);
+ amfree(fstype);
+ amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
+ return(-1);
+ }
#ifdef XFSDUMP /* { */
#ifdef DUMP /* { */
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 /* } */
#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 /* } */
{
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 /* } */
# 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_HONOR_NODUMP,
"s", "f", NULL);
# ifdef HAVE_DUMP_ESTIMATE
# 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 /* } */
}
#endif /* } */
{
error("no dump program available");
+ /*NOTREACHED*/
}
- pipe(killctl);
+ if (pipe(killctl) < 0) {
+ dbprintf(("%s: Could not create pipe: %s\n",
+ debug_prefix_time(NULL), strerror(errno)));
+ /* Message will be printed later... */
+ killctl[0] = killctl[1] = -1;
+ }
start_time = curclock();
switch(dumppid = fork()) {
case -1:
- dbprintf(("%s: cannot fork for killpgrp: %s\n",
- debug_prefix(NULL), strerror(errno)));
+ *errmsg = vstrallocf("cannot fork for killpgrp: %s",
+ strerror(errno));
+ dbprintf(("%s\n", *errmsg));
amfree(dumpkeys);
amfree(cmd);
amfree(rundump_cmd);
amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
amfree(name);
amfree(fstype);
return -1;
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_time(NULL)));
else {
switch(fork()) {
case -1:
dbprintf(("%s: fork failed, trying without killpgrp\n",
- debug_prefix(NULL)));
+ debug_prefix_time(NULL)));
break;
default:
{
+ char *config;
char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp",
versionsuffix(), NULL);
dbprintf(("%s: running %s\n",
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)));
+ debug_prefix_time(NULL), killpgrp_cmd, strerror(errno)));
exit(-1);
}
#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
#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
#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*/
}
}
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;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
- debug_prefix(NULL),
- disk,
+ debug_prefix_time(NULL),
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -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)));
+ if(size == (off_t)-1) {
+ *errmsg = vstrallocf("no size line match in %s%s output",
+ cmd, name);
+ dbprintf(("%s: %s for %s\n", debug_prefix_time(NULL),
+ *errmsg, qdisk));
+
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: Run %s%s manually to check for errors\n",
- debug_prefix(NULL), cmd, name));
- } else if(size == 0 && level == 0) {
+ debug_prefix_time(NULL), cmd, name));
+ } 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)));
+ debug_prefix_time(NULL), cmd, name, disk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
} else {
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
- debug_prefix(NULL),
- disk,
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
+ debug_prefix_time(NULL),
+ qdisk,
level,
- size));
+ (OFF_T_FMT_TYPE)size));
}
if (killctl[1] != -1) {
debug_prefix_time(NULL), (long)dumppid));
if (kill(-dumppid, SIGTERM) == -1) {
dbprintf(("%s: kill failed: %s\n",
- debug_prefix(NULL), strerror(errno)));
+ debug_prefix_time(NULL), strerror(errno)));
}
/* Now check whether it dies */
for(s = 5; s > 0; --s) {
debug_prefix_time(NULL), (long)dumppid));
if (kill(-dumppid, SIGKILL) == -1) {
dbprintf(("%s: kill failed: %s\n",
- debug_prefix(NULL), strerror(errno)));
+ debug_prefix_time(NULL), strerror(errno)));
}
for(s = 5; s > 0; --s) {
sleep(1);
}
dbprintf(("%s: waiting for %s%s \"%s\" child\n",
- debug_prefix_time(NULL), cmd, name, disk));
- wait(NULL);
- dbprintf(("%s: after %s%s \"%s\" wait\n",
- debug_prefix_time(NULL), cmd, name, disk));
+ debug_prefix_time(NULL), cmd, name, qdisk));
+ waitpid(dumppid, &wait_status, 0);
+ if (WIFSIGNALED(wait_status)) {
+ *errmsg = vstrallocf("%s terminated with signal %d: see %s",
+ cmd, WTERMSIG(wait_status), debug_fn());
+ } else if (WIFEXITED(wait_status)) {
+ if (WEXITSTATUS(wait_status) != 0) {
+ *errmsg = vstrallocf("%s exited with status %d: see %s",
+ cmd, WEXITSTATUS(wait_status), debug_fn());
+ } else {
+ /* Normal exit */
+ }
+ } else {
+ *errmsg = vstrallocf("%s got bad exit: see %s",
+ cmd, debug_fn());
+ }
+ dbprintf(("%s: after %s%s %s wait\n",
+ debug_prefix_time(NULL), cmd, name, qdisk));
terminated:
afclose(dumpout);
amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
amfree(fstype);
amfree(cmd);
}
#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,
+ char **errmsg)
{
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);
+ amwait_t wait_status;
+
+ (void)options; /* Quiet unused parameter warning */
error_pn = stralloc2(get_pname(), "-smbclient");
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) {
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));
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));
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));
amfree(sharename);
error("could not open /dev/null: %s\n",
strerror(errno));
+ /*NOTREACHED*/
}
#if SAMBA_VERSION >= 2
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);
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;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
- debug_prefix(NULL),
- disk,
+ debug_prefix_time(NULL),
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -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) {
+ if(size == (off_t)-1) {
+ *errmsg = vstrallocf("no size line match in %s output",
+ SAMBA_CLIENT);
+ dbprintf(("%s: %s for %s\n", debug_prefix_time(NULL),
+ *errmsg, qdisk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+ } 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)));
+ debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
}
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
- debug_prefix(NULL),
- disk,
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
+ debug_prefix_time(NULL),
+ qdisk,
level,
- size));
+ (OFF_T_FMT_TYPE)size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), SAMBA_CLIENT, disk));
- wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+ debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
+ waitpid(dumppid, &wait_status, 0);
+ if (WIFSIGNALED(wait_status)) {
+ *errmsg = vstrallocf("%s terminated with signal %d: see %s",
+ "smbclient", WTERMSIG(wait_status), debug_fn());
+ } else if (WIFEXITED(wait_status)) {
+ if (WEXITSTATUS(wait_status) != 0) {
+ *errmsg = vstrallocf("%s exited with status %d: see %s",
+ "smbclient", WEXITSTATUS(wait_status),
+ debug_fn());
+ } else {
+ /* Normal exit */
+ }
+ } else {
+ *errmsg = vstrallocf("%s got bad exit: see %s",
+ "smbclient", debug_fn());
+ }
+ 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,
+ char **errmsg)
{
- 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;
int infd, outfd;
ssize_t nb;
char buf[32768];
+ char *qdisk = quote_string(disk);
+ char *gnutar_list_dir;
+ amwait_t wait_status;
if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
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 = getconf_str(CNF_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,
* 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);
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 ((infd = open(inputname, O_RDONLY)) == -1) {
- int save_errno = errno;
- dbprintf(("%s: gnutar: error opening %s: %s\n",
- debug_prefix(NULL), inputname, strerror(save_errno)));
+ *errmsg = vstrallocf("gnutar: error opening %s: %s",
+ inputname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
if (baselevel < 0) {
goto common_exit;
}
+ amfree(*errmsg);
}
}
* Copy the previous listed incremental file to the new one.
*/
if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
- dbprintf(("%s: opening %s: %s\n",
- debug_prefix(NULL), incrname, strerror(errno)));
+ *errmsg = vstrallocf("opening %s: %s",
+ incrname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
goto common_exit;
}
- while ((nb = read(infd, &buf, sizeof(buf))) > 0) {
- if (fullwrite(outfd, &buf, nb) < nb) {
- dbprintf(("%s: writing to %s: %s\n",
- debug_prefix(NULL), incrname, strerror(errno)));
+ while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+ if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
+ *errmsg = vstrallocf("writing to %s: %s",
+ incrname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
goto common_exit;
}
}
if (nb < 0) {
- dbprintf(("%s: reading from %s: %s\n",
- debug_prefix(NULL), inputname, strerror(errno)));
+ *errmsg = vstrallocf("reading from %s: %s",
+ inputname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
goto common_exit;
}
if (close(infd) != 0) {
- dbprintf(("%s: closing %s: %s\n",
- debug_prefix(NULL), inputname, strerror(errno)));
+ *errmsg = vstrallocf("closing %s: %s",
+ inputname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
goto common_exit;
}
if (close(outfd) != 0) {
- dbprintf(("%s: closing %s: %s\n",
- debug_prefix(NULL), incrname, strerror(errno)));
+ *errmsg = vstrallocf("closing %s: %s",
+ incrname, strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
goto common_exit;
}
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";
my_argv[i++] = "--directory";
my_argv[i++] = dirname;
my_argv[i++] = "--one-file-system";
- my_argv[i++] = "--numeric-owner";
-#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
start_time = curclock();
- nullfd = open("/dev/null", O_RDWR);
+ if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+ *errmsg = vstrallocf("Cannot access /dev/null : %s",
+ strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
+ 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;
}
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
- debug_prefix(NULL),
- disk,
+ debug_prefix_time(NULL),
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -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) {
+ if(size == (off_t)-1) {
+ *errmsg = vstrallocf("no size line match in %s output", my_argv[0]);
+ dbprintf(("%s: %s for %s\n", debug_prefix_time(NULL),
+ *errmsg, qdisk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+ } 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)));
+ debug_prefix_time(NULL), my_argv[0], disk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
}
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
- debug_prefix(NULL),
- disk,
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
+ debug_prefix_time(NULL),
+ qdisk,
level,
- size));
+ (OFF_T_FMT_TYPE)size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), my_argv[0], disk));
- wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), my_argv[0], disk));
+ debug_prefix_time(NULL), my_argv[0], qdisk));
+ waitpid(dumppid, &wait_status, 0);
+ if (WIFSIGNALED(wait_status)) {
+ *errmsg = vstrallocf("%s terminated with signal %d: see %s",
+ cmd, WTERMSIG(wait_status), debug_fn());
+ } else if (WIFEXITED(wait_status)) {
+ if (WEXITSTATUS(wait_status) != 0) {
+ *errmsg = vstrallocf("%s exited with status %d: see %s",
+ cmd, WEXITSTATUS(wait_status), debug_fn());
+ } else {
+ /* Normal exit */
+ }
+ } else {
+ *errmsg = vstrallocf("%s got bad exit: see %s",
+ cmd, debug_fn());
+ }
+ dbprintf(("%s: after %s %s wait\n",
+ debug_prefix_time(NULL), my_argv[0], qdisk));
common_exit:
amfree(dirname);
amfree(inputname);
amfree(my_argv);
+ amfree(qdisk);
+ amfree(cmd);
+ amfree(file_exclude);
+ amfree(file_include);
aclose(nullfd);
afclose(dumpout);
}
#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_backup_api(
+ char *program,
+ char *disk,
+ char *amdevice,
+ int level,
+ option_t *options,
+ time_t dumpsince,
+ char **errmsg)
{
- int pipefd[2], nullfd, dumppid;
- long size;
- FILE *dumpout;
+ int pipeinfd[2], pipeoutfd[2], nullfd;
+ pid_t dumppid;
+ off_t size = (off_t)-1;
+ FILE *dumpout, *toolin;
char *line = NULL;
char *cmd = NULL;
char dumptimestr[80];
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);
+ amwait_t wait_status;
+ char levelstr[NUM_STR_SIZE];
+ backup_support_option_t *bsu;
+ (void)options;
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);
cmd = vstralloc(DUMPER_DIR, "/", program, NULL);
+ bsu = backup_support_option(program, g_options, disk, amdevice);
+
i=0;
argvchild[i++] = program;
argvchild[i++] = "estimate";
- if(level == 0)
- argvchild[i++] = "full";
- else {
- char levelstr[NUM_STR_SIZE];
- snprintf(levelstr,sizeof(levelstr),"%d",level);
- argvchild[i++] = "level";
- argvchild[i++] = levelstr;
+ if (bsu->message_line == 1) {
+ argvchild[i++] = "--message";
+ argvchild[i++] = "line";
+ }
+ if (g_options->config && bsu->config == 1) {
+ argvchild[i++] = "--config";
+ argvchild[i++] = g_options->config;
+ }
+ if (g_options->hostname && bsu->host == 1) {
+ argvchild[i++] = "--host";
+ argvchild[i++] = g_options->hostname;
}
+ argvchild[i++] = "--device";
argvchild[i++] = amdevice;
- newoptstr = vstralloc(options->str,"estimate-direct;", NULL);
- argvchild[i++] = newoptstr;
+ if (disk && bsu->disk == 1) {
+ argvchild[i++] = "--disk";
+ argvchild[i++] = disk;
+ }
+ if (level <= bsu->max_level) {
+ argvchild[i++] = "--level";
+ snprintf(levelstr,SIZEOF(levelstr),"%d",level);
+ argvchild[i++] = levelstr;
+ }
+
argvchild[i] = NULL;
dbprintf(("%s: running %s", debug_prefix_time(NULL), cmd));
dbprintf((" %s", argvchild[j]));
}
dbprintf(("\n"));
- nullfd = open("/dev/null", O_RDWR);
- pipe(pipefd);
+
+ if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+ *errmsg = vstrallocf("Cannot access /dev/null : %s",
+ strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
+ goto common_exit;
+ }
+
+ if (pipe(pipeinfd) < 0) {
+ *errmsg = vstrallocf("getsize_backup_api could create data pipes: %s",
+ strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
+ goto common_exit;
+ }
+
+ if (pipe(pipeoutfd) < 0) {
+ *errmsg = vstrallocf("getsize_backup_api could create data pipes: %s",
+ strerror(errno));
+ dbprintf(("%s: %s\n", debug_prefix_time(NULL), *errmsg));
+ goto common_exit;
+ }
start_time = curclock();
switch(dumppid = fork()) {
case -1:
- size = -1;
+ size = (off_t)-1;
goto common_exit;
default:
break; /* parent */
case 0:
- dup2(nullfd, 0);
+ dup2(pipeinfd[0], 0);
+ dup2(pipeoutfd[1], 1);
dup2(nullfd, 2);
- dup2(pipefd[1], 1);
- aclose(pipefd[0]);
+ aclose(pipeinfd[1]);
+ aclose(pipeoutfd[0]);
execve(cmd, argvchild, safe_env());
error("exec %s failed: %s", cmd, strerror(errno));
+ /*NOTREACHED*/
}
amfree(newoptstr);
- aclose(pipefd[1]);
- dumpout = fdopen(pipefd[0],"r");
+ aclose(pipeinfd[0]);
+ aclose(pipeoutfd[1]);
+
+ toolin = fdopen(pipeinfd[1],"w");
+ if (!toolin) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ output_tool_property(toolin, options);
+ fflush(toolin);
+ fclose(toolin);
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ dumpout = fdopen(pipeoutfd[0],"r");
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ OFF_T_FMT_TYPE size1_ = (OFF_T_FMT_TYPE)0;
+ OFF_T_FMT_TYPE size2_ = (OFF_T_FMT_TYPE)0;
+ 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, &size1_, &size2_);
+ size1 = (off_t)size1_;
+ size2 = (off_t)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;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
- debug_prefix(NULL),
- amdevice,
+ debug_prefix_time(NULL),
+ qamdevice,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -1) {
- dbprintf(("%s: no size line match in %s output for \"%s\"\n",
- debug_prefix(NULL), cmd, disk));
- dbprintf(("%s: .....\n", debug_prefix(NULL)));
- } else if(size == 0 && level == 0) {
+ if(size == (off_t)-1) {
+ *errmsg = vstrallocf("no size line match in %s output", cmd);
+ dbprintf(("%s: %s for %s\n", debug_prefix_time(NULL), cmd, qdisk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+ } else if(size == (off_t)0 && level == 0) {
dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
- debug_prefix(NULL), cmd, disk));
- dbprintf(("%s: .....\n", debug_prefix(NULL)));
+ debug_prefix_time(NULL), cmd, qdisk));
+ dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
}
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
- debug_prefix(NULL),
- amdevice,
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
+ debug_prefix_time(NULL),
+ qamdevice,
level,
- size));
+ (OFF_T_FMT_TYPE)size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), cmd, disk));
- wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), cmd, disk));
+ debug_prefix_time(NULL), cmd, qdisk));
+ waitpid(dumppid, &wait_status, 0);
+ if (WIFSIGNALED(wait_status)) {
+ *errmsg = vstrallocf("%s terminated with signal %d: see %s",
+ cmd, WTERMSIG(wait_status), debug_fn());
+ } else if (WIFEXITED(wait_status)) {
+ if (WEXITSTATUS(wait_status) != 0) {
+ *errmsg = vstrallocf("%s exited with status %d: see %s", cmd,
+ WEXITSTATUS(wait_status), debug_fn());
+ } else {
+ /* Normal exit */
+ }
+ } else {
+ *errmsg = vstrallocf("%s got bad exit: see %s",
+ cmd, debug_fn());
+ }
+ dbprintf(("%s: after %s %s wait\n",
+ debug_prefix_time(NULL), cmd, qdisk));
aclose(nullfd);
afclose(dumpout);
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;
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;
}