void do_intercom_tell(player * p, char *str) { char *name, *talker, *msg, *oldstack; list_ent *l = 0; /*Assume we have a str and a space and a message, as we checked it before calling it */ name = str; msg = strchr(name, ' '); *msg++ = '\0'; if (strchr(name, ',')) { tell_player(p, " You cannot do chain tells to people and include remote" " talkers.\n"); return; } talker = strchr(name, '@'); if (talker) { l = find_list_entry(p, name); if (!l) l = find_list_entry(p, talker); *talker++ = '\0'; } if (!name || !*name || !talker || !*talker) { tell_player(p, " Badly formed remote address.\n"); return; } if (!l) l = find_list_entry(p, "@"); if (!l) l = find_list_entry(p, name); oldstack = stack; if (l) { if (l->flags & (IGNORE | BLOCK)) { sprintf(oldstack, " You cannot tell to them, as you are %sing" " %s.\n", l->flags & IGNORE ? "ignor" : "block", l->name); stack = end_string(oldstack); tell_player(p, oldstack); return; } } send_to_intercom(p, "%c%c%s:%s:%s:%s", USER_COMMAND, COMMAND_TELL, p->name, talker, name, msg); command_type = 0; return; }
/* filter out entries with same names as specified on the command line */ static char FAST_FUNC filter_replaceable(archive_handle_t *handle) { if (find_list_entry(handle->accept, handle->file_header->name)) return EXIT_FAILURE; return EXIT_SUCCESS; }
/* * Reassign the subarchive metadata parser based on the filename extension * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz * or if its a .tar.bz2 make archive_handle->sub_archive handle that */ char filter_accept_list_reassign(archive_handle_t *archive_handle) { /* Check the file entry is in the accept list */ if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { const char *name_ptr; /* Extract the last 2 extensions */ name_ptr = strrchr(archive_handle->file_header->name, '.'); /* Modify the subarchive handler based on the extension */ #if ENABLE_FEATURE_DEB_TAR_GZ if (strcmp(name_ptr, ".gz") == 0) { archive_handle->action_data_subarchive = get_header_tar_gz; return EXIT_SUCCESS; } #endif #if ENABLE_FEATURE_DEB_TAR_BZ2 if (strcmp(name_ptr, ".bz2") == 0) { archive_handle->action_data_subarchive = get_header_tar_bz2; return EXIT_SUCCESS; } #endif if (ENABLE_FEATURE_DEB_TAR_LZMA && !strcmp(name_ptr, ".lzma")) { archive_handle->action_data_subarchive = get_header_tar_lzma; return EXIT_SUCCESS; } } return EXIT_FAILURE; }
/* * Reassign the subarchive metadata parser based on the filename extension * e.g. if its a .tar.gz modify archive_handle->sub_archive to process a .tar.gz * or if its a .tar.bz2 make archive_handle->sub_archive handle that */ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) { /* Check the file entry is in the accept list */ if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) { const char *name_ptr; /* Find extension */ name_ptr = strrchr(archive_handle->file_header->name, '.'); if (!name_ptr) return EXIT_FAILURE; name_ptr++; /* Modify the subarchive handler based on the extension */ if (strcmp(name_ptr, "tar") == 0) { archive_handle->dpkg__action_data_subarchive = get_header_tar; return EXIT_SUCCESS; } if (ENABLE_FEATURE_SEAMLESS_GZ && strcmp(name_ptr, "gz") == 0 ) { archive_handle->dpkg__action_data_subarchive = get_header_tar_gz; return EXIT_SUCCESS; } if (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(name_ptr, "bz2") == 0 ) { archive_handle->dpkg__action_data_subarchive = get_header_tar_bz2; return EXIT_SUCCESS; } if (ENABLE_FEATURE_SEAMLESS_LZ && strcmp(name_ptr, "lz") == 0 ) { archive_handle->dpkg__action_data_subarchive = get_header_tar_lz; return EXIT_SUCCESS; } if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(name_ptr, "lzma") == 0 ) { archive_handle->dpkg__action_data_subarchive = get_header_tar_lzma; return EXIT_SUCCESS; } if (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(name_ptr, "xz") == 0 ) { archive_handle->dpkg__action_data_subarchive = get_header_tar_xz; return EXIT_SUCCESS; } } return EXIT_FAILURE; }
/* * Accept names that are in the accept list, ignoring reject list. */ char FAST_FUNC filter_accept_list(archive_handle_t *archive_handle) { if (find_list_entry(archive_handle->accept, archive_handle->file_header->name)) return EXIT_SUCCESS; return EXIT_FAILURE; }
int tar_main(int argc UNUSED_PARAM, char **argv) { char FAST_FUNC (*get_header_ptr)(archive_handle_t *) = get_header_tar; archive_handle_t *tar_handle; char *base_dir = NULL; const char *tar_filename = "-"; unsigned opt; int verboseFlag = 0; #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM llist_t *excludes = NULL; #endif /* Initialise default values */ tar_handle = init_handle(); tar_handle->ah_flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; /* Apparently only root's tar preserves perms (see bug 3844) */ if (getuid() != 0) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM; /* Prepend '-' to the first argument if required */ opt_complementary = "--:" // first arg is options "tt:vv:" // count -t,-v "?:" // bail out with usage instead of error return "X::T::" // cumulative lists #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM "\xff::" // cumulative lists for --exclude #endif IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive #if ENABLE_FEATURE_TAR_LONG_OPTIONS applet_long_options = tar_longopts; #endif opt = getopt32(argv, "txC:f:Opvk" IF_FEATURE_TAR_CREATE( "ch" ) IF_FEATURE_SEAMLESS_BZ2( "j" ) IF_FEATURE_SEAMLESS_LZMA("a" ) IF_FEATURE_TAR_FROM( "T:X:") IF_FEATURE_SEAMLESS_GZ( "z" ) IF_FEATURE_SEAMLESS_Z( "Z" ) , &base_dir // -C dir , &tar_filename // -f filename IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM , &excludes // --exclude #endif , &verboseFlag // combined count for -t and -v , &verboseFlag // combined count for -t and -v ); argv += optind; if (verboseFlag) tar_handle->action_header = header_verbose_list; if (verboseFlag == 1) tar_handle->action_header = header_list; if (opt & OPT_EXTRACT) tar_handle->action_data = data_extract_all; if (opt & OPT_2STDOUT) tar_handle->action_data = data_extract_to_stdout; if (opt & OPT_KEEP_OLD) tar_handle->ah_flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; if (opt & OPT_NOPRESERVE_OWN) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_OWN; if (opt & OPT_NOPRESERVE_PERM) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM; if (opt & OPT_NUMERIC_OWNER) tar_handle->ah_flags |= ARCHIVE_NUMERIC_OWNER; if (opt & OPT_GZIP) get_header_ptr = get_header_tar_gz; if (opt & OPT_BZIP2) get_header_ptr = get_header_tar_bz2; if (opt & OPT_LZMA) get_header_ptr = get_header_tar_lzma; if (opt & OPT_COMPRESS) get_header_ptr = get_header_tar_Z; #if ENABLE_FEATURE_TAR_FROM tar_handle->reject = append_file_list_to_list(tar_handle->reject); #if ENABLE_FEATURE_TAR_LONG_OPTIONS /* Append excludes to reject */ while (excludes) { llist_t *next = excludes->link; excludes->link = tar_handle->reject; tar_handle->reject = excludes; excludes = next; } #endif tar_handle->accept = append_file_list_to_list(tar_handle->accept); #endif /* Setup an array of filenames to work with */ /* TODO: This is the same as in ar, separate function ? */ while (*argv) { /* kill trailing '/' unless the string is just "/" */ char *cp = last_char_is(*argv, '/'); if (cp > *argv) *cp = '\0'; llist_add_to_end(&tar_handle->accept, *argv); argv++; } if (tar_handle->accept || tar_handle->reject) tar_handle->filter = filter_accept_reject_list; /* Open the tar file */ { FILE *tar_stream; int flags; if (opt & OPT_CREATE) { /* Make sure there is at least one file to tar up. */ if (tar_handle->accept == NULL) bb_error_msg_and_die("empty archive"); tar_stream = stdout; /* Mimicking GNU tar 1.15.1: */ flags = O_WRONLY | O_CREAT | O_TRUNC; } else { tar_stream = stdin; flags = O_RDONLY; } if (LONE_DASH(tar_filename)) { tar_handle->src_fd = fileno(tar_stream); tar_handle->seek = seek_by_read; } else { if (ENABLE_FEATURE_TAR_AUTODETECT && flags == O_RDONLY) { get_header_ptr = get_header_tar; tar_handle->src_fd = open_zipped(tar_filename); if (tar_handle->src_fd < 0) bb_perror_msg_and_die("can't open '%s'", tar_filename); } else { tar_handle->src_fd = xopen(tar_filename, flags); } } } if (base_dir) xchdir(base_dir); #ifdef CHECK_FOR_CHILD_EXITCODE /* We need to know whether child (gzip/bzip/etc) exits abnormally */ signal(SIGCHLD, handle_SIGCHLD); #endif /* create an archive */ if (opt & OPT_CREATE) { #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 int zipMode = 0; if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP)) zipMode = 1; if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2)) zipMode = 2; #endif /* NB: writeTarFile() closes tar_handle->src_fd */ return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, tar_handle->accept, tar_handle->reject, zipMode); } while (get_header_ptr(tar_handle) == EXIT_SUCCESS) continue; /* Check that every file that should have been extracted was */ while (tar_handle->accept) { if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) && !find_list_entry(tar_handle->passed, tar_handle->accept->data) ) { bb_error_msg_and_die("%s: not found in archive", tar_handle->accept->data); } tar_handle->accept = tar_handle->accept->link; } if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) close(tar_handle->src_fd); return EXIT_SUCCESS; }
int tar_main(int argc, char **argv) { char (*get_header_ptr)(archive_handle_t *) = get_header_tar; archive_handle_t *tar_handle; char *base_dir = NULL; const char *tar_filename = "-"; unsigned long opt; unsigned long ctx_flag = 0; if (argc < 2) { bb_show_usage(); } /* Prepend '-' to the first argument if required */ if (argv[1][0] != '-') { char *tmp; bb_xasprintf(&tmp, "-%s", argv[1]); argv[1] = tmp; } /* Initialise default values */ tar_handle = init_handle(); tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; bb_opt_complementaly = "c~tx:t~cx:x~ct:X*:T*"; #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS bb_applet_long_options = tar_long_options; #endif opt = bb_getopt_ulflags(argc, argv, tar_options, &base_dir, /* Change to dir <optarg> */ &tar_filename /* archive filename */ #ifdef CONFIG_FEATURE_TAR_FROM , NULL, &(tar_handle->reject) #endif ); /* Check one and only one context option was given */ if(opt & 0x80000000UL) { bb_show_usage(); } #ifdef CONFIG_FEATURE_TAR_CREATE ctx_flag = opt & (CTX_CREATE | CTX_TEST | CTX_EXTRACT); #else ctx_flag = opt & (CTX_TEST | CTX_EXTRACT); #endif if (ctx_flag == 0) { bb_show_usage(); } if(ctx_flag & CTX_TEST) { if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { tar_handle->action_header = header_verbose_list; } else { tar_handle->action_header = header_list; } } if(ctx_flag & CTX_EXTRACT) { if (tar_handle->action_data != data_extract_to_stdout) tar_handle->action_data = data_extract_all; } if(opt & TAR_OPT_2STDOUT) { /* To stdout */ tar_handle->action_data = data_extract_to_stdout; } if(opt & TAR_OPT_VERBOSE) { if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { tar_handle->action_header = header_verbose_list; } else { tar_handle->action_header = header_list; } } if (opt & TAR_OPT_KEEP_OLD) { tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; } #ifdef CONFIG_FEATURE_TAR_GZIP if(opt & TAR_OPT_GZIP) { get_header_ptr = get_header_tar_gz; } #endif #ifdef CONFIG_FEATURE_TAR_BZIP2 if(opt & TAR_OPT_BZIP2) { get_header_ptr = get_header_tar_bz2; } #endif #ifdef CONFIG_FEATURE_TAR_COMPRESS if(opt & TAR_OPT_UNCOMPRESS) { get_header_ptr = get_header_tar_Z; } #endif #ifdef CONFIG_FEATURE_TAR_FROM if(opt & TAR_OPT_EXCLUDE_FROM) { tar_handle->reject = append_file_list_to_list(tar_handle->reject); } #endif /* Check if we are reading from stdin */ if ((argv[optind]) && (*argv[optind] == '-')) { /* Default is to read from stdin, so just skip to next arg */ optind++; } /* Setup an array of filenames to work with */ /* TODO: This is the same as in ar, separate function ? */ while (optind < argc) { char *filename_ptr = last_char_is(argv[optind], '/'); if (filename_ptr) { *filename_ptr = '\0'; } tar_handle->accept = llist_add_to(tar_handle->accept, argv[optind]); optind++; } if ((tar_handle->accept) || (tar_handle->reject)) { tar_handle->filter = filter_accept_reject_list; } /* Open the tar file */ { FILE *tar_stream; int flags; #ifdef CONFIG_FEATURE_TAR_CREATE if (opt & CTX_CREATE) { /* Make sure there is at least one file to tar up. */ if (tar_handle->accept == NULL) { bb_error_msg_and_die("Cowardly refusing to create an empty archive"); } tar_stream = stdout; flags = O_WRONLY | O_CREAT | O_EXCL; unlink(tar_filename); } else #endif { tar_stream = stdin; flags = O_RDONLY; } if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) { tar_handle->src_fd = fileno(tar_stream); tar_handle->seek = seek_by_char; } else { tar_handle->src_fd = bb_xopen(tar_filename, flags); } } if ((base_dir) && (chdir(base_dir))) { bb_perror_msg_and_die("Couldnt chdir to %s", base_dir); } #ifdef CONFIG_FEATURE_TAR_CREATE /* create an archive */ if (opt & CTX_CREATE) { int verboseFlag = FALSE; int gzipFlag = FALSE; # ifdef CONFIG_FEATURE_TAR_GZIP if (get_header_ptr == get_header_tar_gz) { gzipFlag = TRUE; } # endif /* CONFIG_FEATURE_TAR_GZIP */ # ifdef CONFIG_FEATURE_TAR_BZIP2 if (get_header_ptr == get_header_tar_bz2) { bb_error_msg_and_die("Creating bzip2 compressed archives is not currently supported."); } # endif /* CONFIG_FEATURE_TAR_BZIP2 */ if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { verboseFlag = TRUE; } writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERNCE, tar_handle->accept, tar_handle->reject, gzipFlag); } else #endif /* CONFIG_FEATURE_TAR_CREATE */ { while (get_header_ptr(tar_handle) == EXIT_SUCCESS); /* Ckeck that every file that should have been extracted was */ while (tar_handle->accept) { if (find_list_entry(tar_handle->reject, tar_handle->accept->data) == NULL) { if (find_list_entry(tar_handle->passed, tar_handle->accept->data) == NULL) { bb_error_msg_and_die("%s: Not found in archive\n", tar_handle->accept->data); } } tar_handle->accept = tar_handle->accept->link; } } #ifdef CONFIG_FEATURE_CLEAN_UP if (tar_handle->src_fd != STDIN_FILENO) { close(tar_handle->src_fd); } #endif /* CONFIG_FEATURE_CLEAN_UP */ return(EXIT_SUCCESS); }
static void intercom_tell_player_and_return(char *str) { char *job_id, *name, *msg = 0, *ptr, *oldstack; player *p = 0; char end_was; char *end_pos; list_ent *l; saved_player *sp; char *end_ptr; if (!str || !*str) { log("error", "Empty message in intercom_tell_player"); return; } job_id = str; name = strchr(job_id, ':'); if (name) { *name++ = '\0'; msg = strchr(name, ':'); if (msg) *msg++ = '\0'; } if (!msg || !*msg || !*name || !*job_id) return; if (strcasecmp(name, "me")) p = find_player_global_quiet(name); if (!p) { send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, NO_SUCH_PLAYER, job_id, name); command_type = 0; return; } if (p->tag_flags & BLOCK_TELLS) { send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, TALKER_BLOCKED, job_id, p->name); return; } /*Check the list entry isnt an ignore */ ptr = strchr(msg, '@'); if (!ptr) { log("error", "intercom tried to send to player without a valid name."); return; } end_pos = ptr + 1; while (*end_pos && *end_pos != ',' && *end_pos != '\'' && *end_pos != ' ') end_pos++; end_was = *end_pos; *end_pos = '\0'; /*Now at the start of the message we have the name and address and thats it */ l = find_list_entry(p, msg); if (!l) l = find_list_entry(p, ptr); if (!l) l = find_list_entry(p, "@"); if (!l) { *ptr = '\0'; l = find_list_entry(p, msg); *ptr = '@'; } /*One quick check, is the sender a banished name here */ oldstack = stack; *ptr = '\0'; strcpy(oldstack, msg); *ptr = '@'; stack = end_string(oldstack); lower_case(oldstack); sp = find_saved_player(oldstack); if (sp) if (sp->residency == BANISHED || sp->residency & BANISHD) { send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, NAME_BANISHED, job_id, p->name); stack = oldstack; return; } if (check_intercom_banished_name(oldstack)) { send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, NAME_BANISHED, job_id, p->name); stack = oldstack; return; } stack = oldstack; *end_pos = end_was; if (l) { if (l->flags & IGNORE) { if (*(l->name) == '@') send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, TALKER_IGNORED, job_id, p->name); else send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, NAME_IGNORED, job_id, p->name); return; } if (l->flags & BLOCK) { if (*(l->name) == '@') send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, TALKER_BLOCKED, job_id, p->name); else send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, NAME_BLOCKED, job_id, p->name); return; } } /*Put the whole thing on the stack, so we can add a \n on it. This is thanks to Nevyn at Crazylands, cos he threw away process output and now Crazylands cant handle the \n at the end cos of colour code methods. */ strcpy(oldstack, msg); stack = end_string(oldstack); end_ptr = stack - 1; if (end_ptr >= oldstack && *end_ptr != '\n') { sprintf(end_ptr, "%s\n", COLOUR_TERMINATOR); stack = end_string(end_ptr); } if (p->flags & PROMPT) pager(p, oldstack); else tell_player(p, oldstack); send_to_intercom(NULL, "%c%c%s:%s", REPLY_IS, COMMAND_SUCCESSFUL, job_id, p->name); return; }
int unzip_main(int argc, char **argv) { enum { O_PROMPT, O_NEVER, O_ALWAYS }; zip_header_t zip_header; smallint verbose = 1; smallint listing = 0; smallint overwrite = O_PROMPT; unsigned total_size; unsigned total_entries; int src_fd = -1; int dst_fd = -1; char *src_fn = NULL; char *dst_fn = NULL; llist_t *zaccept = NULL; llist_t *zreject = NULL; char *base_dir = NULL; int i, opt; int opt_range = 0; char key_buf[80]; struct stat stat_buf; /* '-' makes getopt return 1 for non-options */ while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { switch (opt_range) { case 0: /* Options */ switch (opt) { case 'l': /* List */ listing = 1; break; case 'n': /* Never overwrite existing files */ overwrite = O_NEVER; break; case 'o': /* Always overwrite existing files */ overwrite = O_ALWAYS; break; case 'p': /* Extract files to stdout and fall through to set verbosity */ dst_fd = STDOUT_FILENO; case 'q': /* Be quiet */ verbose = 0; break; case 1: /* The zip file */ /* +5: space for ".zip" and NUL */ src_fn = xmalloc(strlen(optarg) + 5); strcpy(src_fn, optarg); opt_range++; break; default: bb_show_usage(); } break; case 1: /* Include files */ if (opt == 1) { llist_add_to(&zaccept, optarg); break; } if (opt == 'd') { base_dir = optarg; opt_range += 2; break; } if (opt == 'x') { opt_range++; break; } bb_show_usage(); case 2 : /* Exclude files */ if (opt == 1) { llist_add_to(&zreject, optarg); break; } if (opt == 'd') { /* Extract to base directory */ base_dir = optarg; opt_range++; break; } /* fall through */ default: bb_show_usage(); } } if (src_fn == NULL) { bb_show_usage(); } /* Open input file */ if (LONE_DASH(src_fn)) { src_fd = STDIN_FILENO; /* Cannot use prompt mode since zip data is arriving on STDIN */ if (overwrite == O_PROMPT) overwrite = O_NEVER; } else { static const char extn[][5] = {"", ".zip", ".ZIP"}; int orig_src_fn_len = strlen(src_fn); for (i = 0; (i < 3) && (src_fd == -1); i++) { strcpy(src_fn + orig_src_fn_len, extn[i]); src_fd = open(src_fn, O_RDONLY); } if (src_fd == -1) { src_fn[orig_src_fn_len] = '\0'; bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); } } /* Change dir if necessary */ if (base_dir) xchdir(base_dir); if (verbose) { printf("Archive: %s\n", src_fn); if (listing){ puts(" Length Date Time Name\n" " -------- ---- ---- ----"); } } total_size = 0; total_entries = 0; while (1) { uint32_t magic; /* Check magic number */ xread(src_fd, &magic, 4); if (magic == ZIP_CDS_MAGIC) break; if (magic != ZIP_FILEHEADER_MAGIC) bb_error_msg_and_die("invalid zip magic %08X", magic); /* Read the file header */ xread(src_fd, zip_header.raw, ZIP_HEADER_LEN); FIX_ENDIANNESS(zip_header); if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); } /* Read filename */ free(dst_fn); dst_fn = xzalloc(zip_header.formatted.filename_len + 1); xread(src_fd, dst_fn, zip_header.formatted.filename_len); /* Skip extra header bytes */ unzip_skip(src_fd, zip_header.formatted.extra_len); /* Filter zip entries */ if (find_list_entry(zreject, dst_fn) || (zaccept && !find_list_entry(zaccept, dst_fn)) ) { /* Skip entry */ i = 'n'; } else { /* Extract entry */ if (listing) { /* List entry */ if (verbose) { unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); printf("%9u %02u-%02u-%02u %02u:%02u %s\n", zip_header.formatted.ucmpsize, (dostime & 0x01e00000) >> 21, (dostime & 0x001f0000) >> 16, (((dostime & 0xfe000000) >> 25) + 1980) % 100, (dostime & 0x0000f800) >> 11, (dostime & 0x000007e0) >> 5, dst_fn); total_size += zip_header.formatted.ucmpsize; total_entries++; } else { /* short listing -- filenames only */ puts(dst_fn); } i = 'n'; } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ i = -1; } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ if (stat(dst_fn, &stat_buf) == -1) { if (errno != ENOENT) { bb_perror_msg_and_die("cannot stat '%s'",dst_fn); } if (verbose) { printf(" creating: %s\n", dst_fn); } unzip_create_leading_dirs(dst_fn); if (bb_make_directory(dst_fn, 0777, 0)) { bb_error_msg_and_die("exiting"); } } else { if (!S_ISDIR(stat_buf.st_mode)) { bb_error_msg_and_die("'%s' exists but is not directory", dst_fn); } } i = 'n'; } else { /* Extract file */ _check_file: if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ if (errno != ENOENT) { bb_perror_msg_and_die("cannot stat '%s'",dst_fn); } i = 'y'; } else { /* File already exists */ if (overwrite == O_NEVER) { i = 'n'; } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ if (overwrite == O_ALWAYS) { i = 'y'; } else { printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); if (!fgets(key_buf, sizeof(key_buf), stdin)) { bb_perror_msg_and_die("cannot read input"); } i = key_buf[0]; } } else { /* File is not regular file */ bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); } } } }