📄 unpack.c
字号:
i = params->inputfunc(buf2, len, params); if(i < len){ if(fd >= 0){ if(pid > 0){ kill(pid, SIGTERM); waitpid_forced(pid, &pst, 0); } close(fd); } goto eoferr; } if(!fault){ if(write_file(fd, buf2, len, ¶ms->vars.zfile, YES, writefunc) != len){ params->vars.errnum |= EUNPACKWRITE; fprintf(errfp, T_("Error: Writing to `%s' failed.\n"), buf); } }#ifdef USE_ZLIB if(cks) crc32sum = crc32(crc32sum, buf2, len);#endif break; } i = params->inputfunc(buf2, BUFFERSIZ, params); if(i < BUFFERSIZ){ if(fd >= 0){ if(pid >= 0){ kill(pid, SIGTERM); waitpid_forced(pid, &pst, 0); } close(fd); } goto eoferr; } if(!fault){ if(write_file(fd, buf2, BUFFERSIZ, ¶ms->vars.zfile, len < 0xfff ? YES : NO, writefunc) != len){ fprintf(errfp, T_("Error: Writing to `%s' failed.\n"), buf); params->vars.errnum |= EUNPACKWRITE; if(fd >= 0){ if(pid >= 0){ kill(pid, SIGTERM); waitpid_forced(pid, &pst, 0); } close(fd); } fd = -1; fault = YES; } }#ifdef USE_ZLIB if(cks) crc32sum = crc32(crc32sum, buf2, len);#endif filelen -= BUFFERSIZ; } if(fd >= 0){ close(fd); if(pid >= 0){ waitpid_forced(pid, &pst, 0); if(WEXITSTATUS(pst)){ params->vars.errnum |= EUNPACKUNCOMPR; fprintf(errfp, T_("Warning: Uncompress program returned bad status for file `%s'.\n"), buf); } } }#ifdef USE_ZLIB if(builtin_uncompress){ reset_zfile(¶ms->vars.zfile); }#endif } if(!skip && !fault){ set_props(buf, uid, gid, mtime, mode, acls, params); if(verbose && verbosefunc){ mk_esc_seq(buf, ESCAPE_CHARACTER, verbosestr); strcat(verbosestr, "\n"); params->vars.uid = uid; params->vars.mtime = mtime; verbosefunc(verbosestr, params); } } j = (cks ? 4 : 0); i = params->inputfunc(buf2, j + 1, params); if(buf2[j] != '.' || i < j + 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; }#ifdef USE_ZLIB if(cks){ xref_to_Uns32(&lu, buf2); if(lu != crc32sum){ fprintf(errfp, T_("Error: Wrong checksum unpacking file `%s'.\n"), buf); params->vars.errnum |= EUNPACKCKSUM; } }#endif started = YES; have_an_error = NO; break; case FILECONTENTSCKS: cks = YES;#ifdef USE_ZLIB crc32sum = crc32(0L, NULL, 0);#else fprintf(stderr, T_("Warning: CRC32 checksumming not available (requires zlib)\n"));#endif case FILECONTENTS: read_time_t(mtime, time_t); case FILECONTENTS_O: read_size_t(len, size_t); i = params->inputfunc(buf, len, params); /* read filename */ if(i < len) goto eoferr; buf[len] = '\0'; convtorel(buf, params->relative); i = params->inputfunc(&c, 1, params); if(c != ';' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } read_size_t(len, size_t); /* read uncompresscmd */ i = params->inputfunc(buf2, len, params); if(i < len) goto eoferr; buf2[len] = '\0'; i = params->inputfunc(&c, 1, params); if(c != ';' || i < 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } compressed = (buf2[0] ? YES : NO); builtin_uncompress = NO; i = stat(buf, &statb); uid = statb.st_uid; if(i){ fprintf(errfp, T_("Error: Cannot write to file `%s'.\n"), buf); skip = YES; } if(! name_in_list(buf, files, n_files, params->recursive, files_found) || invalid_time_or_uid(mtime, uid, params) || (params->uid && not_allowed(buf, params))) skip = YES; name_in_list(buf, files, n_files, 0, files_found); fd = -10; fault = NO; if(! skip){ fd = open(buf, O_WRONLY | O_BINARY); if(fd < 0){ fd = -10; fault = YES; fprintf(errfp, T_("Error: Cannot write to file `%s'.\n"), buf); params->vars.errnum |= EUNPACKWRITE; } if(compressed && !fault){ /* have to uncompress */ builtin_uncompress = NO; if(buf2[0] == '.' && (! buf2[1] || buf2[1] == ' ')){ if(buf2[1]) memmove(buf2, buf2 + 2, strlen(buf2) - 2 + 1); else buf2[0] = '\0';#ifndef USE_ZLIB fprintf(errfp, T_("Error: Built-in (un)compression not available for file `%s'.\n"), buf); fault = YES; compressed = NO; buf2[0] = '\0'; params->vars.errnum |= EUNPACKNOCOMPR;#else builtin_uncompress = YES;#endif } if(buf2[0]){ i = pipe(pp); if(i){ fprintf(errfp, T_("Error: cannot uncompress contents of file `%s'.\n"), buf); params->vars.errnum |= EUNPACKUNCOMPR; skip = YES; } else{ pid = fork_forced(); if(pid < 0){ fault = YES; fprintf(errfp, T_("Error: Cannot uncompress to file `%s'.\n"), buf); params->vars.errnum |= EUNPACKUNCOMPR; } else if(! pid){ /* child */ char **unzipargv; clr_timer(); close(pp[1]); if(cmd2argvq(&unzipargv, buf2)){ close(pp[0]); exit(1); } dup2(pp[0], 0); dup2(fd, 1); execvp(unzipargv[0], unzipargv + 1); exit(3); } close(pp[0]); close(fd); fd = pp[1]; } }#ifdef USE_ZLIB if(builtin_uncompress){ i = open_file_unzip(¶ms->vars.zfile, fd); if(i){ params->vars.errnum |= EUNPACKUNCOMPR; fprintf(errfp, T_("Error: Cannot uncompress `%s'.\n"), buf); close(fd); fd = -1; fault = YES; } } else params->vars.zfile.fd = fd;#endif }#ifdef USE_ZLIB else params->vars.zfile.fd = fd;#endif } if(skip) fault = YES; do{ i = params->inputfunc(buf2, 1, params); if(i < 1) goto eoferr; cptr = buf2 + 1; i = params->inputfunc(cptr, buf2[0], params); if(i > 0 && ! fault){ j = write_file(fd, cptr, i, ¶ms->vars.zfile, i < 0xff ? YES : NO, writefunc); if(j > 0) num_written += j; if(j < i){ params->vars.errnum |= EUNPACKWRITE; fprintf(errfp, T_("Error: writing to `%s' failed.\n"), buf); fault = YES; close(fd); fd = -10; i = j; } } if(i < buf2[0]){ if(fd >= 0) close(fd);#ifdef USE_ZLIB if(builtin_uncompress) reset_zfile(¶ms->vars.zfile);#endif goto eoferr; }#ifdef USE_ZLIB if(cks) crc32sum = crc32(crc32sum, cptr, i);#endif } while(buf2[0] == (UChar) 0xff); if(fd >= 0) close(fd); if(pid >= 0){ waitpid_forced(pid, &pst, 0); if(WEXITSTATUS(pst)){ params->vars.errnum |= EUNPACKUNCOMPR; fprintf(errfp, T_("Error: uncompressing to `%s' failed.\n"), buf); fault = YES; } }#ifdef USE_ZLIB if(builtin_uncompress){ reset_zfile(¶ms->vars.zfile); }#endif if(verbose && verbosefunc && !skip && !fault){ mk_esc_seq(buf, ESCAPE_CHARACTER, verbosestr); strcat(verbosestr, "\n"); params->vars.uid = uid; params->vars.mtime = mtime; verbosefunc(verbosestr, params); } j = (cks ? 4 : 0); i = params->inputfunc(buf2, j + 1, params); if(buf2[j] != '.' || i < j + 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; }#ifdef USE_ZLIB if(cks){ xref_to_Uns32(&lu, buf2); if(lu != crc32sum){ fprintf(errfp, T_("Error: Wrong checksum unpacking file `%s'.\n"), buf); params->vars.errnum |= EUNPACKCKSUM; } }#endif started = YES; have_an_error = NO; break; case COMMANDINOUTCKS: cks = YES;#ifdef USE_ZLIB crc32sum = crc32(0L, NULL, 0);#else fprintf(stderr, T_("Warning: CRC32 checksumming not available (requires zlib)\n"));#endif case COMMANDINOUT: read_int(i, int); j = params->inputfunc(buf2, i, params); if(j < i){ 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; } cptr = NULL; fault = NO; mk_esc_seq(buf2, ESCAPE_CHARACTER, verbosestr); if(! name_in_list(buf2, files, n_files, params->recursive, files_found)) skip = YES; name_in_list(buf2, files, n_files, 0, files_found); if(skip) fault = YES; if(params->uid && !fault){ fprintf(errfp, T_("Error: unpacking `%s' is only allowed for root.\n"), verbosestr); fault = YES; } pid = pfd = -1; if(!fault){ UChar *cptr2; cptr = buf2 + strlen(CMDINOUTPREFIX); cptr = strstr(cptr, CMDINOUTSEP) + strlen(CMDINOUTSEP); if( (cptr2 = strstr(cptr, CMDINOUTCOMM)) ){ c = *cptr2; *cptr2 = '\0'; } pfd = fdpopen(cptr, O_WRONLY, &pid); if(cptr2) *cptr2 = c; if(pfd < 0){ fault = YES; params->vars.errnum |= EUNPACKWRITECMD; fprintf(errfp, T_("Error: Cannot start program to unpack `%s'\n"), verbosestr); } } do{ UChar nbuf[8196]; i = params->inputfunc(nbuf, 2, params); xref_to_UnsN(&n, nbuf, 16); if(i < 2 || n > 8192){ if(pfd >= 0){ close(pfd); if(pid > 0) waitpid_forced(pid, &pst, 0); pid = pfd = -1; } i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } i = params->inputfunc(nbuf, n, params); if(i < n){ if(pfd >= 0){ close(pfd); if(pid > 0) waitpid_forced(pid, &pst, 0); pid = pfd = -1; } params->vars.errnum |= EUNPACKREAD; i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; } if(!fault){ for(cptr = nbuf, j = n; j > 0; cptr += i, j -= i){ i = writefunc(pfd, cptr, j); POSZ(i); if(i < 1){ fault = YES; params->vars.errnum |= EUNPACKWRITE; fprintf(errfp, T_("Error: Writing to unpack `%s` failed.\n"), verbosestr); close(pfd); if(pid > 0) waitpid_forced(pid, &pst, 0); pid = pfd = -1; } } }#ifdef USE_ZLIB if(cks) crc32sum = crc32(crc32sum, nbuf, i);#endif } while(n == 8192); if(pfd >= 0){ close(pfd); if(pid > 0){ waitpid_forced(pid, &pst, 0); pst = WEXITSTATUS(pst); if(pst){ params->vars.errnum |= EUNPACKWRITECMD; fprintf(errfp, T_("Error: Command to unpack `%s' returned bad status %d.\n"), verbosestr, pst); fault = YES; } } pfd = pid = -1; } if(verbose && verbosefunc && !skip && !fault){ strcat(verbosestr, "\n"); verbosefunc(verbosestr, params); } j = (cks ? 4 : 0); i = params->inputfunc(buf2, j + 1, params); if(buf2[j] != '.' || i < j + 1){ i = formaterr(&type, params, started); have_an_error = YES; goto tryagain; }#ifdef USE_ZLIB if(cks){ xref_to_Uns32(&lu, buf2); if(lu != crc32sum){ fprintf(errfp, T_("Error: Wrong checksum unpacking file `%s'.\n"), verbosestr); params->vars.errnum |= EUNPACKCKSUM; } }#endif started = YES; have_an_error = NO; break; default: i = formaterr(&type, params, started); goto tryagain; } } cleanup: if(files){ for(fileidx = files; *fileidx; fileidx++) free(*fileidx); free(files); } ZFREE_ACL_STRUCT(acls, params); return(r); eoferr: r = EOF; fprintf(errfp, T_("Error: unexpected end of file.\n")); params->vars.errnum |= EUNPACKREAD; goto cleanup;}static voidprint_if_false( UChar *name, UChar *type_n, UChar *false, AarParams *params){ UChar verbosestr[MAXPATHLEN * 4 + 100]; if(! *false){ sprintf(verbosestr, "%s%s\n", name, type_n); params->verbosefunc(verbosestr, params); *false = 1; }}static voidprint_if_unequal_u( Uns32 is, Uns32 should, UChar *paramname, UChar *name, UChar *tname, UChar *false, AarParams *params){ UChar verbosestr[MAXPATHLEN * 4 + 100]; if(is == should) return; print_if_false(name, tname, false, params); sprintf(verbosestr, DP "%s is %lu, should be %lu.\n", paramname, (unsigned long) is, (unsigned long) should); params->verbosefunc(verbosestr, params);}static voidprint_if_unequal_i( Int32 is, Int32 should, UChar *paramname, UChar *name, UChar *tname, UChar *false, AarParams *params){ UChar verbosestr[MAXPATHLEN * 4 + 100]; if(is == should) return; print_if_false(name, tname, false, params); sprintf(verbosestr, DP "%s is %ld, should be %ld.\n", paramname, (long int) is, (long int) should); params->verbosefunc(verbosestr, params);}static voidprint_if_unequal_t( time_t is, time_t should, UChar *paramname, UChar *name, UChar *tname, UChar *false, AarParams *params){ UChar verbosestr[MAXPATHLEN * 4 + 100], timestr1[50], timestr2[50]; if(is == should) return; print_if_false(name, tname, false, params); sprintf(verbosestr, DP "%s is %s, should be %s.\n", paramname, (char *) time_t_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -