⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendbackup.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
	    error(_("error [opening mesg pipe: %s]"), s);	}	program->start_backup(g_options->hostname, disk, amdevice, level,			      dumpdate, datafd, mesgpipe[1], indexfd);	dbprintf(_("Started backup\n"));	parse_backup_messages(mesgpipe[0]);	dbprintf(_("Parsed backup messages\n"));    }    amfree(prog);    amfree(disk);    amfree(qdisk);    amfree(amdevice);    amfree(qamdevice);    amfree(dumpdate);    amfree(stroptions);    amfree(our_feature_string);    am_release_feature_set(our_features);    our_features = NULL;    free_g_options(g_options);    dbclose();    return 0; err:    g_printf(_("FORMAT ERROR IN REQUEST PACKET\n"));    dbprintf(_("REQ packet is bogus%s%s\n"),	      err_extra ? ": " : "",	      err_extra ? err_extra : "");    dbclose();    return 1;}/* * Returns a string for a child process.  Checks the saved dump and * compress pids to see which it is. */char *childstr(    pid_t pid){    if(pid == dumppid) return program->backup_name;    if(pid == comppid) return "compress";    if(pid == encpid) return "encrypt";    if(pid == indexpid) return "index";    return "unknown";}/* * Determine if the child return status really indicates an error. * If so, add the error message to the error string; more than one * child can have an error. */intcheck_status(    pid_t	pid,    amwait_t	w){    char *thiserr = NULL;    char *str, *strX;    int ret, sig, rc;    str = childstr(pid);    if(WIFSIGNALED(w)) {	ret = 0;	rc = sig = WTERMSIG(w);    } else {	sig = 0;	rc = ret = WEXITSTATUS(w);    }    if(pid == indexpid) {	/*	 * Treat an index failure (other than signal) as a "STRANGE"	 * rather than an error so the dump goes ahead and gets processed	 * but the failure is noted.	 */	if(ret != 0) {	    g_fprintf(stderr, _("? index %s returned %d\n"), str, ret);	    rc = 0;	}	indexpid = -1;	strX = "index ";    } else if(pid == comppid) {	/*	 * compress returns 2 sometimes, but it is ok.	 */#ifndef HAVE_GZIP	if(ret == 2) {	    rc = 0;	}#endif	comppid = -1;	strX = "compress ";    } else if(pid == dumppid && tarpid == -1) {        /*	 * Ultrix dump returns 1 sometimes, but it is ok.	 */#ifdef DUMP_RETURNS_1        if(ret == 1) {	    rc = 0;	}#endif	dumppid = -1;	strX = "dump ";    } else if(pid == tarpid) {	if (ret == 1) {	    rc = 0;	}	/*	 * tar bitches about active filesystems, but we do not care.	 */#ifdef IGNORE_TAR_ERRORS        if(ret == 2) {	    rc = 0;	}#endif	dumppid = tarpid = -1;	strX = "dump ";    } else {	strX = "unknown ";    }    if(rc == 0) {	return 0;				/* normal exit */    }    if(ret == 0) {	thiserr = vstrallocf(_("%s (%d) %s got signal %d"), strX, (int)pid, str,			     sig);    } else {	thiserr = vstrallocf(_("%s (%d) %s returned %d"), strX, (int)pid, str, ret);    }    if(errorstr) {	errorstr =  newvstrallocf(errorstr, "%s, %s", errorstr, thiserr);	amfree(thiserr);    } else {	errorstr = thiserr;	thiserr = NULL;    }    return 1;}/* *Send header info to the message file. */voidinfo_tapeheader(void){    g_fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name);    g_fprintf(stderr, "%s: info RECOVER_CMD=", get_pname());    if (options->compress == COMP_FAST || options->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 (options->compress == COMP_FAST || options->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());}voidbackup_api_info_tapeheader(    int       mesgfd,    char     *prog,    option_t *options){    char line[1024];    g_snprintf(line, 1024, "%s: info BACKUP=DUMPER\n", get_pname());    if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	return;    }    g_snprintf(line, 1024, "%s: info DUMPER=%s\n", get_pname(), prog);    if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	return;    }    g_snprintf(line, 1024, "%s: info RECOVER_CMD=", get_pname());    if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	return;    }    if (options->compress) {	g_snprintf(line, 1024, "%s %s |", UNCOMPRESS_PATH,#ifdef UNCOMPRESS_OPT		 UNCOMPRESS_OPT#else		 ""#endif		 );	if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	    dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	    return;	}    }    g_snprintf(line, 1024, "%s -f... -\n", prog);    if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	return;    }    if (options->compress) {	g_snprintf(line, 1024, "%s: info COMPRESS_SUFFIX=%s\n",		 get_pname(), COMPRESS_SUFFIX);	if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	    dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	    return;	}    }    g_snprintf(line, 1024, "%s: info end\n", get_pname());    if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) {	dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno));	return;    }}pid_tpipefork(    void	(*func)(void),    char *	fname,    int *	stdinfd,    int		stdoutfd,    int		stderrfd){    int inpipe[2];    pid_t pid;    dbprintf(_("Forking function %s in pipeline\n"), fname);    if(pipe(inpipe) == -1) {	error(_("error [open pipe to %s: %s]"), fname, strerror(errno));	/*NOTREACHED*/    }    switch(pid = fork()) {    case -1:	error(_("error [fork %s: %s]"), fname, strerror(errno));	/*NOTREACHED*/    default:	/* parent process */	aclose(inpipe[0]);	/* close input side of pipe */	*stdinfd = inpipe[1];	break;    case 0:		/* child process */	aclose(inpipe[1]);	/* close output side of pipe */	if(dup2(inpipe[0], 0) == -1) {	    error(_("error [fork %s: dup2(%d, in): %s]"),		  fname, inpipe[0], strerror(errno));	    /*NOTRACHED*/	}	if(dup2(stdoutfd, 1) == -1) {	    error(_("error [fork %s: dup2(%d, out): %s]"),		  fname, stdoutfd, strerror(errno));	    /*NOTRACHED*/	}	if(dup2(stderrfd, 2) == -1) {	    error(_("error [fork %s: dup2(%d, err): %s]"),		  fname, stderrfd, strerror(errno));	    /*NOTRACHED*/	}	func();	exit(0);	/*NOTREACHED*/    }    return pid;}voidparse_backup_messages(    int		mesgin){    int goterror;    pid_t wpid;    amwait_t retstat;    char *line;    goterror = 0;    amfree(errorstr);    for(; (line = areads(mesgin)) != NULL; free(line)) {	process_dumpline(line);    }    if(errno) {	error(_("error [read mesg pipe: %s]"), strerror(errno));	/*NOTREACHED*/    }    while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) {	if(check_status(wpid, retstat)) goterror = 1;    }    if (dumppid != -1) {	sleep(5);	while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) {	    if(check_status(wpid, retstat)) goterror = 1;	}    }    if (dumppid != -1) {	dbprintf(_("Sending SIGHUP to dump process %d\n"),		  (int)dumppid);	if(dumppid != -1) {	    if(kill(dumppid, SIGHUP) == -1) {		dbprintf(_("Can't send SIGHUP to %d: %s\n"),			  (int)dumppid,			  strerror(errno));	    }	}	sleep(5);	while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) {	    if(check_status(wpid, retstat)) goterror = 1;	}    }    if (dumppid != -1) {	dbprintf(_("Sending SIGKILL to dump process %d\n"),		  (int)dumppid);	if(dumppid != -1) {	    if(kill(dumppid, SIGKILL) == -1) {		dbprintf(_("Can't send SIGKILL to %d: %s\n"),			  (int)dumppid,			  strerror(errno));	    }	}	sleep(5);	while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) {	    if(check_status(wpid, retstat)) goterror = 1;	}    }    if(errorstr) {	error(_("error [%s]"), errorstr);	/*NOTREACHED*/    } else if(dump_size == -1) {	error(_("error [no backup size line]"));	/*NOTREACHED*/    }    program->end_backup(goterror);    g_fprintf(stderr, _("%s: size %ld\n"), get_pname(), dump_size);    g_fprintf(stderr, _("%s: end\n"), get_pname());}/* * Returns the value of the first integer in a string. */doublethe_num(    char *	str,    int         pos){    char *num;    int ch;    double d;    do {	ch = *str++;	while(ch && !isdigit(ch)) ch = *str++;	if (pos == 1) break;	pos--;	while(ch && (isdigit(ch) || ch == '.')) ch = *str++;    } while (ch);    num = str - 1;    while(isdigit(ch) || ch == '.') ch = *str++;    str[-1] = '\0';    d = atof(num);    str[-1] = (char)ch;    return d;}static voidprocess_dumpline(    char *	str){    amregex_t *rp;    char *type;    char startchr;    for(rp = program->re_table; rp->regex != NULL; rp++) {	if(match(rp->regex, str)) {	    break;	}    }    if(rp->typ == DMP_SIZE) {	dump_size = (long)((the_num(str, rp->field)* rp->scale+1023.0)/1024.0);    }    switch(rp->typ) {    case DMP_NORMAL:	type = "normal";	startchr = '|';	break;    case DMP_STRANGE:	type = "strange";	startchr = '?';	break;    case DMP_SIZE:	type = "size";	startchr = '|';	break;    case DMP_ERROR:	type = "error";	startchr = '?';	break;    default:	/*	 * Should never get here.	 */	type = "unknown";	startchr = '!';	break;    }    dbprintf("%3d: %7s(%c): %s\n",	      rp->srcline,	      type,	      startchr,	      str);    g_fprintf(stderr, "%c %s\n", startchr, str);}/* * start_index.  Creates an index file from the output of dump/tar. * It arranges that input is the fd to be written by the dump process. * If createindex is not enabled, it does nothing.  If it is not, a * new process will be created that tees input both to a pipe whose * read fd is dup2'ed input and to a program that outputs an index * file to `index'. * * make sure that the chat from restore doesn't go to stderr cause * this goes back to amanda which doesn't expect to see it * (2>/dev/null should do it) * * Originally by Alan M. McIvor, 13 April 1996 * * Adapted by Alexandre Oliva, 1 May 1997 * * This program owes a lot to tee.c from GNU sh-utils and dumptee.c * from the DeeJay backup package. */static voidsave_fd(    int *	fd,    int		min){  int origfd = *fd;  while (*fd >= 0 && *fd < min) {    int newfd = dup(*fd);    if (newfd == -1)      dbprintf(_("Unable to save file descriptor [%s]\n"), strerror(errno));    *fd = newfd;  }  if (origfd != *fd)    dbprintf(_("Dupped file descriptor %i to %i\n"), origfd, *fd);}voidstart_index(    int		createindex,    int		input,    int		mesg,    int		index,    char *	cmd){  int pipefd[2];  FILE *pipe_fp;  int exitcode;  if (!createindex)    return;  if (pipe(pipefd) != 0) {    error(_("creating index pipe: %s"), strerror(errno));    /*NOTREACHED*/  }  switch(indexpid = fork()) {  case -1:    error(_("forking index tee process: %s"), strerror(errno));    /*NOTREACHED*/  default:    aclose(pipefd[0]);    if (dup2(pipefd[1], input) == -1) {      error(_("dup'ping index tee output: %s"), strerror(errno));      /*NOTREACHED*/    }    aclose(pipefd[1]);    return;  case 0:    break;  }  /* now in a child process */  save_fd(&pipefd[0], 4);  save_fd(&index, 4);  save_fd(&mesg, 4);  save_fd(&input, 4);  dup2(pipefd[0], 0);  dup2(index, 1);  dup2(mesg, 2);  dup2(input, 3);  for(index = 4; index < (int)FD_SETSIZE; index++) {    if (index != dbfd()) {      close(index);    }  }  if ((pipe_fp = popen(cmd, "w")) == NULL) {    error(_("couldn't start index creator [%s]"), strerror(errno));    /*NOTREACHED*/  }  dbprintf(_("Started index creator: \"%s\"\n"), cmd);  while(1) {    char buffer[BUFSIZ], *ptr;    ssize_t bytes_read;    size_t bytes_written;    ssize_t just_written;    do {	bytes_read = read(0, buffer, SIZEOF(buffer));    } while ((bytes_read < 0) && ((errno == EINTR) || (errno == EAGAIN)));    if (bytes_read < 0) {      error(_("index tee cannot read [%s]"), strerror(errno));      /*NOTREACHED*/    }    if (bytes_read == 0)      break; /* finished */    /* write the stuff to the subprocess */    ptr = buffer;    bytes_written = 0;    just_written = fullwrite(fileno(pipe_fp), ptr, (size_t)bytes_read);    if (just_written < 0) {	/* 	 * just as we waited for write() to complete.	 */	if (errno != EPIPE) {	    dbprintf(_("Index tee cannot write to index creator [%s]\n"),			    strerror(errno));	}    } else {	bytes_written += just_written;	ptr += just_written;    }    /* write the stuff to stdout, ensuring none lost when interrupt       occurs */    ptr = buffer;    bytes_written = 0;    just_written = fullwrite(3, ptr, (size_t)bytes_read);    if (just_written < 0) {	error(_("index tee cannot write [%s]"), strerror(errno));	/*NOTREACHED*/    } else {	bytes_written += just_written;	ptr += just_written;    }  }  aclose(pipefd[1]);  /* finished */  /* check the exit code of the pipe and moan if not 0 */  if ((exitcode = pclose(pipe_fp)) != 0) {    char *exitstr = str_exit_status("Index pipe", exitcode);    dbprintf("%s\n", exitstr);    amfree(exitstr);  } else {    dbprintf(_("Index created successfully\n"));  }  pipe_fp = NULL;  exit(exitcode);}extern backup_program_t dump_program, gnutar_program;backup_program_t *programs[] = {  &dump_program, &gnutar_program, NULL};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -