Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit c3a7d672 authored by rswindell's avatar rswindell

Move the download file attachment logic from readmail() to a new function:

download_file_attachments() and expose via new JS "bbs" method. Currently
this only reall works for the mail base.
parent 6b140b6f
......@@ -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 */
/****************************************************************************/
......
......@@ -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>)")
......
......@@ -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)
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment