diff --git a/src/sbbs3/filedat.c b/src/sbbs3/filedat.c index a86ad6cd719b07fb561516863ca16be81d372843..cdba39e4a1d82dfc1d885423f248b13dfc516024 100644 --- a/src/sbbs3/filedat.c +++ b/src/sbbs3/filedat.c @@ -914,8 +914,10 @@ long create_archive(const char* archive, const char* format return archived; } +// 'with_path' means to extract with sub-dirs +// 'recurse' means to apply the file_list filter (if non-NULL) recursively long extract_files_from_archive(const char* archive, const char* outdir, const char* allowed_filename_chars - ,bool with_path, bool overwrite, long max_files, str_list_t file_list, char* error, size_t maxerrlen) + ,bool with_path, bool overwrite, long max_files, str_list_t file_list, bool recurse, char* error, size_t maxerrlen) { int result; struct archive *ar; @@ -971,9 +973,9 @@ long extract_files_from_archive(const char* archive, const char* outdir, const c if(filetype != AE_IFREG) continue; char* filename = getfname(pathname); - if(!with_path) - pathname = filename; if(file_list != NULL) { + if(recurse) + pathname = filename; int i; for (i = 0; file_list[i] != NULL; i++) if(wildmatch(pathname, file_list[i], with_path, /* case-sensitive: */false)) @@ -987,6 +989,8 @@ long extract_files_from_archive(const char* archive, const char* outdir, const c safe_snprintf(error, maxerrlen, "disallowed filename '%s'", pathname); break; } + if(!with_path) + pathname = filename; SAFECOPY(fpath, outdir); backslash(fpath); SAFECAT(fpath, pathname); @@ -1053,10 +1057,11 @@ bool extract_diz(scfg_t* cfg, file_t* f, str_list_t diz_fnames, char* path, size if(extract_files_from_archive(archive ,/* outdir: */cfg->temp_dir ,/* allowed_filename_chars: */NULL /* any */ - ,/* with_path: */!nested + ,/* with_path: */false ,/* overwrite: */false ,/* max_files: */strListCount(diz_fnames) ,/* file_list: */diz_fnames + ,/* recurse: */nested ,/* error: */NULL, 0) >= 0) { for(i = 0; diz_fnames[i] != NULL; i++) { safe_snprintf(path, maxlen, "%s%s", cfg->temp_dir, diz_fnames[i]); // no slash diff --git a/src/sbbs3/filedat.h b/src/sbbs3/filedat.h index 8c2a1b4d01057048e25706f519f482292188b49c..b99de1391cf9f8bf9875743831e5f7a058db5d5b 100644 --- a/src/sbbs3/filedat.h +++ b/src/sbbs3/filedat.h @@ -74,7 +74,7 @@ DLLEXPORT long create_archive(const char* archive, const char* format ,bool with_path, str_list_t file_list, char* error, size_t maxerrlen); DLLEXPORT char* cmdstr(scfg_t*, user_t*, const char* instr, const char* fpath, const char* fspec, char* cmd, size_t); DLLEXPORT long extract_files_from_archive(const char* archive, const char* outdir, const char* allowed_filename_chars - ,bool with_path, bool overwrite, long max_files, str_list_t file_list, char* error, size_t); + ,bool with_path, bool overwrite, long max_files, str_list_t file_list, bool recurse, char* error, size_t); DLLEXPORT int archive_type(const char* archive, char* str, size_t size); extern const char* supported_archive_formats[]; DLLEXPORT bool file_type_match(const char* filename, const char* type); diff --git a/src/sbbs3/js_archive.c b/src/sbbs3/js_archive.c index fe3caf6a9a27d64d6b8ff76468d90df10e48de48..9dfc7403bf0a684c127c9a08ef56a39df23b10de 100644 --- a/src/sbbs3/js_archive.c +++ b/src/sbbs3/js_archive.c @@ -110,6 +110,7 @@ js_extract(JSContext *cx, uintN argc, jsval *arglist) str_list_t file_list = NULL; bool with_path = false; bool overwrite = true; + bool recurse = false; int32 max_files = 0; char error[256] = ""; jsrefcount rc; @@ -149,17 +150,20 @@ js_extract(JSContext *cx, uintN argc, jsval *arglist) } argn++; } - for(; argn < argc; argn++) { - if(JSVAL_IS_STRING(argv[argn])) { - char path[MAX_PATH + 1]; - JSVALUE_TO_STRBUF(cx, argv[argn], path, sizeof(path), NULL); - strListPush(&file_list, path); - } + while(argc > argn && JSVAL_IS_STRING(argv[argn])) { + char path[MAX_PATH + 1]; + JSVALUE_TO_STRBUF(cx, argv[argn], path, sizeof(path), NULL); + strListPush(&file_list, path); + argn++; + } + if(argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) { + recurse = JSVAL_TO_BOOLEAN(argv[argn]); + argn++; } rc = JS_SUSPENDREQUEST(cx); long extracted = extract_files_from_archive(filename, outdir, allowed_filename_chars - ,with_path, overwrite, (ulong)max_files, file_list, error, sizeof(error)); + ,with_path, overwrite, (ulong)max_files, file_list, recurse, error, sizeof(error)); strListFree(&file_list); free(outdir); JS_RESUMEREQUEST(cx, rc); @@ -555,7 +559,7 @@ js_read(JSContext *cx, uintN argc, jsval *arglist) static jsSyncMethodSpec js_archive_functions[] = { { "create", js_create, 1, JSTYPE_NUMBER - ,JSDOCSTR("[string format] [,boolean with_path = false] [,array file_list]") + ,JSDOCSTR("[string format] [,boolean with_path=false] [,array file_list]") ,JSDOCSTR("Create an archive of the specified format (e.g. 'zip', '7z', 'tgz').<br>" "Returns the number of files archived.<br>" "Will throw exception upon error.") @@ -567,14 +571,14 @@ static jsSyncMethodSpec js_archive_functions[] = { ,31900 }, { "extract", js_extract, 1, JSTYPE_NUMBER - ,JSDOCSTR("output_directory [,boolean with_path = false] [,boolean overwrite = true] [,number max_files = 0] [,string file/pattern [...]]") + ,JSDOCSTR("output_directory [,boolean with_path=false] [,boolean overwrite=true] [,number max_files=0] [,string file/pattern [...]] [,boolean recurse=false]") ,JSDOCSTR("Extract files from an archive to specified output directory.<br>" "Returns the number of files extracted.<br>" "Will throw exception upon error.") ,31900 }, { "list", js_list, 1, JSTYPE_ARRAY - ,JSDOCSTR("[,boolean hash = false] [,string file/pattern]") + ,JSDOCSTR("[,boolean hash=false] [,string file/pattern]") ,JSDOCSTR("Get list of archive contents as an array of objects.<br>" "Archived object properties:<br>" "<ol>" diff --git a/src/sbbs3/pack_qwk.cpp b/src/sbbs3/pack_qwk.cpp index f028a25fd75bb8d84401ffc46a6aa115da05a2a5..5a254cf692971d33c1632017cfe4547ff7c9385d 100644 --- a/src/sbbs3/pack_qwk.cpp +++ b/src/sbbs3/pack_qwk.cpp @@ -76,6 +76,7 @@ bool sbbs_t::pack_qwk(char *packet, uint *msgcnt, bool prepack) ,/* overwrite: */true ,/* max_files: */0 /* unlimited */ ,/* file_list: */NULL /* all files */ + ,/* recurse: */false ,error, sizeof(error)); if(file_count > 0) { lprintf(LOG_DEBUG, "libarchive extracted %u files from %s", file_count, str); diff --git a/src/sbbs3/pack_rep.cpp b/src/sbbs3/pack_rep.cpp index 8f70d9069ee860f7ef2edb7f2349a46191e9ae02..56c163091c2c2a20c7b7a85b16b8798b73c78f67 100644 --- a/src/sbbs3/pack_rep.cpp +++ b/src/sbbs3/pack_rep.cpp @@ -70,6 +70,7 @@ bool sbbs_t::pack_rep(uint hubnum) ,/* overwrite: */true ,/* max_files: */0 /* unlimited */ ,/* file_list: */NULL /* all files */ + ,/* recurse: */false ,error, sizeof(error)); if(file_count > 0) { lprintf(LOG_DEBUG, "libarchive extracted %lu files from %s", file_count, str); diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c index d76c71e4b745b1cc16948455356a3c6696cf31a0..a365c7d02b93ef9b48d3e6868b26aec6c2f6a358 100644 --- a/src/sbbs3/sbbsecho.c +++ b/src/sbbs3/sbbsecho.c @@ -2265,7 +2265,7 @@ int unpack(const char *infile, const char* outdir) file_count = extract_files_from_archive(infile, outdir ,/* allowed_filename_chars: */SAFEST_FILENAME_CHARS, /* with_path */false, /* overwrite: */true - ,/* max_files: */0, /* file_list = ALL */NULL, error, sizeof(error)); + ,/* max_files: */0, /* file_list = ALL */NULL, /* recurse: */false, error, sizeof(error)); if(file_count > 0) { lprintf(LOG_DEBUG, "libarchive extracted %lu files from %s", file_count, infile); return 0; diff --git a/src/sbbs3/un_qwk.cpp b/src/sbbs3/un_qwk.cpp index ac359740411736f87c71ff14d622bcc46876bc94..d717482153394b0ecd30c2e18c4a2830026b3639 100644 --- a/src/sbbs3/un_qwk.cpp +++ b/src/sbbs3/un_qwk.cpp @@ -80,6 +80,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum) ,/* overwrite: */true ,/* max_files: */0 /* unlimited */ ,/* file_list: */NULL /* all files */ + ,/* recurse: */false ,error, sizeof(error)); if(file_count >= 0) { lprintf(LOG_DEBUG, "libarchive extracted %ld files from %s", file_count, packet); diff --git a/src/sbbs3/un_rep.cpp b/src/sbbs3/un_rep.cpp index f1721bd6310d2a55cf0cfd011158ac513a952047..1d3571d0ed8c6adaa43f1d3720b9ed3991738427 100644 --- a/src/sbbs3/un_rep.cpp +++ b/src/sbbs3/un_rep.cpp @@ -76,6 +76,7 @@ bool sbbs_t::unpack_rep(char* repfile) ,/* overwrite: */true ,/* max_files */1000 ,/* file_list: */NULL /* all files */ + ,/* recurse: */false ,error, sizeof(error)); if(file_count > 0) { lprintf(LOG_DEBUG, "libarchive extracted %lu files from %s", file_count, rep_fname);