diff --git a/src/sbbs3/pack_rep.cpp b/src/sbbs3/pack_rep.cpp index 86b3e5297d34aa2c686fc9205343795f44887b3d..190bba9ebbbc6ec16c001f0a2b3502386651d52c 100644 --- a/src/sbbs3/pack_rep.cpp +++ b/src/sbbs3/pack_rep.cpp @@ -21,6 +21,7 @@ #include "sbbs.h" #include "qwk.h" +#include "filedat.h" /****************************************************************************/ /* Creates an REP packet for upload to QWK hub 'hubnum'. */ @@ -32,6 +33,7 @@ bool sbbs_t::pack_rep(uint hubnum) char tmp[MAX_PATH+1],tmp2[MAX_PATH+1]; char hubid_upper[LEN_QWKID+1]; char hubid_lower[LEN_QWKID+1]; + char error[256]; int mode; const char* fmode; uint i,j,k; @@ -61,7 +63,21 @@ bool sbbs_t::pack_rep(uint hubnum) SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); if(fexistcase(str)) { lprintf(LOG_INFO,"Updating %s", str); - external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE); + long file_count = extract_files_from_archive(str + ,/* outdir: */cfg.temp_dir + ,/* allowed_filename_chars: */NULL /* any */ + ,/* with_path: */false + ,/* max_files: */0 /* unlimited */ + ,/* file_list: */NULL /* all files */ + ,error, sizeof(error)); + if(file_count > 0) { + lprintf(LOG_DEBUG, "libarchive extracted %lu files from %s", file_count, str); + } else { + if(*error) + lprintf(LOG_NOTICE, "libarchive error (%s) extracting %s", error, str); + if(*cfg.qhub[hubnum]->unpack) + external(cmdstr(cfg.qhub[hubnum]->unpack,str,ALLFILES,NULL),EX_OFFLINE); + } } else lprintf(LOG_INFO,"Creating %s", str); /*************************************************/ @@ -268,14 +284,23 @@ bool sbbs_t::pack_rep(uint hubnum) /*******************/ SAFEPRINTF2(str,"%s%s.REP",cfg.data_dir,hubid_upper); SAFEPRINTF2(tmp2,"%s%s",cfg.temp_dir,ALLFILES); - i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL) - ,EX_OFFLINE|EX_WILDCARD); - if(!fexistcase(str)) { - lprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp)); + if(strListFind((str_list_t)supported_archive_formats, cfg.qhub[hubnum]->fmt, /* case_sensitive */FALSE) >= 0) { + str_list_t file_list = directory(tmp2); + long file_count = create_archive(str, cfg.qhub[hubnum]->fmt, /* with_path: */false, file_list, error, sizeof(error)); + strListFree(&file_list); + if(file_count < 0) + lprintf(LOG_ERR, "libarchive error %ld (%s) creating %s", file_count, error, str); + else + lprintf(LOG_INFO, "libarchive created %s from %ld files", str, file_count); + } else { + i=external(cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL) + ,EX_OFFLINE|EX_WILDCARD); if(i) errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->pack,str,tmp2,NULL),i); - else - lprintf(LOG_ERR, "Couldn't compress REP packet"); + } + if(!fexistcase(str)) { + lprintf(LOG_WARNING,"%s",remove_ctrl_a(text[QWKCompressionFailed],tmp)); + lprintf(LOG_ERR, "Couldn't compress REP packet"); return(false); } SAFEPRINTF2(str,"%sqnet/%s.out/",cfg.data_dir,hubid_lower); diff --git a/src/sbbs3/scfg/scfgnet.c b/src/sbbs3/scfg/scfgnet.c index ff8317fef04777d1e44b6e6f37db317ab7dbd774..360a8a32619c8b38473ac0c281b01eefaa3163de 100644 --- a/src/sbbs3/scfg/scfgnet.c +++ b/src/sbbs3/scfg/scfgnet.c @@ -238,8 +238,7 @@ void net_cfg() if(!new_qhub(i)) continue; SAFECOPY(cfg.qhub[i]->id,str); - SAFECOPY(cfg.qhub[i]->pack,"%@zip -jD %f %s"); - SAFECOPY(cfg.qhub[i]->unpack,"%@unzip -Coj %f %s -d %g"); + SAFECOPY(cfg.qhub[i]->fmt, "ZIP"); SAFECOPY(cfg.qhub[i]->call,"*qnet-ftp %s hub.address YOURPASS"); cfg.qhub[i]->node = NODE_ANY; cfg.qhub[i]->days=0x7f; /* all days */ @@ -824,6 +823,7 @@ void qhub_edit(int num) while(!done) { i=0; sprintf(opt[i++],"%-27.27s%s","Hub System ID",cfg.qhub[num]->id); + sprintf(opt[i++],"%-27.27s%s","Archive Format",cfg.qhub[num]->fmt); sprintf(opt[i++],"%-27.27s%s","Pack Command Line",cfg.qhub[num]->pack); sprintf(opt[i++],"%-27.27s%s","Unpack Command Line",cfg.qhub[num]->unpack); sprintf(opt[i++],"%-27.27s%s","Call-out Command Line",cfg.qhub[num]->call); @@ -859,8 +859,13 @@ void qhub_edit(int num) "\n" "The `Hub System ID` must match the QWK System ID of this network hub.\n" "\n" + "The `Archive Format` should be set to an archive/compression format\n" + "that the hub will expect your REP packets to be submitted with\n" + "(typically, ZIP).\n" + "\n" "The `Pack` and `Unpack Command Lines` are used for creating and extracting\n" - "REP (reply) and QWK message packets (files, usually in PKZIP format).\n" + "REP (reply) and QWK message packets using an external archive utility\n" + "(these command-lines are optional).\n" "\n" "The `Call-out Command Line` is executed when your system attempts a packet\n" "exchange with the QWKnet hub (e.g. executes a script).\n" @@ -904,7 +909,7 @@ void qhub_edit(int num) case -1: done=1; break; - case 0: + case __COUNTER__: uifc.helpbuf= "`QWK Network Hub System ID:`\n" "\n" @@ -916,7 +921,17 @@ void qhub_edit(int num) ,cfg.qhub[num]->id,LEN_QWKID,K_UPPER|K_EDIT)) strcpy(cfg.qhub[num]->id,str); break; - case 1: + case __COUNTER__: + uifc.helpbuf= + "`REP Packet Archive Format:`\n" + "\n" + "This is the archive format used for REP packets created for this QWK\n" + "network hub (typically, this would be `ZIP`).\n" + ; + uifc.input(WIN_MID|WIN_SAV,0,0,"REP Packet Archive Format" + ,cfg.qhub[num]->fmt,sizeof(cfg.qhub[num]->fmt)-1,K_EDIT|K_UPPER); + break; + case __COUNTER__: uifc.helpbuf= "`REP Packet Creation Command:`\n" "\n" @@ -928,7 +943,7 @@ void qhub_edit(int num) uifc.input(WIN_MID|WIN_SAV,0,0,"" ,cfg.qhub[num]->pack,sizeof(cfg.qhub[num]->pack)-1,K_EDIT); break; - case 2: + case __COUNTER__: uifc.helpbuf= "`QWK Packet Extraction Command:`\n" "\n" @@ -940,7 +955,7 @@ void qhub_edit(int num) uifc.input(WIN_MID|WIN_SAV,0,0,"" ,cfg.qhub[num]->unpack,sizeof(cfg.qhub[num]->unpack)-1,K_EDIT); break; - case 3: + case __COUNTER__: uifc.helpbuf= "`QWK Network Hub Call-out Command Line:`\n" "\n" @@ -952,7 +967,7 @@ void qhub_edit(int num) uifc.input(WIN_MID|WIN_SAV,0,0,"" ,cfg.qhub[num]->call,sizeof(cfg.qhub[num]->call)-1,K_EDIT); break; - case 4: + case __COUNTER__: if(cfg.qhub[num]->node == NODE_ANY) SAFECOPY(str, "Any"); else @@ -971,7 +986,7 @@ void qhub_edit(int num) cfg.qhub[num]->node = NODE_ANY; } break; - case 5: + case __COUNTER__: j=0; while(1) { for(i=0;i<7;i++) @@ -992,7 +1007,7 @@ void qhub_edit(int num) uifc.changes=1; } break; - case 6: + case __COUNTER__: i=1; uifc.helpbuf= "`Perform Call-out at a Specific Time:`\n" @@ -1046,27 +1061,27 @@ void qhub_edit(int num) } } break; - case 7: + case __COUNTER__: cfg.qhub[num]->misc^=QHUB_NOKLUDGES; uifc.changes=1; break; - case 8: + case __COUNTER__: cfg.qhub[num]->misc^=QHUB_NOVOTING; uifc.changes=1; break; - case 9: + case __COUNTER__: cfg.qhub[num]->misc^=QHUB_NOHEADERS; uifc.changes=1; break; - case 10: + case __COUNTER__: cfg.qhub[num]->misc^=QHUB_UTF8; uifc.changes=1; break; - case 11: + case __COUNTER__: cfg.qhub[num]->misc^=QHUB_EXT; uifc.changes=1; break; - case 12: + case __COUNTER__: i = cfg.qhub[num]->misc&QHUB_CTRL_A; i++; if(i == QHUB_CTRL_A) i = 0; @@ -1074,10 +1089,10 @@ void qhub_edit(int num) cfg.qhub[num]->misc |= i; uifc.changes=1; break; - case 13: + case __COUNTER__: import_qwk_conferences(num); break; - case 14: + case __COUNTER__: qhub_sub_edit(num); break; } diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index 77aa946882d6fba7f365a80681e8cbd7c85ae1b7..6ebf654d046f39b5b1e4f46da877e4642d5587bc 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -312,6 +312,7 @@ typedef struct { /* QWK Network Hub */ call[LEN_CMD+1], /* Call-out command line to execute */ pack[LEN_CMD+1], /* Packing command line */ unpack[LEN_CMD+1]; /* Unpacking command line */ + char fmt[4]; /* Archive format */ uint16_t time, /* Time to call-out */ node, /* Node to do the call-out */ freq, /* Frequency of call-outs */ diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index f3e92c7db298aec2d5ce92210a37ed0c9690c82f..f274307026e731eb0449316a818463476895243b 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -625,7 +625,8 @@ BOOL read_msgs_cfg(scfg_t* cfg, char* error, size_t maxerrlen) } } get_int(cfg->qhub[i]->misc, instream); - for(j=0;j<30;j++) + get_str(cfg->qhub[i]->fmt,instream); + for(j=0;j<28;j++) get_int(n,instream); } diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c index 14ab2dcb6a3c5cc671a3da3bed04638095a8fbdd..5be3129b0d4d4560f28446d7dae8198f283206fb 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -540,8 +540,9 @@ BOOL DLLCALL write_msgs_cfg(scfg_t* cfg, int backup_level) put_int(cfg->qhub[i]->mode[j],stream); } put_int(cfg->qhub[i]->misc, stream); + put_str(cfg->qhub[i]->fmt,stream); n=0; - for(j=0;j<30;j++) + for(j=0;j<28;j++) put_int(n,stream); } n=0; diff --git a/src/sbbs3/un_qwk.cpp b/src/sbbs3/un_qwk.cpp index 0d35a98cc6325465695361370cbc5eab6d366745..ac05baf2f7003144c0e4db524a0d2573e2d6499c 100644 --- a/src/sbbs3/un_qwk.cpp +++ b/src/sbbs3/un_qwk.cpp @@ -21,6 +21,7 @@ #include "sbbs.h" #include "qwk.h" +#include "filedat.h" static void log_qwk_import_stats(sbbs_t* sbbs, ulong msgs, time_t start) { @@ -39,6 +40,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum) { char str[MAX_PATH+1],fname[MAX_PATH+1]; char tmp[512]; + char error[256] = ""; char inbox[MAX_PATH+1]; uchar block[QWK_BLOCK_LEN]; int k,file; @@ -74,10 +76,24 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum) return(false); } delfiles(cfg.temp_dir,ALLFILES); - i=external(cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),EX_OFFLINE); - if(i) { - errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),i); - return(false); + long file_count = extract_files_from_archive(packet + ,/* outdir: */cfg.temp_dir + ,/* allowed_filename_chars: */NULL /* any */ + ,/* with_path: */false + ,/* max_files: */0 /* unlimited */ + ,/* file_list: */NULL /* all files */ + ,error, sizeof(error)); + if(file_count >= 0) { + lprintf(LOG_DEBUG, "libarchive extracted %ld files from %s", file_count, packet); + } else { + lprintf(LOG_ERR, "libarchive error %ld (%s) extracting %s", file_count, error, packet); + if(*cfg.qhub[hubnum]->unpack == '\0') + return false; + i=external(cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),EX_OFFLINE); + if(i) { + errormsg(WHERE,ERR_EXEC,cmdstr(cfg.qhub[hubnum]->unpack,packet,ALLFILES,NULL),i); + return(false); + } } SAFEPRINTF(str,"%sMESSAGES.DAT",cfg.temp_dir); if(!fexistcase(str)) {