📄 full_backup.c
字号:
start_msg_proc_msg( UChar *server, Int32 port){ Int32 i; i = start_msg_proc(server, port); if(i > 0) errmsg(T_("Warning: Obtaining the server's informational messages might not work.\n")); if(i < 0) errmsg(T_("Warning: Obtaining the server's informational messages fails.\n")); return(i);}main(int argc, char ** argv){/* uninitialized ok: uncompcmd, j, ifd, infile, outfile, inunzip, outzip unzipfile, unzipfilecmd */ UChar *backuphome, *programfile, c; UChar *cptr, *cptr2, *cptr3, **cpptr, **cpptr2, **cpptr3; UChar *zippedidxf, *tmpidxf; UChar *tmperrf, ***cppptr, *uncompcmd; UChar *dirsarr[2], *crucial_tapes_str = NULL, *header; UChar kbuf[64], vbuf[128]; Flag must_read_fnamlog = NO, one_server; Flag remove_previous_equal_level, errflp, success = YES; UChar *filename, **dirlists[10], *tmpstartposfile; Int32 i, j, n, lck, num_inlines = 0, num_outlines = 0; Int32 startcart, startfile, last_idx_num = 0, used_port; Int32 rc, rf; int pos, p; FILE *fp; int pid, pst, ppi[3], ppo[3], ppe[3], lfd, fd; int ifd, opid, ipid, i1, fdflags, ofdflags, efdflags, eofdflags; FindParams findparams; UChar *infile, *outfile, inunzip, outzip; UChar *unzipfile, **unzipfilecmd; UChar *rename_from = NULL, *rename_to = NULL, **lines; UChar *new_needed_tapes_file = NULL; Int32 effective_backup_level, num_server_ids, num_servers; Uns32Range *new_tape_ranges, *all_tape_ranges; Uns32Range *needed_tapes_before = NULL; struct stat statb, statb2; ServerIdTab *server_id_tab = NULL; StreamerStat *stst;#ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE);#endif SETZERO(dirlists); SETZERO(tmpfiles); strcpy(server_id, ""); curuid = getuid(); curgid = getgid(); curngids = 0; curgids = NULL; get_groups(&curngids, &curgids); ieuid = geteuid(); iegid = getegid(); programfile = find_program(argv[0]); if(!programfile){ errmsg(T_("Error: Cannot find program file of `%s'.\n"), argv[0]); exit(4); } /* use the name of how we were invoked to set our operating mode */ cptr = FN_BASENAME((UChar *) argv[0]); for(i = 0; i < sizeof(cmd_res) / sizeof(*cmd_res); i++){ if(re_find_match_once(cmd_res[i], cptr, NULL, NULL) >= 0){ mode = i; break; } } if(mode < 0){ fprintf(stderr, T_("Error: Command name %s not recognized.\n"), cptr); do_exit(1); } i = stat(programfile, &statb); if(i){ errmsg(T_("Error: Cannot stat %s.\n"), programfile); exit(41); } /* * If we're not in restore or "update indices" mode, make sure we're not * setuid/setgid */ if(((statb.st_mode & (S_ISUID | S_ISGID)) || curuid != ieuid || curgid != iegid) && mode != MODE_RESTORE && mode != MODE_UPDATE_INDEXES){ errmsg(T_("Error: %s is installed SUID or SGID. Please check installation.\n"), programfile); exit(42); } /* check usage */ get_args(argc, argv); systemname = get_my_off_hn(); if(!systemname){ i = uname(&systeminfo); if(i < 0){ fprintf(stderr, T_("Warning: Cannot determine hostname.\n")); systemname = "???"; } else systemname = systeminfo.nodename; }/* cptr = strchr(systemname, '.'); if(cptr) *cptr = '\0';*/ /* not needed anymore, have same_host() function now */ if(detach){ if(fork()){ exit(0); } else{ detach_from_tty(); ms_sleep(1000 * 30); } } /* set signal handlers */ signal(SIGTERM, sig_handler); signal(SIGABRT, sig_handler); signal(SIGQUIT, sig_handler); signal(SIGHUP, sig_handler); signal(SIGINT, sig_handler); signal(SIGPIPE, sig_handler); /* signals blocked during execution of index processing processes */ sigemptyset(&idxproc_blk_sigs); sigaddset(&idxproc_blk_sigs, SIGINT); /* this is advanced from Ctrl-C */ /* compile some regular expressions */ SETZERO(backup_re); SETZERO(cartridge_re); SETZERO(file_re); SETZERO(server_re); SETZERO(port_re); SETZERO(ncarts_re); if(re_compile_pattern(T_(CARTRIDGE_RE), strlen(T_(CARTRIDGE_RE)), &cartridge_re) || re_compile_pattern(T_(FILE_RE), strlen(T_(FILE_RE)), &file_re) || re_compile_pattern(T_(SERVER_RE), strlen(T_(SERVER_RE)), &server_re) || re_compile_pattern(T_(PORT_RE), strlen(T_(PORT_RE)), &port_re) || re_compile_pattern(T_(NCARTS_RE), strlen(T_(NCARTS_RE)), &ncarts_re) || re_compile_pattern(T_(BACKUP_RE), strlen(T_(BACKUP_RE)), &backup_re)) ENM__; /* determine home directory */ backuphome = getenv("BACKUP_HOME");#ifdef ORIG_DEFAULTS if(!backuphome){ backuphome = programfile; EM__(cptr = mkabspath(backuphome, NULL)); free(backuphome); backuphome = resolve_path__(cptr, NULL); if(!backuphome){ errmsg(T_("Error: Cannot follow path `%s'.\n"), cptr); do_exit(29); } free(cptr); cptr = FN_LASTDIRDELIM(backuphome); if(!cptr){ errmsg(T_("Strange error: cannot separate binary directory.\n")); do_exit(5); } *cptr = '\0'; cptr = FN_LASTDIRDELIM(backuphome); if(!cptr){ errmsg(T_("Strange error: cannot separate client directory.\n")); do_exit(5); } *cptr = '\0'; } else backuphome = strdup(backuphome); EM__(backuphome); /* construct file- and dirnames */ bindir = strapp(backuphome, FN_DIRSEPSTR "bin"); vardir = strapp(backuphome, FN_DIRSEPSTR "var"); libdir = strapp(backuphome, FN_DIRSEPSTR "lib"); confdir = strapp(backuphome, FN_DIRSEPSTR "etc"); logdir = strdup(vardir); if(!bindir || !vardir || !libdir || !logdir || !confdir) ENM__; if(!paramfile) EM__(paramfile = strapp(confdir, FN_DIRSEPSTR "backup.conf"));#else /* defined(ORIG_DEFAULTS) */ if(!backuphome){ /* construct file- and dirnames */ bindir = strdup(DEFBINDIR); vardir = strdup(DEFVARDIR); libdir = strdup(DEFLIBDIR); logdir = strdup(DEFLOGDIR); confdir = strdup(DEFCONFDIR); } else{ EM__(backuphome = strdup(backuphome)); /* construct file- and dirnames */ /* first bin or sbin ? */ EM__(bindir = strapp(backuphome, FN_DIRSEPSTR "bin")); EM__(cptr = strapp(bindir, FN_DIRSEPSTR "afbackup")); if(access(cptr, X_OK)){ free(cptr); EM__(cptr = strapp(backuphome, FN_DIRSEPSTR "sbin" FN_DIRSEPSTR "afbackup")); if(!access(cptr, X_OK)){ free(bindir); bindir = strapp(backuphome, FN_DIRSEPSTR "sbin"); } } ZFREE(cptr); vardir = strapp(backuphome, FN_DIRSEPSTR "var"); libdir = strapp(backuphome, FN_DIRSEPSTR "lib"); logdir = strapp(backuphome, FN_DIRSEPSTR "var"); confdir = strapp(backuphome, FN_DIRSEPSTR "etc"); } if(!bindir || !vardir || !libdir || !logdir || !confdir) ENM__; if(!paramfile) EM__(paramfile = strapp(confdir, FN_DIRSEPSTR DEFCLIENTCONF));#endif /* if else defined(ORIG_DEFAULTS) */ if((mode == MODE_UPDATE_INDEXES || mode == MODE_RESTORE) && curuid){ if(setuid(0)){ errmsg(T_("Error: Cannot setuid root, sorry.\n")); do_exit(17); } } /* * Locate our configuration file. */ if(!stat(paramfile, &statb) && access(paramfile, R_OK)){ errmsg(T_("Error: Cannot read parameter file `%s'. %s.\n"), paramfile, T_("File not readable")); do_exit(6); } if(stat(paramfile, &statb)){ for(cpptr = default_paramfiles; *cpptr; cpptr++){ paramfile = *cpptr; if(!stat(paramfile, &statb) && access(paramfile, R_OK)){ errmsg(T_("Error: Cannot read parameter file `%s'.\n"), paramfile); do_exit(6); } if(!stat(paramfile, &statb)) break; } if(!*cpptr){ errmsg(T_("Warning: No configuration file found, using defaults.\n")); paramfile = NULL; /*do_exit(6);*/ /* Note: in this case the statb still contains the inode data of * the binary of this program, what can be used in the next if * i.e. then the binary must be owned by the calling user not * to compromise it (? superfluous paranoia) */ } } if(statb.st_uid && curuid){ errmsg(T_("Error: Configuration file must be owned by root when running as normal user.\n")); do_exit(7); } if(paramfile){ /* read parameter file */ i = read_param_file(paramfile, entries, sizeof(entries) / sizeof(entries[0]), NULL, NULL); if(i){ errmsg(T_("Error: Cannot read parameter file.\n")); do_exit(6); } /* override by commandline-arguments */ get_args(argc, argv); }#ifndef USE_ZLIB if(builtin_compr_level){ fprintf(stderr, T_("Warning: Built-in compression requested, but not compiled in. Ignoring request for built-in compression.\n")); builtin_compr_level = 0; }#endif massage_string(vardir); partfile = strapp(vardir, FN_DIRSEPSTR "part"); numfile = strapp(vardir, FN_DIRSEPSTR "num"); oldmarkfile = strapp(vardir, FN_DIRSEPSTR "oldmark"); newmarkfile = strapp(vardir, FN_DIRSEPSTR "newmark"); orgoldmarkfile = strapp(vardir, FN_DIRSEPSTR "oldmark.org"); clientprogram = strapp(bindir, FN_DIRSEPSTR "afbackup"); if(!dont_compress_str) dont_compress_str = ""; num_dont_compress = str2wordsq(&dont_compress, dont_compress_str); piperprogram = strapp(bindir, FN_DIRSEPSTR "__piper"); zprogram = strapp(bindir, FN_DIRSEPSTR "__z"); server_ids_file = strapp(vardir, FN_DIRSEPSTR "server_ids"); index_ages_file = strapp(vardir, FN_DIRSEPSTR "index_ages"); if(!partfile || !oldmarkfile || !orgoldmarkfile || !clientprogram || !newmarkfile || !piperprogram || !zprogram || num_dont_compress < 0 || !numfile || !index_ages_file || !server_ids_file) ENM__; if(!cryptfile){ EM__(cryptfile = strapp(confdir, FN_DIRSEPSTR "cryptkey")); if(access(cryptfile, R_OK)) ZFREE(cryptfile); } if(cryptfile) massage_string(cryptfile); /* correct parameter values, if unreasonable or set defaults */ if(!dirstobackupraw) EM__(dirstobackupraw = strdup("*")); if(backuphostlist && empty_string(backuphostlist)) ZFREE(backuphostlist); if(!backuphostlist) /* set default server name */ EM__(backuphostlist = strdup(DEFAULT_SERVER)); while( (cptr = strchr(backuphostlist, ',')) ) /* [,;] -> SPC */ *cptr = ' '; while( (cptr = strchr(backuphostlist, ';')) ) *cptr = ' '; if(backupportlist && empty_string(backupportlist)) ZFREE(backupportlist); if(!backupportlist) /* set default port number */ EM__(backupportlist = strdup(DEFAULT_SERVICE)); while( (cptr = strchr(backupportlist, ',')) ) /* [,;] -> SPC */ *cptr = ' '; while( (cptr = strchr(backupportlist, ';')) ) *cptr = ' '; num_backuphosts = str2words(&backuphosts, backuphostlist); num_backupports = str2words(&backupportstrs, backupportlist); if(num_backuphosts < 0 || num_backupports < 0) ENM__; EM__(backupports = ZRENEWP(backupports, Int32, num_backuphosts * sizeof(Int32))); if(num_backupports > num_backuphosts) /* ports: no more than hosts */ num_backupports = num_backuphosts; EM__(msgports = ZRENEWP(msgports, Int32, num_backuphosts * sizeof(Int32))); for(i = 0; i < num_backupports; i++){ p = get_tcp_portnum(backupportstrs[i]); if(p < 0){ errmsg(T_("Error: Cannot resolve TCP service name `%s'.\n"), backupportstrs[i]); exit(1); } backupports[i] = p; } while(num_backupports < num_backuphosts) /* set default values */ backupports[num_backupports++] = -1; one_server = (num_backuphosts == 1 ? YES : NO); if(msgs_config_str){ if((n = word_count(msgs_config_str)) < 1){ ZFREE(msgs_config_str); } else{ EM__(cptr2 = strdup(msgs_config_str)); cptr3 = sscanword(msgs_config_str, cptr2); for(cptr = cptr2; *cptr; cptr++){ switch(*cptr){ case 'b': case 'B': output_server_msgs |= (mode == MODE_FULL_BACKUP || mode == MODE_INCR_BACKUP); break; case 'v': case 'V': output_server_msgs |= (mode == MODE_VERIFYBU); break; case 'r': case 'R': output_server_msgs |= (mode == MODE_RESTORE); break; case 'C': case 'c': output_server_msgs |= (mode == MODE_COPY_TAPE); break; default: errmsg(T_("Warning: unknown character %c in server message configuration.\n")); } } n--; if(n > num_backuphosts) n = num_backuphosts; for(i = 0; i < num_backuphosts; i++){ if(i >= n){ p = backupports[i]; } else{ cptr3 = sscanword(cptr3, cptr2); cptr = cptr2; p = get_tcp_portnum(cptr); if(p < 0){ errmsg(T_("Error: Cannot resolve TCP service name `%s'.\n"), cptr2); exit(1); } } msgports[i] = p; } } } EM__(cartsets = ZRENEWP(cartsets, Int32, num_backuphosts * sizeof(Int32))); if(num_cartsets > num_backuphosts) /* sets: no more than hosts */ num_cartsets = num_backuphosts; i = 0; if( (cptr = cartsetlist) ){ /* evaluate list */ while(sscanf(cptr, "%d%n", &p, &pos) > 0 && i < num_backuphosts){ cartsets[i++] = p; cptr += pos; while(!isdigit(*cptr) && *cptr) /* skip to next number */ cptr++; } } if(i > num_cartsets) /* max of given is new # sets */ num_cartsets = i; if(num_cartsets < num_backuphosts){ while(num_cartsets < num_backuphosts) cartsets[num_cartsets++] = 1; /* set default values */ } if(!rootdir) EM__(rootdir = strdup(FN_DIRSEPSTR)); if(!indexfilepart) EM__(indexfilepart = strapp(logdir, FN_DIRSEPSTR "backup_log.")); if(numparts <= 0) numparts = 1; if(numindexestostore >= 0 && daystostoreindexes >= 0.0) errmsg(T_("Warning: Both DaysToStoreIndexes and NumIndexesToStore configured. Ignoring the shorter duration.\n")); if(numindexestostore < 0) numindexestostore = 0; if(!compresscmd || !uncompresscmd) uncompresscmd = compresscmd = ""; if(!compresscmd[0] || !uncompresscmd[0]) uncompresscmd = compresscmd = ""; EEM__(repl_dirs(&compresscmd) || repl_dirs(&uncompresscmd) || repl_dirs(&idxcompresscmd) || repl_dirs(&idxuncompresscmd)); /* check, if compress/uncompress commands are executable */ cptr = check_commands_executable(YES, compresscmd, uncompresscmd, idxcompresscmd, idxuncompresscmd, NULL); if(cptr){ errmsg(T_("Error: Cannot execute `%s'.\n"), cptr); exit(43); } /* set compression commands, as appropriate */ if(!builtin_compr_level){ if(!idxcompresscmd) idxcompresscmd = compresscmd; if(!idxuncompresscmd) idxuncompresscmd = uncompresscmd; } else{ /* Instead of hacking all the zlib stuff in here i construct * pipes through the __z program, that does the same as the * built-in zlib compression. This is much easier to implement, * much less error prone and affects performance only little,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -