Exemple #1
0
void XParam::saveXmlDoc(string xdoc, bool show_runtime, const int &indent,
	bool with_endl) const throw (Exception)
{
	string sxml;
	try {
		sxml = xml(show_runtime, indent, with_endl);
	} catch (std::exception &e) {
		throw Exception("Can't generate xml to save " 
				+ get_pname() + " !: " + e.what(), 
				TracePoint("pparam"));
	}
	std::fstream xfile;
	try {
		xfile.open(xdoc.c_str(),
			std::ios_base::trunc | std::ios_base::out);
	} catch (std::exception &e) {
		throw Exception("Can't open file to save " 
				+ get_pname() + " !: " + e.what(),
				TracePoint("pparam"));
	}
	if (xfile.fail())
		throw Exception("Can't open file to save " 
				+ get_pname() + " !",
				TracePoint("pparam"));
	xfile << sxml;
	xfile.close();
}
Exemple #2
0
void
parse_backup_messages(
    dle_t      *dle,
    int		mesgin)
{
    int goterror;
    char *line;

    amfree(errorstr);

    for(; (line = areads(mesgin)) != NULL; free(line)) {
	process_dumpline(line);
    }

    if(errno) {
	error(_("error [read mesg pipe: %s]"), strerror(errno));
	/*NOTREACHED*/
    }

    goterror = check_result(mesgfd);

    if(errorstr) {
	error(_("error [%s]"), errorstr);
	/*NOTREACHED*/
    } else if(dump_size == -1) {
	error(_("error [no backup size line]"));
	/*NOTREACHED*/
    }

    program->end_backup(dle, goterror);

    fdprintf(mesgfd, _("%s: size %ld\n"), get_pname(), dump_size);
    fdprintf(mesgfd, _("%s: end\n"), get_pname());
}
Exemple #3
0
int cmp(const void *a, const void *b)
{
	char *pa;
	char *pb;
	pa=get_pname(*(char **)a);
	pb=get_pname(*(char **)b);
	return strcmp(pa, pb);
}
Exemple #4
0
int
get_line(void)
{
    char *line = NULL;
    char *part = NULL;
    size_t len;

    while(1) {
	if((part = areads(server_socket)) == NULL) {
	    int save_errno = errno;

	    if(server_line) {
		fputs(server_line, stderr);	/* show the last line read */
		fputc('\n', stderr);
	    }
	    if(save_errno != 0) {
		g_fprintf(stderr, _("%s: Error reading line from server: %s\n"),
				get_pname(),
				strerror(save_errno));
	    } else {
		g_fprintf(stderr, _("%s: Unexpected end of file, check amindexd*debug on server %s\n"),
			get_pname(),
			server_name);
	    }
	    errno = save_errno;
	    break;	/* exit while loop */
	}
	if(line) {
	    strappend(line, part);
	    amfree(part);
	} else {
	    line = part;
	    part = NULL;
	}
	if((len = strlen(line)) > 0 && line[len-1] == '\r') {
	    line[len-1] = '\0';
	    g_free(server_line);
	    server_line = g_strdup(line);
	    amfree(line);
	    return 0;
	}
	/*
	 * Hmmm.  We got a "line" from areads(), which means it saw
	 * a '\n' (or EOF, etc), but there was not a '\r' before it.
	 * Put a '\n' back in the buffer and loop for more.
	 */
	strappend(line, "\n");
    }
    amfree(line);
    amfree(server_line);
    return -1;
}
Exemple #5
0
/*
 * Open file descriptor for current disk (cur_file)
 *	with "p0" path or cur_disk->disk_path
 */
void
open_cur_file(int mode)
{
	char	*dkpath;
	char	pbuf[MAXPATHLEN];

	switch (mode) {
	    case FD_USE_P0_PATH:
		(void) get_pname(&pbuf[0]);
		dkpath = pbuf;
		break;
	    case FD_USE_CUR_DISK_PATH:
		if (cur_disk->fdisk_part.systid == SUNIXOS ||
		    cur_disk->fdisk_part.systid == SUNIXOS2) {
			(void) get_sname(&pbuf[0]);
			dkpath = pbuf;
		} else {
			dkpath = cur_disk->disk_path;
		}
		break;
	    default:
		err_print("Error: Invalid mode option for opening cur_file\n");
		fullabort();
	}

	/* Close previous cur_file */
	(void) close(cur_file);
	/* Open cur_file with the required path dkpath */
	if ((cur_file = open_disk(dkpath, O_RDWR | O_NDELAY)) < 0) {
		err_print(
		    "Error: can't open selected disk '%s'.\n", dkpath);
		fullabort();
	}
}
Exemple #6
0
printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
{
    va_list argp;
    char *leader = NULL;
    char *xlated_fmt = gettext(format);
    char linebuf[STR_SIZE];
    size_t n;
    static gboolean in_log_add = 0;

    /* avoid recursion */
    if (in_log_add)
	return;

    /* format error message */

    if((int)typ <= (int)L_BOGUS || (int)typ > (int)L_MARKER) typ = L_BOGUS;

    if(multiline > 0) {
	leader = stralloc("  ");		/* continuation line */
    } else {
	leader = vstralloc(logtype_str[(int)typ], " ", get_pname(), " ", NULL);
    }

    arglist_start(argp, format);
    /* use sizeof(linebuf)-2 to save space for a trailing newline */
    g_vsnprintf(linebuf, SIZEOF(linebuf)-2, xlated_fmt, argp);
						/* -1 to allow for '\n' */
    arglist_end(argp);

    /* avoid recursive call from error() */

    in_log_add = 1;

    /* append message to the log file */

    if(multiline == -1) open_log();

    if (full_write(logfd, leader, strlen(leader)) < strlen(leader)) {
	error(_("log file write error: %s"), strerror(errno));
	/*NOTREACHED*/
    }

    amfree(leader);

    /* add a newline if necessary */
    n = strlen(linebuf);
    if(n == 0 || linebuf[n-1] != '\n') linebuf[n++] = '\n';
    linebuf[n] = '\0';

    if (full_write(logfd, linebuf, n) < n) {
	error(_("log file write error: %s"), strerror(errno));
	/*NOTREACHED*/
    }

    if(multiline != -1) multiline++;
    else close_log();

    in_log_add = 0;
}
Exemple #7
0
void log_add(logtype_t typ, char *format, ...)
{
    va_list argp;

    arglist_start(argp, format);
    log_add_full_v(typ, get_pname(), format, argp);
    arglist_end(argp);
}
void plot_output(
  double *t,      ///< time (I)
  double *xd,     ///< differential states (I)
  double *xa,     ///< algebraic states (I)
  double *u,      ///< controls (I)
  double *p_free,      ///< global model parameters (I)
  double *rwh,    ///< real work array (I)
  long   *iwh,     ///< integer work array (I)
  InfoPtr *info
){
	FILE *fp;
	stringstream output_filename("");
	// Filename
	char problemname[50];
	get_pname(problemname);
	output_filename << "./RES/" << problemname <<".plt";
	if (*t == 0)
		fp = fopen(output_filename.str().c_str(), "w");
	else
		fp = fopen(output_filename.str().c_str(), "a");
	if (!fp) {
		fprintf(stderr, "Error: Could not open file '%s'!\n",
				output_filename.str().c_str());
		return;
	}
	if (*t == 0) {
		// write header:
		/// Get names of model quantities.
		char **xd_name[1];  /* differential state names (O) */
		char **xa_name[1];  /* algebraic state names (O) */
		char **u_name[1];   /* control names (O) */
		char **h_name[1];   /* model stage duration names (O) */
		char **p_name[1];   /* global model parameter names (O) */
		char *of_name[1];   /* objective name (O) */
		get_names(xd_name, xa_name, u_name, h_name, p_name, of_name);
		fprintf(fp, "//time\t");
		for (int i = 0; i<NY; i++){
			fprintf(fp, "%s\t",xd_name[0][i]);
		}
		for (int i = 0; i<NU; i++){
			fprintf(fp, "%s\t",u_name[0][i]);
		}
		fprintf(fp, "\n");
	}
	fprintf(fp, "%e\t", *t);
	for (int i = 0; i<NY; i++){
		fprintf(fp, "%e\t",xd[i]);
	}
	for (int i = 0; i<NU; i++){
		fprintf(fp, "%e\t",u[i]);
	}

	fprintf(fp, "\n");
	// Close file
	fclose(fp);
}
Exemple #9
0
/*  The tape drive does not have an idea of current slot so
 *  we use a file to store the current slot.  It is not ideal
 *  but it gets the job done  
 */
int get_current_slot(char *count_file)
{
  FILE *inf;
  int retval;
  if ((inf=fopen(count_file,"r")) == NULL) {
    g_fprintf(stderr, _("%s: unable to open current slot file (%s)\n"),
            get_pname(), count_file);
    return 0;
  }

  if (fscanf(inf, "%d", &retval) != 1) {
    g_fprintf(stderr, _("%s: unable to read current slot file (%s)\n"),
            get_pname(), count_file);
    retval = 0;
  }

  fclose(inf);
  return retval;
}
Exemple #10
0
void put_current_slot(char *count_file,int slot)
{
  FILE *inf;

  if ((inf=fopen(count_file,"w")) == NULL) {
    g_fprintf(stderr, _("%s: unable to open current slot file (%s)\n"),
            get_pname(), count_file);
    exit(2);
  }
  g_fprintf(inf, "%d\n", slot);
  fclose(inf);
}
Exemple #11
0
static void
strange_header(
    dumpfile_t *file,
    const char *buffer,
    size_t	buflen,
    const char *expected,
    const char *actual)
{
    if (actual == NULL)
	actual = "<null>";
    if (expected == NULL)
	expected = "<null>";

    g_fprintf(stderr, _("%s: strange amanda header: \"%.*s\"\n"), get_pname(),
		(int)buflen, buffer);

    g_fprintf(stderr, _("%s: Expected: \"%s\"  Actual: \"%s\"\n"), get_pname(),
		expected, actual);

    file->type = F_WEIRD;
}
Exemple #12
0
/*
 *Send header info to the message file.
 */
void
info_tapeheader(
    dle_t *dle)
{
    g_fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name);

    g_fprintf(stderr, "%s: info RECOVER_CMD=", get_pname());
    if (dle->compress == COMP_FAST || dle->compress == COMP_BEST)
	g_fprintf(stderr, "%s %s |", UNCOMPRESS_PATH,
#ifdef UNCOMPRESS_OPT
		UNCOMPRESS_OPT
#else
		""
#endif
		);

    g_fprintf(stderr, "%s -xpGf - ...\n", program->restore_name);

    if (dle->compress == COMP_FAST || dle->compress == COMP_BEST)
	g_fprintf(stderr, "%s: info COMPRESS_SUFFIX=%s\n",
			get_pname(), COMPRESS_SUFFIX);

    g_fprintf(stderr, "%s: info end\n", get_pname());
}
Exemple #13
0
XParam& XFloatParam::operator =(const XParam& xp) throw (Exception)
{
	const XFloatParam* xip = dynamic_cast<const XFloatParam*>(&xp);
	if (xip == NULL)
		throw Exception(
			get_pname() + ": Bad XFloatParam in assignment !",
			TracePoint("pparam"));

	// check prameter name.
	if (get_pname() != xip->get_pname())
		throw Exception("Different mix xparameters "
			"in assignment !", TracePoint("pparam"));

	try {
		assignHelper(xp);
	} catch (Exception &e) {
		e.addTracePoint(TracePoint("pparam"));
		throw e;
	}
	min = xip->min;
	max = xip->max;
	val = xip->val;
	return *this;
}
Exemple #14
0
static void
end_backup(
    dle_t      *dle,
    int		goterror)
{
    char *amandates_file = NULL;

    if(dle->record && !goterror) {
	if (incrname != NULL && strlen(incrname) > 4) {
	    char *nodotnew;

	    nodotnew = g_strdup(incrname);
	    nodotnew[strlen(nodotnew)-4] = '\0';
	    if (rename(incrname, nodotnew)) {
		g_fprintf(stderr, _("%s: warning [renaming %s to %s: %s]\n"), 
			get_pname(), incrname, nodotnew, strerror(errno));
	    }
	    amfree(nodotnew);
	    amfree(incrname);
	}

	/* update the amandates file */
	amandates_file = getconf_str(CNF_AMANDATES);
	if(start_amandates(amandates_file, 1)) {
	    amandates_updateone(cur_disk, cur_level, cur_dumptime);
	    finish_amandates();
	    free_amandates();
	} else {
	    /* failure is only fatal if we didn't get a gnutar-listdir */
	    char *gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR);
	    if (!gnutar_list_dir || !*gnutar_list_dir) {
		error(_("error [opening %s for writing: %s]"), amandates_file, strerror(errno));
		/* NOTREACHED */
	    } else {
		g_debug(_("non-fatal error opening '%s' for writing: %s]"),
			amandates_file, strerror(errno));
	    }
	}
    }
}
Exemple #15
0
/*
 * Generate a debug file name.  The name is based on the program name,
 * followed by a timestamp, an optional sequence number, and ".debug".
 *
 * @param t: timestamp
 * @param n: sequence number between 1 and 1000; if zero, no sequence number
 * is included.
 */
static char *
get_debug_name(
    time_t	t,
    int		n)
{
    char number[NUM_STR_SIZE];
    char *ts;
    char *result;

    if(n < 0 || n > 1000) {
	return NULL;
    }
    ts = get_timestamp_from_time(t);
    if(n == 0) {
	number[0] = '\0';
    } else {
	g_snprintf(number, SIZEOF(number), "%03d", n - 1);
    }
    result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL);
    amfree(ts);
    return result;
}
Exemple #16
0
int
good_fdisk()
{
	char		buf[MAXPATHLEN];
	struct stat	statbuf;

	(void) get_pname(&buf[0]);
	if (stat(buf, &statbuf) == -1 ||
	    !S_ISCHR(statbuf.st_mode) ||
	    cur_label == L_TYPE_EFI) {
		/*
		 * Return if this disk does not support fdisk table or
		 * if the disk is labeled with EFI.
		 */
		return (1);
	}

	if (lel(cur_disk->fdisk_part.numsect) > 0)
		return (1);
	else
		return (0);
}
Exemple #17
0
XParam &XTextParam::operator = (const XParam &xp) throw (Exception)
{
	const XTextParam* xtp = dynamic_cast<const XTextParam*>(&xp);

	if (xtp == NULL)
		throw Exception("Bad text XParam in assignment !",
			TracePoint("pparam"));

	// check prameter name.
	if (get_pname() != xtp->get_pname())
		throw Exception("Different test xparameters "
			"in assignment !", TracePoint("pparam"));

	try {
		assignHelper(xp);
	} catch (Exception &e) {
		e.addTracePoint(TracePoint("pparam"));
		throw e;
	}
	val = xtp->val;

	return *this;
}
Exemple #18
0
struct cmdargs *
getcmd(void)
{
    char *line;
    cmd_t cmd_i;
    struct cmdargs *cmdargs = g_new0(struct cmdargs, 1);

    if (isatty(0)) {
	g_printf("%s> ", get_pname());
	fflush(stdout);
        line = agets(stdin);
    } else {
        line = areads(0);
    }
    if (line == NULL) {
	line = g_strdup("QUIT");
    }

    dbprintf(_("getcmd: %s\n"), line);

    cmdargs->argv = split_quoted_strings(line);
    cmdargs->argc = g_strv_length(cmdargs->argv);
    cmdargs->cmd = BOGUS;

    amfree(line);

    if (cmdargs->argc < 1) {
	return cmdargs;
    }

    for(cmd_i=BOGUS; cmdstr[cmd_i] != NULL; cmd_i++)
	if(g_str_equal(cmdargs->argv[0], cmdstr[cmd_i])) {
	    cmdargs->cmd = cmd_i;
	    return cmdargs;
	}
    return cmdargs;
}
Exemple #19
0
int
main(
    int		argc,
    char **	argv)
{
#ifndef ERRMSG
    char *dump_program;
    int i;
    char *e;
    char *cmdline;
#endif /* ERRMSG */

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);
    safe_cd();

    set_pname("rundump");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_CLIENT);
    config_init(CONFIG_INIT_CLIENT, NULL);

    if (argc < 3) {
	error(_("Need at least 3 arguments\n"));
	/*NOTREACHED*/
    }

    dbprintf(_("version %s\n"), VERSION);

#ifdef ERRMSG							/* { */

    g_fprintf(stderr, ERRMSG);
    dbprintf("%s: %s", argv[0], ERRMSG);
    dbclose();
    return 1;

#else								/* } { */

#ifdef WANT_SETUID_CLIENT
    check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY);
    if (!become_root()) {
	error(_("error [%s could not become root (is the setuid bit set?)]\n"), get_pname());
	/*NOTREACHED*/
    }
#else
    check_running_as(RUNNING_AS_CLIENT_LOGIN);
#endif

    /* skip argv[0] */
    argc--;
    argv++;

    dbprintf(_("config: %s\n"), argv[0]);
    if (strcmp(argv[0], "NOCONFIG") != 0)
	dbrename(argv[0], DBG_SUBDIR_CLIENT);
    argc--;
    argv++;

#ifdef XFSDUMP

    if (strcmp(argv[0], "xfsdump") == 0)
        dump_program = XFSDUMP;
    else /* strcmp(argv[0], "xfsdump") != 0 */

#endif

#ifdef VXDUMP

    if (strcmp(argv[0], "vxdump") == 0)
        dump_program = VXDUMP;
    else /* strcmp(argv[0], "vxdump") != 0 */

#endif

#ifdef VDUMP

    if (strcmp(argv[0], "vdump") == 0)
	dump_program = VDUMP;
    else /* strcmp(argv[0], "vdump") != 0 */

#endif

#if defined(DUMP)
        dump_program = DUMP;
#else
# if defined(XFSDUMP)
        dump_program = XFSDUMP;
# else
#  if defined(VXDUMP)
	dump_program = VXDUMP;
#  else
        dump_program = "dump";
#  endif
# endif
#endif

    cmdline = stralloc(dump_program);
    for (i = 1; argv[i]; i++) {
	char *quoted;

	quoted = quote_string(argv[i]);
	cmdline = vstrextend(&cmdline, " ", quoted, NULL);
	amfree(quoted);
    }
    dbprintf(_("running: %s\n"), cmdline);
    amfree(cmdline);

    execve(dump_program, argv, safe_env());

    e = strerror(errno);
    dbprintf(_("failed (%s)\n"), e);
    dbclose();

    g_fprintf(stderr, _("rundump: could not exec %s: %s\n"), dump_program, e);
    return 1;
#endif								/* } */
}
Exemple #20
0
void
parse_file_header(
    const char *buffer,
    dumpfile_t *file,
    size_t	buflen)
{
    char *buf, *line, *tok, *line1;
    size_t lsize;
    char *uqname;
    int in_quotes;
    char *saveptr = NULL;

    /* put the buffer into a writable chunk of memory and nul-term it */
    buf = alloc(buflen + 1);
    memcpy(buf, buffer, buflen);
    buf[buflen] = '\0';
    fh_init(file); 

    /* extract the first unquoted line */
    in_quotes = 0;
    for (line = buf, lsize = 0; lsize < buflen; line++) {
	if ((*line == '\n') && !in_quotes)
	    break;

	if (*line == '"') {
	    in_quotes = !in_quotes;
	} else if ((*line == '\\') && (*(line + 1) == '"')) {
	    line++;
	    lsize++;
	}
	lsize++;
    }
    *line = '\0';
    line1 = alloc(lsize + 1);
    strncpy(line1, buf, lsize);
    line1[lsize] = '\0';
    *line = '\n';

    tok = strtok_r(line1, " ", &saveptr);
    if (tok == NULL) {
        g_fprintf(stderr, _("%s: Empty amanda header: buflen=%zu lsize=%zu\n"), get_pname(),
	    buflen, 
	    lsize);
	hexdump(buffer, lsize);
	strange_header(file, buffer, buflen, _("<Non-empty line>"), tok);
	goto out;
    }

    if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {
	amfree(buf);
	file->type = F_UNKNOWN;
	amfree(line1);
	return;
    }

    tok = strtok_r(NULL, " ", &saveptr);
    if (tok == NULL) {
	strange_header(file, buffer, buflen, _("<file type>"), tok);
	goto out;
    }
    file->type = str2filetype(tok);
    
    switch (file->type) {
    case F_TAPESTART:
	tok = strtok_r(NULL, " ", &saveptr);
	if ((tok == NULL) || (strcmp(tok, "DATE") != 0)) {
	    strange_header(file, buffer, buflen, "DATE", tok);
	    goto out;
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<date stamp>"), tok);
	    goto out;
	}
	strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);

	tok = strtok_r(NULL, " ", &saveptr);
	if ((tok == NULL) || (strcmp(tok, "TAPE") != 0)) {
	    strange_header(file, buffer, buflen, "TAPE", tok);
	    goto out;
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<file type>"), tok);
	    goto out;
	}
	strncpy(file->name, tok, SIZEOF(file->name) - 1);
	break;

    case F_DUMPFILE:
    case F_CONT_DUMPFILE:
    case F_SPLIT_DUMPFILE:
	tok = strtok_r(NULL, " ", &saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<date stamp>"), tok);
	    goto out;
	}
	strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);

	tok = strtok_r(NULL, " ", &saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<file name>"), tok);
	    goto out;
	}
	strncpy(file->name, tok, SIZEOF(file->name) - 1);

	tok = strquotedstr(&saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<disk name>"), tok);
	    goto out;
	}
	uqname = unquote_string(tok);
	strncpy(file->disk, uqname, SIZEOF(file->disk) - 1);
 	amfree(uqname);
	
	if(file->type == F_SPLIT_DUMPFILE) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL || strcmp(tok, "part") != 0) {
		strange_header(file, buffer, buflen, "part", tok);
		goto out;
	    }

	    tok = strtok_r(NULL, "/", &saveptr);
	    if ((tok == NULL) || (sscanf(tok, "%d", &file->partnum) != 1)) {
		strange_header(file, buffer, buflen, _("<part num param>"), tok);
		goto out;
	    }

	    /* If totalparts == -1, then the original dump was done in 
 	       streaming mode (no holding disk), thus we don't know how 
               many parts there are. */
	    tok = strtok_r(NULL, " ", &saveptr);
            if((tok == NULL) || (sscanf(tok, "%d", &file->totalparts) != 1)) {
		strange_header(file, buffer, buflen, _("<total parts param>"), tok);
		goto out;
	    }
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if ((tok == NULL) || (strcmp(tok, "lev") != 0)) {
	    strange_header(file, buffer, buflen, "lev", tok);
	    goto out;
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if ((tok == NULL) || (sscanf(tok, "%d", &file->dumplevel) != 1)) {
	    strange_header(file, buffer, buflen, _("<dump level param>"), tok);
	    goto out;
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if ((tok == NULL) || (strcmp(tok, "comp") != 0)) {
	    strange_header(file, buffer, buflen, "comp", tok);
	    goto out;
	}

	tok = strtok_r(NULL, " ", &saveptr);
	if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<comp param>"), tok);
	    goto out;
	}
	strncpy(file->comp_suffix, tok, SIZEOF(file->comp_suffix) - 1);

	file->compressed = strcmp(file->comp_suffix, "N");
	/* compatibility with pre-2.2 amanda */
	if (strcmp(file->comp_suffix, "C") == 0)
	    strncpy(file->comp_suffix, ".Z", SIZEOF(file->comp_suffix) - 1);
	       
	tok = strtok_r(NULL, " ", &saveptr);
        /* "program" is optional */
        if (tok == NULL || strcmp(tok, "program") != 0) {
	    break;
	}

        tok = strtok_r(NULL, " ", &saveptr);
        if (tok == NULL) {
	    strange_header(file, buffer, buflen, _("<program name>"), tok);
	    goto out;
	}
        strncpy(file->program, tok, SIZEOF(file->program) - 1);
        if (file->program[0] == '\0')
            strncpy(file->program, "RESTORE", SIZEOF(file->program) - 1);

	if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL)
             break;          /* reached the end of the buffer */

	/* "encryption" is optional */
	if (BSTRNCMP(tok, "crypt") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen, _("<crypt param>"), tok);
		goto out;
	    }
	    strncpy(file->encrypt_suffix, tok,
		    SIZEOF(file->encrypt_suffix) - 1);
	    file->encrypted = BSTRNCMP(file->encrypt_suffix, "N");
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL)
		break;
	}

	/* "srvcompprog" is optional */
	if (BSTRNCMP(tok, "server_custom_compress") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<server custom compress param>"), tok);
		goto out;
	    }
	    strncpy(file->srvcompprog, tok, SIZEOF(file->srvcompprog) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL)
		break;      
	}

	/* "clntcompprog" is optional */
	if (BSTRNCMP(tok, "client_custom_compress") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<client custom compress param>"), tok);
		goto out;
	    }
	    strncpy(file->clntcompprog, tok, SIZEOF(file->clntcompprog) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL)
		break;
	}

	/* "srv_encrypt" is optional */
	if (BSTRNCMP(tok, "server_encrypt") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<server encrypt param>"), tok);
		goto out;
	    }
	    strncpy(file->srv_encrypt, tok, SIZEOF(file->srv_encrypt) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) 
		break;
	}

	/* "clnt_encrypt" is optional */
	if (BSTRNCMP(tok, "client_encrypt") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<client encrypt param>"), tok);
		goto out;
	    }
	    strncpy(file->clnt_encrypt, tok, SIZEOF(file->clnt_encrypt) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) 
		break;
	}

	/* "srv_decrypt_opt" is optional */
	if (BSTRNCMP(tok, "server_decrypt_option") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<server decrypt param>"), tok);
		goto out;
	    }
	    strncpy(file->srv_decrypt_opt, tok,
		    SIZEOF(file->srv_decrypt_opt) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) 
		break;
	}

	/* "clnt_decrypt_opt" is optional */
	if (BSTRNCMP(tok, "client_decrypt_option") == 0) {
	    tok = strtok_r(NULL, " ", &saveptr);
	    if (tok == NULL) {
		strange_header(file, buffer, buflen,
				_("<client decrypt param>"), tok);
		goto out;
	    }
	    strncpy(file->clnt_decrypt_opt, tok,
		    SIZEOF(file->clnt_decrypt_opt) - 1);
	    if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) 
		break;
	}
      break;
      

    case F_TAPEEND:
	tok = strtok_r(NULL, " ", &saveptr);
	/* DATE is optional */
	if (tok != NULL) {
	    if (strcmp(tok, "DATE") == 0) {
		tok = strtok_r(NULL, " ", &saveptr);
		if(tok == NULL)
		    file->datestamp[0] = '\0';
		else
		    strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
	    } else {
		strange_header(file, buffer, buflen, _("<DATE>"), tok);
	   }
	} else {
	    file->datestamp[0] = '\0';
	}
	break;

    case F_NOOP:
	/* nothing follows */
	break;

    default:
	strange_header(file, buffer, buflen,
		_("TAPESTART|DUMPFILE|CONT_DUMPFILE|SPLIT_DUMPFILE|TAPEEND|NOOP"), tok);
	goto out;
    }

    (void)strtok_r(buf, "\n", &saveptr); /* this is the first line */
    /* iterate through the rest of the lines */
    while ((line = strtok_r(NULL, "\n", &saveptr)) != NULL) {
#define SC "CONT_FILENAME="
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
	    line += SIZEOF(SC) - 1;
	    strncpy(file->cont_filename, line,
		    SIZEOF(file->cont_filename) - 1);
	    continue;
	}
