📄 unpack.c
字号:
/****************** Start of $RCSfile: unpack.c,v $ ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/unpack.c,v $* $Id: unpack.c,v 1.5 2005/01/24 18:58:10 alb Exp alb $* $Date: 2005/01/24 18:58:10 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h> static char * fileversion = "$RCSfile: unpack.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/unpack.c,v $ $Id: unpack.c,v 1.5 2005/01/24 18:58:10 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#include <dirent.h>#include <fcntl.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <signal.h>#include <utime.h>#include <unistd.h>#include <genutils.h>#include <fileutil.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>#define write_file(fd, cp, n, z, e, f) write_file_unzip(z, cp, n, e, f)#else /* defined(USE_ZLIB) */#define write_file(fd, cp, n, z, e, f) (*f)(fd, cp, n)#endif /* defined(USE_ZLIB) */#define CLEANUPR(x) { r = x; goto cleanup; }typedef struct __solaris2_acl__ { int acltype; int nacls; void *acls;} Solaris2ACL;typedef Solaris2ACL HPUX10ACL; /* quite the same for us */typedef struct __posix_acl__ { int acltype; int acl_types; void *acl_arr[3];} POSIXACL;typedef struct __unknown_acl__ { int acltype;} UnknownACL;#define ZFREE_ACL_STRUCT(acls, params) { if(acls){ \ free_acl_struct(acls, params); acls = NULL; }}static voidfree_acl_struct(void * acls, AarParams * params){ if(!acls) return; switch(((UnknownACL *) acls)->acltype){ case SOLARIS2_ACL: ZFREE(((Solaris2ACL *) acls)->acls); break; case HPUX10_ACL: ZFREE(((HPUX10ACL *) acls)->acls); break; case POSIX_ACL:#ifdef USE_POSIX_ACLS { Int32 i, acl_types; acl_t acl; acl_types = ((POSIXACL *) acls)->acl_types; for(i = 0; i < 3; i++){ if(acl_types & (1 << i)){ if( (acl = ((POSIXACL *) acls)->acl_arr[i]) ){ acl_free(acl); ((POSIXACL *) acls)->acl_arr[i] = (acl_t) 0; } } } }#endif break; default: fprintf(params->errfp, "Warning: Unkknown ACL type %d, possible memory" " leak - should never happen.\n", ((UnknownACL *) acls)->acltype); return; } free(acls);}static Int32get_int(AarParams * params, Int32 * rptr){ Int32 i, s; UChar c, n; Int32 r; n = 0; r = 0; s = 1; forever{ i = params->inputfunc(&c, 1, params); if(i == 0) return(-1); if(c == ';') break; if(c == '-'){ if(n || s == -1) return(0); s = -1; } else if(isspace(c)){ continue; } else if(c <= '9' && c >= '0'){ r = (r << 3) + (r << 1) + (c - '0'); n = 1; } else return(0); } if(!n) return(0); *rptr = r * s; return(1);} static Int32get_uns(AarParams * params, Uns32 * rptr){ Int32 i; UChar c, n; Uns32 r; n = 0; r = 0; forever{ i = params->inputfunc(&c, 1, params); if(i == 0) return(-1); if(c == ';') break; if(isspace(c)){ continue; } else if(c <= '9' && c >= '0'){ r = (r << 3) + (r << 1) + (c - '0'); n = 1; } else return(0); } if(!n) return(0); *rptr = r; return(1);}static Int32get_time_t(AarParams * params, time_t * rptr){ Int32 i, s; UChar c, n; time_t r; n = 0; r = (time_t) 0; s = 1; /* time_t can be fucking negative */ forever{ i = params->inputfunc(&c, 1, params); if(i == 0) return(-1); if(c == ';') break; if(c == '-'){ if(n || s == -1) return(0); s = -1; } else if(isspace(c)){ continue; } else if(c <= '9' && c >= '0'){ r = (r << 3) + (r << 1) + (c - '0'); n = 1; } else return(0); } if(!n) return(0); *rptr = r * s; return(1);} static Int32get_size_t(AarParams * params, size_t * rptr){ Int32 i; UChar c, n; size_t r; n = 0; r = (size_t) 0; forever{ i = params->inputfunc(&c, 1, params); if(i == 0) return(-1); if(c == ';') break; if(isspace(c)){ continue; } else if(c <= '9' && c >= '0'){ r = (r << 3) + (r << 1) + (c - '0'); n = 1; } else return(0); } if(!n) return(0); *rptr = r; return(1);} static Int32get_off_t(AarParams * params, off_t * rptr){ Int32 i; UChar c, n; off_t r; n = 0; r = (off_t) 0; forever{ i = params->inputfunc(&c, 1, params); if(i == 0) return(-1); if(c == ';') break; if(isspace(c)){ continue; } else if(c <= '9' && c >= '0'){ r = (r << 3) + (r << 1) + (c - '0'); n = 1; } else return(0); } if(!n) return(0); *rptr = r; return(1);} static Int32name_in_list( UChar *name, UChar **list, Int32 len, UChar subdir, UChar *found){ UChar **listptr; if(!list) return(1); if(len < 0) for(len = 0, listptr = list; *listptr; listptr++, len++); if(!subdir){ listptr = (UChar **) b_search(&name, list, len, sizeof(UChar *), cmp_UCharPTR); if(listptr){ found[listptr - list] = 1; return(1); } return(0); } if(subdir) for(; *list; list++, found++){ len = strlen(*list); if(!strcmp(*list, name) || (!strncmp(*list, name, len) && (name[len] == FN_DIRSEPCHR || name[len - 1] == FN_DIRSEPCHR))){ *found = 1; return(1); } } return(0);}static Int32formaterr(Int32 * type, AarParams * params, Flag started){ Int32 i; Int32 li; if(!(!started && params->skip_garbage)){ fprintf(params->errfp, T_("Error: format error in input, trying to skip to the next file ...\n")); params->vars.errnum |= EUNPACKFORMAT; } forever{ if(params->pre_verbosefunc) (*params->pre_verbosefunc)(NULL, params); i = get_int(params, &li); if(i < 0) return(-1); /* -1 */ if(i == 1){ *type = (Int32) li; return(1); } }}#define read_int(val, typ) { rvr = get_int(params, &li); \ if(rvr < 1){ \ i = formaterr(&type, params, started); \ have_an_error = YES; \ goto tryagain; \ } \ val = (typ) li; }#define read_uns(val, typ) { rvr = get_uns(params, &lu); \ if(rvr < 1){ \ i = formaterr(&type, params, started); \ have_an_error = YES; \ goto tryagain; \ } \ val = (typ) lu; }#define read_time_t(val, typ) { rvr = get_time_t(params, <t); \ if(rvr < 1){ \ i = formaterr(&type, params, started); \ have_an_error = YES; \ goto tryagain; \ } \ val = (typ) ltt; }#define read_size_t(val, typ) { rvr = get_size_t(params, &stt); \ if(rvr < 1){ \ i = formaterr(&type, params, started); \ have_an_error = YES; \ goto tryagain; \ } \ val = (typ) stt; }#define read_off_t(val, typ) { rvr = get_off_t(params, &ott); \ if(rvr < 1){ \ i = formaterr(&type, params, started); \ have_an_error = YES; \ goto tryagain; \ } \ val = (typ) ott; }#define POSZ(x) { if(x < 0) x = 0; }#define DP "--> " /* the DIFFERENCES_PREFIX */static Flaginvalid_time_or_uid(time_t mtime, int uid, AarParams * params){ return((params->uid && params->uid != uid) || (params->time_older && params->time_older <= mtime) || (params->time_newer && params->time_newer > mtime));}static Flagnot_allowed(UChar * name, AarParams * params){ UChar lname[MAXPATHLEN * 2 + 2], *cptr; uid_t uid; Flag r; /* uninitialized ok */ struct stat statb; if(!(uid = params->uid)) CLEANUPR(NO); if(!name[0]) CLEANUPR(YES); strcpy(lname, name); cleanpath(lname); forever{ if(!stat(lname, &statb)) /* fs-entry exists, can read it */ CLEANUPR(statb.st_uid != uid ? YES : NO); cptr = FN_LASTDIRDELIM(lname); /* get last / */ if(cptr) *cptr = '\0'; if(!lname[0]) CLEANUPR(YES); /* was absolute path, at root now */ if(!cptr){ /* name remaining in current dir */ if(stat(FN_CURDIR, &statb)) CLEANUPR(YES); CLEANUPR(statb.st_uid != uid ? YES : NO); } } cleanup: if(r){ fprintf(params->errfp, T_("Error: No write permission for `%s'.\n"), name); params->vars.errnum |= EUNPACKACCESS; } return(r);}Int32pack_contents(AarParams * params){ UChar buf[BUFFERSIZ], buf2[BUFFERSIZ]; UChar verbosestr[MAXPATHLEN * 2 + 100], c, *cptr; Flag have_an_error, started, var_compr, fmterr; Flag compressed, builtin_uncompress; Uns8 verbose; Int32 type, i, j, k, n, uid, gid, ifd, rvr; Uns32 mode, lu; time_t mtime, ltt; size_t len, stt; off_t filelen, ott; FILE *errfp; Int32 li; int pid, pst, pp[2], ucfd; dev_t rdev; void *to_be_freed = NULL; void (*verbosefunc)(UChar *, struct aar_params *); Int32 (*writefunc)(int, UChar *, Int32); Flag cks, biu_error; Uns32 crc32sum; /* uninitialized OK */ errfp = params->errfp; verbose = params->verbose; verbosefunc = params->verbosefunc; if(!verbosefunc) verbosefunc = pack_default_verbose; ifd = params->infd; writefunc = params->writefunc; started = have_an_error = NO; forever{ pid = -1; if(params->pre_verbosefunc) (*params->pre_verbosefunc)(NULL, params); i = get_int(params, &li); type = (Int32) li; tryagain: if(i < 1){ if(i < 0) return(EOF); i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } type = (ABS(type) & PACK_TYPEMASK) * SIGN(type); cks = NO; switch(type){ case ENDOFARCHIVE: if(have_an_error){ i = formaterr(&type, params, started); goto tryagain; } return(0); case INFORMATION: read_size_t(len, size_t); if(len + 1 > BUFFERSIZ) cptr = to_be_freed = NEWP(UChar, len + 1); else cptr = buf; i = params->inputfunc(cptr, len, params); if(i < len){ ZFREE(to_be_freed); goto eoferr; } i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ ZFREE(to_be_freed); i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } cptr[len] = '\0'; verbosefunc(cptr, params); ZFREE(to_be_freed); started = YES; have_an_error = NO; break; case DIRECTORY: read_uns(mode, Uns32); read_time_t(mtime, time_t); read_int(uid, Int32); read_int(gid, Int32); read_size_t(len, size_t); i = params->inputfunc(buf, len, params); if(i < len) goto eoferr; buf[len] = '\0'; i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } mk_esc_seq(buf, ESCAPE_CHARACTER, verbosestr); if(verbose) strcat(verbosestr, "/"); strcat(verbosestr, "\n"); params->vars.uid = uid; params->vars.mtime = mtime; verbosefunc(verbosestr, params); started = YES; have_an_error = NO; break; case FIFO: case SOCKET: read_uns(mode, Uns32); read_time_t(mtime, time_t); read_int(uid, Int32); read_int(gid, Int32); read_size_t(len, size_t); i = params->inputfunc(buf, len, params); if(i < 1) goto eoferr; buf[len] = '\0'; mk_esc_seq(buf, ESCAPE_CHARACTER, verbosestr); if(verbose) strcat(verbosestr, (type == FIFO ? "|" : "[")); strcat(verbosestr, "\n"); params->vars.uid = uid; params->vars.mtime = mtime; verbosefunc(verbosestr, params); i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } started = YES; have_an_error = NO; break; case BLOCKDEVICE: case CHARDEVICE: read_uns(mode, Uns32); read_time_t(mtime, time_t); read_int(uid, Int32); read_int(gid, Int32); read_uns(rdev, dev_t); read_size_t(len, size_t); i = params->inputfunc(buf, len, params); if(i < 1) goto eoferr; buf[len] = '\0'; mk_esc_seq(buf, ESCAPE_CHARACTER, verbosestr); if(verbose) strcat(verbosestr, (type == BLOCKDEVICE ? "#" : "*")); strcat(verbosestr, "\n"); params->vars.uid = uid; params->vars.mtime = mtime; verbosefunc(verbosestr, params); i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } started = YES; have_an_error = NO;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -