...
 
Commits (4)
/* Synchronet message retrieval functions */
/* $Id: getmsg.cpp,v 1.102 2020/05/08 05:19:29 rswindell Exp $ */
// vi: tabstop=4
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
......@@ -16,21 +13,9 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
......@@ -357,6 +342,8 @@ bool sbbs_t::show_msg(smb_t* smb, smbmsg_t* msg, long p_mode, post_t* post)
p_mode |= cfg.sub[smb->subnum]->pmode;
p_mode &= ~cfg.sub[smb->subnum]->n_pmode;
}
if(console & CON_RAW_IN)
p_mode = P_NOATCODES;
putmsg(p, p_mode, msg->columns);
smb_freemsgtxt(txt);
if(column)
......
/* js_bbs.cpp */
/* Synchronet JavaScript "bbs" Object */
/* $Id: js_bbs.cpp,v 1.198 2020/05/26 03:07:05 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
......@@ -17,21 +13,9 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
......@@ -3630,6 +3614,90 @@ js_post_msg(JSContext *cx, uintN argc, jsval *arglist)
return(JS_TRUE);
}
static JSBool
js_forward_msg(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;
char* to = NULL;
char* subject = NULL;
char* comment = NULL;
jsrefcount rc;
if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
for(n=0; n<argc; n++) {
if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(argv[n])) {
if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL)
return JS_FALSE;
if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &smb, &msg, /* post_t */NULL)) {
JS_ReportError(cx, "msg hdr object lacks privates");
return JS_FALSE;
}
} else if(JSVAL_IS_STRING(argv[n])) {
JSString* str = JS_ValueToString(cx, argv[n]);
if(to == NULL) {
JSSTRING_TO_MSTRING(cx, str, to, NULL);
} else if(subject == NULL) {
JSSTRING_TO_MSTRING(cx, str, subject, NULL);
} else if(comment == NULL) {
JSSTRING_TO_MSTRING(cx, str, comment, NULL);
}
}
}
if(smb != NULL && msg != NULL && to != NULL) {
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->forwardmsg(smb, msg, to, subject, comment)));
JS_RESUMEREQUEST(cx, rc);
}
FREE_AND_NULL(subject);
FREE_AND_NULL(comment);
FREE_AND_NULL(to);
return JS_TRUE;
}
static JSBool
js_edit_msg(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;
jsrefcount rc;
if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
for(n=0; n<argc; n++) {
if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(argv[n])) {
if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL)
return JS_FALSE;
if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &smb, &msg, /* post_t */NULL)) {
JS_ReportError(cx, "msg hdr object lacks privates");
return JS_FALSE;
}
}
}
if(smb != NULL && msg != NULL) {
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->editmsg(smb, msg)));
JS_RESUMEREQUEST(cx, rc);
}
return JS_TRUE;
}
static JSBool
js_show_msg(JSContext *cx, uintN argc, jsval *arglist)
{
......@@ -3712,17 +3780,16 @@ js_show_msg_header(JSContext *cx, uintN argc, jsval *arglist)
}
}
}
if(smb == NULL || msg == NULL)
return JS_TRUE;
rc=JS_SUSPENDREQUEST(cx);
sbbs->show_msghdr(smb, msg, subject, from, to);
JS_RESUMEREQUEST(cx, rc);
if(smb != NULL && msg != NULL) {
rc=JS_SUSPENDREQUEST(cx);
sbbs->show_msghdr(smb, msg, subject, from, to);
JS_RESUMEREQUEST(cx, rc);
}
FREE_AND_NULL(subject);
FREE_AND_NULL(from);
FREE_AND_NULL(to);
return(JS_TRUE);
return JS_TRUE;
}
static JSBool
......@@ -4387,6 +4454,14 @@ static jsSyncMethodSpec js_bbs_functions[] = {
"will be used for the in-reply-to header fields.")
,313
},
{"forward_msg", js_forward_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("object header, string to [,string subject] [,string comment]")
,JSDOCSTR("Forward a message")
,31802
},
{"edit_msg", js_edit_msg, 1, JSTYPE_BOOLEAN, JSDOCSTR("object header")
,JSDOCSTR("Edit a message")
,31802
},
{"show_msg", js_show_msg, 1, JSTYPE_BOOLEAN, JSDOCSTR("object header [,mode=<tt>P_NONE</tt>] ")
,JSDOCSTR("show a message's header and body (text) with optional print <i>mode</i> (bitfield)<br>"
"<i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)")
......
......@@ -1109,11 +1109,12 @@ static JSBool
js_prompt(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
char instr[81];
char instr[128] = "";
JSString * str;
sbbs_t* sbbs;
jsrefcount rc;
char* prompt=NULL;
int32 mode = K_EDIT;
size_t result;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
......@@ -1121,16 +1122,22 @@ js_prompt(JSContext *cx, uintN argc, jsval *arglist)
if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
if(argc) {
JSVALUE_TO_MSTRING(cx, argv[0], prompt, NULL);
uintN argn = 0;
if(argc > argn && JSVAL_IS_STRING(argv[argn])) {
JSVALUE_TO_MSTRING(cx, argv[argn], prompt, NULL);
if(prompt==NULL)
return(JS_FALSE);
argn++;
}
if(argc > argn && JSVAL_IS_STRING(argv[argn])) {
JSVALUE_TO_STRBUF(cx, argv[argn], instr, sizeof(instr), NULL);
argn++;
}
if(argc > argn && JSVAL_IS_NUMBER(argv[argn])) {
if(!JS_ValueToInt32(cx,argv[argn], &mode))
return JS_FALSE;
argn++;
}
if(argc>1) {
JSVALUE_TO_STRBUF(cx, argv[1], instr, sizeof(instr), NULL);
} else
instr[0]=0;
rc=JS_SUSPENDREQUEST(cx);
if(prompt != NULL) {
......@@ -1138,7 +1145,7 @@ js_prompt(JSContext *cx, uintN argc, jsval *arglist)
free(prompt);
}
result = sbbs->getstr(instr,sizeof(instr)-1,K_EDIT);
result = sbbs->getstr(instr, sizeof(instr)-1, mode);
sbbs->attr(LIGHTGRAY);
if(!result) {
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
......@@ -1191,8 +1198,8 @@ static jsSyncMethodSpec js_global_functions[] = {
,JSDOCSTR("print an alert message (ala client-side JS)")
,310
},
{"prompt", js_prompt, 1, JSTYPE_STRING, JSDOCSTR("[value]")
,JSDOCSTR("displays a prompt (<i>value</i>) and returns a string of user input (ala clent-side JS)")
{"prompt", js_prompt, 1, JSTYPE_STRING, JSDOCSTR("[text] [,value] [,mode=K_EDIT]")
,JSDOCSTR("displays a prompt (<i>text</i>) and returns a string of user input (ala client-side JS)")
,310
},
{"confirm", js_confirm, 1, JSTYPE_BOOLEAN, JSDOCSTR("value")
......
......@@ -422,7 +422,7 @@ void sbbs_t::readmail(uint usernumber, int which, long lm_mode)
if(!getstr(str, sizeof(str) - 1, K_TRIM))
break;
smb_getmsgidx(&smb,&msg);
if(!forwardmail(&msg, str))
if(!forwardmsg(&smb, &msg, str))
break;
domsg=1;
if(smb.curmsg<smb.msgs-1) smb.curmsg++;
......@@ -642,7 +642,7 @@ void sbbs_t::readmail(uint usernumber, int which, long lm_mode)
msgtotxt(&smb, &msg, str, /* header: */true, /* mode: */GETMSGTXT_ALL);
break;
case 'E':
editmsg(&msg,INVALID_SUB);
editmsg(&smb, &msg);
break;
case 'T':
domsg=0;
......
/* Synchronet public message reading function */
// vi: tabstop=4
/* $Id: readmsgs.cpp,v 1.133 2020/05/14 03:04:51 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
......@@ -16,21 +13,9 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
......@@ -949,7 +934,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
}
}
FREE_AND_NULL(post);
editmsg(&msg,subnum);
editmsg(&smb, &msg);
break;
case 'F': /* find text in messages */
domsg=0;
......@@ -1245,7 +1230,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find)
break;
case 'E': /* edit last post */
FREE_AND_NULL(post);
editmsg(&msg,subnum);
editmsg(&smb, &msg);
break;
case 'H': /* View message header */
dump_msghdr(&msg);
......
......@@ -681,13 +681,13 @@ public:
bool msgabort(void);
bool email(int usernumber, const char *top = NULL, const char *title = NULL
, long mode = WM_NONE, smb_t* resmb = NULL, smbmsg_t* remsg = NULL);
bool forwardmail(smbmsg_t* msg, const char* to, const char* subject = NULL, const char* comment = NULL);
bool forwardmsg(smb_t*, smbmsg_t*, const char* to, const char* subject = NULL, const char* comment = NULL);
void removeline(char *str, char *str2, char num, char skip);
ulong msgeditor(char *buf, const char *top, char *title);
bool editfile(char *path, bool msg=false);
ushort chmsgattr(smbmsg_t);
bool quotemsg(smb_t*, smbmsg_t*, bool tails = false);
void editmsg(smbmsg_t* msg, uint subnum);
bool editmsg(smb_t*, smbmsg_t*);
void editor_inf(int xeditnum, const char *to, const char* from, const char *subj, long mode
,uint subnum, const char* tagfile);
bool copyfattach(uint to, uint from, const char* subj);
......
......@@ -1324,11 +1324,11 @@ bool sbbs_t::copyfattach(uint to, uint from, const char* subj)
}
/****************************************************************************/
/* Forwards mail 'orgmsg' to 'to' with optional 'comment'. */
/* Forwards msg 'orgmsg' to 'to' with optional 'comment' */
/* If comment is NULL, comment lines will be prompted for. */
/* If comment is a zero-length string, no comments will be included. */
/****************************************************************************/
bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject, const char* comment)
bool sbbs_t::forwardmsg(smb_t* smb, smbmsg_t* orgmsg, const char* to, const char* subject, const char* comment)
{
char str[256],touser[128];
char tmp[512];
......@@ -1385,7 +1385,7 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject,
msg.hdr.when_written = msg.hdr.when_imported;
smb_hfield_str(&msg, SUBJECT, subject);
add_msg_ids(&cfg, &smb, &msg, orgmsg);
add_msg_ids(&cfg, smb, &msg, orgmsg);
smb_hfield_str(&msg,SENDER,useron.alias);
SAFEPRINTF(str,"%u",useron.number);
......@@ -1491,17 +1491,17 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject,
smb_hfield_string(&msg, SMB_COMMENT, pg);
// Re-use the original message's data
if((result = smb_open_da(&smb)) != SMB_SUCCESS) {
if((result = smb_open_da(smb)) != SMB_SUCCESS) {
smb_freemsgmem(&msg);
errormsg(WHERE, ERR_OPEN, smb.file, result, smb.last_error);
errormsg(WHERE, ERR_OPEN, smb->file, result, smb->last_error);
return false;
}
if((result = smb_incmsg_dfields(&smb, orgmsg, 1)) != SMB_SUCCESS) {
if((result = smb_incmsg_dfields(smb, orgmsg, 1)) != SMB_SUCCESS) {
smb_freemsgmem(&msg);
errormsg(WHERE, ERR_WRITE, smb.file, result, smb.last_error);
errormsg(WHERE, ERR_WRITE, smb->file, result, smb->last_error);
return false;
}
smb_close_da(&smb);
smb_close_da(smb);
msg.dfield = orgmsg->dfield;
msg.hdr.offset = orgmsg->hdr.offset;
......@@ -1512,12 +1512,12 @@ bool sbbs_t::forwardmail(smbmsg_t* orgmsg, const char* to, const char* subject,
msg.hdr.auxattr |= MSG_FILEATTACH;
}
result = smb_addmsghdr(&smb, &msg, smb_storage_mode(&cfg, &smb));
result = smb_addmsghdr(smb, &msg, smb_storage_mode(&cfg, smb));
msg.dfield = NULL;
smb_freemsgmem(&msg);
if(result != SMB_SUCCESS) {
errormsg(WHERE, ERR_WRITE, smb.file, result, smb.last_error);
smb_freemsg_dfields(&smb, orgmsg, 1);
errormsg(WHERE, ERR_WRITE, smb->file, result, smb->last_error);
smb_freemsg_dfields(smb, orgmsg, 1);
return false;
}
......@@ -1574,7 +1574,7 @@ void sbbs_t::automsg()
/****************************************************************************/
/* Edits messages */
/****************************************************************************/
void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
bool sbbs_t::editmsg(smb_t* smb, smbmsg_t *msg)
{
char buf[SDT_BLOCK_LEN];
char msgtmp[MAX_PATH+1];
......@@ -1584,36 +1584,36 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
FILE *instream;
if(!msg->hdr.total_dfields)
return;
return false;
msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp));
removecase(msgtmp);
msgtotxt(&smb, msg, msgtmp, /* header: */false, /* mode: */GETMSGTXT_ALL);
msgtotxt(smb, msg, msgtmp, /* header: */false, /* mode: */GETMSGTXT_ALL);
if(!editfile(msgtmp, /* msg: */true))
return;
return false;
length=(long)flength(msgtmp);
if(length<1L)
return;
return false;
length+=2; /* +2 for translation string */
if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
return;
if((i=smb_locksmbhdr(smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_LOCK,smb->file,i,smb->last_error);
return false;
}
if((i=smb_getstatus(&smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
return;
if((i=smb_getstatus(smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_READ,smb->file,i,smb->last_error);
return false;
}
if(!(smb.status.attr&SMB_HYPERALLOC)) {
if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
return;
if(!(smb->status.attr&SMB_HYPERALLOC)) {
if((i=smb_open_da(smb))!=SMB_SUCCESS) {
errormsg(WHERE,ERR_OPEN,smb->file,i,smb->last_error);
return false;
}
if((i=smb_freemsg_dfields(&smb,msg,1))!=SMB_SUCCESS)
errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
if((i=smb_freemsg_dfields(smb,msg,1))!=SMB_SUCCESS)
errormsg(WHERE,ERR_WRITE,smb->file,i,smb->last_error);
}
msg->dfield[0].type=TEXT_BODY; /* Make one single data field */
......@@ -1626,30 +1626,30 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
}
if(smb.status.attr&SMB_HYPERALLOC)
offset=smb_hallocdat(&smb);
if(smb->status.attr&SMB_HYPERALLOC)
offset=smb_hallocdat(smb);
else {
if((subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_FAST)
|| (subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL))
offset=smb_fallocdat(&smb,length,1);
if((smb->subnum!=INVALID_SUB && cfg.sub[smb->subnum]->misc&SUB_FAST)
|| (smb->subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL))
offset=smb_fallocdat(smb,length,1);
else
offset=smb_allocdat(&smb,length,1);
smb_close_da(&smb);
offset=smb_allocdat(smb,length,1);
smb_close_da(smb);
}
msg->hdr.offset=offset;
if((file=open(msgtmp,O_RDONLY|O_BINARY))==-1
|| (instream=fdopen(file,"rb"))==NULL) {
smb_unlocksmbhdr(&smb);
smb_freemsgdat(&smb,offset,length,1);
smb_unlocksmbhdr(smb);
smb_freemsgdat(smb,offset,length,1);
errormsg(WHERE,ERR_OPEN,msgtmp,O_RDONLY|O_BINARY);
return;
return false;
}
setvbuf(instream,NULL,_IOFBF,2*1024);
fseek(smb.sdt_fp,offset,SEEK_SET);
fseek(smb->sdt_fp,offset,SEEK_SET);
xlat=XLAT_NONE;
fwrite(&xlat,2,1,smb.sdt_fp);
fwrite(&xlat,2,1,smb->sdt_fp);
x=SDT_BLOCK_LEN-2; /* Don't read/write more than 255 */
while(!feof(instream)) {
memset(buf,0,x);
......@@ -1658,16 +1658,17 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
break;
if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
buf[j-1]=buf[j-2]=0; /* Convert to NULL */
fwrite(buf,j,1,smb.sdt_fp);
fwrite(buf,j,1,smb->sdt_fp);
x=SDT_BLOCK_LEN;
}
fflush(smb.sdt_fp);
fflush(smb->sdt_fp);
fclose(instream);
smb_unlocksmbhdr(&smb);
smb_unlocksmbhdr(smb);
msg->hdr.length=(ushort)smb_getmsghdrlen(msg);
if((i=smb_putmsghdr(&smb,msg))!=SMB_SUCCESS)
errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
if((i=smb_putmsghdr(smb,msg))!=SMB_SUCCESS)
errormsg(WHERE,ERR_WRITE,smb->file,i,smb->last_error);
return i == SMB_SUCCESS;
}
/****************************************************************************/
......