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

📄 amflush.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
	g_fprintf(stderr,		"FLUSH %s %s %s %d %s\n",		file.name,		qdisk,		file.datestamp,		file.dumplevel,		qhname);	g_fprintf(driver_stream,		"FLUSH %s %s %s %d %s\n",		file.name,		qdisk,		file.datestamp,		file.dumplevel,		qhname);	amfree(qdisk);	amfree(qhname);    }    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;	}    }    g_slist_free_full(datestamp_list);    datestamp_list = NULL;    g_slist_free_full(holding_list);    holding_list = NULL;    if(redirect) { /* rename errfile */	char *errfile, *errfilex, *nerrfilex, number[100];	int tapecycle;	int maxdays, days;			struct stat stat_buf;	errfile = vstralloc(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 = vstralloc(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(2);	config_options[0] = "amreport";	config_options[1] = config_name;	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;	}    }    /*     * 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] = 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 */}static intget_letter_from_user(void){    int r, ch;    fflush(stdout); fflush(stderr);    while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {	(void)ch; /* Quite lint */    }    if(ch == '\n') {	r = '\0';    } else if (ch != EOF) {	r = ch;	if(islower(r)) r = toupper(r);	while((ch = getchar()) != EOF && ch != '\n') { 	    (void)ch; /* Quite lint */	}    } else {	r = ch;	clearerr(stdin);    }    return r;}/* Allow the user to select a set of datestamps from those in * holding disks.  The result can be passed to  * holding_get_files_for_flush.  If less than two dates are * available, then no user interaction takes place. * * @returns: a new GSList listing the selected datestamps */static GSList *pick_datestamp(void){    GSList *datestamp_list;    GSList *r_datestamp_list = NULL;    GSList *ds;    char **datestamps = NULL;    int i;    char *answer = NULL;    char *a = NULL;    int ch = 0;    char max_char = '\0', chupper = '\0';    datestamp_list = holding_get_all_datestamps();    if(g_slist_length(datestamp_list) < 2) {	return datestamp_list;    } else {	datestamps = alloc(g_slist_length(datestamp_list) * SIZEOF(char *));	for(ds = datestamp_list, i=0; ds != NULL; ds = ds->next,i++) {	    datestamps[i] = (char *)ds->data; /* borrowing reference */	}	while(1) {	    puts(_("\nMultiple Amanda runs in holding disks; please pick one by letter:"));	    for(ds = datestamp_list, max_char = 'A';		ds != NULL && max_char <= 'Z';		ds = ds->next, max_char++) {		g_printf("  %c. %s\n", max_char, (char *)ds->data);	    }	    max_char--;	    g_printf(_("Select datestamps to flush [A..%c or <enter> for all]: "), max_char);	    fflush(stdout); fflush(stderr);	    amfree(answer);	    if ((answer = agets(stdin)) == NULL) {		clearerr(stdin);		continue;	    }	    if (*answer == '\0' || strncasecmp(answer, "ALL", 3) == 0) {		break;	    }	    a = answer;	    while ((ch = *a++) != '\0') {		if (!isspace(ch))		    break;	    }	    /* rewrite the selected list into r_datestamp_list, then copy it over	     * to datestamp_list */	    do {		if (isspace(ch) || ch == ',') {		    continue;		}		chupper = (char)toupper(ch);		if (chupper < 'A' || chupper > max_char) {		    g_slist_free_full(r_datestamp_list);		    r_datestamp_list = NULL;		    break;		}		r_datestamp_list = g_slist_append(r_datestamp_list,					   stralloc(datestamps[chupper - 'A']));	    } while ((ch = *a++) != '\0');	    if (r_datestamp_list && ch == '\0') {		g_slist_free_full(datestamp_list);		datestamp_list = r_datestamp_list;		break;	    }	}    }    amfree(datestamps); /* references in this array are borrowed */    amfree(answer);    return datestamp_list;}/* * confirm before detaching and running */voidconfirm(GSList *datestamp_list){    tape_t *tp;    char *tpchanger;    GSList *datestamp;    int ch;    char *extra;    g_printf(_("\nToday is: %s\n"),amflush_datestamp);    g_printf(_("Flushing dumps from"));    extra = "";    for(datestamp = datestamp_list; datestamp != NULL; datestamp = datestamp->next) {	g_printf("%s %s", extra, (char *)datestamp->data);	extra = ",";    }    tpchanger = getconf_str(CNF_TPCHANGER);    if(*tpchanger != '\0') {	g_printf(_(" using tape changer \"%s\".\n"), tpchanger);    } else {	g_printf(_(" to tape drive \"%s\".\n"), getconf_str(CNF_TAPEDEV));    }    g_printf(_("Expecting "));    tp = lookup_last_reusable_tape(0);    if(tp != NULL)	g_printf(_("tape %s or "), tp->label);    g_printf(_("a new tape."));    tp = lookup_tapepos(1);    if(tp != NULL)	g_printf(_("  (The last dumps were to tape %s)"), tp->label);    while (1) {	g_printf(_("\nAre you sure you want to do this [yN]? "));	if((ch = get_letter_from_user()) == 'Y') {	    return;	} else if (ch == 'N' || ch == '\0' || ch == EOF) {	    if (ch == EOF) {		putchar('\n');	    }	    break;	}    }    g_printf(_("Ok, quitting.  Run amflush again when you are ready.\n"));    exit(1);}voidredirect_stderr(void){    int fderr;    char *errfile;    fflush(stdout); fflush(stderr);    errfile = vstralloc(conf_logdir, "/amflush", NULL);    if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1) {	error(_("could not open %s: %s"), errfile, strerror(errno));	/*NOTREACHED*/    }    dup2(fderr,1);    dup2(fderr,2);    aclose(fderr);    amfree(errfile);}voiddetach(void){    int fd;    fflush(stdout); fflush(stderr);    if((fd = open("/dev/null", O_RDWR, 0666)) == -1) {	error(_("could not open /dev/null: %s"), strerror(errno));	/*NOTREACHED*/    }    dup2(fd,0);    aclose(fd);    switch(fork()) {    case -1:    	error(_("could not fork: %s"), strerror(errno));	/*NOTREACHED*/    case 0:	setsid();	return;    }    exit(0);}

⌨️ 快捷键说明

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