📄 pack.c
字号:
/****************** Start of $RCSfile: pack.c,v $ ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/pack.c,v $* $Id: pack.c,v 1.5 2005/01/15 08:59:32 alb Exp alb $* $Date: 2005/01/15 08:59:32 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h> static char * fileversion = "$RCSfile: pack.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/pack.c,v $ $Id: pack.c,v 1.5 2005/01/15 08:59:32 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <dirent.h>#include <fcntl.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_RESOURCE_H#include <sys/resource.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#include <utime.h>#ifdef HAVE_SYS_MOUNT_H#include <sys/mount.h>#endif#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <signal.h>#include <unistd.h>#include <genutils.h>#include <sysutils.h>#include <fileutil.h>#include <mvals.h>#include <packer.h>#if defined(USE_SOLARIS2_ACLS) || defined(USE_HPUX10_ACLS) || defined(USE_POSIX_ACLS)#include <sys/acl.h>#endif#ifdef USE_ZLIB#include <zutils.h>#endif#define CLEANUP { goto cleanup; }#define GETOUT { goto getout; }#define ER__(func, i) { if( (i = func) ) return(i); }static Int32 write_filecont(UChar *, struct stat *, AarParams *, Flag, int);struct hl_spec { ino_t ino; dev_t dev; UChar *name;};static struct hl_spec *hardlinks = NULL;static Int32 num_hardlinks = 0;#ifdef USE_ZLIB#define read_file(fd, cp, n, z, f) read_file_zip(z, cp, n, f)#else /* defined(USE_ZLIB) */#define read_file(fd, cp, n, z, f) (*f)(fd, cp, n)#endif /* defined(USE_ZLIB) */static Int32add_link(UChar * name, ino_t ino, dev_t dev){ struct hl_spec *newlinks; newlinks = (struct hl_spec *) realloc_forced(hardlinks, (num_hardlinks + 1) * sizeof(struct hl_spec)); if(! newlinks) return(-ENOMEM); hardlinks = newlinks; hardlinks[num_hardlinks].ino = ino; hardlinks[num_hardlinks].dev = dev; hardlinks[num_hardlinks].name = strdup(name); if(!hardlinks[num_hardlinks].name) return(-ENOMEM); num_hardlinks++; return(0);}static Int32link_in_list(ino_t ino, dev_t dev, UChar ** real_name){ Int32 i; for(i = 0; i < num_hardlinks; i++){ if(hardlinks[i].ino == ino && hardlinks[i].dev == dev){ *real_name = hardlinks[i].name; return(1); } } return(0);}static voidwrite_dummy_bytes( off_t num, AarParams *params){ Int32 i; UChar buf[BUFFERSIZ]; memset(buf, 0, BUFFERSIZ * sizeof(UChar)); do{ i = (Int32) (num < BUFFERSIZ ? num : BUFFERSIZ); params->outputfunc(buf, i, params); num -= i; } while(num > 0);}#ifdef S_ENFMT/* check for l-bit on platforms supporting that: * if l-bit set (== SetGID and no execute permission for group): * try to get lock. If that succeeds, backup file as normal * holding the lock. If lock cannot be obtained: error message */static intopen_check_rlock(char * filen, int flags){ struct stat statb; struct flock lockb; int i, fd; if((i = stat(filen, &statb)) < 0) return(i); fd = open(filen, flags); if(fd < 0) return(fd); if((statb.st_mode & S_ENFMT) && !(statb.st_mode & S_IXGRP)){ /* the pathological case */ SETZERO(lockb); lockb.l_type = F_RDLCK; i = fcntl(fd, F_SETLK, &lockb); if(i < 0){ close(fd); return((int) i); } /* lock is released on close, so we don't * have to care about that further */ } return(fd);}#define open_for_pack open_check_rlock#else#define open_for_pack open#endifstatic Int32open_for_compress( int *fd, UChar *name, UChar *zipcmd, int *pid, AarParams *params){ int i, pp[2], lpid; *pid = -1; *fd = -1;#ifdef USE_ZLIB SETZERO(params->vars.zfile); if(!zipcmd){ *fd = open_for_pack(name, O_RDONLY | O_BINARY); if(params->bi_compr_level){ i = open_file_zip(¶ms->vars.zfile, *fd, params->bi_compr_level, params->bi_compr_maxblock); if(i) return(i); } return(!(*fd >= 0)); }#endif i = pipe(pp); if(i){ return(1); } lpid = fork_forced(); if(lpid < 0){ close(pp[0]); close(pp[1]); return(2); } if(lpid){ /* parent */ close(pp[1]); *fd = pp[0]; *pid = lpid;#ifdef USE_ZLIB i = open_file_zip(¶ms->vars.zfile, *fd, params->bi_compr_level, params->bi_compr_maxblock); if(i) return(i);#endif return(0); } else{ /* child */ int ifd; char **zipargv; clr_timer(); close(pp[0]); if(cmd2argvq(&zipargv, zipcmd)){ close(pp[1]); exit(1); } ifd = open_for_pack(name, O_RDONLY | O_BINARY); if(ifd < 0){ exit(2); } dup2(ifd, 0); dup2(pp[1], 1); execvp(zipargv[0], zipargv + 1); close(pp[1]); exit(3); }}static Int32write_cmdio(UChar * cmd, AarParams * params, int tattrs){ Int32 r = NO_ERROR, i, n; FILE *errfp; int pfd, pid, pst, ftype; UChar buf[8196], *cmd1, *cmd2, c, *cptr; Int32 (*ofunc)(UChar *, Int32, AarParams *); Int32 (*readfunc)(int, UChar *, Int32); Flag cks; Uns32 crc32sum; /* uninitialized OK */ cks = NO; ftype = COMMANDINOUT;#ifdef USE_ZLIB cks = params->check; if(cks){ ftype = COMMANDINOUTCKS; crc32sum = crc32(0L, Z_NULL, 0); }#endif ftype |= tattrs; cmd1 = cmd + strlen(CMDINOUTPREFIX); cmd2 = strstr(cmd1, CMDINOUTSEP); c = *cmd2; *cmd2 = '\0'; errfp = params->errfp; readfunc = params->readfunc; strcpy(buf, cmd1); repl_esc_seq(buf, ESCAPE_CHARACTER); pid = -1; pfd = fdpopen(buf, O_RDONLY, &pid); if(pfd < 0){ fprintf(errfp, T_("Error: Cannot run command `%s' to read output.\n"), cmd1); params->vars.errnum |= EPACKREADCMD; return(-EINVAL); } *cmd2 = c; ofunc = params->outputfunc; if(params->pre_verbosefunc) (*params->pre_verbosefunc)(NULL, params); sprintf(buf, "%d;%d;%s;", ftype, (int) strlen(cmd), cmd); if( (r = ofunc(buf, strlen(buf), params)) ) CLEANUP; do{ for(n = 8192, cptr = buf + 2; n >= 0; cptr += i, n -= i){ i = readfunc(pfd, cptr, n); if(i < 1) break;#ifdef USE_ZLIB if(cks) crc32sum = crc32(crc32sum, cptr, i);#endif } n = 8192 - n; UnsN_to_xref(buf, n, 16); if( (r = ofunc(buf, n + 2, params)) ) CLEANUP; } while(n == 8192); if(cks) Uns32_to_xref(buf, crc32sum); buf[4] = '.'; i = (cks ? 0 : 4); if( (i = ofunc(buf + i, 1 + 4 - i, params)) ) if(!r) r = i; if(params->verbose && params->verbosefunc){ sprintf(buf, "%s\n", cmd); params->verbosefunc(buf, params); } cleanup: if(pfd >= 0){ close(pfd); if(pid > 0){ waitpid_forced(pid, &pst, 0); pst = WEXITSTATUS(pst); if(pst) r = - pst; } } return(r);}#define time_cond(statb, params) \ ((! params->time_newer || params->time_newer <= statb.st_mtime) \ && (! params->time_older || params->time_older > statb.st_mtime))#define uid_cond(statb, params) \ (! params->uid || (statb.st_uid == params->uid))static Int32write_file_uncompressed( UChar *name, struct stat *statb, AarParams *params, int type_attrs){ int fd, ftype; Int32 i; off_t rd_bytes; off_t bytes; UChar buf[BUFFERSIZ + 100], mtimestr[50], sizestr[50]; FILE *errfp; Int32 (*ofunc)(UChar *, Int32, AarParams *); Int32 (*readfunc)(int, UChar *, Int32); Flag cks; Uns32 crc32sum; /* uninitialized OK */ cks = NO; ftype = REGFILE;#ifdef USE_ZLIB cks = params->check; if(cks){ ftype = REGFILECKS; crc32sum = crc32(0L, Z_NULL, 0); }#endif ftype |= type_attrs; ofunc = params->outputfunc; errfp = params->errfp; readfunc = params->readfunc; fd = open_for_pack(name, O_RDONLY | O_BINARY); if(fd < 0){ fprintf(errfp, T_("Error: cannot open file `%s'.\n"), name); params->vars.errnum |= EPACKNOENT; return(-ENOENT); } sprintf(buf, "%d;%lu;%s;%d;%d;%d;%s;%d;%s;%s;", ftype, (unsigned long) statb->st_mode, (char *) time_t_to_intstr(statb->st_mtime, mtimestr), (int) statb->st_uid, (int) statb->st_gid, (int) strlen(name), name, 0, "", (char *) off_t_to_intstr(statb->st_size, sizestr)); if( (i = ofunc(buf, strlen(buf), params)) ){ close(fd); params->vars.errnum |= EPACKWRITE; return(i); } rd_bytes = 0; if(statb->st_size > 0){ do{ i = readfunc(fd, buf, BUFFERSIZ); if(i < 0) i = 0;#ifdef USE_ZLIB if(cks && i > 0) crc32sum = crc32(crc32sum, buf, i);#endif bytes = i; if(rd_bytes + bytes > statb->st_size){ fprintf(errfp, T_("Error: File `%s' changed size while reading, trailing bytes not saved.\n"), name); bytes = statb->st_size - rd_bytes; params->vars.errnum |= EPACKSIZECH; } rd_bytes += bytes; if( (i = ofunc(buf, bytes, params)) ){ close(fd); params->vars.errnum |= EPACKWRITE; return(i); } } while(rd_bytes < statb->st_size && bytes > 0); } close(fd); if(rd_bytes < statb->st_size){ fprintf(errfp, T_("Error: Unexpected fault reading `%s'.\n"), name); params->vars.errnum |= EPACKREAD; write_dummy_bytes(statb->st_size - rd_bytes, params); } else{ if(cks){ Uns32_to_xref(buf, crc32sum);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -