📄 unpack.c
字号:
case COMMANDINOUT: read_int(i, int); j = params->inputfunc(buf2, i, params); if(j < i){ params->vars.errnum |= EUNPACKREAD; i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } buf2[i] = '\0'; i = params->inputfunc(&c, 1, params); if(i < 1 || c != ';'){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } do{ UChar nbuf[8196]; i = params->inputfunc(buf, 2, params); if(i < 2){ params->vars.errnum |= EUNPACKREAD; i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } xref_to_UnsN(&j, buf, 16); if(j > 8192){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } i = params->inputfunc(nbuf, j, params); if(i < j){ params->vars.errnum |= EUNPACKREAD; i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; }#ifdef USE_ZLIB if(params->check && cks) crc32sum = crc32(crc32sum, nbuf, i);#endif } while(j == 8192); j = (cks ? 4 : 0); i = params->inputfunc(buf, 1 + j, params); if(buf[j] != '.' || i < 1 + j){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; }#ifdef USE_ZLIB if(cks && params->check){ xref_to_Uns32(&lu, buf); if(lu != crc32sum){ fprintf(stderr, T_("Integrity check: Wrong CRC32 checksum.\n")); params->vars.errnum |= EUNPACKUNCOMPR; } }#endif strcpy(verbosestr, buf2); strcat(verbosestr, "\n"); verbosefunc(verbosestr, params); started = YES; have_an_error = NO; break; default: i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } } return(0); eoferr: fprintf(errfp, T_("Error: unexpected end of file.\n")); params->vars.errnum |= EUNPACKREAD; return(EOF);}static Int32check_dir_writable(UChar * name, AarParams * params){ uid_t ceuid; gid_t cegid, *cegids; int negids; Int32 i; if(!params->uid && !params->gid && !params->ngids) /* superuser */ return(0); cegids = NULL; negids = 0; ceuid = geteuid(); cegid = getegid(); if(get_groups(&negids, &cegids)){ params->vars.errnum |= EGENFAULT; return(-1); } i = set_eff_ugids(params->uid, params->gid, params->ngids, params->gids); if(!i) i = access(name, W_OK); set_eff_ugids(ceuid, cegid, negids, cegids); /* reset effective IDs */ ZFREE(cegids); if(i){ params->vars.errnum |= EUNPACKACCESS; return(-1); } return(0);}static Int32make_check_basedir(UChar * name, Uns32 mode, Int32 uid, Int32 gid, AarParams * params){ UChar *cptr; struct stat statb; Int32 res, i, statres; FILE *errfp; errfp = params->errfp; res = 0; if(FN_ISROOTDIR(name)){ if(params->check) return(check_dir_writable(name, params)); return(0); } cptr = FN_LASTDIRDELIM(name); if(cptr){ *cptr = '\0'; if( (statres = stat(name, &statb)) ){ statres = lstat(name, &statb); } if(!statres){ if(IS_DIRECTORY(statb)){ if(params->check){ i = check_dir_writable(name, params); if(i) return(i); } } else{ if(params->unlink){ unlink(name); } else{ if(IS_SYMLINK(statb)){ char linkb[BUFFERSIZ + 1]; i = readlink(name, linkb, BUFFERSIZ); if(i >= 0) linkb[i] = '\0'; fprintf(errfp, T_("Warning: removing symlink `%s' pointing to unaccessible destination `%s'.\n"), name, i >= 0 ? linkb : T_("<symlink-unreadable>")); unlink(name); } } } } if(lstat(name, &statb) < 0){ if( (res = make_check_basedir(name, mode, uid, gid, params)) ){ *cptr = FN_DIRSEPCHR; return(-errno); } res = mkdir(name, mode); if(res){ fprintf(errfp, T_("Error: cannot create directory `%s'.\n"), name); *cptr = FN_DIRSEPCHR; params->vars.errnum |= EUNPACKMKDIR; return(-errno); } if(!params->ignoreown){ res = chown(name, uid, gid); if(res){ fprintf(errfp, T_("Error: cannot chown of directory `%s'.\n"), name); *cptr = FN_DIRSEPCHR; params->vars.errnum |= EUNPACKMKDIR; return(-errno); } } } *cptr = FN_DIRSEPCHR; return(res); } if(params->check) return(check_dir_writable(FN_CURDIR, params)); return(0);}voidset_props(UChar * buf, Int32 uid, Int32 gid, time_t mtime, Uns32 mode, void * acls, AarParams * params){ struct utimbuf utim; Int32 r; if(!params->ignoreown){ if(chown(buf, uid, gid)){ fprintf(params->errfp, T_("Warning: cannot chown %s\n"), buf); } } /*else*/{ SETZERO(utim); /* on some architectures utim is more complex */ utim.actime = utim.modtime = mtime; if(utime(buf, &utim)){ fprintf(params->errfp, T_("Warning: cannot set modificaton time on %s.\n"), buf); params->vars.errnum |= EUNPACKSETPROPS; } /*else*/{ if(chmod(buf, mode)){ fprintf(params->errfp, T_("Warning: cannot set permissions on %s.\n"), buf); params->vars.errnum |= EUNPACKSETPROPS; } /*else*/ if(acls){ switch(((UnknownACL *) acls)->acltype){ case SOLARIS2_ACL:#ifdef USE_SOLARIS2_ACLS if(acl(buf, SETACL, ((Solaris2ACL *) acls)->nacls, (aclent_t *)(((Solaris2ACL *) acls)->acls)) < 0)#endif { fprintf(params->errfp, T_("Warning: cannot set Solaris2 ACLs on %s.\n"), buf); params->vars.errnum |= EUNPACKACLS; } break; case HPUX10_ACL:#ifdef USE_HPUX10_ACLS if(setacl(buf, ((HPUX10ACL *) acls)->nacls, (struct acl_entry *)(((HPUX10ACL *) acls)->acls)) < 0)#endif { fprintf(params->errfp, T_("Warning: cannot set HPUX10 ACLs on %s.\n"), buf); params->vars.errnum |= EUNPACKACLS; } break; case POSIX_ACL:#ifdef USE_POSIX_ACLS { Int32 i, acl_types; for(i = r = 0; i < 3; i++){ acl_types = ((POSIXACL *) acls)->acl_types; if(acl_types & (1 << i)){ r = acl_set_file(buf, packer_posix_acl_types(i), (acl_t) ((POSIXACL *) acls)->acl_arr[i]); if(r) break; } } } if(r)#endif { fprintf(params->errfp, T_("Warning: cannot set POSIX ACLs on %s.\n"), buf); params->vars.errnum |= EUNPACKACLS; } break; default: fprintf(params->errfp, T_("Warning: Unkknown ACL type %d.\n"), ((UnknownACL *) acls)->acltype); params->vars.errnum |= EUNPACKACLS; } } } }}static voidconvtorel(UChar * buf, Int32 rel){ cleanpath(buf); if(rel) mkrelpath(buf);}/* prepend absolute path with as many ../ as needed to get to the * root directory */static voidconvtorelcwd(UChar * buf, UChar * thecwd, Int32 rel){ Int32 i, n, len; UChar *cptr, *cptr2; convtorel(buf, 0); if(!FN_ISABSPATH(buf) || !rel) return; n = 0; cptr = thecwd; while( (cptr = FN_FIRSTDIRSEP(cptr)) ){ cptr++; n++; while(FN_ISDIRSEP(*cptr)) cptr++; if(cptr[0] == '.'){ if(FN_ISDIRSEP(cptr[1])){ n--; } else if(cptr[1] == '.'){ if(FN_ISDIRSEP(cptr[2])){ n -= 2; } } } } len = strlen(buf); cptr = buf + len; cptr2 = cptr + n * 3 - 1; for(i = 0; i < len; i++) *(cptr2--) = *(cptr--); for(i = 0; i < n; i++){ buf[i * 3] = buf[i * 3 + 1] = '.'; buf[i * 3 + 2] = FN_DIRSEPCHR; }}Int32pack_readin(UChar ** filelist, AarParams * params, UChar * files_found){ UChar buf[BUFFERSIZ], buf2[BUFFERSIZ]; UChar verbosestr[MAXPATHLEN * 4 + 100], c; Flag started, have_an_error, var_compr, fmterr, try_cont; Flag builtin_uncompress, compressed, skip, fault; Uns8 verbose; Int32 type, i, j, k, n, gid, uid, fd, r, rvr, ifd; Uns32 mode, lu; time_t mtime = 0, ltt; size_t len, stt; off_t filelen, ott; FILE *errfp; UChar **files, *cptr, **fileidx; Int32 li, n_files; dev_t rdev; int pfd, pid, pst, pp[2]; int num_written = 0; void (*verbosefunc)(UChar *, struct aar_params *); Int32 (*writefunc)(int, UChar *, Int32); struct stat statb; void *to_be_freed = NULL; void *acls = NULL; Flag cks; Uns32 crc32sum; /* uninitialized OK */ verbose = params->verbose; verbosefunc = params->verbosefunc; writefunc = params->writefunc; files = filelist; i = r = n_files = 0; ifd = params->infd; if(files){ while(*files){ cleanpath(*files); repl_esc_seq(*files, ESCAPE_CHARACTER); files++, i++; } files = NEWP(UChar *, i + 1); if(!files) return(-ENOMEM); memset(files, 0, (i + 1) * sizeof(UChar *)); n_files = i; while(i > 0){ i--; if(params->relative && FN_ISABSPATH(filelist[i])){ cptr = filelist[i]; cptr = FN_FIRSTDIRSEP(cptr); while(FN_ISDIRSEP(*cptr)) cptr++; files[i] = strdup(cptr); } else files[i] = strdup(filelist[i]); if(!files[i]){ for(i++; i < n_files; i++) free(files[i]); free(files); return(-ENOMEM); } } q_sort(files, n_files, sizeof(UChar *), cmp_UCharPTR); } errfp = params->errfp; started = have_an_error = NO; forever{ pid = -1; if(filelist && !params->recursive){ for(fileidx = filelist, cptr = files_found; *fileidx; fileidx++, cptr++){ if(! (*cptr)) break; } if(! (*fileidx)) goto cleanup; } if(params->pre_verbosefunc) (*params->pre_verbosefunc)(NULL, params); i = get_int(params, &li); type = (Int32) li; tryagain: ZFREE_ACL_STRUCT(acls, params); if(i < 1){ if(i < 0){ r = EOF; goto cleanup; } i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } skip = NO; type = (ABS(type) & PACK_TYPEMASK) * SIGN(type); if(type == SOLARIS2_ACL){ Int32 t, id, p; read_int(j, Int32); acls = NEWP(Solaris2ACL, 1); if(!acls){ r = -ENOMEM; goto cleanup; }#ifdef USE_SOLARIS2_ACLS ((Solaris2ACL *) acls)->nacls = j; ((Solaris2ACL *) acls)->acls = NEWP(aclent_t, j);#else ((Solaris2ACL *) acls)->nacls = 0; ((Solaris2ACL *) acls)->acls = NULL;#endif ((Solaris2ACL *) acls)->acltype = SOLARIS2_ACL; for(i = 0; i < j; i++){ read_int(t, Int32); read_int(id, Int32); read_int(p, Int32);#ifdef USE_SOLARIS2_ACLS ((aclent_t *)(((Solaris2ACL *) acls)->acls))[i].a_type = t; ((aclent_t *)(((Solaris2ACL *) acls)->acls))[i].a_id = id; ((aclent_t *)(((Solaris2ACL *) acls)->acls))[i].a_perm = p;#endif } i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } i = get_int(params, &li); type = (Int32) li; started = YES; have_an_error = NO; } else if(type == HPUX10_ACL){ Int32 u, g, m; read_int(j, Int32); acls = NEWP(HPUX10ACL, 1); if(!acls){ r = -ENOMEM; goto cleanup; }#ifdef USE_HPUX10_ACLS ((HPUX10ACL *) acls)->nacls = j; ((HPUX10ACL *) acls)->acls = NEWP(struct acl_entry, j);#else ((HPUX10ACL *) acls)->nacls = 0; ((HPUX10ACL *) acls)->acls = NULL;#endif ((HPUX10ACL *) acls)->acltype = HPUX10_ACL; for(i = 0; i < j; i++){ read_int(u, Int32); read_int(g, Int32); read_int(m, Int32);#ifdef USE_HPUX10_ACLS ((struct acl_entry *)(((HPUX10ACL *) acls)->acls))[i].uid = u; ((struct acl_entry *)(((HPUX10ACL *) acls)->acls))[i].gid = g; ((struct acl_entry *)(((HPUX10ACL *) acls)->acls))[i].mode = m;#endif } i = params->inputfunc(&c, 1, params); if(c != '.' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } i = get_int(params, &li); type = (Int32) li; started = YES; have_an_error = NO; } else if(type == POSIX_ACL){ UChar *aclstrbuf = NULL; Int32 aclstrall = 0, acl_types; read_int(j, Int32); acls = NEWP(POSIXACL, 1); if(!acls){ r = -ENOMEM; goto cleanup; } ((POSIXACL *) acls)->acltype = POSIX_ACL; ((POSIXACL *) acls)->acl_types = acl_types = j; for(i = 0; i < 3; i++){ if(acl_types & (1 << i)){ read_int(k, Int32); k++; if(k > BUFFERSIZ){ if(k > aclstrall) aclstrbuf = ZRENEWP(aclstrbuf, UChar, aclstrall = k); if(!aclstrbuf){ r = -ENOMEM; goto cleanup; } } else aclstrbuf = buf; k--; j = params->inputfunc(aclstrbuf, k, params); if(j < k){ i = formaterr(&type, params, started); have_an_error = YES; if(aclstrall > 0) free(aclstrbuf); goto tryagain; }#ifdef USE_POSIX_ACLS aclstrbuf[k] = '\0'; if(!(((POSIXACL *) acls)->acl_arr[i] = acl_from_text(aclstrbuf))){ i = formaterr(&type, params, started); have_an_error = YES; if(aclstrall > 0) free(aclstrbuf); goto tryagain; }#else ((POSIXACL *) acls)->acl_arr[i] = NULL;#endif j = params->inputfunc(aclstrbuf, 1, params); if(j < 1 || aclstrbuf[0] != ';'){ i = formaterr(&type, params, started); have_an_error = YES; if(aclstrall > 0) free(aclstrbuf); goto tryagain; } } } if(aclstrall > 0) free(aclstrbuf); j = params->inputfunc(buf, 1, params); if(j < 1 || buf[0] != '.'){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } i = get_int(params, &li); type = (Int32) li; started = YES; have_an_error = NO; } cks = NO; switch(type){ case ENDOFARCHIVE:#if 0 if(filelist){ for(fileidx = filelist, cptr = files_found; *fileidx; fileidx++, cptr++){ if(! (*cptr)){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -