📄 full_backup.c
字号:
default: break; } } do_exit(2);}static voidfailed_exit(Int32 s){ exitcleanup(); if(logfile){ if(mode == MODE_FULL_BACKUP){ if(numparts > 1) errmsg(T_("Full backup part %d failed.\n"), part); else errmsg(T_("Full backup failed.\n")); } if(mode == MODE_INCR_BACKUP){ errmsg(T_("Incremental backup failed.\n")); } } do_exit(s);}/* * Obtain a mutex. Returns a value indicating a sucessful lock or otherwise */Int32set_lock(){ struct stat statb; char buf[20]; Int32 i; if(locked == BU_GOT_LOCK) return((Int32) locked); if(!lockfile) return((Int32) BU_CANT_LOCK); i = lstat(lockfile, &statb); if(!i && !IS_REGFILE(statb)){ if(unlink(lockfile)){ errmsg(T_("Error: Cannot remove lock file entry `%s', that is not a file.\n"), lockfile); return( (Int32) (locked = BU_CANT_LOCK) ); } i = 1; } if(!i){ lockfd = open(lockfile, O_WRONLY | O_SYNC); if(lockfd < 0){ errmsg(T_("Warning: Lock file `%s' exists, but can't open it.\n"), lockfile); return( (Int32) (locked = BU_CANT_LOCK) ); } /* Note: could be, the file exists, belongs to a wrong user, is writable * and there is yet no lock on it. In this case some kind of attack is * possible. Such an attack might lead to concurrent access to var * files maintained by this program, possibly scrambling them up or * destroying them. The administrator should avoid this configuring a * lock file, that is in a safe place i.e. within the mentioned var * directory, that must not be writable by normal users. */ } else{ lockfd = open(lockfile, O_WRONLY | O_CREAT | O_SYNC | O_EXCL, 0644); if(lockfd < 0){ errmsg(T_("Error: Cannot create lock file `%s'.\n"), lockfile); return( (Int32) (locked = BU_CANT_LOCK) ); } } lockb.l_type = F_WRLCK; if(fcntl(lockfd, F_SETLK, &lockb)){ return( (Int32) (locked = BU_LOCKED) ); /* GDR: this ignores other ways in which fcntl can fail */ /* No problem here. fcntl should not fail in any way */ } sprintf(buf, "%d\n", (int) getpid()); write(lockfd, buf, strlen(buf) + 1); return( (Int32) (locked = BU_GOT_LOCK) );}/* * reads the first characters of a file. If they contain a textual * representation of a positive integer, place that integer into num * and return zero. Otherwise, initialize num to zero and returns * nonzero. */static Int32read_pint_file(UChar * filename, int * num){ FILE *fp; *num = 0; fp = fopen(filename, "r"); if(fp){ if(fscanf(fp, "%d", num) <= 0) *num = 0; fclose(fp); } return(*num <= 0);}static Int32write_uns_file(UChar * filename, int num){ FILE *fp; Int32 ret = 0; fp = fopen(filename, "w"); if(fp){ if(fprintf(fp, "%d\n", num) <= 0) ret = 1; fclose(fp); } else ret = 1; return(ret);}static Int32handle_client_output(ScanDirArgs * arg, Flag * got_output){ Int32 i, n; UChar *cptr; if(got_output) *got_output = NO; while((i = read(arg->cfromfd, arg->read_data, arg->read_data_nall)) > 0){ n = write_forced(arg->fd, arg->read_data, i); if(n < i) return(-1); if(got_output) *got_output = YES; } forever{ if(arg->num_read_err + 1024 > arg->read_err_nall){ arg->read_err = RENEWP(arg->read_err, UChar, arg->read_err_nall + 1024); EM__(arg->read_err); arg->read_err_nall += 1024; } i = read(arg->cerrfd, arg->read_err + arg->num_read_err, 1023); if(i > 0){ arg->num_read_err += i; if(got_output) *got_output = YES; } else break; arg->read_err[arg->num_read_err] = '\0'; while( (cptr = strchr(arg->read_err, '\n')) ){ *(cptr++) = '\0'; for(i = 2; cptr - i >= arg->read_err && *(cptr - i) == '.'; i++) *(cptr - i) = '\0'; errmsg("%s\n", arg->read_err); n = (arg->read_err + arg->num_read_err) - cptr; memmove(arg->read_err, cptr, n * sizeof(UChar)); arg->num_read_err = n; } } return(0);}static Int32write_filename(UChar * name, void * data, struct stat * statbp){ int maxfd; UChar *cptr = NULL; Int32 ret = 0, needed_size, n, i, j, nfd; Flag allocated = NO, got_output; ScanDirArgs *scandirargs; fd_set ifds, ofds; scandirargs = (ScanDirArgs *) data; if(name){ needed_size = strlen(name) * 4 + 5; if(needed_size > TMPBUFSIZ){ cptr = NEWP(UChar, needed_size); if(!cptr){ ret = errno; CLEANUP; } allocated = YES; } else{ cptr = tmpbuf; } mk_esc_seq(name, ESCAPE_CHARACTER, cptr); strcat(cptr, "\n"); name = cptr; n = strlen(name); } else{ n = 1; } maxfd = MAX(MAX(scandirargs->ctofd, scandirargs->cfromfd), scandirargs->cerrfd); for(i = 0; i < n;){ if(interrupted && name) break; FD_ZERO(&ifds); FD_ZERO(&ofds); FD_SET(scandirargs->ctofd, &ofds); FD_SET(scandirargs->cfromfd, &ifds); FD_SET(scandirargs->cerrfd, &ifds); got_output = NO; nfd = select(maxfd + 1, &ifds, name ? (&ofds) : NULL, NULL, NULL); if(nfd > 0){ if(name){ if(FD_ISSET(scandirargs->ctofd, &ofds)){ j = write(scandirargs->ctofd, name + i, n - i); if(j > 0) i += j; } } if(FD_ISSET(scandirargs->cfromfd, &ifds) || FD_ISSET(scandirargs->cerrfd, &ifds)){ j = handle_client_output(scandirargs, &got_output); if(j){ ret = j; CLEANUP; } } } if(!name && (nfd < 1 || !got_output)) break; }#if 0 if(i < n){ errmsg(T_("Error: Could not send filename to afclient process.\n")); scandirargs->write_failed = YES; ret = errno; }#endif if(name) scandirargs->entry_found = YES; cleanup: if(cptr && allocated) free(cptr); if(interrupted) return(1000); return(ret);}static Int32err_write_filename(UChar * name, void * data){ int fd; ScanDirArgs *scandirargs; scandirargs = (ScanDirArgs *) data; fd = scandirargs->fd; scandirargs->fd = 1; /* don't: write_filename(name, data));*/ scandirargs->fd = fd; return(0);}/* returns: -1 empty -2 comment <= -10: not recognized >=0 fileposition*/static Int32eval_index_line( UChar *line, UChar **server, Int32 *port, Int32 *cart, Int32 *fileno, int *uid, time_t *mtime){ UChar *cptr, *orgline, *newmem, *colon = NULL, a; int p = 0, c = 0, f = 0, u = - MAXINT, servlen = 0, i, n; time_t m = UNSPECIFIED_TIME; if(empty_string(line)) return(-1); if(*(first_nospace(line)) == '#') return(-2); orgline = line; if( (colon = strchr(line, ':')) ) *colon = '\0'; cptr = strstr(line, PORTSEP); if(colon) *colon = ':'; if(cptr){ servlen = cptr - line; a = *cptr; *cptr = '\0'; i = isfqhn(line); *cptr = a; if(!i || sscanf(cptr + 1, "%d" LOCSEP, &p) <= 0) return(-10); line = strstr(line, LOCSEP) + 1; } i = sscanf(line, "%d.%d%n", &c, &f, &n); if(i < 2) return(-11); if(!strncmp(line + n, UIDSEP, strlen(UIDSEP))){ i = sscanf(line, "%d.%d" UIDSEP "%d%n", &c, &f, &u, &n); if(i < 3) return(-12); if(line[n] != ':' && strncmp(line + n, MTIMESEP, strlen(MTIMESEP))) return(-13); } else if(line[n] != ':') return(-14); if(!strncmp(line + n, MTIMESEP, i = strlen(MTIMESEP))) m = strint2time(line + n + i); if(servlen && server){ do{ newmem = NEWP(UChar, servlen + 1); if(!newmem) ms_sleep(200); }while(!newmem); strncpy(newmem, orgline, servlen); newmem[servlen] = '\0'; *server = newmem; } if(p && port) *port = p; if(u != - MAXINT && uid) *uid = u; if(c && cart) *cart = c; if(f && fileno) *fileno = f; if(m != UNSPECIFIED_TIME && mtime) *mtime = m; if(colon) return(first_nospace(colon + 1) - orgline); return(strlen(line));}Int32start_msg_proc( UChar *server, Int32 port){ UChar cmd[1024]; int fd, inp[2], pid; Int32 r = 0, i; if(!output_server_msgs) return(0); if(msgprocpid > 0 && ! kill(msgprocpid, 0)) return(0); if(!server) server = backuphosts[serveridx]; if(port == 0) port = backupports[serveridx]; if(port < 0){ for(i = 0; i < num_backuphosts; i++){ if(backupports[i] == - port && !strcmp(backuphosts[i], server)){ port = msgports[i]; break; } } if(port < 0){ port = - port; r = 1; } } if(pipe(inp)) return(-2); pid = fork_forced(); if(pid < 0){ close(inp[0]); close(inp[1]); return(-1); } if(pid == 0){ close(inp[1]); compose_clntcmd(cmd, "m", NULL, server, port, 0, cryptfile, 0, 0, 0, 0, 0, NULL); fd = open_to_pipe(cmd, NULL, 0, &pid, 0); if(fd < 0) exit(5); /* it is better to exec here because of easier handling of * file descriptors to be closed, so let's dare to rely on * the presence of /bin/sh for effectiveness */ dup2(inp[0], 0); sprintf(tmpbuf, "read a ; kill -9 %d ; exit 0", pid); execl("/bin/sh", "sh", "-c", tmpbuf, NULL); exit(6);#if 0 read(inp[0], cmd, 1); /* wait until parent dies or closes fd */ close(fd); close(inp[0]); kill(pid, SIGKILL); waitpid(pid, &pst, 0); exit(0);#endif } close(inp[0]); msgprocpid = pid; msgprocfd = inp[1]; return(r);}Int32stop_msg_proc(){ int pst; if(msgprocpid < 0) return(0); close(msgprocfd); waitpid(msgprocpid, &pst, 0); return(WEXITSTATUS(pst));}Int32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -