diff --git a/src/sbbs3/getmsg.cpp b/src/sbbs3/getmsg.cpp index a344af34387720cb78b4da13c3d6f443d87ae96c..0837a6f7a4e0b82cfb2ee98834e0c57c3e4cdb8a 100644 --- a/src/sbbs3/getmsg.cpp +++ b/src/sbbs3/getmsg.cpp @@ -119,19 +119,24 @@ void sbbs_t::show_msgattr(smbmsg_t* msg) /****************************************************************************/ /* Displays a message header to the screen */ /****************************************************************************/ -void sbbs_t::show_msghdr(smbmsg_t* msg) +void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg) { char str[MAX_PATH+1]; char age[64]; char *sender=NULL; int i; + smb_t saved_smb = this->smb; - attr(LIGHTGRAY); - if(useron.misc&CLRSCRN) - outchar(FF); - else - CRLF; + this->smb = *smb; // Needed for @-codes and JS bbs.smb_* properties + current_msg = msg; // Needed for @-codes and JS bbs.msg_* properties + attr(LIGHTGRAY); + if(!tos) { + if(useron.misc&CLRSCRN) + outchar(FF); + else + CRLF; + } if(!menu("msghdr", P_NOERROR)) { bprintf(text[MsgSubj],msg->subj); if(msg->tags && *msg->tags) @@ -170,23 +175,24 @@ void sbbs_t::show_msghdr(smbmsg_t* msg) bprintf(text[ForwardedFrom],sender ,timestr(*(time32_t *)msg->hfield_dat[i])); } + this->smb = saved_smb; } /****************************************************************************/ /* Displays message header and text (if not deleted) */ /****************************************************************************/ -void sbbs_t::show_msg(smbmsg_t* msg, long mode, post_t* post) +bool sbbs_t::show_msg(smb_t* smb, smbmsg_t* msg, long p_mode, post_t* post) { char* txt; if((msg->hdr.type == SMB_MSG_TYPE_NORMAL && post != NULL && (post->upvotes || post->downvotes)) || msg->hdr.type == SMB_MSG_TYPE_POLL) - msg->user_voted = smb_voted_already(&smb, msg->hdr.number - ,cfg.sub[smb.subnum]->misc&SUB_NAME ? useron.name : useron.alias, NET_NONE, NULL); + msg->user_voted = smb_voted_already(smb, msg->hdr.number + ,cfg.sub[smb->subnum]->misc&SUB_NAME ? useron.name : useron.alias, NET_NONE, NULL); - show_msghdr(msg); + show_msghdr(smb, msg); - if(msg->hdr.type == SMB_MSG_TYPE_POLL && post != NULL && smb.subnum < cfg.total_subs) { + if(msg->hdr.type == SMB_MSG_TYPE_POLL && post != NULL && smb->subnum < cfg.total_subs) { char* answer; int longest_answer = 0; @@ -222,8 +228,8 @@ void sbbs_t::show_msg(smbmsg_t* msg, long mode, post_t* post) bool results_visible = false; if((msg->hdr.auxattr&POLL_RESULTS_MASK) == POLL_RESULTS_OPEN) results_visible = true; - else if((msg->from_net.type == NET_NONE && sub_op(smb.subnum)) - || smb_msg_is_from(msg, cfg.sub[smb.subnum]->misc&SUB_NAME ? useron.name : useron.alias, NET_NONE, NULL)) + else if((msg->from_net.type == NET_NONE && sub_op(smb->subnum)) + || smb_msg_is_from(msg, cfg.sub[smb->subnum]->misc&SUB_NAME ? useron.name : useron.alias, NET_NONE, NULL)) results_visible = true; else if((msg->hdr.auxattr&POLL_RESULTS_MASK) == POLL_RESULTS_CLOSED) results_visible = (msg->hdr.auxattr&POLL_CLOSED) ? true : false; @@ -244,44 +250,46 @@ void sbbs_t::show_msg(smbmsg_t* msg, long mode, post_t* post) } if(!msg->user_voted && !(useron.misc&EXPERT) && !(msg->hdr.auxattr&POLL_CLOSED) && !(useron.rest&FLAG('V'))) mnemonics(text[VoteInThisPollNow]); - return; + return true; } - if((txt=smb_getmsgtxt(&smb, msg, 0)) != NULL) { - char* p = txt; - if(!(console&CON_RAW_IN)) { - mode|=P_WORDWRAP; - p = smb_getplaintext(msg, txt); - if(p == NULL) - p = txt; - else - bputs(text[MIMEDecodedPlainText]); - } - truncsp(p); - SKIP_CRLF(p); - putmsg(p, mode); - smb_freemsgtxt(txt); - if(column) - CRLF; - } - if((txt=smb_getmsgtxt(&smb,msg,GETMSGTXT_TAIL_ONLY))!=NULL) { - putmsg(txt, mode&(~P_WORDWRAP)); - smb_freemsgtxt(txt); + if((txt=smb_getmsgtxt(smb, msg, 0)) == NULL) + return false; + char* p = txt; + if(!(console&CON_RAW_IN)) { + p_mode|=P_WORDWRAP; + p = smb_getplaintext(msg, txt); + if(p == NULL) + p = txt; + else + bputs(text[MIMEDecodedPlainText]); } + truncsp(p); + SKIP_CRLF(p); + putmsg(p, p_mode, msg->columns); + smb_freemsgtxt(txt); + if(column) + CRLF; + if((txt=smb_getmsgtxt(smb,msg,GETMSGTXT_TAIL_ONLY))==NULL) + return false; + + putmsg(txt, p_mode&(~P_WORDWRAP)); + smb_freemsgtxt(txt); + return true; } /****************************************************************************/ /* Writes message header and text data to a text file */ /****************************************************************************/ -void sbbs_t::msgtotxt(smbmsg_t* msg, char *str, bool header, ulong mode) +bool sbbs_t::msgtotxt(smb_t* smb, smbmsg_t* msg, const char *fname, bool header, ulong gettxt_mode) { char *buf; char tmp[128]; int i; FILE *out; - if((out=fnopen(&i,str,O_WRONLY|O_CREAT|O_APPEND))==NULL) { - errormsg(WHERE,ERR_OPEN,str,0); - return; + if((out=fnopen(&i,fname,O_WRONLY|O_CREAT|O_APPEND))==NULL) { + errormsg(WHERE,ERR_OPEN,fname,0); + return false; } if(header) { fprintf(out,"\r\n"); @@ -302,14 +310,17 @@ void sbbs_t::msgtotxt(smbmsg_t* msg, char *str, bool header, ulong mode) fprintf(out,"\r\n\r\n"); } - buf=smb_getmsgtxt(&smb,msg,mode); + bool result = false; + buf=smb_getmsgtxt(smb, msg, gettxt_mode); if(buf!=NULL) { strip_invalid_attr(buf); fputs(buf,out); smb_freemsgtxt(buf); + result = true; } else if(smb_getmsgdatlen(msg)>2) - errormsg(WHERE,ERR_READ,smb.file,smb_getmsgdatlen(msg)); + errormsg(WHERE,ERR_READ,smb->file,smb_getmsgdatlen(msg)); fclose(out); + return result; } /****************************************************************************/ diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp index 5ab10728b4920b6050bcb746fb3aeb505131144a..03ffafc8e7e27790dc05d1c5e2e6a5883f9252f7 100644 --- a/src/sbbs3/js_bbs.cpp +++ b/src/sbbs3/js_bbs.cpp @@ -2632,7 +2632,7 @@ js_email(JSContext *cx, uintN argc, jsval *arglist) else if(JSVAL_IS_OBJECT(argv[i])) { if((hdrobj = JSVAL_TO_OBJECT(argv[i])) == NULL) return JS_FALSE; - if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg)) { + if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg, /* post: */NULL)) { if(!js_ParseMsgHeaderObject(cx, hdrobj, &msg)) return JS_FALSE; remsg = &msg; @@ -2668,13 +2668,11 @@ js_netmail(JSContext *cx, uintN argc, jsval *arglist) { jsval *argv=JS_ARGV(cx, arglist); int32 mode=0; - const char *def=""; - char* subj=(char *)def; - JSString* js_to; - JSString* js_subj=NULL; + char* to = NULL; + char* subj = NULL; + JSString* js_str; JSObject* hdrobj; sbbs_t* sbbs; - char* cstr; smb_t* resmb = NULL; smbmsg_t* remsg = NULL; smbmsg_t msg; @@ -2689,20 +2687,23 @@ js_netmail(JSContext *cx, uintN argc, jsval *arglist) if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL) return(JS_FALSE); - if((js_to=JS_ValueToString(cx, argv[0]))==NULL) - return(JS_FALSE); - - for(uintN i=1;i<argc;i++) { + for(uintN i=0; i<argc; i++) { if(JSVAL_IS_NUMBER(argv[i])) { if(!JS_ValueToInt32(cx,argv[i],&mode)) return JS_FALSE; } - else if(JSVAL_IS_STRING(argv[i])) - js_subj=JS_ValueToString(cx,argv[i]); + else if(JSVAL_IS_STRING(argv[i])) { + js_str = JS_ValueToString(cx, argv[i]); + if(to == NULL) { + JSSTRING_TO_MSTRING(cx, js_str, to, NULL); + } else if(subj == NULL) { + JSSTRING_TO_MSTRING(cx, js_str, subj, NULL); + } + } else if(JSVAL_IS_OBJECT(argv[i])) { if((hdrobj = JSVAL_TO_OBJECT(argv[i])) == NULL) return JS_FALSE; - if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg)) { + if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg, /* post: */NULL)) { if(!js_ParseMsgHeaderObject(cx, hdrobj, &msg)) return JS_FALSE; remsg = &msg; @@ -2710,24 +2711,11 @@ js_netmail(JSContext *cx, uintN argc, jsval *arglist) } } - if(js_subj!=NULL) { - JSSTRING_TO_MSTRING(cx, js_subj, subj, NULL); - if(subj==NULL) - return JS_FALSE; - } - - JSSTRING_TO_MSTRING(cx, js_to, cstr, NULL); - if(cstr==NULL) { - if(subj != def) - free(subj); - return JS_FALSE; - } rc=JS_SUSPENDREQUEST(cx); - JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->netmail(cstr, subj, mode, resmb, remsg))); + JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->netmail(to, subj, mode, resmb, remsg))); smb_freemsgmem(&msg); - if(subj != def) - free(subj); - free(cstr); + FREE_AND_NULL(subj); + FREE_AND_NULL(to); JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -3543,7 +3531,7 @@ js_post_msg(JSContext *cx, uintN argc, jsval *arglist) else if(JSVAL_IS_OBJECT(argv[n])) { if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL) return JS_FALSE; - if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg)) { + if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &resmb, &remsg, /* post: */NULL)) { if(!js_ParseMsgHeaderObject(cx, hdrobj, &msg)) return JS_FALSE; remsg = &msg; @@ -3559,6 +3547,82 @@ js_post_msg(JSContext *cx, uintN argc, jsval *arglist) return(JS_TRUE); } +static JSBool +js_show_msg(JSContext *cx, uintN argc, jsval *arglist) +{ + jsval *argv=JS_ARGV(cx, arglist); + int32 p_mode = 0; + uintN n; + JSObject* hdrobj; + sbbs_t* sbbs; + smb_t* smb = NULL; + smbmsg_t* msg = NULL; + post_t* post = NULL; + jsrefcount rc; + + JS_SET_RVAL(cx, arglist, JSVAL_FALSE); + + if((sbbs=js_GetPrivate(cx, JS_THIS_OBJECT(cx, arglist)))==NULL) + return(JS_FALSE); + + for(n=0; n<argc; n++) { + if(JSVAL_IS_NUMBER(argv[n])) { + if(!JS_ValueToInt32(cx, argv[n], &p_mode)) + return JS_FALSE; + } + else if(JSVAL_IS_OBJECT(argv[n])) { + if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL) + return JS_FALSE; + if(!js_GetMsgHeaderObjectPrivates(cx, hdrobj, &smb, &msg, &post)) { + return JS_FALSE; + } + } + } + if(smb == NULL || msg == NULL) + return JS_TRUE; + + rc=JS_SUSPENDREQUEST(cx); + JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->show_msg(smb, msg, p_mode, post))); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} + +static JSBool +js_show_msg_header(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; + + 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; + } + } + } + if(smb == NULL || msg == NULL) + return JS_TRUE; + + rc=JS_SUSPENDREQUEST(cx); + sbbs->show_msghdr(smb, msg); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} + static JSBool js_msgscan_cfg(JSContext *cx, uintN argc, jsval *arglist) { @@ -4138,11 +4202,21 @@ static jsSyncMethodSpec js_bbs_functions[] = { }, {"post_msg", js_post_msg, 1, JSTYPE_BOOLEAN, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>WM_NONE</tt>] [,object reply_header]") ,JSDOCSTR("post a message in the specified message sub-board (number or internal code) " - "with optinal <i>mode</i> (bitfield)<br>" + "with optional <i>mode</i> (bitfield)<br>" "If <i>reply_header</i> is specified (a header object returned from <i>MsgBase.get_msg_header()</i>), that header " "will be used for the in-reply-to header fields.") ,313 }, + {"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>)") + ,31702 + }, + {"show_msg_header", js_show_msg_header, 1, JSTYPE_VOID, JSDOCSTR("[object header]") + ,JSDOCSTR("show a message's header (only)<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/js_console.cpp b/src/sbbs3/js_console.cpp index e15af41ccf2d164c21f119345c3778e40492f22f..83b7d319d177358b70481a31f8c0bb16ba6a4270 100644 --- a/src/sbbs3/js_console.cpp +++ b/src/sbbs3/js_console.cpp @@ -1156,6 +1156,7 @@ js_putmsg(JSContext *cx, uintN argc, jsval *arglist) { jsval *argv=JS_ARGV(cx, arglist); int32 mode=0; + int32 columns=0; JSString* str; sbbs_t* sbbs; char* cstr; @@ -1174,12 +1175,16 @@ js_putmsg(JSContext *cx, uintN argc, jsval *arglist) if(!JS_ValueToInt32(cx,argv[1],&mode)) return JS_FALSE; } + if(argc>2 && JSVAL_IS_NUMBER(argv[2])) { + if(!JS_ValueToInt32(cx,argv[2],&columns)) + return JS_FALSE; + } JSSTRING_TO_MSTRING(cx, str, cstr, NULL); if(cstr==NULL) return JS_FALSE; rc=JS_SUSPENDREQUEST(cx); - sbbs->putmsg(cstr,mode); + sbbs->putmsg(cstr, mode, columns); free(cstr); JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); @@ -1921,9 +1926,10 @@ static jsSyncMethodSpec js_console_functions[] = { ,JSDOCSTR("display one or more values as raw strings followed by a single carriage-return/line-feed pair (new-line)") ,315 }, - {"putmsg", js_putmsg, 1, JSTYPE_VOID, JSDOCSTR("text [,mode=<tt>P_NONE</tt>]") + {"putmsg", js_putmsg, 1, JSTYPE_VOID, JSDOCSTR("text [,mode=<tt>P_NONE</tt>] [,orig_columns=0]") ,JSDOCSTR("display message text (Ctrl-A codes, @-codes, pipe codes, etc), " - "see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits") + "see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits.<br>" + "When <tt>P_WORDWRAP</tt> mode flag is specified, <i>orig_columns</i> specifies the original text column width, if known") ,310 }, {"center", js_center, 1, JSTYPE_VOID, JSDOCSTR("text") diff --git a/src/sbbs3/js_msgbase.c b/src/sbbs3/js_msgbase.c index 16039843e04316c225a887c536747ebaf96d2050..37e7d97c8c558d5a60557e4f8e2d84039e1c48a7 100644 --- a/src/sbbs3/js_msgbase.c +++ b/src/sbbs3/js_msgbase.c @@ -53,6 +53,7 @@ typedef struct private_t *p; BOOL expand_fields; smbmsg_t msg; + post_t post; } privatemsg_t; @@ -954,7 +955,7 @@ BOOL DLLCALL js_ParseMsgHeaderObject(JSContext* cx, JSObject* obj, smbmsg_t* msg } /* obj must've been previously returned from get_msg_header() */ -BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* obj, smb_t** smb, smbmsg_t** msg) +BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* obj, smb_t** smb, smbmsg_t** msg, post_t** post) { privatemsg_t* p; @@ -968,6 +969,8 @@ BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* obj, smb_t** } if(msg != NULL) *msg = &p->msg; + if(post != NULL) + *post = &p->post; return TRUE; } @@ -1674,6 +1677,7 @@ js_get_all_msg_headers(JSContext *cx, uintN argc, jsval *arglist) JSObject* retobj; char numstr[16]; JSBool include_votes=JS_FALSE; + JSBool expand_fields=JS_TRUE; post_t* post; idxrec_t* idx; @@ -1706,8 +1710,15 @@ js_get_all_msg_headers(JSContext *cx, uintN argc, jsval *arglist) return JS_FALSE; } - if(argc && JSVAL_IS_BOOLEAN(argv[0])) - include_votes = JSVAL_TO_BOOLEAN(argv[0]); + uintN argn = 0; + if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) { + include_votes = JSVAL_TO_BOOLEAN(argv[argn]); + argn++; + } + if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) { + expand_fields = JSVAL_TO_BOOLEAN(argv[argn]); + argn++; + } retobj = JS_NewObject(cx, NULL, NULL, obj); JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(retobj)); @@ -1782,9 +1793,10 @@ js_get_all_msg_headers(JSContext *cx, uintN argc, jsval *arglist) /* Parse boolean arguments first */ p->p=priv; - p->expand_fields=JS_TRUE; /* This parameter defaults to true */ + p->expand_fields = expand_fields; p->msg.idx = post[off].idx; + p->post = post[off]; rc=JS_SUSPENDREQUEST(cx); priv->smb_result = smb_getmsghdr(&(priv->smb), &(p->msg)); @@ -1848,8 +1860,8 @@ js_put_msg_header(JSContext *cx, uintN argc, jsval *arglist) jsval *argv=JS_ARGV(cx, arglist); uintN n; JSBool by_offset=JS_FALSE; - JSBool msg_specified=JS_FALSE; smbmsg_t msg; + smbmsg_t* modmsg = &msg; JSObject* hdr=NULL; private_t* p; jsrefcount rc; @@ -1880,9 +1892,6 @@ js_put_msg_header(JSContext *cx, uintN argc, jsval *arglist) if(!JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number)) return JS_FALSE; } - msg_specified=JS_TRUE; - n++; - break; } else if(JSVAL_IS_STRING(argv[n])) { /* Get by ID */ JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL); HANDLE_PENDING(cx, cstr); @@ -1896,59 +1905,57 @@ js_put_msg_header(JSContext *cx, uintN argc, jsval *arglist) } free(cstr); JS_RESUMEREQUEST(cx, rc); - msg_specified=JS_TRUE; - n++; - break; + } + else if(JSVAL_IS_OBJECT(argv[n])) { + hdr = JSVAL_TO_OBJECT(argv[n++]); } } - if(!msg_specified) - return JS_TRUE; - - if(n==argc || !JSVAL_IS_OBJECT(argv[n])) /* no header supplied? */ + if(hdr == NULL) /* no header supplied? */ return JS_TRUE; - hdr = JSVAL_TO_OBJECT(argv[n++]); - privatemsg_t* mp; mp=(privatemsg_t*)JS_GetPrivate(cx,hdr); - if(mp != NULL && mp->expand_fields) { - JS_ReportError(cx, "Message header has 'expanded fields'", WHERE); - return JS_FALSE; + if(mp != NULL) { + if(mp->expand_fields) { + JS_ReportError(cx, "Message header has 'expanded fields'", WHERE); + return JS_FALSE; + } + modmsg = &mp->msg; } rc=JS_SUSPENDREQUEST(cx); - if((p->smb_result=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS) { + if((p->smb_result=smb_getmsgidx(&(p->smb), modmsg))!=SMB_SUCCESS) { JS_RESUMEREQUEST(cx, rc); return JS_TRUE; } - if((p->smb_result=smb_lockmsghdr(&(p->smb),&msg))!=SMB_SUCCESS) { + if((p->smb_result=smb_lockmsghdr(&(p->smb),modmsg))!=SMB_SUCCESS) { JS_RESUMEREQUEST(cx, rc); return JS_TRUE; } do { - if((p->smb_result=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS) + if((p->smb_result=smb_getmsghdr(&(p->smb), modmsg))!=SMB_SUCCESS) break; - smb_freemsghdrmem(&msg); /* prevent duplicate header fields */ + smb_freemsghdrmem(modmsg); /* prevent duplicate header fields */ JS_RESUMEREQUEST(cx, rc); - if(!parse_header_object(cx, p, hdr, &msg, TRUE)) { + if(!parse_header_object(cx, p, hdr, modmsg, TRUE)) { SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)"); ret=JS_FALSE; break; } rc=JS_SUSPENDREQUEST(cx); - if((p->smb_result=smb_putmsg(&(p->smb), &msg))!=SMB_SUCCESS) + if((p->smb_result=smb_putmsg(&(p->smb), modmsg))!=SMB_SUCCESS) break; JS_SET_RVAL(cx, arglist, JSVAL_TRUE); } while(0); - smb_unlockmsghdr(&(p->smb),&msg); + smb_unlockmsghdr(&(p->smb),modmsg); smb_freemsgmem(&msg); JS_RESUMEREQUEST(cx, rc); @@ -2876,14 +2883,14 @@ static jsSyncMethodSpec js_msgbase_functions[] = { "if you will be re-writing the header later with <i>put_msg_header()</i>") ,312 }, - {"get_all_msg_headers", js_get_all_msg_headers, 1, JSTYPE_ARRAY, JSDOCSTR("[include_votes=<tt>false</tt>]") + {"get_all_msg_headers", js_get_all_msg_headers, 1, JSTYPE_ARRAY, JSDOCSTR("[include_votes=<tt>false</tt>] [,expand_fields=<tt>true</tt>]") ,JSDOCSTR("returns an object of all message headers indexed by message number.<br>" "Message headers returned by this function include 2 additional properties: <tt>upvotes</tt> and <tt>downvotes</tt>.<br>" "Vote messages are excluded by default.") ,316 }, - {"put_msg_header", js_put_msg_header, 2, JSTYPE_BOOLEAN, JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_offset, object header") - ,JSDOCSTR("modify an existing message header") + {"put_msg_header", js_put_msg_header, 2, JSTYPE_BOOLEAN, JSDOCSTR("[by_offset=<tt>false</tt>,] [number_or_offset_or_id,] object header") + ,JSDOCSTR("modify an existing message header (must have been 'got' without expanded fields)") ,310 }, {"get_msg_body", js_get_msg_body, 2, JSTYPE_STRING, JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_offset_or_id_or_header [,strip_ctrl_a=<tt>false</tt>] " diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp index 8b47738fb86c09b62ae3e0945d33c1794a63483c..01553e8b5b6e09ff07fcc864e8cf3504333a1c73 100644 --- a/src/sbbs3/putmsg.cpp +++ b/src/sbbs3/putmsg.cpp @@ -47,7 +47,7 @@ /* the attributes prior to displaying the message are always restored. */ /* Stops parsing/displaying upon CTRL-Z (only in P_CPM_EOF mode). */ /****************************************************************************/ -char sbbs_t::putmsg(const char *buf, long mode) +char sbbs_t::putmsg(const char *buf, long mode, long org_cols) { char tmpatr,tmp2[256],tmp3[128]; char ret; @@ -77,7 +77,9 @@ char sbbs_t::putmsg(const char *buf, long mode) *wrapoff = 0; } char *wrapped; - if((wrapped=::wordwrap((char*)str+l, cols-1, 79, /* handle_quotes: */TRUE)) == NULL) + if(org_cols < TERM_COLS_MIN) + org_cols = TERM_COLS_DEFAULT; + if((wrapped=::wordwrap((char*)str+l, cols - 1, org_cols - 1, /* handle_quotes: */TRUE)) == NULL) errormsg(WHERE,ERR_ALLOC,"wordwrap buffer",0); else { truncsp_lines(wrapped); @@ -305,7 +307,7 @@ char sbbs_t::putmsg(const char *buf, long mode) } if(memcmp(str+l, "@WORDWRAP@", 10) == 0) { l += 10; - putmsg(str+l, mode|P_WORDWRAP); + putmsg(str+l, mode|P_WORDWRAP, org_cols); break; } diff --git a/src/sbbs3/readmail.cpp b/src/sbbs3/readmail.cpp index fef033743cecf519aebb3683e59333c387a20c3e..543ada4a9b9f01ed4023b558ade30004e7eaf710 100644 --- a/src/sbbs3/readmail.cpp +++ b/src/sbbs3/readmail.cpp @@ -259,7 +259,7 @@ void sbbs_t::readmail(uint usernumber, int which, long lm_mode) if(domsg && !(sys_status&SS_ABORT)) { - show_msg(&msg + show_msg(&smb, &msg ,msg.from_ext && msg.idx.from==1 && !msg.from_net.type ? 0:P_NOATCODES); @@ -739,7 +739,7 @@ void sbbs_t::readmail(uint usernumber, int which, long lm_mode) */ bputs(text[FileToWriteTo]); if(getstr(str,50,K_LINE)) - msgtotxt(&msg,str, /* header: */true, /* mode: */GETMSGTXT_ALL); + msgtotxt(&smb, &msg, str, /* header: */true, /* mode: */GETMSGTXT_ALL); break; case 'E': editmsg(&msg,INVALID_SUB); diff --git a/src/sbbs3/readmsgs.cpp b/src/sbbs3/readmsgs.cpp index 2f5b01fe356f5ffc859cc0aa4a25879a9df13017..1ecaffb61fb27d3690bdd75daeac6c3a24be9a1d 100644 --- a/src/sbbs3/readmsgs.cpp +++ b/src/sbbs3/readmsgs.cpp @@ -771,7 +771,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find) msg.upvotes = post[smb.curmsg].upvotes; msg.downvotes = post[smb.curmsg].downvotes; msg.total_votes = post[smb.curmsg].total_votes; - show_msg(&msg + show_msg(&smb, &msg ,msg.from_ext && !strcmp(msg.from_ext,"1") && !msg.from_net.type ? 0:P_NOATCODES ,&post[smb.curmsg]); @@ -1365,7 +1365,7 @@ int sbbs_t::scanposts(uint subnum, long mode, const char *find) */ bputs(text[FileToWriteTo]); if(getstr(str,50,K_LINE)) - msgtotxt(&msg,str, /* header: */true, /* mode: */GETMSGTXT_ALL); + msgtotxt(&smb, &msg, str, /* header: */true, /* mode: */GETMSGTXT_ALL); break; case 'U': /* User edit */ useredit(cfg.sub[subnum]->misc&SUB_NAME diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index bdccfbf1f25c47ec0ed01b6d1c0aa2441a60b329..07c532f85e2623f0d71e0ec7fb4d7e957010b320 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -645,7 +645,7 @@ public: ,const char *to, const char* from, char** editor=NULL); char* quotes_fname(int xedit, char* buf, size_t len); char* msg_tmp_fname(int xedit, char* fname, size_t len); - char putmsg(const char *str, long mode); + char putmsg(const char *str, long mode, long org_cols = 0); 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); @@ -674,9 +674,9 @@ public: /* getmsg.cpp */ int loadmsg(smbmsg_t *msg, ulong number); void show_msgattr(smbmsg_t*); - void show_msghdr(smbmsg_t* msg); - void show_msg(smbmsg_t* msg, long mode, post_t* post = NULL); - void msgtotxt(smbmsg_t* msg, char *str, bool header, ulong mode); + void show_msghdr(smb_t*, smbmsg_t*); + bool show_msg(smb_t*, smbmsg_t*, long p_mode = 0, post_t* post = NULL); + bool msgtotxt(smb_t*, smbmsg_t*, const char *fname, bool header = true, ulong gettxt_mode = GETMSGTXT_ALL); ulong getlastmsg(uint subnum, uint32_t *ptr, time_t *t); time_t getmsgtime(uint subnum, ulong ptr); ulong getmsgnum(uint subnum, time_t t); @@ -1317,7 +1317,7 @@ extern "C" { /* js_msgbase.c */ DLLEXPORT JSObject* DLLCALL js_CreateMsgBaseClass(JSContext* cx, JSObject* parent, scfg_t* cfg); DLLEXPORT BOOL DLLCALL js_ParseMsgHeaderObject(JSContext* cx, JSObject* hdrobj, smbmsg_t*); - DLLEXPORT BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* hdrobj, smb_t**, smbmsg_t**); + DLLEXPORT BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* hdrobj, smb_t**, smbmsg_t**, post_t**); /* js_socket.c */ DLLEXPORT JSObject* DLLCALL js_CreateSocketClass(JSContext* cx, JSObject* parent); diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp index 05bddd041f26ffff9818994306f7d9edb397e971..e2de158202a26b15f626adf9eeac6125837ecf2f 100644 --- a/src/sbbs3/writemsg.cpp +++ b/src/sbbs3/writemsg.cpp @@ -1370,7 +1370,7 @@ void sbbs_t::editmsg(smbmsg_t *msg, uint subnum) msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp)); removecase(msgtmp); - msgtotxt(msg,msgtmp, /* header: */false, /* mode: */GETMSGTXT_ALL); + msgtotxt(&smb, msg, msgtmp, /* header: */false, /* mode: */GETMSGTXT_ALL); if(!editfile(msgtmp, /* msg: */true)) return; length=(long)flength(msgtmp);