#undef SC

#define SC "PARTIAL="
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
	    line += SIZEOF(SC) - 1;
	    file->is_partial = !strcasecmp(line, "yes");
	    continue;
	}
#undef SC
#define SC "APPLICATION="
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
	    line += SIZEOF(SC) - 1;
	    strncpy(file->application, line,
		    SIZEOF(file->application) - 1);
	    continue;
	}
#undef SC

#define SC "DLE="
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
	    line += SIZEOF(SC) - 1;
	    file->dle_str = parse_heredoc(line, &saveptr);
	}
#undef SC

#define SC _("To restore, position tape at start of file and run:")
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0)
	    continue;
#undef SC

#define SC "\tdd if=<tape> "
	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
	    char *cmd1, *cmd2, *cmd3=NULL;

	    /* skip over dd command */
	    if ((cmd1 = strchr(line, '|')) == NULL) {

	        strncpy(file->recover_cmd, "BUG",
		        SIZEOF(file->recover_cmd) - 1);
	        continue;
	    }
	    *cmd1++ = '\0';

	    /* block out first pipeline command */
	    if ((cmd2 = strchr(cmd1, '|')) != NULL) {
	      *cmd2++ = '\0';
	      if ((cmd3 = strchr(cmd2, '|')) != NULL)
		*cmd3++ = '\0';
	    }
	   
	    /* clean up some extra spaces in various fields */
	    chomp(cmd1);
	    chomp(cmd2);
	    chomp(cmd3);

	    /* three cmds: decrypt    | uncompress | recover
	     * two   cmds: uncompress | recover
	     * XXX note that if there are two cmds, the first one 
	     * XXX could be either uncompress or decrypt. Since no
	     * XXX code actually call uncompress_cmd/decrypt_cmd, it's ok
	     * XXX for header information.
	     * one   cmds: recover
	     */

	    if ( cmd3 == NULL) {
	      if (cmd2 == NULL) {
		strncpy(file->recover_cmd, cmd1,
			SIZEOF(file->recover_cmd) - 1);
	      } else {
		g_snprintf(file->uncompress_cmd,
			 SIZEOF(file->uncompress_cmd), "%s |", cmd1);
		strncpy(file->recover_cmd, cmd2,
			SIZEOF(file->recover_cmd) - 1);
	      }
	    } else {    /* cmd3 presents:  decrypt | uncompress | recover */
	      g_snprintf(file->decrypt_cmd,
		       SIZEOF(file->decrypt_cmd), "%s |", cmd1);
	      g_snprintf(file->uncompress_cmd,
		       SIZEOF(file->uncompress_cmd), "%s |", cmd2);
	      strncpy(file->recover_cmd, cmd3,
		      SIZEOF(file->recover_cmd) - 1);
	    }
	    continue;
	}
#undef SC
	/* XXX complain about weird lines? */
    }

out:
    amfree(buf);
    amfree(line1);
}
Exemple #21
0
int
main(
    int		argc,
    char **	argv)
{
#ifdef TEST
/* standalone test to ckeck wether the calculated file size is ok */
    struct stat finfo;
    int i;
    off_t dump_total = (off_t)0;
    off_t gtar_total = (off_t)0;
    char *d;
    int l, w;

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);

    set_pname("calcsize");

    dbopen(NULL);
    config_init(CONFIG_INIT_CLIENT, NULL);

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    if (argc < 2) {
	g_fprintf(stderr,_("Usage: %s file[s]\n"),argv[0]);
	return 1;
    }
    for(i=1; i<argc; i++) {
	if(lstat(argv[i], &finfo) == -1) {
	    g_fprintf(stderr, "%s: %s\n", argv[i], strerror(errno));
	    continue;
	}
	g_printf("%s: st_size=%lu", argv[i],(unsigned long)finfo.st_size);
	g_printf(": blocks=%llu\n", ST_BLOCKS(finfo));
	dump_total += (ST_BLOCKS(finfo) + (off_t)1) / (off_t)2 + (off_t)1;
	gtar_total += ROUND(4,(ST_BLOCKS(finfo) + (off_t)1));
    }
    g_printf("           gtar           dump\n");
    g_printf("total      %-9lu         %-9lu\n",gtar_total,dump_total);
    return 0;
#else
    int i;
    char *dirname=NULL;
    char *amname=NULL, *qamname=NULL;
    char *filename=NULL, *qfilename = NULL;

    if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) {
	printf("calcsize-%s\n", VERSION);
	return (0);
    }

    safe_fd(-1, 0);
    safe_cd();

    set_pname("calcsize");

    dbopen(DBG_SUBDIR_CLIENT);
    config_init(CONFIG_INIT_CLIENT, NULL);
    dbprintf(_("version %s\n"), VERSION);

    /* drop root privileges; we'll regain them for the required operations */
#ifdef WANT_SETUID_CLIENT
    check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY);
    if (!set_root_privs(0)) {
	error(_("calcsize must be run setuid root"));
    }
#else
    check_running_as(RUNNING_AS_CLIENT_LOGIN);
#endif

    argc--, argv++;	/* skip program name */

    /* need at least program, amname, and directory name */

    if(argc < 4) {
	error(_("Usage: %s config [DUMP|STAR|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*"),
	      get_pname());
        /*NOTREACHED*/
    }

    dbprintf(_("config: %s\n"), *argv);
    if (!g_str_equal(*argv, "NOCONFIG")) {
	dbrename(*argv, DBG_SUBDIR_CLIENT);
    }
    argc--;
    argv++;

    /* parse backup program name */

    if(g_str_equal(*argv, "DUMP")) {
#if !defined(DUMP) && !defined(XFSDUMP)
	error("dump not available on this system");
	/*NOTREACHED*/
#else
	add_file_name = add_file_name_dump;
	add_file = add_file_dump;
	final_size = final_size_dump;
#endif
    }
    else if(g_str_equal(*argv, "GNUTAR")) {
#ifndef GNUTAR
	error("gnutar not available on this system");
	/*NOTREACHED*/
#else
	add_file_name = add_file_name_gnutar;
	add_file = add_file_gnutar;
	final_size = final_size_gnutar;
	use_gtar_excl++;
#endif
    }
    else {
	add_file_name = add_file_name_unknown;
	add_file = add_file_unknown;
	final_size = final_size_unknown;
    }
    argc--, argv++;

    /* the amanda name can be different from the directory name */

    if (argc > 0) {
	amname = *argv;
	qamname = quote_string(amname);
	argc--, argv++;
    } else {
	error("missing <name>");
	/*NOTREACHED*/
    }

    /* the toplevel directory name to search from */
    if (argc > 0) {
	dirname = *argv;
	argc--, argv++;
    } else {
	error("missing <dir>");
	/*NOTREACHED*/
    }

    if ((argc > 1) && g_str_equal(*argv, "-X")) {
	argv++;

	if (!(use_gtar_excl || use_star_excl)) {
	  error("exclusion specification not supported");
	  /*NOTREACHED*/
	}
	
	filename = g_strdup(*argv);
	qfilename = quote_string(filename);
	if (access(filename, R_OK) != 0) {
	    g_fprintf(stderr,"Cannot open exclude file %s\n", qfilename);
	    use_gtar_excl = use_star_excl = 0;
	} else {
	    exclude_sl = calc_load_file(filename);
	    if (!exclude_sl) {
		g_fprintf(stderr,"Cannot open exclude file %s: %s\n", qfilename,
			strerror(errno));
		use_gtar_excl = use_star_excl = 0;
	    }
	}
	amfree(qfilename);
	amfree(filename);
	argc -= 2;
	argv++;
    } else {
	use_gtar_excl = use_star_excl = 0;
    }

    if ((argc > 1) && g_str_equal(*argv, "-I")) {
	argv++;
	
	filename = g_strdup(*argv);
	qfilename = quote_string(filename);
	if (access(filename, R_OK) != 0) {
	    g_fprintf(stderr,"Cannot open include file %s\n", qfilename);
	    use_gtar_excl = use_star_excl = 0;
	} else {
	    include_sl = calc_load_file(filename);
	    if (!include_sl) {
		g_fprintf(stderr,"Cannot open include file %s: %s\n", qfilename,
			strerror(errno));
		use_gtar_excl = use_star_excl = 0;
	    }
	}
	amfree(qfilename);
	amfree(filename);
	argc -= 2;
	argv++;
    }

    /* the dump levels to calculate sizes for */

    ndumps = 0;
    while(argc >= 2) {
	if(ndumps < MAXDUMPS) {
	    dumplevel[ndumps] = atoi(argv[0]);
	    dumpdate [ndumps] = (time_t) atol(argv[1]);
	    ndumps++;
	    argc -= 2, argv += 2;
	}
    }

    if(argc) {
	error("leftover arg \"%s\", expected <level> and <date>", *argv);
	/*NOTREACHED*/
    }

    if(is_empty_sl(include_sl)) {
	traverse_dirs(dirname,".");
    }
    else {
	sle_t *an_include = include_sl->first;
	while(an_include != NULL) {
/*
	    char *adirname = stralloc2(dirname, an_include->name+1);
	    traverse_dirs(adirname);
	    amfree(adirname);
*/
	    traverse_dirs(dirname, an_include->name);
	    an_include = an_include->next;
	}
    }
    for(i = 0; i < ndumps; i++) {

	amflock(1, "size");

	dbprintf("calcsize: %s %d SIZE %lld\n",
	       qamname, dumplevel[i],
	       (long long)final_size(i, dirname));
	g_fprintf(stderr, "%s %d SIZE %lld\n",
	       qamname, dumplevel[i],
	       (long long)final_size(i, dirname));
	fflush(stderr);

	amfunlock(1, "size");
    }
    amfree(qamname);

    return 0;
#endif
}
Exemple #22
0
static void
amgtar_backup(
    application_argument_t *argument)
{
    int         dumpin;
    char      *cmd = NULL;
    char      *qdisk;
    char      *incrname;
    char       line[32768];
    amregex_t *rp;
    off_t      dump_size = -1;
    char      *type;
    char       startchr;
    int        dataf = 1;
    int        mesgf = 3;
    int        indexf = 4;
    int        outf;
    FILE      *mesgstream;
    FILE      *indexstream = NULL;
    FILE      *outstream;
    char      *errmsg = NULL;
    amwait_t   wait_status;
    GPtrArray *argv_ptr;
    int        tarpid;

    mesgstream = fdopen(mesgf, "w");
    if (!mesgstream) {
	error(_("error mesgstream(%d): %s\n"), mesgf, strerror(errno));
    }

    if (!gnutar_path) {
	error(_("GNUTAR-PATH not defined"));
    }
    if (!gnutar_listdir) {
	error(_("GNUTAR-LISTDIR not defined"));
    }

    if (!argument->level) {
        fprintf(mesgstream, "? No level argument\n");
        error(_("No level argument"));
    }
    if (!argument->dle.disk) {
        fprintf(mesgstream, "? No disk argument\n");
        error(_("No disk argument"));
    }
    if (!argument->dle.device) {
        fprintf(mesgstream, "? No device argument\n");
        error(_("No device argument"));
    }

    qdisk = quote_string(argument->dle.disk);

    incrname = amgtar_get_incrname(argument,
				   GPOINTER_TO_INT(argument->level->data));
    cmd = stralloc(gnutar_path);
    argv_ptr = amgtar_build_argv(argument, incrname, CMD_BACKUP);

    tarpid = pipespawnv(cmd, STDIN_PIPE|STDERR_PIPE, 1,
			&dumpin, &dataf, &outf, (char **)argv_ptr->pdata);
    /* close the write ends of the pipes */

    aclose(dumpin);
    aclose(dataf);
    if (argument->dle.create_index) {
	indexstream = fdopen(indexf, "w");
	if (!indexstream) {
	    error(_("error indexstream(%d): %s\n"), indexf, strerror(errno));
	}
    }
    outstream = fdopen(outf, "r");
    if (!outstream) {
	error(_("error outstream(%d): %s\n"), outf, strerror(errno));
    }

    while (fgets(line, sizeof(line), outstream) != NULL) {
	if (line[strlen(line)-1] == '\n') /* remove trailling \n */
	    line[strlen(line)-1] = '\0';
	if (*line == '.' && *(line+1) == '/') { /* filename */
	    if (argument->dle.create_index) {
		fprintf(indexstream, "%s\n", &line[1]); /* remove . */
	    }
	} else { /* message */
	    for(rp = re_table; rp->regex != NULL; rp++) {
		if(match(rp->regex, line)) {
		    break;
		}
	    }
	    if(rp->typ == DMP_SIZE) {
		dump_size = (long)((the_num(line, rp->field)* rp->scale+1023.0)/1024.0);
	    }
	    switch(rp->typ) {
	    case DMP_NORMAL:
		type = "normal";
		startchr = '|';
		break;
	    case DMP_IGNORE:
		continue;
	    case DMP_STRANGE:
		type = "strange";
		startchr = '?';
		break;
	    case DMP_SIZE:
		type = "size";
		startchr = '|';
		break;
	    case DMP_ERROR:
		type = "error";
		startchr = '?';
		break;
	    default:
		type = "unknown";
		startchr = '!';
		break;
	    }
	    dbprintf("%3d: %7s(%c): %s\n", rp->srcline, type, startchr, line);
	    fprintf(mesgstream,"%c %s\n", startchr, line);
        }
    }

    waitpid(tarpid, &wait_status, 0);
    if (WIFSIGNALED(wait_status)) {
	errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
			    cmd, WTERMSIG(wait_status), dbfn());
    } else if (WIFEXITED(wait_status)) {
	if (exit_value[WEXITSTATUS(wait_status)] == 1) {
	    errmsg = vstrallocf(_("%s exited with status %d: see %s"),
				cmd, WEXITSTATUS(wait_status), dbfn());
	} else {
	    /* Normal exit */
	}
    } else {
	errmsg = vstrallocf(_("%s got bad exit: see %s"),
			    cmd, dbfn());
    }
    dbprintf(_("after %s %s wait\n"), cmd, qdisk);
    dbprintf(_("amgtar: %s: pid %ld\n"), cmd, (long)tarpid);
    if (errmsg) {
	dbprintf("%s", errmsg);
	g_fprintf(mesgstream, "sendbackup: error [%s]\n", errmsg);
    }

    if (!errmsg && incrname && strlen(incrname) > 4) {
	char *nodotnew;
	nodotnew = stralloc(incrname);
	nodotnew[strlen(nodotnew)-4] = '\0';
	if (rename(incrname, nodotnew)) {
	    dbprintf(_("%s: warning [renaming %s to %s: %s]\n"),
		     get_pname(), incrname, nodotnew, strerror(errno));
	    g_fprintf(mesgstream, _("? warning [renaming %s to %s: %s]\n"),
		      incrname, nodotnew, strerror(errno));
	}
	amfree(nodotnew);
    }

    dbprintf("sendbackup: size %lld\n", (long long)dump_size);
    fprintf(mesgstream, "sendbackup: size %lld\n", (long long)dump_size);
    dbprintf("sendbackup: end\n");
    fprintf(mesgstream, "sendbackup: end\n");

    if (argument->dle.create_index)
	fclose(indexstream);

    fclose(mesgstream);

    amfree(incrname);
    amfree(qdisk);
    amfree(cmd);
    g_ptr_array_free_full(argv_ptr);
}
Exemple #23
0
int
main(
    int		argc,
    char **	argv)
{
    int c;
    char *command;
    application_argument_t argument;
    int i;

#ifdef GNUTAR
    gnutar_path = GNUTAR;
#else
    gnutar_path = NULL;
#endif
    gnutar_directory = NULL;
    gnutar_onefilesystem = 1;
    gnutar_atimepreserve = 1;
    gnutar_checkdevice = 1;
    gnutar_sparse = 1;
    gnutar_no_unquote = 0;
    exit_handling = NULL;

    /* initialize */

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");

    if (argc < 2) {
        printf("ERROR no command given to amgtar\n");
        error(_("No command given to amgtar"));
    }

    /* drop root privileges */
    if (!set_root_privs(0)) {
	if (strcmp(argv[1], "selfcheck") == 0) {
	    printf("ERROR amgtar must be run setuid root\n");
	}
	error(_("amgtar must be run setuid root"));
    }

    safe_fd(3, 2);

    set_pname("amgtar");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

#if defined(USE_DBMALLOC)
    malloc_size_1 = malloc_inuse(&malloc_hist_1);
#endif

    add_amanda_log_handler(amanda_log_stderr);
    add_amanda_log_handler(amanda_log_syslog);
    dbopen(DBG_SUBDIR_CLIENT);
    startclock();
    dbprintf(_("version %s\n"), version());

    config_init(CONFIG_INIT_CLIENT, NULL);

    //check_running_as(RUNNING_AS_DUMPUSER_PREFERRED);
    //root for amrecover
    //RUNNING_AS_CLIENT_LOGIN from selfcheck, sendsize, sendbackup

    /* parse argument */
    command = argv[1];

    argument.config     = NULL;
    argument.host       = NULL;
    argument.message    = 0;
    argument.collection = 0;
    argument.calcsize   = 0;
    argument.tar_blocksize = NULL;
    argument.level      = NULL;
    init_dle(&argument.dle);

    while (1) {
	int option_index = 0;
    	c = getopt_long (argc, argv, "", long_options, &option_index);
	if (c == -1) {
	    break;
	}
	switch (c) {
	case 1: argument.config = stralloc(optarg);
		break;
	case 2: argument.host = stralloc(optarg);
		break;
	case 3: argument.dle.disk = stralloc(optarg);
		break;
	case 4: argument.dle.device = stralloc(optarg);
		break;
	case 5: argument.level = g_slist_append(argument.level,
					        GINT_TO_POINTER(atoi(optarg)));
		break;
	case 6: argument.dle.create_index = 1;
		break;
	case 7: argument.message = 1;
		break;
	case 8: argument.collection = 1;
		break;
	case 9: argument.dle.record = 1;
		break;
	case 10: gnutar_path = stralloc(optarg);
		 break;
	case 11: gnutar_listdir = stralloc(optarg);
		 break;
	case 12: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_onefilesystem = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_onefilesystem = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad ONE-FILE-SYSTEM property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 13: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_sparse = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_sparse = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad SPARSE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 14: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_atimepreserve = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_atimepreserve = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad ATIME-PRESERVE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 15: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_checkdevice = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_checkdevice = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad CHECK-DEVICE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case 16: if (optarg)
		     argument.dle.include_file =
			 append_sl(argument.dle.include_file, optarg);
		 break;
	case 17: if (optarg)
		     argument.dle.include_list =
			 append_sl(argument.dle.include_list, optarg);
		 break;
	case 18: argument.dle.include_optional = 1;
		 break;
	case 19: if (optarg)
		     argument.dle.exclude_file =
			 append_sl(argument.dle.exclude_file, optarg);
		 break;
	case 20: if (optarg)
		     argument.dle.exclude_list =
			 append_sl(argument.dle.exclude_list, optarg);
		 break;
	case 21: argument.dle.exclude_optional = 1;
		 break;
	case 22: gnutar_directory = stralloc(optarg);
		 break;
	case 23: if (optarg)
		     normal_message = 
			 g_slist_append(normal_message, optarg);
		 break;
	case 24: if (optarg)
		     ignore_message = 
			 g_slist_append(ignore_message, optarg);
		 break;
	case 25: if (optarg)
		     strange_message = 
			 g_slist_append(strange_message, optarg);
		 break;
	case 26: if (optarg)
		     exit_handling = stralloc(optarg);
		 break;
	case 27: argument.calcsize = 1;
		 break;
	case 28: argument.tar_blocksize = stralloc(optarg);
		 break;
	case 29: if (optarg && strcasecmp(optarg, "NO") == 0)
		     gnutar_no_unquote = 0;
		 else if (optarg && strcasecmp(optarg, "YES") == 0)
		     gnutar_no_unquote = 1;
		 else if (strcasecmp(command, "selfcheck") == 0)
		     printf(_("ERROR [%s: bad No_UNQUOTE property value (%s)]\n"), get_pname(), optarg);
		 break;
	case ':':
	case '?':
		break;
	}
    }

    argument.argc = argc - optind;
    argument.argv = argv + optind;

    if (argument.config) {
	config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
		    argument.config);
	dbrename(get_config_name(), DBG_SUBDIR_CLIENT);
    }

    if (config_errors(NULL) >= CFGERR_ERRORS) {
	g_critical(_("errors processing config file"));
    }

    re_table = build_re_table(init_re_table, normal_message, ignore_message,
			      strange_message);

    for(i=0;i<256;i++)
	exit_value[i] = 1; /* BAD  */
    exit_value[0] = 0;     /* GOOD */
    exit_value[1] = 0;     /* GOOD */
    if (exit_handling) {
	char *s = exit_handling;
	while (s) {
	    char *r = strchr(s, '=');
	    if (r) {
		int j = atoi(s);
		if (j >= 0 && j < 256) {
		    r++;
		    if (strncasecmp(r, "GOOD", 4) == 0) {
			exit_value[j] = 0;
		    }
		}
	    }
	    s = strchr(s+1, ' ');
	}
    }

    gnutar_listdir = getconf_str(CNF_GNUTAR_LIST_DIR);
    if (strlen(gnutar_listdir) == 0)
	gnutar_listdir = NULL;

    if (gnutar_path) {
	dbprintf("GNUTAR-PATH %s\n", gnutar_path);
    } else {
	dbprintf("GNUTAR-PATH is not set\n");
    }
    if (gnutar_listdir) {
	    dbprintf("GNUTAR-LISTDIR %s\n", gnutar_listdir);
    } else {
	dbprintf("GNUTAR-LISTDIR is not set\n");
    }
    if (gnutar_directory) {
	dbprintf("DIRECTORY %s\n", gnutar_directory);
    }
    dbprintf("ONE-FILE-SYSTEM %s\n", gnutar_onefilesystem? "yes":"no");
    dbprintf("SPARSE %s\n", gnutar_sparse? "yes":"no");
    dbprintf("NO-UNQUOTE %s\n", gnutar_no_unquote? "yes":"no");
    dbprintf("ATIME-PRESERVE %s\n", gnutar_atimepreserve? "yes":"no");
    dbprintf("CHECK-DEVICE %s\n", gnutar_checkdevice? "yes":"no");
    {
	amregex_t *rp;
	for (rp = re_table; rp->regex != NULL; rp++) {
	    switch (rp->typ) {
		case DMP_NORMAL : dbprintf("NORMAL %s\n", rp->regex); break;
		case DMP_IGNORE : dbprintf("IGNORE %s\n", rp->regex); break;
		case DMP_STRANGE: dbprintf("STRANGE %s\n", rp->regex); break;
		case DMP_SIZE   : dbprintf("SIZE %s\n", rp->regex); break;
		case DMP_ERROR  : dbprintf("ERROR %s\n", rp->regex); break;
	    }
	}
    }

    if (strcmp(command, "support") == 0) {
	amgtar_support(&argument);
    } else if (strcmp(command, "selfcheck") == 0) {
	amgtar_selfcheck(&argument);
    } else if (strcmp(command, "estimate") == 0) {
	amgtar_estimate(&argument);
    } else if (strcmp(command, "backup") == 0) {
	amgtar_backup(&argument);
    } else if (strcmp(command, "restore") == 0) {
	amgtar_restore(&argument);
    } else if (strcmp(command, "validate") == 0) {
	amgtar_validate(&argument);
    } else {
	dbprintf("Unknown command `%s'.\n", command);
	fprintf(stderr, "Unknown command `%s'.\n", command);
	exit (1);
    }
    return 0;
}
Exemple #24
0
static void
start_backup(
    dle_t      *dle,
    char       *host,
    int		dataf,
    int		mesgf,
    int		indexf)
{
    int dumpin, dumpout, compout;
    char *dumpkeys = NULL;
    char *device = NULL;
    char *fstype = NULL;
    char *cmd = NULL;
    char *cmdX = NULL;
    char *indexcmd = NULL;
    char level_str[NUM_STR_SIZE];
    char *compopt  = NULL;
    char *encryptopt = skip_argument;
    char *qdisk;
    char *config;
    am_level_t *alevel = (am_level_t *)dle->levellist->data;
    int      level  = alevel->level;

    g_snprintf(level_str, sizeof(level_str), "%d", level);

    qdisk = quote_string(dle->disk);
    dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level);

    g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"),
	    get_pname(), host, qdisk, level);
    amfree(qdisk);

    /*  apply client-side encryption here */
    if (dle->encrypt == ENCRYPT_CUST ) {
        encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0,
	                   &compout, &dataf, &mesgf,
	                   dle->clnt_encrypt, encryptopt, NULL);
        dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt);
    } else {
        compout = dataf;
        encpid = -1;
    }
    /*  now do the client-side compression */


    if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) {
	compopt = skip_argument;

#if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
	if(dle->compress == COMP_BEST) {
	    compopt = COMPRESS_BEST_OPT;
	} else {
	    compopt = COMPRESS_FAST_OPT;
	}
#endif
	comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    COMPRESS_PATH, compopt, NULL);
	dbprintf(_("dump: pid %ld: %s"), (long)comppid, COMPRESS_PATH);
	if(compopt != skip_argument) {
	    dbprintf(" %s", compopt);
	}
	dbprintf("\n");
     } else if (dle->compress == COMP_CUST) {
        compopt = skip_argument;
	comppid = pipespawn(dle->compprog, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    dle->compprog, compopt, NULL);
	dbprintf(_("gnutar-cust: pid %ld: %s"),
		(long)comppid, dle->compprog);
	if(compopt != skip_argument) {
	    dbprintf(" %s", compopt);
	}
	dbprintf("\n");
    } else {
	dumpout = compout;
	comppid = -1;
    }

    /* invoke dump */
    device = amname_to_devname(dle->device);
    fstype = amname_to_fstype(dle->device);

    dbprintf(_("dumping device '%s' with '%s'\n"), device, fstype);

#if defined(USE_RUNDUMP) || !defined(DUMP)
    cmd = g_strjoin(NULL, amlibexecdir, "/", "rundump", NULL);
    cmdX = cmd;
    if (g_options->config)
	config = g_options->config;
    else
	config = "NOCONFIG";
#else
    cmd = g_strdup(DUMP);
    cmdX = skip_argument;
    config = skip_argument;
#endif

#ifndef AIX_BACKUP					/* { */
    /* normal dump */
#ifdef XFSDUMP						/* { */
#ifdef DUMP						/* { */
    if (g_str_equal(amname_to_fstype(dle->device), "xfs"))
#else							/* } { */
    if (1)
#endif							/* } */
    {
        char *progname;
        g_free(cmd);
        progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL);
	cmdX = cmd;
	if (g_options->config)
	    config = g_options->config;
	else
	    config = "NOCONFIG";

	program->backup_name  = XFSDUMP;
	program->restore_name = XFSRESTORE;

	indexcmd = g_strjoin(NULL, XFSRESTORE, " -t", " -v", " silent", " -",
	    " 2>/dev/null", " | sed", " -e", " \'s/^/\\//\'", NULL);

	info_tapeheader(dle);

	start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);

	dumpkeys = g_strdup(level_str);
	dumppid = pipespawn(progname, STDIN_PIPE, 0,
			    &dumpin, &dumpout, &mesgf,
			    cmdX, config,
			    "xfsdump",
			    !dle->record ? "-J" : skip_argument,
			    "-F",
			    "-l", dumpkeys,
			    "-",
			    device,
			    NULL);
    }
    else
#endif							/* } */
#ifdef VXDUMP						/* { */
#ifdef DUMP
    if (g_str_equal(amname_to_fstype(dle->device), "vxfs"))
#else
    if (1)
#endif
    {
char *progname;
#ifdef USE_RUNDUMP
        g_free(cmd);
        progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL);
	cmdX = cmd;
	if (g_options->config)
	    config = g_options->config;
	else
	    config = "NOCONFIG";
#else
	char *progname;
        g_free(cmd);
        progname = cmd = g_strdup(VXDUMP);
	cmdX = skip_argument;
	config = skip_argument;
#endif
	program->backup_name  = VXDUMP;
	program->restore_name = VXRESTORE;

	dumpkeys = g_strjoin(NULL, level_str,
			     !dle->record ? "" : "u",
			     "s",
			     "f",
			     NULL);

	indexcmd = g_strjoin(NULL, VXRESTORE,
			     " -tvf", " -",
			     " 2>/dev/null",
			     " | ",
			     LEAF_AND_DIRS,
			     NULL);
	info_tapeheader(dle);

	start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);

	dumppid = pipespawn(progname, STDIN_PIPE, 0,
			    &dumpin, &dumpout, &mesgf, 
			    cmdX, config,
			    "vxdump",
			    dumpkeys,
			    "1048576",
			    "-",
			    device,
			    NULL);
    }
    else
#endif							/* } */

#ifdef VDUMP						/* { */
#ifdef DUMP
    if (g_str_equal(amname_to_fstype(dle->device), "advfs"))
#else
    if (1)
#endif
    {
        g_free(cmd);
        cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL);
	cmdX = cmd;
	if (g_options->config)
	    config = g_options->config;
	else
	    config = "NOCONFIG";
	g_free(device);
	device = g_strdup(amname_to_dirname(dle->device));
	program->backup_name  = VDUMP;
	program->restore_name = VRESTORE;

	dumpkeys = g_strjoin(NULL, level_str,
			     !dle->record ? "" : "u",
			     "b",
			     "f",
			     NULL);

	indexcmd = g_strjoin(NULL, VRESTORE,
			     " -tvf", " -",
			     " 2>/dev/null",
			     " | ",
			     "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'",
			     NULL);
	info_tapeheader(dle);

	start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);

	dumppid = pipespawn(cmd, STDIN_PIPE, 0,
			    &dumpin, &dumpout, &mesgf, 
			    cmdX, config,
			    "vdump",
			    dumpkeys,
			    "60",
			    "-",
			    device,
			    NULL);
    }
    else
#endif							/* } */

    {
#ifndef RESTORE
#define RESTORE "restore"
#endif

#ifdef HAVE_HONOR_NODUMP
#  define PARAM_HONOR_NODUMP "h"
#else
#  define PARAM_HONOR_NODUMP ""
#endif

#ifdef __FreeBSD__
# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
#  define FREEBSD_EXTRA_KEYS "bL"
# else
#  define FREEBSD_EXTRA_KEYS "b"
# endif
#else
# define FREEBSD_EXTRA_KEYS ""
#endif

	dumpkeys = g_strjoin(NULL, level_str,
			     !dle->record ? "" : "u",
			     FREEBSD_EXTRA_KEYS,
			     "s",
			     PARAM_HONOR_NODUMP,
			     "f",
			     NULL);

	indexcmd = g_strjoin(NULL, RESTORE,
			     " -tvf", " -",
			     " 2>&1",
			     /* not to /dev/null because of DU's dump */
			     " | ",
			     LEAF_AND_DIRS,
			     NULL);
	info_tapeheader(dle);

	start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);

	dumppid = pipespawn(cmd, STDIN_PIPE, 0,
			    &dumpin, &dumpout, &mesgf, 
			    cmdX, config,
			    "dump",
			    dumpkeys,
#ifdef __FreeBSD__
			    "64",
#endif
			    "1048576",
#ifdef HAVE_HONOR_NODUMP
			    "0",
#endif
			    "-",
			    device,
			    NULL);
    }
#else							/* } { */
    /* AIX backup program */
    dumpkeys = g_strjoin(NULL, "-",
			 level_str,
			 !dle->record ? "" : "u",
			 "f",
			 NULL);

    indexcmd = g_strjoin(NULL, RESTORE,
			 " -B",
			 " -tvf", " -",
			 " 2>/dev/null",
			 " | ",
			 LEAF_AND_DIRS,
			 NULL);
    info_tapeheader(dle);

    start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);

    dumppid = pipespawn(cmd, STDIN_PIPE, 0,
			&dumpin, &dumpout, &mesgf, 
			cmdX, config,
			"backup",
			dumpkeys,
			"-",
			device,
			NULL);
#endif							/* } */

    amfree(dumpkeys);
    amfree(fstype);
    amfree(device);
    amfree(cmd);
    amfree(indexcmd);

    /* close the write ends of the pipes */

    aclose(dumpin);
    aclose(dumpout);
    aclose(compout);
    aclose(dataf);
    aclose(mesgf);
    if (dle->create_index)
	aclose(indexf);
}
Exemple #25
0
int main(int argc, char ** argv) {
    char * tapelist_name;
    taper_state_t state;
    config_overwrites_t *cfg_ovr = NULL;
    char *cfg_opt = NULL;

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");
    
    safe_fd(-1, 0);
    set_pname("taper");

    dbopen("server");

    device_api_init();
    init_taper_state(&state);

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    g_fprintf(stderr, _("%s: pid %ld executable %s version %s\n"),
	    get_pname(), (long) getpid(), argv[0], version());
    dbprintf(_("%s: pid %ld executable %s version %s\n"),
              get_pname(), (long) getpid(), argv[0], version());

    /* Process options */

    cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);

    if(argc > 2) {
        error("Too many arguments!\n");
        g_assert_not_reached();
    }
    if (argc > 1)
	cfg_opt = argv[1];
    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt);
    apply_config_overwrites(cfg_ovr);

    if (config_errors(NULL) >= CFGERR_ERRORS) {
	g_critical(_("errors processing config file"));
    }

    safe_cd();

    add_amanda_log_handler(amanda_log_stderr);
    add_amanda_log_handler(amanda_log_trace_log);

    check_running_as(RUNNING_AS_DUMPUSER);

    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid());

    tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST));

    if (read_tapelist(tapelist_name) != 0) {
	log_add(L_INFO, "pid-done %ld", (long)getpid());
        error("could not load tapelist \"%s\"", tapelist_name);
        g_assert_not_reached();
    }
    amfree(tapelist_name);

    state.have_changer = changer_init();
    if (state.have_changer < 0) {
	log_add(L_INFO, "pid-done %ld", (long)getpid());
        error("changer initialization failed: %s", strerror(errno));
        g_assert_not_reached();
    }

    state.next_tape_label = NULL;
    state.next_tape_device = NULL;
    state.cur_tape = 0;
    
    if (!find_first_tape(&state)) {
	log_add(L_INFO, "pid-done %ld", (long)getpid());
        return EXIT_SUCCESS;
    }

    while (process_driver_command(&state));
    log_add(L_INFO, "pid-done %ld", (long)getpid());
    return EXIT_SUCCESS;
}
Exemple #26
0
int
main(
    int		argc,
    char **	argv)
{
#ifdef GNUTAR
    int i;
    char *e;
    char *dbf;
    char *cmdline;
    GPtrArray *array = g_ptr_array_new();
    gchar **strings;
    char **new_argv;
#endif

    if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) {
	printf("runtar-%s\n", VERSION);
	return (0);
    }

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);
    safe_cd();

    set_pname("runtar");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_CLIENT);
    config_init(CONFIG_INIT_CLIENT, NULL);

    if (argc < 3) {
	error(_("Need at least 3 arguments\n"));
	/*NOTREACHED*/
    }

    dbprintf(_("version %s\n"), VERSION);

    if (!g_str_equal(argv[3], "--create")) {
	error(_("Can only be used to create tar archives\n"));
	/*NOTREACHED*/
    }

#ifndef GNUTAR

    g_fprintf(stderr,_("gnutar not available on this system.\n"));
    dbprintf(_("%s: gnutar not available on this system.\n"), argv[0]);
    dbclose();
    return 1;

#else

    /*
     * Print out version information for tar.
     */
    do {
	FILE *	version_file;
	char	version_buf[80];

	if ((version_file = popen(GNUTAR " --version 2>&1", "r")) != NULL) {
	    if (fgets(version_buf, (int)sizeof(version_buf), version_file) != NULL) {
		dbprintf(_(GNUTAR " version: %s\n"), version_buf);
	    } else {
		if (ferror(version_file)) {
		    dbprintf(_(GNUTAR " version: Read failure: %s\n"), strerror(errno));
		} else {
		    dbprintf(_(GNUTAR " version: Read failure; EOF\n"));
		}
	    }
	} else {
	    dbprintf(_(GNUTAR " version: unavailable: %s\n"), strerror(errno));
	}
    } while(0);

#ifdef WANT_SETUID_CLIENT
    check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY);
    if (!become_root()) {
	error(_("error [%s could not become root (is the setuid bit set?)]\n"), get_pname());
	/*NOTREACHED*/
    }
#else
    check_running_as(RUNNING_AS_CLIENT_LOGIN);
#endif

    /* skip argv[0] */
    argc--;
    argv++;

    dbprintf(_("config: %s\n"), argv[0]);
    if (!g_str_equal(argv[0], "NOCONFIG"))
	dbrename(argv[0], DBG_SUBDIR_CLIENT);
    argc--;
    argv++;

    new_argv = g_new0(char *, argc+1);

    new_argv[0] = g_strdup_printf("%s", argv[0]);
    g_ptr_array_add(array, g_strdup(GNUTAR));
    for (i = 1; argv[i]; i++) {
        g_ptr_array_add(array, quote_string(argv[i]));
	new_argv[i] = g_strdup_printf("%s", argv[i]);
    }

    g_ptr_array_add(array, NULL);
    strings = (gchar **)g_ptr_array_free(array, FALSE);

    cmdline = g_strjoinv(" ", strings);
    g_strfreev(strings);

    dbprintf(_("running: %s\n"), cmdline);
    amfree(cmdline);

    dbf = dbfn();
    if (dbf) {
	dbf = g_strdup(dbf);
    }
    dbclose();

    execve(GNUTAR, new_argv, safe_env());

    e = strerror(errno);
    dbreopen(dbf, "more");
    amfree(dbf);
    dbprintf(_("execve of %s failed (%s)\n"), GNUTAR, e);
    dbclose();

    g_fprintf(stderr, _("runtar: could not exec %s: %s\n"), GNUTAR, e);
    return 1;
#endif
}
Exemple #27
0
/*
 *  doing similar to $ gtar | compression | encryption 
 */
static void
start_backup(
    dle_t      *dle,
    char       *host,
    int		dataf,
    int		mesgf,
    int		indexf)
{
    char tmppath[PATH_MAX];
    int dumpin, dumpout, compout;
    char *cmd = NULL;
    char *indexcmd = NULL;
    char *dirname = NULL;
    int l;
    char dumptimestr[80] = "UNUSED";
    struct tm *gmtm;
    amandates_t *amdates = NULL;
    time_t prev_dumptime = 0;
    char *error_pn = NULL;
    char *compopt  = NULL;
    char *encryptopt = skip_argument;
    char *tquoted;
    char *fquoted;
    char *qdisk;
    int infd, outfd;
    ssize_t nb;
    char buf[32768];
    char *amandates_file = NULL;
    am_level_t *alevel = (am_level_t *)dle->levellist->data;
    int      level  = alevel->level;
    int        native_pipe[2];
    int        client_pipe[2];
    int        data_out;

    have_filter = FALSE;
    crc32_init(&native_crc.crc);
    crc32_init(&client_crc.crc);

    /* create pipes to compute the native CRC */
    if (pipe(native_pipe) < 0) {
	char  *errmsg;
	char  *qerrmsg;
	errmsg = g_strdup_printf(_("Program '%s': can't create pipe"),
				 dle->program);
	qerrmsg = quote_string(errmsg);
	fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg);
	dbprintf(_("ERROR %s\n"), qerrmsg);
	amfree(qerrmsg);
	amfree(errmsg);
	return;
    }

    if (dle->encrypt == ENCRYPT_CUST ||
        dle->compress == COMP_FAST ||
        dle->compress == COMP_BEST ||
        dle->compress == COMP_CUST) {

        have_filter = TRUE;

        /* create pipes to compute the client CRC */
        if (pipe(client_pipe) < 0) {
            char  *errmsg;
            char  *qerrmsg;
            errmsg = g_strdup_printf(_("Application '%s': can't create pipe"),
                                     dle->program);
            qerrmsg = quote_string(errmsg);
            fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg);
            dbprintf(_("ERROR %s\n"), qerrmsg);
            amfree(qerrmsg);
            amfree(errmsg);
            return;
        }
        data_out = client_pipe[1];
	client_pipe[1] = -1;
    } else {
        data_out = dataf;
	dataf = -1;
    }

    error_pn = g_strconcat(get_pname(), "-smbclient", NULL);

    qdisk = quote_string(dle->disk);
    dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level);

    g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"),
	    get_pname(), host, qdisk, level);

     /*  apply client-side encryption here */
     if ( dle->encrypt == ENCRYPT_CUST ) {
        encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0,
			&compout, &data_out, &mesgf,
			dle->clnt_encrypt, encryptopt, NULL);
        dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt);
	aclose(data_out);
    } else {
        compout = data_out;
	data_out = -1;
        encpid = -1;
    }
    /*  now do the client-side compression */
    if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) {
        compopt = skip_argument;
#if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
	if(dle->compress == COMP_BEST) {
	    compopt = COMPRESS_BEST_OPT;
	} else {
	    compopt = COMPRESS_FAST_OPT;
	}
#endif
	comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    COMPRESS_PATH, compopt, NULL);
	dbprintf(_("gnutar: pid %ld: %s"), (long)comppid, COMPRESS_PATH);
	if(compopt != skip_argument) {
	    dbprintf(_("pid %ld: %s %s\n"),
			(long)comppid, COMPRESS_PATH, compopt);
	} else {
	    dbprintf(_("pid %ld: %s\n"), (long)comppid, COMPRESS_PATH);
	}
	aclose(compout);
     } else if (dle->compress == COMP_CUST) {
        compopt = skip_argument;
	comppid = pipespawn(dle->compprog, STDIN_PIPE, 0,
			    &dumpout, &compout, &mesgf,
			    dle->compprog, compopt, NULL);
	if(compopt != skip_argument) {
	    dbprintf(_("pid %ld: %s %s\n"),
		     (long)comppid, dle->compprog, compopt);
	} else {
	    dbprintf(_("pid %ld: %s\n"), (long)comppid, dle->compprog);
	}
	aclose(compout);
    } else {
	dumpout = compout;
	compout = -1;
	comppid = -1;
    }

    gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR);
    if (strlen(gnutar_list_dir) == 0)
	gnutar_list_dir = NULL;

#ifdef SAMBA_CLIENT							/* { */
    if (dle->device[0] == '/' && dle->device[1]=='/')
	amfree(incrname);
    else
#endif									/* } */
    if (gnutar_list_dir) {
	char *basename = NULL;
	char number[NUM_STR_SIZE];
	char *inputname = NULL;
	int baselevel;
	char *sdisk = sanitise_filename(dle->disk);

	basename = g_strjoin(NULL, gnutar_list_dir,
			     "/",
			     host,
			     sdisk,
			     NULL);
	amfree(sdisk);

	g_snprintf(number, sizeof(number), "%d", level);
	incrname = g_strjoin(NULL, basename, "_", number, ".new", NULL);
	unlink(incrname);

	/*
	 * Open the listed incremental file from the previous level.  Search
	 * backward until one is found.  If none are found (which will also
	 * be true for a level 0), arrange to read from /dev/null.
	 */
	baselevel = level;
	infd = -1;
	while (infd == -1) {
	    if (--baselevel >= 0) {
		g_snprintf(number, sizeof(number), "%d", baselevel);
		g_free(inputname);
		inputname = g_strconcat(basename, "_", number, NULL);
	    } else {
		g_free(inputname);
		inputname = g_strdup("/dev/null");
	    }
	    if ((infd = open(inputname, O_RDONLY)) == -1) {
		int save_errno = errno;
		char *qname = quote_string(inputname);

		dbprintf(_("gnutar: error opening '%s': %s\n"),
			  qname,
			  strerror(save_errno));
		if (baselevel < 0) {
		    error(_("error [opening '%s': %s]"), qname, strerror(save_errno));
		    /*NOTREACHED*/
		}
		amfree(qname);
	    }
	}

	/*
	 * Copy the previous listed incremental file to the new one.
	 */
	if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
	    error(_("error [opening '%s': %s]"), incrname, strerror(errno));
	    /*NOTREACHED*/
	}

	while ((nb = read(infd, &buf, sizeof(buf))) > 0) {
	    if (full_write(outfd, &buf, (size_t)nb) < (size_t)nb) {
		error(_("error [writing to '%s': %s]"), incrname,
		       strerror(errno));
		/*NOTREACHED*/
	    }
	}

	if (nb < 0) {
	    error(_("error [reading from '%s': %s]"), inputname, strerror(errno));
	    /*NOTREACHED*/
	}

	if (close(infd) != 0) {
	    error(_("error [closing '%s': %s]"), inputname, strerror(errno));
	    /*NOTREACHED*/
	}
	if (close(outfd) != 0) {
	    error(_("error [closing '%s': %s]"), incrname, strerror(errno));
	    /*NOTREACHED*/
	}

	tquoted = quote_string(incrname);
	if(baselevel >= 0) {
	    fquoted = quote_string(inputname);
	    dbprintf(_("doing level %d dump as listed-incremental from '%s' to '%s'\n"),
		     level, fquoted, tquoted);
	    amfree(fquoted);
	} else {
	    dbprintf(_("doing level %d dump as listed-incremental to '%s'\n"),
		     level, tquoted);
	}
	amfree(tquoted);
	amfree(inputname);
	amfree(basename);
    } else {
	/* no gnutar-listdir, so we're using amandates */

	/* find previous dump time, failing completely if there's a problem */
	amandates_file = getconf_str(CNF_AMANDATES);
	if(!start_amandates(amandates_file, 0)) {
	    error(_("error [opening %s: %s]"), amandates_file, strerror(errno));
	    /*NOTREACHED*/
	}

	amdates = amandates_lookup(dle->disk);

	prev_dumptime = EPOCH;
	for(l = 0; l < level; l++) {
	    if(amdates->dates[l] > prev_dumptime)
		prev_dumptime = amdates->dates[l];
	}

	finish_amandates();
	free_amandates();

	gmtm = gmtime(&prev_dumptime);
	g_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);

	dbprintf(_("gnutar: doing level %d dump from amandates-derived date: %s\n"),
		  level, dumptimestr);
    }

    dirname = amname_to_dirname(dle->device);

    cur_dumptime = time(0);
    cur_level = level;
    cur_disk = g_strdup(dle->disk);
#ifdef GNUTAR
#  define PROGRAM_GNUTAR GNUTAR
#else
#  define PROGRAM_GNUTAR "tar"
#endif
    indexcmd = g_strjoin(NULL, 
			 PROGRAM_GNUTAR,
			 " -tf", " -",
			 " 2>/dev/null",
			 " | sed", " -e",
			 " \'s/^\\.//\'",
			 NULL);

#ifdef SAMBA_CLIENT							/* { */
    /* Use sambatar if the disk to back up is a PC disk */
    if (dle->device[0] == '/' && dle->device[1]=='/') {
	char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
	char *share = NULL, *subdir = NULL;
	char *pwtext = NULL;
	char *taropt;
	int passwdf = -1;
	size_t lpass;
	size_t pwtext_len;
	char *pw_fd_env;

	parsesharename(dle->device, &share, &subdir);
	if (!share) {
	    amfree(share);
	    amfree(subdir);
	    set_pname(error_pn);
	    amfree(error_pn);
	    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"), qdisk);
	    /*NOTREACHED*/
	}
	if ((user_and_password = findpass(share, &domain)) == NULL) {
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [invalid samba host or password not found?]"));
	    /*NOTREACHED*/
	}
	lpass = strlen(user_and_password);
	if ((pwtext = strchr(user_and_password, '%')) == NULL) {
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("password field not \'user%%pass\' for %s"), qdisk);
	    /*NOTREACHED*/
	}
	*pwtext++ = '\0';
	pwtext_len = strlen(pwtext);
	if ((sharename = makesharename(share, 0)) == 0) {
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    if(domain) {
		memset(domain, '\0', strlen(domain));
		amfree(domain);
	    }
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [can't make share name of %s]"), share);
	    /*NOTREACHED*/
	}

	taropt = g_strdup("-T");
	if(dle->exclude_file && dle->exclude_file->nb_element == 1) {
	    strappend(taropt, "X");
	}
#if SAMBA_VERSION >= 2
	strappend(taropt, "q");
#endif
	strappend(taropt, "c");
	if (level != 0) {
	    strappend(taropt, "g");
	} else if (dle->record) {
	    strappend(taropt, "a");
	}

	if (subdir) {
	    dbprintf(_("gnutar: backup of %s/%s\n"), sharename, subdir);
	} else {
	    dbprintf(_("gnutar: backup of %s\n"), sharename);
	}

	program->backup_name = program->restore_name = SAMBA_CLIENT;
	cmd = g_strdup(program->backup_name);
	info_tapeheader(dle);

	start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd);

	if (pwtext_len > 0) {
	    pw_fd_env = "PASSWD_FD";
	} else {
	    pw_fd_env = "dummy_PASSWD_FD";
	}
	dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE, 0,
			    &dumpin, &native_pipe[1], &mesgf,
			    pw_fd_env, &passwdf,
			    "smbclient",
			    sharename,
			    *user_and_password ? "-U" : skip_argument,
			    *user_and_password ? user_and_password : skip_argument,
			    "-E",
			    domain ? "-W" : skip_argument,
			    domain ? domain : skip_argument,
#if SAMBA_VERSION >= 2
			    subdir ? "-D" : skip_argument,
			    subdir ? subdir : skip_argument,
#endif
			    "-d0",
			    taropt,
			    "-",
			    dle->exclude_file && dle->exclude_file->nb_element == 1 ? dle->exclude_file->first->name : skip_argument,
			    NULL);
	if(domain) {
	    memset(domain, '\0', strlen(domain));
	    amfree(domain);
	}
	if(pwtext_len > 0 && full_write(passwdf, pwtext, pwtext_len) < pwtext_len) {
	    int save_errno = errno;

	    aclose(passwdf);
	    memset(user_and_password, '\0', lpass);
	    amfree(user_and_password);
	    set_pname(error_pn);
	    amfree(error_pn);
	    error(_("error [password write failed: %s]"), strerror(save_errno));
	    /*NOTREACHED*/
	}
	memset(user_and_password, '\0', lpass);
	amfree(user_and_password);
	aclose(passwdf);
	amfree(sharename);
	amfree(share);
	amfree(subdir);
	amfree(taropt);
	tarpid = dumppid;
    } else
#endif			/*end of samba */
    {

	int nb_exclude = 0;
	int nb_include = 0;
	GPtrArray *argv_ptr = g_ptr_array_new();
	char *file_exclude = NULL;
	char *file_include = NULL;
	messagelist_t mlist = NULL;

	if (dle->exclude_file) nb_exclude+=dle->exclude_file->nb_element;
	if (dle->exclude_list) nb_exclude+=dle->exclude_list->nb_element;
	if (dle->include_file) nb_include+=dle->include_file->nb_element;
	if (dle->include_list) nb_include+=dle->include_list->nb_element;

	if (nb_exclude > 0) file_exclude = build_exclude(dle, &mlist);
	if (nb_include > 0) file_include = build_include(dle, dirname, &mlist);
	g_slist_free(mlist); // MUST also free the message

	cmd = g_strjoin(NULL, amlibexecdir, "/", "runtar", NULL);
	info_tapeheader(dle);

	start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd);

	g_ptr_array_add(argv_ptr, g_strdup("runtar"));
	if (g_options->config)
	    g_ptr_array_add(argv_ptr, g_strdup(g_options->config));
	else
	    g_ptr_array_add(argv_ptr, g_strdup("NOCONFIG"));
#ifdef GNUTAR
	g_ptr_array_add(argv_ptr, g_strdup(GNUTAR));
#else
	g_ptr_array_add(argv_ptr, g_strdup("tar"));
#endif
	g_ptr_array_add(argv_ptr, g_strdup("--create"));
	g_ptr_array_add(argv_ptr, g_strdup("--file"));
	g_ptr_array_add(argv_ptr, g_strdup("-"));
	g_ptr_array_add(argv_ptr, g_strdup("--directory"));
	canonicalize_pathname(dirname, tmppath);
	g_ptr_array_add(argv_ptr, g_strdup(tmppath));
	g_ptr_array_add(argv_ptr, g_strdup("--one-file-system"));
	if (gnutar_list_dir && incrname) {
	    g_ptr_array_add(argv_ptr, g_strdup("--listed-incremental"));
	    g_ptr_array_add(argv_ptr, g_strdup(incrname));
	} else {
	    g_ptr_array_add(argv_ptr, g_strdup("--incremental"));
	    g_ptr_array_add(argv_ptr, g_strdup("--newer"));
	    g_ptr_array_add(argv_ptr, g_strdup(dumptimestr));
	}
#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
	/* --atime-preserve causes gnutar to call
	 * utime() after reading files in order to
	 * adjust their atime.  However, utime()
	 * updates the file's ctime, so incremental
	 * dumps will think the file has changed. */
	g_ptr_array_add(argv_ptr, g_strdup("--atime-preserve"));
#endif
	g_ptr_array_add(argv_ptr, g_strdup("--sparse"));
	g_ptr_array_add(argv_ptr, g_strdup("--ignore-failed-read"));
	g_ptr_array_add(argv_ptr, g_strdup("--totals"));

	if(file_exclude) {
	    g_ptr_array_add(argv_ptr, g_strdup("--exclude-from"));
	    g_ptr_array_add(argv_ptr, g_strdup(file_exclude));
	}

	if(file_include) {
	    g_ptr_array_add(argv_ptr, g_strdup("--files-from"));
	    g_ptr_array_add(argv_ptr, g_strdup(file_include));
	}
	else {
	    g_ptr_array_add(argv_ptr, g_strdup("."));
	}
	    g_ptr_array_add(argv_ptr, NULL);
	dumppid = pipespawnv(cmd, STDIN_PIPE, 0,
			     &dumpin, &native_pipe[1], &mesgf,
			     (char **)argv_ptr->pdata);
	tarpid = dumppid;
	amfree(file_exclude);
	amfree(file_include);
	g_ptr_array_free_full(argv_ptr);
    }
    dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)dumppid);

    amfree(qdisk);
    amfree(dirname);
    amfree(cmd);
    amfree(indexcmd);
    amfree(error_pn);

    /* close the write ends of the pipes */

    aclose(dumpin);
    aclose(native_pipe[1]);
    aclose(mesgf);
    if (dle->create_index)
	aclose(indexf);

    if (shm_control_name) {
	shm_ring = shm_ring_link(shm_control_name);
	shm_ring_producer_set_size(shm_ring, NETWORK_BLOCK_BYTES*16, NETWORK_BLOCK_BYTES*4);
	native_crc.in  = native_pipe[0];
	if (!have_filter) {
	    native_crc.out = dumpout;
	    native_crc.shm_ring = shm_ring;
	    native_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread,
					(gpointer)&native_crc, TRUE, NULL);
	} else {
	    native_crc.out = dumpout;
	    native_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&native_crc, TRUE, NULL);
	    client_crc.in  = client_pipe[0];
	    client_crc.out = dataf;
	    client_crc.shm_ring = shm_ring;
	    client_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread,
					(gpointer)&client_crc, TRUE, NULL);
	}
    } else {
	native_crc.in  = native_pipe[0];
	native_crc.out = dumpout;
	native_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&native_crc, TRUE, NULL);

	if (have_filter) {
	    client_crc.in  = client_pipe[0];
	    client_crc.out = dataf;
	    client_crc.thread = g_thread_create(handle_crc_thread,
					(gpointer)&client_crc, TRUE, NULL);
	}
    }
}
Exemple #28
0
int
main(
    int		argc,
    char **	argv)
{
    int foreground;
    int batch;
    int redirect;
    char **datearg = NULL;
    int nb_datearg = 0;
    char *conf_diskfile;
    char *conf_tapelist;
    char *conf_logfile;
    int conf_usetimestamps;
    disklist_t diskq;
    disk_t *dp;
    pid_t pid;
    pid_t driver_pid, reporter_pid;
    amwait_t exitcode;
    int opt;
    GSList *holding_list=NULL, *holding_file;
    int driver_pipe[2];
    char date_string[100];
    char date_string_standard[100];
    time_t today;
    char *errstr;
    struct tm *tm;
    char *tapedev;
    char *tpchanger;
    char *qdisk, *qhname;
    GSList *datestamp_list = NULL;
    config_overrides_t *cfg_ovr;
    char **config_options;
    find_result_t *holding_files;
    disklist_t holding_disklist = { NULL, NULL };

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);
    safe_cd();

    set_pname("amflush");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_SERVER);

    add_amanda_log_handler(amanda_log_stderr);
    foreground = 0;
    batch = 0;
    redirect = 1;

    /* process arguments */

    cfg_ovr = new_config_overrides(argc/2);
    while((opt = getopt(argc, argv, "bfso:D:")) != EOF) {
	switch(opt) {
	case 'b': batch = 1;
		  break;
	case 'f': foreground = 1;
		  break;
	case 's': redirect = 0;
		  break;
	case 'o': add_config_override_opt(cfg_ovr, optarg);
		  break;
	case 'D': if (datearg == NULL)
		      datearg = g_malloc(21*sizeof(char *));
		  if(nb_datearg == 20) {
		      g_fprintf(stderr,_("maximum of 20 -D arguments.\n"));
		      exit(1);
		  }
		  datearg[nb_datearg++] = g_strdup(optarg);
		  datearg[nb_datearg] = NULL;
		  break;
	}
    }
    argc -= optind, argv += optind;

    if(!foreground && !redirect) {
	g_fprintf(stderr,_("Can't redirect to stdout/stderr if not in forground.\n"));
	exit(1);
    }

    if(argc < 1) {
	error(_("Usage: amflush [-b] [-f] [-s] [-D date]* [-o configoption]* <confdir> [host [disk]* ]*"));
	/*NOTREACHED*/
    }

    set_config_overrides(cfg_ovr);
    config_init(CONFIG_INIT_EXPLICIT_NAME,
		argv[0]);

    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
    read_diskfile(conf_diskfile, &diskq);
    amfree(conf_diskfile);

    if (config_errors(NULL) >= CFGERR_WARNINGS) {
	config_print_errors();
	if (config_errors(NULL) >= CFGERR_ERRORS) {
	    g_critical(_("errors processing config file"));
	}
    }

    check_running_as(RUNNING_AS_DUMPUSER);

    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    /* load DLEs from the holding disk, in case there's anything to flush there */
    search_holding_disk(&holding_files, &holding_disklist);
    /* note that the dumps are added to the global disklist, so we need not
     * consult holding_files or holding_disklist after this.  The holding-only
     * dumps will be filtered properly by match_disklist, setting the dp->todo
     * flag appropriately. */

    errstr = match_disklist(&diskq, argc-1, argv+1);
    if (errstr) {
	g_printf(_("%s"),errstr);
	amfree(errstr);
    }

    conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
    if(read_tapelist(conf_tapelist)) {
	error(_("could not load tapelist \"%s\""), conf_tapelist);
	/*NOTREACHED*/
    }
    amfree(conf_tapelist);

    conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS);

    amflush_datestamp = get_datestamp_from_time(0);
    if(conf_usetimestamps == 0) {
	amflush_timestamp = g_strdup(amflush_datestamp);
    }
    else {
	amflush_timestamp = get_timestamp_from_time(0);
    }

    conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR));
    conf_logfile = g_strjoin(NULL, conf_logdir, "/log", NULL);
    if (access(conf_logfile, F_OK) == 0) {
	run_amcleanup(get_config_name());
    }
    if (access(conf_logfile, F_OK) == 0) {
	char *process_name = get_master_process(conf_logfile);
	error(_("%s exists: %s is already running, or you must run amcleanup"), conf_logfile, process_name);
	/*NOTREACHED*/
    }

    driver_program = g_strjoin(NULL, amlibexecdir, "/", "driver", NULL);
    reporter_program = g_strjoin(NULL, sbindir, "/", "amreport", NULL);
    logroll_program = g_strjoin(NULL, amlibexecdir, "/", "amlogroll", NULL);

    tapedev = getconf_str(CNF_TAPEDEV);
    tpchanger = getconf_str(CNF_TPCHANGER);
    if (tapedev == NULL && tpchanger == NULL) {
	error(_("No tapedev or tpchanger specified"));
    }

    /* if dates were specified (-D), then use match_datestamp
     * against the list of all datestamps to turn that list
     * into a set of existing datestamps (basically, evaluate the
     * expressions into actual datestamps) */
    if(datearg) {
	GSList *all_datestamps;
	GSList *datestamp;
	int i, ok;

	all_datestamps = holding_get_all_datestamps();
	for(datestamp = all_datestamps; datestamp != NULL; datestamp = datestamp->next) {
	    ok = 0;
	    for(i=0; i<nb_datearg && ok==0; i++) {
		ok = match_datestamp(datearg[i], (char *)datestamp->data);
	    }
	    if (ok)
		datestamp_list = g_slist_insert_sorted(datestamp_list,
		    g_strdup((char *)datestamp->data),
		    g_compare_strings);
	}
	slist_free_full(all_datestamps, g_free);
    }
    else {
	/* otherwise, in batch mode, use all datestamps */
	if(batch) {
	    datestamp_list = holding_get_all_datestamps();
	}
	/* or allow the user to pick datestamps */
	else {
	    datestamp_list = pick_datestamp();
	}
    }

    if(!datestamp_list) {
	g_printf(_("Could not find any Amanda directories to flush.\n"));
	exit(1);
    }

    holding_list = holding_get_files_for_flush(datestamp_list);
    if (holding_list == NULL) {
	g_printf(_("Could not find any valid dump image, check directory.\n"));
	exit(1);
    }

    if (access(conf_logfile, F_OK) == 0) {
	char *process_name = get_master_process(conf_logfile);
	error(_("%s exists: someone started %s"), conf_logfile, process_name);
	/*NOTREACHED*/
    }
    log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid());

    if(!batch) confirm(datestamp_list);

    for(dp = diskq.head; dp != NULL; dp = dp->next) {
	if(dp->todo) {
	    char *qname;
	    qname = quote_string(dp->name);
	    log_add(L_DISK, "%s %s", dp->host->hostname, qname);
	    amfree(qname);
	}
    }

    if(!foreground) { /* write it before redirecting stdout */
	puts(_("Running in background, you can log off now."));
	puts(_("You'll get mail when amflush is finished."));
    }

    if(redirect) redirect_stderr();

    if(!foreground) detach();

    add_amanda_log_handler(amanda_log_stderr);
    add_amanda_log_handler(amanda_log_trace_log);
    today = time(NULL);
    tm = localtime(&today);
    if (tm) {
	strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", tm);
	strftime(date_string_standard, 100, "%Y-%m-%d %H:%M:%S %Z", tm);
    } else {
	error(_("BAD DATE")); /* should never happen */
    }
    g_fprintf(stderr, _("amflush: start at %s\n"), date_string);
    g_fprintf(stderr, _("amflush: datestamp %s\n"), amflush_timestamp);
    g_fprintf(stderr, _("amflush: starttime %s\n"), amflush_timestamp);
    g_fprintf(stderr, _("amflush: starttime-locale-independent %s\n"),
	      date_string_standard);
    log_add(L_START, _("date %s"), amflush_timestamp);

    /* START DRIVER */
    if(pipe(driver_pipe) == -1) {
	error(_("error [opening pipe to driver: %s]"), strerror(errno));
	/*NOTREACHED*/
    }
    if((driver_pid = fork()) == 0) {
	/*
	 * This is the child process.
	 */
	dup2(driver_pipe[0], 0);
	close(driver_pipe[1]);
	config_options = get_config_options(3);
	config_options[0] = "driver";
	config_options[1] = get_config_name();
	config_options[2] = "nodump";
	safe_fd(-1, 0);
	execve(driver_program, config_options, safe_env());
	error(_("cannot exec %s: %s"), driver_program, strerror(errno));
	/*NOTREACHED*/
    } else if(driver_pid == -1) {
	error(_("cannot fork for %s: %s"), driver_program, strerror(errno));
	/*NOTREACHED*/
    }
    driver_stream = fdopen(driver_pipe[1], "w");
    if (!driver_stream) {
	error(_("Can't fdopen: %s"), strerror(errno));
	/*NOTREACHED*/
    }

    g_fprintf(driver_stream, "DATE %s\n", amflush_timestamp);
    for(holding_file=holding_list; holding_file != NULL;
				   holding_file = holding_file->next) {
	dumpfile_t file;
	holding_file_get_dumpfile((char *)holding_file->data, &file);

	if (holding_file_size((char *)holding_file->data, 1) <= 0) {
	    g_debug("%s is empty - ignoring", (char *)holding_file->data);
	    log_add(L_INFO, "%s: removing file with no data.",
		    (char *)holding_file->data);
	    holding_file_unlink((char *)holding_file->data);
	    dumpfile_free_data(&file);
	    continue;
	}

	/* search_holding_disk should have already ensured that every
	 * holding dumpfile has an entry in the dynamic disklist */
	dp = lookup_disk(file.name, file.disk);
	assert(dp != NULL);

	/* but match_disklist may have indicated we should not flush it */
	if (dp->todo == 0) continue;

	qdisk = quote_string(file.disk);
	qhname = quote_string((char *)holding_file->data);
	g_fprintf(stderr,
		"FLUSH %s %s %s %d %s\n",
		file.name,
		qdisk,
		file.datestamp,
		file.dumplevel,
		qhname);

	g_debug("flushing '%s'", (char *)holding_file->data);
	g_fprintf(driver_stream,
		"FLUSH %s %s %s %d %s\n",
		file.name,
		qdisk,
		file.datestamp,
		file.dumplevel,
		qhname);
	amfree(qdisk);
	amfree(qhname);
	dumpfile_free_data(&file);
    }
    g_fprintf(stderr, "ENDFLUSH\n"); fflush(stderr);
    g_fprintf(driver_stream, "ENDFLUSH\n"); fflush(driver_stream);
    fclose(driver_stream);

    /* WAIT DRIVER */
    while(1) {
	if((pid = wait(&exitcode)) == -1) {
	    if(errno == EINTR) {
		continue;
	    } else {
		error(_("wait for %s: %s"), driver_program, strerror(errno));
		/*NOTREACHED*/
	    }
	} else if (pid == driver_pid) {
	    break;
	}
    }

    slist_free_full(datestamp_list, g_free);
    datestamp_list = NULL;
    slist_free_full(holding_list, g_free);
    holding_list = NULL;

    if(redirect) { /* rename errfile */
	char *errfile, *errfilex, *nerrfilex, number[100];
	int tapecycle;
	int maxdays, days;
		
	struct stat stat_buf;

	errfile = g_strjoin(NULL, conf_logdir, "/amflush", NULL);
	errfilex = NULL;
	nerrfilex = NULL;
	tapecycle = getconf_int(CNF_TAPECYCLE);
	maxdays = tapecycle + 2;
	days = 1;
	/* First, find out the last existing errfile,           */
	/* to avoid ``infinite'' loops if tapecycle is infinite */

	g_snprintf(number,100,"%d",days);
	errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
	while ( days < maxdays && stat(errfilex,&stat_buf)==0) {
	    days++;
	    g_snprintf(number,100,"%d",days);
	    errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
	}
	g_snprintf(number,100,"%d",days);
	errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
	nerrfilex = NULL;
	while (days > 1) {
	    amfree(nerrfilex);
	    nerrfilex = errfilex;
	    days--;
	    g_snprintf(number,100,"%d",days);
	    errfilex = g_strjoin(NULL, errfile, ".", number, NULL);
	    if (rename(errfilex, nerrfilex) != 0) {
		error(_("cannot rename \"%s\" to \"%s\": %s"),
		      errfilex, nerrfilex, strerror(errno));
	        /*NOTREACHED*/
	    }
	}
	errfilex = newvstralloc(errfilex, errfile, ".1", NULL);
	if (rename(errfile,errfilex) != 0) {
	    error(_("cannot rename \"%s\" to \"%s\": %s"),
		  errfilex, nerrfilex, strerror(errno));
	    /*NOTREACHED*/
	}
	amfree(errfile);
	amfree(errfilex);
	amfree(nerrfilex);
    }

    /*
     * Have amreport generate report and send mail.  Note that we do
     * not bother checking the exit status.  If it does not work, it
     * can be rerun.
     */

    if((reporter_pid = fork()) == 0) {
	/*
	 * This is the child process.
	 */
	config_options = get_config_options(3);
	config_options[0] = "amreport";
	config_options[1] = get_config_name();
        config_options[2] = "--from-amdump";
	safe_fd(-1, 0);
	execve(reporter_program, config_options, safe_env());
	error(_("cannot exec %s: %s"), reporter_program, strerror(errno));
	/*NOTREACHED*/
    } else if(reporter_pid == -1) {
	error(_("cannot fork for %s: %s"), reporter_program, strerror(errno));
	/*NOTREACHED*/
    }
    while(1) {
	if((pid = wait(&exitcode)) == -1) {
	    if(errno == EINTR) {
		continue;
	    } else {
		error(_("wait for %s: %s"), reporter_program, strerror(errno));
		/*NOTREACHED*/
	    }
	} else if (pid == reporter_pid) {
	    break;
	}
    }

    log_add(L_INFO, "pid-done %ld", (long)getpid());

    /*
     * Call amlogroll to rename the log file to its datestamped version.
     * Since we exec at this point, our exit code will be that of amlogroll.
     */
    config_options = get_config_options(2);
    config_options[0] = "amlogroll";
    config_options[1] = get_config_name();
    safe_fd(-1, 0);
    execve(logroll_program, config_options, safe_env());
    error(_("cannot exec %s: %s"), logroll_program, strerror(errno));
    /*NOTREACHED*/
    return 0;				/* keep the compiler happy */
}
Exemple #29
0
char *look_in_lisp_variable(char *o, int prefix)
{
    Lisp_Object nil, var;
/*
 * I will start by tagging a '$' (or whatever) on in front of the
 * parameter name.
 */
    o[0] = (char)prefix;
    var = make_undefined_symbol(o);
    nil = C_nil;
/*
 * make_undefined_symbol() could fail either if we had utterly run out
 * of memory or if somebody generated an interrupt (eg ^C) around now. Ugh.
 */
    if (exception_pending())
    {   flip_exception();
        return NULL;
    }
/*
 * If the variable $name was undefined then I use an empty replacement
 * text for it. Otherwise I need to look harder at its value.
 */
    if (qvalue(var) == unset_var) return o;
    else
    {   Header h;
        intptr_t len;
        var = qvalue(var);
/*
 * Mostly I expect that the value will be a string or symbol.
 */
#ifdef COMMON
        if (complex_stringp(var))
        {   var = simplify_string(var);
            nil = C_nil;
            if (exception_pending())
            {   flip_exception();
                return NULL;
            }
        }
#endif /* COMMON */
        if (symbolp(var))
        {   var = get_pname(var);
            nil = C_nil;
            if (exception_pending())
            {   flip_exception();
                return NULL;
            }
            h = vechdr(var);
        }
        else if (!is_vector(var) ||
                 type_of_header(h = vechdr(var)) != TYPE_STRING)
            return NULL;
        len = length_of_header(h) - CELL;
/*
 * Copy the characters from the string or from the name of the variable
 * into the file-name buffer. There could at present be a crash here
 * if the expansion was very very long and overflowed my buffer. Tough
 * luck for now - people doing that (maybe) get what they (maybe) deserve.
 */
        memcpy(o, (char *)var + (CELL - TAG_VECTOR), (size_t)len);
        o = o + len;
        return o;
    }
}
Exemple #30
0
static void
amgtar_restore(
    application_argument_t *argument)
{
    char       *cmd;
    GPtrArray  *argv_ptr = g_ptr_array_new();
    char      **env;
    int         j;
    char       *e;
    char       *include_filename = NULL;
    char       *exclude_filename = NULL;
    int         tarpid;

    if (!gnutar_path) {
	error(_("GNUTAR-PATH not defined"));
    }

    cmd = g_strdup(gnutar_path);
    g_ptr_array_add(argv_ptr, g_strdup(gnutar_path));
    g_ptr_array_add(argv_ptr, g_strdup("--numeric-owner"));
    if (gnutar_no_unquote)
	g_ptr_array_add(argv_ptr, g_strdup("--no-unquote"));
    if (gnutar_acls)
	g_ptr_array_add(argv_ptr, g_strdup("--acls"));
    if (gnutar_selinux)
	g_ptr_array_add(argv_ptr, g_strdup("--selinux"));
    if (gnutar_xattrs)
	g_ptr_array_add(argv_ptr, g_strdup("--xattrs"));
    /* ignore trailing zero blocks on input (this was the default until tar-1.21) */
    if (argument->ignore_zeros) {
	g_ptr_array_add(argv_ptr, g_strdup("--ignore-zeros"));
    }
    if (argument->tar_blocksize) {
	g_ptr_array_add(argv_ptr, g_strdup("--blocking-factor"));
	g_ptr_array_add(argv_ptr, g_strdup(argument->tar_blocksize));
    }
    g_ptr_array_add(argv_ptr, g_strdup("-xpGvf"));
    g_ptr_array_add(argv_ptr, g_strdup("-"));
    if (gnutar_directory) {
	struct stat stat_buf;
	if(stat(gnutar_directory, &stat_buf) != 0) {
	    fprintf(stderr,"can not stat directory %s: %s\n", gnutar_directory, strerror(errno));
	    exit(1);
	}
	if (!S_ISDIR(stat_buf.st_mode)) {
	    fprintf(stderr,"%s is not a directory\n", gnutar_directory);
	    exit(1);
	}
	if (access(gnutar_directory, W_OK) != 0) {
	    fprintf(stderr, "Can't write to %s: %s\n", gnutar_directory, strerror(errno));
	    exit(1);
	}
	g_ptr_array_add(argv_ptr, g_strdup("--directory"));
	g_ptr_array_add(argv_ptr, g_strdup(gnutar_directory));
    }

    g_ptr_array_add(argv_ptr, g_strdup("--wildcards"));
    if (argument->dle.exclude_list &&
	argument->dle.exclude_list->nb_element == 1) {
	FILE      *exclude;
	char      *sdisk;
	int        in_argv;
	int        entry_in_exclude = 0;
	char       line[2*PATH_MAX];
	FILE      *exclude_list;

	if (argument->dle.disk) {
	    sdisk = sanitise_filename(argument->dle.disk);
	} else {
	    sdisk = g_strdup_printf("no_dle-%d", (int)getpid());
	}
	exclude_filename= g_strjoin(NULL, AMANDA_TMPDIR, "/", "exclude-", sdisk,  NULL);
	exclude_list = fopen(argument->dle.exclude_list->first->name, "r");
	if (!exclude_list) {
	    fprintf(stderr, "Cannot open exclude file '%s': %s\n",
		    argument->dle.exclude_list->first->name, strerror(errno));
	    error("Cannot open exclude file '%s': %s\n",
		  argument->dle.exclude_list->first->name, strerror(errno));
	    /*NOTREACHED*/
	}
	exclude = fopen(exclude_filename, "w");
	if (!exclude) {
	    fprintf(stderr, "Cannot open exclude file '%s': %s\n",
		    exclude_filename, strerror(errno));
	    fclose(exclude_list);
	    error("Cannot open exclude file '%s': %s\n",
		  exclude_filename, strerror(errno));
	    /*NOTREACHED*/
	}
	while (fgets(line, 2*PATH_MAX, exclude_list)) {
	    char *escaped;
	    line[strlen(line)-1] = '\0'; /* remove '\n' */
	    escaped = escape_tar_glob(line, &in_argv);
	    if (in_argv) {
		g_ptr_array_add(argv_ptr, "--exclude");
		g_ptr_array_add(argv_ptr, escaped);
	    } else {
		fprintf(exclude,"%s\n", escaped);
		entry_in_exclude++;
		amfree(escaped);
	    }
	}
	fclose(exclude_list);
	fclose(exclude);
	g_ptr_array_add(argv_ptr, g_strdup("--exclude-from"));
	g_ptr_array_add(argv_ptr, exclude_filename);
    }

    if (argument->exclude_list_glob) {
	g_ptr_array_add(argv_ptr, g_strdup("--exclude-from"));
	g_ptr_array_add(argv_ptr, g_strdup(argument->exclude_list_glob));
    }

    {
	GPtrArray *argv_include = g_ptr_array_new();
	FILE      *include;
	char      *sdisk;
	int        in_argv;
	guint      i;
	int        entry_in_include = 0;

	if (argument->dle.disk) {
	    sdisk = sanitise_filename(argument->dle.disk);
	} else {
	    sdisk = g_strdup_printf("no_dle-%d", (int)getpid());
	}
	include_filename = g_strjoin(NULL, AMANDA_TMPDIR, "/", "include-", sdisk,  NULL);
	include = fopen(include_filename, "w");
	if (!include) {
	    fprintf(stderr, "Cannot open include file '%s': %s\n",
		    include_filename, strerror(errno));
	    error("Cannot open include file '%s': %s\n",
		  include_filename, strerror(errno));
	    /*NOTREACHED*/
	}
	if (argument->dle.include_list &&
	    argument->dle.include_list->nb_element == 1) {
	    char line[2*PATH_MAX];
	    FILE *include_list = fopen(argument->dle.include_list->first->name, "r");
	    if (!include_list) {
		fclose(include);
		fprintf(stderr, "Cannot open include file '%s': %s\n",
			argument->dle.include_list->first->name,
			strerror(errno));
		error("Cannot open include file '%s': %s\n",
		      argument->dle.include_list->first->name,
		      strerror(errno));
		/*NOTREACHED*/
	    }
	    while (fgets(line, 2*PATH_MAX, include_list)) {
		char *escaped;
		line[strlen(line)-1] = '\0'; /* remove '\n' */
		escaped = escape_tar_glob(line, &in_argv);
		if (in_argv) {
		    g_ptr_array_add(argv_include, escaped);
		} else {
		    fprintf(include,"%s\n", escaped);
		    entry_in_include++;
		    amfree(escaped);
		}
	    }
	    fclose(include_list);
	}

	for (j=1; j< argument->argc; j++) {
	    char *escaped = escape_tar_glob(argument->argv[j], &in_argv);
	    if (in_argv) {
		g_ptr_array_add(argv_include, escaped);
	    } else {
		fprintf(include,"%s\n", escaped);
		entry_in_include++;
		amfree(escaped);
	    }
	}
	fclose(include);

	if (entry_in_include) {
	    g_ptr_array_add(argv_ptr, g_strdup("--files-from"));
	    g_ptr_array_add(argv_ptr, include_filename);
	}

	if (argument->include_list_glob) {
	    g_ptr_array_add(argv_ptr, g_strdup("--files-from"));
	    g_ptr_array_add(argv_ptr, g_strdup(argument->include_list_glob));
	}

	for (i = 0; i < argv_include->len; i++) {
	    g_ptr_array_add(argv_ptr, (char *)g_ptr_array_index(argv_include,i));
	}
	amfree(sdisk);
    }
    g_ptr_array_add(argv_ptr, NULL);

    debug_executing(argv_ptr);

    tarpid = fork();
    switch (tarpid) {
    case -1: error(_("%s: fork returned: %s"), get_pname(), strerror(errno));
    case 0:
	env = safe_env();
	become_root();
	execve(cmd, (char **)argv_ptr->pdata, env);
	e = strerror(errno);
	error(_("error [exec %s: %s]"), cmd, e);
	break;
    default: break;
    }

    waitpid(tarpid, NULL, 0);
    if (argument->verbose == 0) {
	if (exclude_filename)
	    unlink(exclude_filename);
	unlink(include_filename);
    }
    amfree(cmd);
    amfree(include_filename);
    amfree(exclude_filename);
}