diff --git a/src/sbbs3/getmsg.cpp b/src/sbbs3/getmsg.cpp index 0837a6f7a4e0b82cfb2ee98834e0c57c3e4cdb8a..9ba56172a2cffc420da08e514cc0fc0c5414e71b 100644 --- a/src/sbbs3/getmsg.cpp +++ b/src/sbbs3/getmsg.cpp @@ -277,6 +277,119 @@ bool sbbs_t::show_msg(smb_t* smb, smbmsg_t* msg, long p_mode, post_t* post) return true; } +void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del) +{ + char str[256]; + char fpath[MAX_PATH+1]; + char* txt; + int attachment_index = 0; + bool found = true; + while((txt=smb_getmsgtxt(smb, msg, 0)) != NULL && found) { + char filename[MAX_PATH+1] = {0}; + uint32_t filelen = 0; + uint8_t* filedata; + if((filedata = smb_getattachment(msg, txt, filename, &filelen, attachment_index++)) != NULL + && filename[0] != 0 && filelen > 0) { + char tmp[32]; + SAFEPRINTF2(str, text[DownloadAttachedFileQ], filename, ultoac(filelen,tmp)); + if(!noyes(str)) { + SAFEPRINTF2(fpath, "%s%s", cfg.temp_dir, filename); + FILE* fp = fopen(fpath, "wb"); + if(fp == NULL) + errormsg(WHERE, ERR_OPEN, fpath, 0); + else { + int result = fwrite(filedata, filelen, 1, fp); + fclose(fp); + if(!result) + errormsg(WHERE, ERR_WRITE, fpath, filelen); + else + sendfile(fpath, useron.prot, "attachment"); + } + } + } else + found = false; + smb_freemsgtxt(txt); + } + + if(msg->hdr.auxattr&MSG_FILEATTACH) { /* Attached file */ + smb_getmsgidx(smb, msg); + SAFECOPY(str, msg->subj); /* filenames (multiple?) in title */ + char *p,*tp,*sp,ch; + tp=str; + while(online) { + p=strchr(tp,' '); + if(p) *p=0; + sp=strrchr(tp,'/'); /* sp is slash pointer */ + if(!sp) sp=strrchr(tp,'\\'); + if(sp) tp=sp+1; + file_t fd; + padfname(tp,fd.name); + SAFEPRINTF3(fpath,"%sfile/%04u.in/%s" /* path is path/fname */ + ,cfg.data_dir, msg->idx.to, tp); + if(!fexistcase(fpath) && msg->idx.from) + SAFEPRINTF3(fpath,"%sfile/%04u.out/%s" /* path is path/fname */ + ,cfg.data_dir, msg->idx.from,tp); + long length=(long)flength(fpath); + if(length<1) + bprintf(text[FileDoesNotExist], tp); + else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP + && length/(long)cur_cps>(time_t)timeleft) + bputs(text[NotEnoughTimeToDl]); + else { + char tmp[512]; + int i; + SAFEPRINTF2(str, text[DownloadAttachedFileQ] + ,tp,ultoac(length,tmp)); + if(length>0L && text[DownloadAttachedFileQ][0] && yesno(str)) { + { /* Remote User */ + xfer_prot_menu(XFER_DOWNLOAD); + mnemonics(text[ProtocolOrQuit]); + strcpy(str,"Q"); + for(i=0;i<cfg.total_prots;i++) + if(cfg.prot[i]->dlcmd[0] + && chk_ar(cfg.prot[i]->ar,&useron,&client)) { + sprintf(tmp,"%c",cfg.prot[i]->mnemonic); + strcat(str,tmp); + } + ch=(char)getkeys(str,0); + for(i=0;i<cfg.total_prots;i++) + if(cfg.prot[i]->dlcmd[0] && ch==cfg.prot[i]->mnemonic + && chk_ar(cfg.prot[i]->ar,&useron,&client)) + break; + if(i<cfg.total_prots) { + int error = protocol(cfg.prot[i], XFER_DOWNLOAD, fpath, nulstr, false); + if(checkprotresult(cfg.prot[i],error,&fd)) { + if(del) + remove(fpath); + logon_dlb+=length; /* Update stats */ + logon_dls++; + useron.dls=(ushort)adjustuserrec(&cfg,useron.number + ,U_DLS,5,1); + useron.dlb=adjustuserrec(&cfg,useron.number + ,U_DLB,10,length); + bprintf(text[FileNBytesSent] + ,fd.name,ultoac(length,tmp)); + SAFEPRINTF(str + ,"downloaded attached file: %s" + ,fd.name); + logline("D-",str); + } + autohangup(); + } + } + } + } + if(!p) + break; + tp=p+1; + while(*tp==' ') tp++; + } + // Remove the *.in directory, only if its empty + SAFEPRINTF2(fpath, "%sfile/%04u.in", cfg.data_dir, msg->idx.to); + rmdir(fpath); + } +} + /****************************************************************************/ /* Writes message header and text data to a text file */ /****************************************************************************/ diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp index 03ffafc8e7e27790dc05d1c5e2e6a5883f9252f7..e809d532c02fada06a3504be49b6f965fb78d12e 100644 --- a/src/sbbs3/js_bbs.cpp +++ b/src/sbbs3/js_bbs.cpp @@ -3623,6 +3623,44 @@ js_show_msg_header(JSContext *cx, uintN argc, jsval *arglist) return(JS_TRUE); } +static JSBool +js_download_msg_attachments(JSContext *cx, uintN argc, jsval *arglist) +{ + jsval *argv=JS_ARGV(cx, arglist); + uintN n; + JSObject* hdrobj; + sbbs_t* sbbs; + smb_t* smb = NULL; + smbmsg_t* msg = NULL; + bool del = true; + jsrefcount rc; + + JS_SET_RVAL(cx, arglist, JSVAL_VOID); + + if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL) + return(JS_FALSE); + + for(n=0; n<argc; n++) { + if(JSVAL_IS_OBJECT(argv[n])) { + if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL) + return JS_FALSE; + if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &smb, &msg, NULL)) { + return JS_FALSE; + } + } else if(JSVAL_IS_BOOLEAN(argv[n])) { + del = JSVAL_TO_BOOLEAN(argv[n]); + } + } + if(smb == NULL || msg == NULL) + return JS_TRUE; + + rc=JS_SUSPENDREQUEST(cx); + sbbs->download_msg_attachments(smb, msg, del); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} + static JSBool js_msgscan_cfg(JSContext *cx, uintN argc, jsval *arglist) { @@ -4217,6 +4255,11 @@ static jsSyncMethodSpec js_bbs_functions[] = { "<i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)") ,31702 }, + {"download_msg_attachments", js_download_msg_attachments, 1, JSTYPE_VOID, JSDOCSTR("[object header]") + ,JSDOCSTR("prompt the user to download each of the message's file attachments (if there are any)<br>" + "<i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)") + ,31702 + }, {"cfg_msg_scan", js_msgscan_cfg, 0, JSTYPE_VOID, JSDOCSTR("[type=<tt>SCAN_CFG_NEW</tt>]") ,JSDOCSTR("configure message scan " "(<i>type</i> is either <tt>SCAN_CFG_NEW</tt> or <tt>SCAN_CFG_TOYOU</tt>)") diff --git a/src/sbbs3/readmail.cpp b/src/sbbs3/readmail.cpp index 2fdd6cff7c9c043cd1241bc2b2a28c967118e8b6..88804324b3d7f56f7200f02ae1f685e6b7732bc7 100644 --- a/src/sbbs3/readmail.cpp +++ b/src/sbbs3/readmail.cpp @@ -57,16 +57,14 @@ static char mail_listing_flag(smbmsg_t* msg) /****************************************************************************/ void sbbs_t::readmail(uint usernumber, int which, long lm_mode) { - char str[256],str2[256],str3[256],done=0,domsg=1 - ,*p,*tp,*sp,ch; - char path[MAX_PATH+1]; + char str[256],str2[256],done=0,domsg=1 + ,*p; char tmp[512]; int i; uint32_t u,v; - int error; int mismatches=0,act; uint unum; - long length,l,last_mode; + long l,last_mode; ulong last; bool replied; file_t fd; @@ -262,110 +260,7 @@ void sbbs_t::readmail(uint usernumber, int which, long lm_mode) show_msg(&smb, &msg ,msg.from_ext && msg.idx.from==1 && !msg.from_net.type ? 0:P_NOATCODES); - - char* txt; - int attachment_index = 0; - bool found = true; - while((txt=smb_getmsgtxt(&smb,&msg, 0)) != NULL && found) { - char filename[MAX_PATH+1] = {0}; - uint32_t filelen = 0; - uint8_t* filedata; - if((filedata = smb_getattachment(&msg, txt, filename, &filelen, attachment_index++)) != NULL - && filename[0] != 0 && filelen > 0) { - char tmp[32]; - SAFEPRINTF2(str3, text[DownloadAttachedFileQ], filename, ultoac(filelen,tmp)); - if(!noyes(str3)) { - char fpath[MAX_PATH+1]; - SAFEPRINTF2(fpath, "%s%s", cfg.temp_dir, filename); - FILE* fp = fopen(fpath, "wb"); - if(fp == NULL) - errormsg(WHERE, ERR_OPEN, fpath, 0); - else { - int result = fwrite(filedata, filelen, 1, fp); - fclose(fp); - if(!result) - errormsg(WHERE, ERR_WRITE, fpath, filelen); - else - sendfile(fpath, useron.prot, "attachment"); - } - } - } else - found = false; - smb_freemsgtxt(txt); - } - - if(msg.hdr.auxattr&MSG_FILEATTACH) { /* Attached file */ - smb_getmsgidx(&smb,&msg); - SAFECOPY(str, msg.subj); /* filenames (multiple?) in title */ - tp=str; - while(online) { - p=strchr(tp,' '); - if(p) *p=0; - sp=strrchr(tp,'/'); /* sp is slash pointer */ - if(!sp) sp=strrchr(tp,'\\'); - if(sp) tp=sp+1; - padfname(tp,fd.name); - SAFEPRINTF3(path,"%sfile/%04u.in/%s" /* path is path/fname */ - ,cfg.data_dir,msg.idx.to,tp); - if(!fexistcase(path) && msg.idx.from) - SAFEPRINTF3(path,"%sfile/%04u.out/%s" /* path is path/fname */ - ,cfg.data_dir,msg.idx.from,tp); - length=(long)flength(path); - if(length<1) - bprintf(text[FileDoesNotExist], tp); - else if(!(useron.exempt&FLAG('T')) && cur_cps && !SYSOP - && length/(long)cur_cps>(time_t)timeleft) - bputs(text[NotEnoughTimeToDl]); - else { - SAFEPRINTF2(str3,text[DownloadAttachedFileQ] - ,tp,ultoac(length,tmp)); - if(length>0L && text[DownloadAttachedFileQ][0] && yesno(str3)) { - { /* Remote User */ - xfer_prot_menu(XFER_DOWNLOAD); - mnemonics(text[ProtocolOrQuit]); - strcpy(str3,"Q"); - for(i=0;i<cfg.total_prots;i++) - if(cfg.prot[i]->dlcmd[0] - && chk_ar(cfg.prot[i]->ar,&useron,&client)) { - sprintf(tmp,"%c",cfg.prot[i]->mnemonic); - strcat(str3,tmp); - } - ch=(char)getkeys(str3,0); - for(i=0;i<cfg.total_prots;i++) - if(cfg.prot[i]->dlcmd[0] && ch==cfg.prot[i]->mnemonic - && chk_ar(cfg.prot[i]->ar,&useron,&client)) - break; - if(i<cfg.total_prots) { - error=protocol(cfg.prot[i],XFER_DOWNLOAD,path,nulstr,false); - if(checkprotresult(cfg.prot[i],error,&fd)) { - if(which==MAIL_YOUR) - remove(path); - logon_dlb+=length; /* Update stats */ - logon_dls++; - useron.dls=(ushort)adjustuserrec(&cfg,useron.number - ,U_DLS,5,1); - useron.dlb=adjustuserrec(&cfg,useron.number - ,U_DLB,10,length); - bprintf(text[FileNBytesSent] - ,fd.name,ultoac(length,tmp)); - SAFEPRINTF(str3 - ,"downloaded attached file: %s" - ,fd.name); - logline("D-",str3); - } - autohangup(); - } - } - } - } - if(!p) - break; - tp=p+1; - while(*tp==' ') tp++; - } - SAFEPRINTF2(str,"%sfile/%04u.in",cfg.data_dir,usernumber); - rmdir(str); - } + download_msg_attachments(&smb, &msg, which == MAIL_YOUR); if(which==MAIL_YOUR && !(msg.hdr.attr&MSG_READ)) { mail[smb.curmsg].attr|=MSG_READ; if(thisnode.status==NODE_INUSE) diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 8678956e0451506550db47d537594b15bb819735..1b79a910edea48452d53d90c2f08ee8ab3a768de 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -685,6 +685,7 @@ public: ulong getlastmsg(uint subnum, uint32_t *ptr, time_t *t); time_t getmsgtime(uint subnum, ulong ptr); ulong getmsgnum(uint subnum, time_t t); + void download_msg_attachments(smb_t*, smbmsg_t*, bool del); /* readmail.cpp */ void readmail(uint usernumber, int which, long lm_mode = 0);