📄 sendsize.c
字号:
dbfn()); } else { /* Normal exit */ } } else { *errmsg = vstrallocf(_("%s got bad exit: see %s"), SAMBA_CLIENT, dbfn()); } dbprintf(_("after %s %s wait\n"), SAMBA_CLIENT, qdisk); afclose(dumpout); pipefd = -1; amfree(error_pn); amfree(qdisk); return size;}#endif#ifdef GNUTARoff_tgetsize_gnutar( char *disk, char *amdevice, int level, option_t *options, time_t dumpsince, char **errmsg){ int pipefd = -1, nullfd = -1; pid_t dumppid; off_t size = (off_t)-1; FILE *dumpout = NULL; char *incrname = NULL; char *basename = NULL; char *dirname = NULL; char *inputname = NULL; FILE *in = NULL; FILE *out = NULL; char *line = NULL; char *cmd = NULL; char dumptimestr[80]; struct tm *gmtm; int nb_exclude = 0; int nb_include = 0; char **my_argv; int i; char *file_exclude = NULL; char *file_include = NULL; times_t start_time; int infd, outfd; ssize_t nb; char buf[32768]; char *qdisk = quote_string(disk); char *gnutar_list_dir; amwait_t wait_status; char tmppath[PATH_MAX]; if(options->exclude_file) nb_exclude += options->exclude_file->nb_element; if(options->exclude_list) nb_exclude += options->exclude_list->nb_element; if(options->include_file) nb_include += options->include_file->nb_element; if(options->include_list) nb_include += options->include_list->nb_element; if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0); if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0); my_argv = alloc(SIZEOF(char *) * 22); i = 0; gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_list_dir) == 0) gnutar_list_dir = NULL; if (gnutar_list_dir) { char number[NUM_STR_SIZE]; int baselevel; char *sdisk = sanitise_filename(disk); basename = vstralloc(gnutar_list_dir, "/", g_options->hostname, sdisk, NULL); amfree(sdisk); g_snprintf(number, SIZEOF(number), "%d", level); incrname = vstralloc(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); inputname = newvstralloc(inputname, basename, "_", number, NULL); } else { inputname = newstralloc(inputname, "/dev/null"); } if ((infd = open(inputname, O_RDONLY)) == -1) { *errmsg = vstrallocf(_("gnutar: error opening %s: %s"), inputname, strerror(errno)); dbprintf("%s\n", *errmsg); if (baselevel < 0) { goto common_exit; } amfree(*errmsg); } } /* * Copy the previous listed incremental file to the new one. */ if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) { *errmsg = vstrallocf(_("opening %s: %s"), incrname, strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) { if (fullwrite(outfd, &buf, (size_t)nb) < nb) { *errmsg = vstrallocf(_("writing to %s: %s"), incrname, strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } } if (nb < 0) { *errmsg = vstrallocf(_("reading from %s: %s"), inputname, strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } if (close(infd) != 0) { *errmsg = vstrallocf(_("closing %s: %s"), inputname, strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } if (close(outfd) != 0) { *errmsg = vstrallocf(_("closing %s: %s"), incrname, strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } amfree(inputname); amfree(basename); } gmtm = gmtime(&dumpsince); 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); dirname = amname_to_dirname(amdevice); cmd = vstralloc(amlibexecdir, "/", "runtar", versionsuffix(), NULL); my_argv[i++] = "runtar"; if (g_options->config) my_argv[i++] = g_options->config; else my_argv[i++] = "NOCONFIG";#ifdef GNUTAR my_argv[i++] = GNUTAR;#else my_argv[i++] = "tar";#endif my_argv[i++] = "--create"; my_argv[i++] = "--file"; my_argv[i++] = "/dev/null"; my_argv[i++] = "--directory"; canonicalize_pathname(dirname, tmppath); my_argv[i++] = tmppath; my_argv[i++] = "--one-file-system"; if (gnutar_list_dir) { my_argv[i++] = "--listed-incremental"; my_argv[i++] = incrname; } else { my_argv[i++] = "--incremental"; my_argv[i++] = "--newer"; my_argv[i++] = dumptimestr; }#ifdef ENABLE_GNUTAR_ATIME_PRESERVE /* --atime-preserve causes gnutar to call * utime() after reading files in order to * adjust their atime. However, utime() * updates the file's ctime, so incremental * dumps will think the file has changed. */ my_argv[i++] = "--atime-preserve";#endif my_argv[i++] = "--sparse"; my_argv[i++] = "--ignore-failed-read"; my_argv[i++] = "--totals"; if(file_exclude) { my_argv[i++] = "--exclude-from"; my_argv[i++] = file_exclude; } if(file_include) { my_argv[i++] = "--files-from"; my_argv[i++] = file_include; } else { my_argv[i++] = "."; } my_argv[i++] = NULL; start_time = curclock(); if ((nullfd = open("/dev/null", O_RDWR)) == -1) { *errmsg = vstrallocf(_("Cannot access /dev/null : %s"), strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv); dumpout = fdopen(pipefd,"r"); if (!dumpout) { error(_("Can't fdopen: %s"), strerror(errno)); /*NOTREACHED*/ } for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { if (line[0] == '\0') continue; dbprintf("%s\n", line); size = handle_dumpline(line); if(size > (off_t)-1) { amfree(line); while ((line = agets(dumpout)) != NULL) { if (line[0] != '\0') { break; } amfree(line); } if (line != NULL) { dbprintf("%s\n", line); break; } break; } } amfree(line); dbprintf(".....\n"); dbprintf(_("estimate time for %s level %d: %s\n"), qdisk, level, walltime_str(timessub(curclock(), start_time))); if(size == (off_t)-1) { *errmsg = vstrallocf(_("no size line match in %s output"), my_argv[0]); dbprintf(_("%s for %s\n"), *errmsg, qdisk); dbprintf(".....\n"); } else if(size == (off_t)0 && level == 0) { dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"), my_argv[0], disk); dbprintf(".....\n"); } dbprintf(_("estimate size for %s level %d: %lld KB\n"), qdisk, level, (long long)size); kill(-dumppid, SIGTERM); dbprintf(_("waiting for %s \"%s\" child\n"), my_argv[0], qdisk); waitpid(dumppid, &wait_status, 0); if (WIFSIGNALED(wait_status)) { *errmsg = vstrallocf(_("%s terminated with signal %d: see %s"), cmd, WTERMSIG(wait_status), dbfn()); } else if (WIFEXITED(wait_status)) { if (WEXITSTATUS(wait_status) != 0) { *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"), my_argv[0], qdisk);common_exit: if (incrname) { unlink(incrname); } amfree(incrname); amfree(basename); amfree(dirname); amfree(inputname); amfree(my_argv); amfree(qdisk); amfree(cmd); amfree(file_exclude); amfree(file_include); aclose(nullfd); afclose(dumpout); afclose(in); afclose(out); return size;}#endifoff_tgetsize_backup_api( char *program, char *disk, char *amdevice, int level, option_t *options, time_t dumpsince, char **errmsg){ int pipeinfd[2], pipeoutfd[2], nullfd; pid_t dumppid; off_t size = (off_t)-1; FILE *dumpout, *toolin; char *line = NULL; char *cmd = NULL; char *cmdline; char dumptimestr[80]; struct tm *gmtm; int i, j; char *argvchild[10]; char *newoptstr = NULL; off_t size1, size2; times_t start_time; char *qdisk = quote_string(disk); char *qamdevice = quote_string(amdevice); amwait_t wait_status; char levelstr[NUM_STR_SIZE]; backup_support_option_t *bsu; (void)options; gmtm = gmtime(&dumpsince); 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); cmd = vstralloc(DUMPER_DIR, "/", program, NULL); bsu = backup_support_option(program, g_options, disk, amdevice); i=0; argvchild[i++] = program; argvchild[i++] = "estimate"; if (bsu->message_line == 1) { argvchild[i++] = "--message"; argvchild[i++] = "line"; } if (g_options->config && bsu->config == 1) { argvchild[i++] = "--config"; argvchild[i++] = g_options->config; } if (g_options->hostname && bsu->host == 1) { argvchild[i++] = "--host"; argvchild[i++] = g_options->hostname; } argvchild[i++] = "--device"; argvchild[i++] = amdevice; if (disk && bsu->disk == 1) { argvchild[i++] = "--disk"; argvchild[i++] = disk; } if (level <= bsu->max_level) { argvchild[i++] = "--level"; g_snprintf(levelstr,SIZEOF(levelstr),"%d",level); argvchild[i++] = levelstr; } argvchild[i] = NULL; cmdline = stralloc(cmd); for(j = 1; j < i; j++) cmdline = vstrextend(&cmdline, " ", argvchild[i], NULL); dbprintf("running: \"%s\"\n", cmdline); amfree(cmdline); if ((nullfd = open("/dev/null", O_RDWR)) == -1) { *errmsg = vstrallocf(_("Cannot access /dev/null : %s"), strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } if (pipe(pipeinfd) < 0) { *errmsg = vstrallocf(_("getsize_backup_api could create data pipes: %s"), strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } if (pipe(pipeoutfd) < 0) { *errmsg = vstrallocf(_("getsize_backup_api could create data pipes: %s"), strerror(errno)); dbprintf("%s\n", *errmsg); goto common_exit; } start_time = curclock(); switch(dumppid = fork()) { case -1: size = (off_t)-1; goto common_exit; default: break; /* parent */ case 0: dup2(pipeinfd[0], 0); dup2(pipeoutfd[1], 1); dup2(nullfd, 2); aclose(pipeinfd[1]); aclose(pipeoutfd[0]); safe_fd(-1, 0); execve(cmd, argvchild, safe_env()); error(_("exec %s failed: %s"), cmd, strerror(errno)); /*NOTREACHED*/ } amfree(newoptstr); aclose(pipeinfd[0]); aclose(pipeoutfd[1]); toolin = fdopen(pipeinfd[1],"w"); if (!toolin) { error("Can't fdopen: %s", strerror(errno)); /*NOTREACHED*/ } output_tool_property(toolin, options); fflush(toolin); fclose(toolin); dumpout = fdopen(pipeoutfd[0],"r"); if (!dumpout) { error(_("Can't fdopen: %s"), strerror(errno)); /*NOTREACHED*/ } for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) { long long size1_ = (long long)0; long long size2_ = (long long)0; if (line[0] == '\0') continue; dbprintf("%s\n", line); i = sscanf(line, "%lld %lld", &size1_, &size2_); size1 = (off_t)size1_; size2 = (off_t)size2_; if(i == 2) { size = size1 * size2; } if(size > -1) { amfree(line); while ((line = agets(dumpout)) != NULL) { if (line[0] != '\0') break; amfree(line); } if(line != NULL) { dbprintf(_("%s\n"), line); } break; } } amfree(line); dbprintf(".....\n"); dbprintf(_("estimate time for %s level %d: %s\n"), qamdevice, level, walltime_str(timessub(curclock(), start_time))); if(size == (off_t)-1) { *errmsg = vstrallocf(_("no size line match in %s output"), cmd); dbprintf(_("%s for %s\n"), cmd, qdisk); dbprintf(".....\n"); } else if(size == (off_t)0 && level == 0) { dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"), cmd, qdisk); dbprintf(".....\n"); } dbprintf(_("estimate size for %s level %d: %lld KB\n"), qamdevice, level, (long long)size); kill(-dumppid, SIGTERM); dbprintf(_("waiting for %s \"%s\" child\n"), cmd, qdisk); waitpid(dumppid, &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 (WEXITSTATUS(wait_status) != 0) { *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); aclose(nullfd); afclose(dumpout);common_exit: amfree(cmd); amfree(newoptstr); amfree(qdisk); amfree(qamdevice); return size;}/* * Returns the value of the first integer in a string. */doublefirst_num( char * str){ char *start; int ch; double d; ch = *str++; while(ch && !isdigit(ch)) ch = *str++; start = str-1; while(isdigit(ch) || (ch == '.')) ch = *str++; str[-1] = '\0'; d = atof(start); str[-1] = (char)ch; return d;}/* * Checks the dump output line against the error and size regex tables. */off_thandle_dumpline( char * str){ regex_scale_t *rp; double size; /* check for size match */ /*@ignore@*/ for(rp = re_size; rp->regex != NULL; rp++) { if(match(rp->regex, str)) { size = ((first_num(str)*rp->scale+1023.0)/1024.0); if(size < 0.0) size = 1.0; /* found on NeXT -- sigh */ return (off_t)size; } } /*@end@*/ return (off_t)-1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -