Newer
Older
dirnum=get_dirnum(cx,sbbs,argv[0], argc == 0);
if(dirnum>=sbbs->cfg.total_dirs) {
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
return(JS_TRUE);
}
for(uintN i=1;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_str = JS_ValueToString(cx, argv[i]);
JSSTRING_TO_MSTRING(cx, js_str, fspec, NULL);
if(fspec==NULL)
return JS_FALSE;
}
}
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(sbbs->listfileinfo(dirnum,padfname(fspec,buf),mode)));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_postmsg(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
int32 mode=0;
uint subnum;
uintN n;
JSObject* hdrobj;
sbbs_t* sbbs;
smbmsg_t* remsg=NULL;
smbmsg_t msg;
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
subnum=get_subnum(cx,sbbs,argv,argc,0);
if(subnum>=sbbs->cfg.total_subs) // invalid sub-board
return(JS_TRUE);
ZERO_VAR(msg);
for(n=1; n<argc; n++) {
if(JSVAL_IS_NUMBER(argv[n])) {
if(!JS_ValueToInt32(cx,argv[n],&mode))
return JS_FALSE;
}
else if(JSVAL_IS_OBJECT(argv[n])) {
if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL)
return(JS_TRUE);
remsg=&msg;
if(!js_ParseMsgHeaderObject(cx,hdrobj,remsg))
return(JS_FALSE);
}
}
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->postmsg(subnum,remsg,mode)));
smb_freemsgmem(&msg);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_msgscan_cfg(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
int32 mode=SUB_CFG_NSCAN;
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
if(argc && JSVAL_IS_NUMBER(argv[0])) {
if(!JS_ValueToInt32(cx,argv[0],&mode))
return JS_FALSE;
}
rc=JS_SUSPENDREQUEST(cx);
sbbs->new_scan_cfg(mode);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_msgscan_ptrs(JSContext *cx, uintN argc, jsval *arglist)
{
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
sbbs->new_scan_ptr_cfg();
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_msgscan_reinit(JSContext *cx, uintN argc, jsval *arglist)
{
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
for(uint i=0;i<sbbs->cfg.total_subs;i++) {
sbbs->subscan[i].ptr=sbbs->subscan[i].sav_ptr;
sbbs->subscan[i].last=sbbs->subscan[i].sav_last;
}
sbbs->bputs(sbbs->text[MsgPtrsInitialized]);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_scansubs(JSContext *cx, uintN argc, jsval *arglist)
jsval *argv=JS_ARGV(cx, arglist);
int32 mode=SCAN_NEW;
BOOL all=FALSE;
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
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_BOOLEAN(argv[i]))
all=JSVAL_TO_BOOLEAN(argv[i]);
}
rc=JS_SUSPENDREQUEST(cx);
if(all)
sbbs->scanallsubs(mode);
else
sbbs->scansubs(mode);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_scandirs(JSContext *cx, uintN argc, jsval *arglist)
jsval *argv=JS_ARGV(cx, arglist);
int32 mode=0;
BOOL all=FALSE;
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
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_BOOLEAN(argv[i]))
all=JSVAL_TO_BOOLEAN(argv[i]);
}
rc=JS_SUSPENDREQUEST(cx);
if(all)
sbbs->scanalldirs(mode);
else
sbbs->scandirs(mode);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_scanposts(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
const char *def="";
char* find=(char *)def;
int32 mode=0;
uint subnum;
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
subnum=get_subnum(cx,sbbs,argv,argc,0);
if(subnum>=sbbs->cfg.total_subs) { // invalid sub-board
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
return(JS_TRUE);
}
for(uintN i=1;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]) && find==def) {
JSVALUE_TO_MSTRING(cx, argv[i], find, NULL);
if(find==NULL)
return JS_FALSE;
}
}
if(*find)
mode|=SCAN_FIND;
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->scanposts(subnum,mode,find)==0));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_listmsgs(JSContext *cx, uintN argc, jsval *arglist)
jsval *argv=JS_ARGV(cx, arglist);
const char *def="";
char* find=(char *)def;
int32 mode=0;
int32 start=0;
uint subnum;
sbbs_t* sbbs;
uintN argn=0;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
subnum=get_subnum(cx,sbbs,argv,argc,argn++);
if(subnum>=sbbs->cfg.total_subs) // invalid sub-board
return(JS_TRUE);
if(argc > argn && JSVAL_IS_NUMBER(argv[argn])) {
if(!JS_ValueToInt32(cx,argv[argn++],&mode))
return JS_FALSE;
}
if(argc > argn && JSVAL_IS_NUMBER(argv[argn])) {
if(!JS_ValueToInt32(cx,argv[argn++],&start))
return JS_FALSE;
}
if(argc > argn && JSVAL_IS_STRING(argv[argn])) {
JSVALUE_TO_MSTRING(cx, argv[argn++], find, NULL);
if(find==NULL)
return JS_FALSE;
}
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(sbbs->listsub(subnum,mode,start,find)));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_getnstime(JSContext *cx, uintN argc, jsval *arglist)
jsval *argv=JS_ARGV(cx, arglist);
time_t t=time(NULL);
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
if(argc && JSVAL_IS_NUMBER(argv[0])) {
if(!JS_ValueToInt32(cx,argv[0],(int32*)&t))
return JS_FALSE;
}
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist,DOUBLE_TO_JSVAL((double)t));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_select_shell(JSContext *cx, uintN argc, jsval *arglist)
{
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->select_shell()));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_select_editor(JSContext *cx, uintN argc, jsval *arglist)
{
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->select_editor()));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_get_time_left(JSContext *cx, uintN argc, jsval *arglist)
{
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(sbbs->gettimeleft()));
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_chk_ar(JSContext *cx, uintN argc, jsval *arglist)
jsval *argv=JS_ARGV(cx, arglist);
uchar* ar;
sbbs_t* sbbs;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=js_GetContextPrivate(cx))==NULL)
return(JS_FALSE);
return JS_FALSE;
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(sbbs->chk_ar(ar,&sbbs->useron,&sbbs->client)));
if(ar!=NULL && ar!=nular)
free(ar);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
static jsSyncMethodSpec js_bbs_functions[] = {
{"atcode", js_atcode, 1, JSTYPE_STRING, JSDOCSTR("code_string")
,JSDOCSTR("returns @-code value, specified <i>code</i> string does not include @ character delimiters")
,310
},
{"text", js_text, 1, JSTYPE_STRING, JSDOCSTR("line_number")
,JSDOCSTR("returns specified text string from text.dat")
,310
},
{"replace_text", js_replace_text, 2, JSTYPE_BOOLEAN, JSDOCSTR("line_number, string text")
,JSDOCSTR("replaces specified text string in memory")
,310
},
{"revert_text", js_revert_text, 1, JSTYPE_BOOLEAN, JSDOCSTR("[line_number=<i>all</i>]")
,JSDOCSTR("reverts specified text string to original text string; "
"if <i>line_number</i> unspecified, reverts all text lines")
,310
},
{"load_text", js_load_text, 1, JSTYPE_BOOLEAN, JSDOCSTR("base_filename")
,JSDOCSTR("load an alternate text.dat from ctrl directory, automatically appends '.dat' to basefilename")
,310
},
{"newuser", js_newuser, 0, JSTYPE_VOID, JSDOCSTR("")
,310
},
{"login", js_login, 2, JSTYPE_BOOLEAN, JSDOCSTR("user_name, password_prompt")
,JSDOCSTR("login with <i>user_name</i>, displaying <i>password_prompt</i> for password (if required)")
,310
},
{"logon", js_logon, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,310
},
{"logoff", js_logoff, 1, JSTYPE_VOID, JSDOCSTR("[prompt=<i>true</i>]")
,JSDOCSTR("interactive logoff procedure, pass <i>false</i> for <i>prompt</i> argument to avoid yes/no prompt")
,315
},
{"logout", js_logout, 0, JSTYPE_VOID, JSDOCSTR("")
,310
},
{"hangup", js_hangup, 0, JSTYPE_VOID, JSDOCSTR("")
,310
},
{"node_sync", js_nodesync, 0, JSTYPE_ALIAS },
{"nodesync", js_nodesync, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("synchronize with node database, checks for messages, interruption, etc. (AKA node_sync)")
,310
},
{"auto_msg", js_automsg, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("read/create system's auto-message")
,310
},
{"time_bank", js_time_bank, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the time banking system")
,310
},
{"qwk_sec", js_qwk_sec, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the QWK message packet upload/download/config section")
,310
},
{"text_sec", js_text_sec, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the text files section")
,310
},
{"xtrn_sec", js_xtrn_sec, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the external programs section")
,310
},
{"xfer_policy", js_xfer_policy, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display the file transfer policy")
,310
},
{"batch_menu", js_batchmenu, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the batch file transfer menu")
,310
},
{"batch_download", js_batchdownload, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,310
},
{"batch_add_list", js_batchaddlist, 1, JSTYPE_VOID, JSDOCSTR("list_filename")
,JSDOCSTR("add file list to batch download queue")
,310
},
{"send_file", js_sendfile, 1, JSTYPE_BOOLEAN, JSDOCSTR("filename [,protocol]")
,JSDOCSTR("send specified filename (complete path) to user via user-prompted "
"(or optionally specified) protocol")
,314
},
{"receive_file", js_recvfile, 1, JSTYPE_BOOLEAN, JSDOCSTR("filename [,protocol]")
,JSDOCSTR("received specified filename (complete path) frome user via user-prompted "
"(or optionally specified) protocol")
,314
},
{"temp_xfer", js_temp_xfer, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the temporary file tranfer menu")
,310
},
{"user_sync", js_user_sync, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("read the current user data from the database")
,310
},
{"user_config", js_user_config, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter the user settings configuration menu")
,310
},
{"sys_info", js_sys_info, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display system information")
,310
},
{"sub_info", js_sub_info, 1, JSTYPE_VOID, JSDOCSTR("[sub-board=<i>current</i>]")
,JSDOCSTR("display message sub-board information (current <i>sub-board</i>, if unspecified)")
,310
},
{"dir_info", js_dir_info, 0, JSTYPE_VOID, JSDOCSTR("[directory=<i>current</i>]")
,JSDOCSTR("display file directory information (current <i>directory</i>, if unspecified)")
,310
},
{"user_info", js_user_info, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display current user information")
,310
},
{"ver", js_ver, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display software version information")
,310
},
{"sys_stats", js_sys_stats, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display system statistics")
,310
},
{"node_stats", js_node_stats, 0, JSTYPE_VOID, JSDOCSTR("[node_number=<i>current</i>]")
,JSDOCSTR("display current (or specified) node statistics")
,310
},
{"list_users", js_userlist, 0, JSTYPE_VOID, JSDOCSTR("[mode=<tt>UL_ALL</tt>]")
,JSDOCSTR("display user list"
"(see <tt>UL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> values)")
,310
},
{"edit_user", js_useredit, 0, JSTYPE_VOID, JSDOCSTR("[user_number=<i>current</i>]")
,JSDOCSTR("enter the user editor")
,310
},
{"change_user", js_change_user, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("change to a different user")
,310
},
{"list_logons", js_logonlist, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("display the logon list")
,310
},
{"read_mail", js_readmail, 0, JSTYPE_VOID, JSDOCSTR("[which=<tt>MAIL_YOUR</tt>] [,user_number=<i>current</i>]")
,JSDOCSTR("read private e-mail"
"(see <tt>MAIL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>which</i> values)")
,310
},
{"email", js_email, 1, JSTYPE_BOOLEAN, JSDOCSTR("to_user_number [,mode=<tt>WM_EMAIL</tt>] [,top=<i>none</i>] [,subject=<i>none</i>]")
,JSDOCSTR("send private e-mail to a local user")
,310
},
{"netmail", js_netmail, 1, JSTYPE_BOOLEAN, JSDOCSTR("address [,mode=<tt>WM_NONE</tt>] [,subject=<i>none</i>]")
,310
},
{"bulk_mail", js_bulkmail, 0, JSTYPE_VOID, JSDOCSTR("[ars]")
,JSDOCSTR("send bulk private e-mail, if <i>ars</i> not specified, prompt for destination users")
,310
},
{"upload_file", js_upload_file, 1, JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
,JSDOCSTR("upload file to file directory specified by number or internal code")
,310
},
{"bulk_upload", js_bulkupload, 1, JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
,JSDOCSTR("add files (already in local storage path) to file directory "
"specified by number or internal code")
,310
},
{"resort_dir", js_resort_dir, 1, JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
,JSDOCSTR("re-sort the file directory specified by number or internal code)")
,310
},
{"list_files", js_listfiles, 1, JSTYPE_NUMBER, JSDOCSTR("[directory=<i>current</i>] [,filespec=<tt>\"*.*\"</tt> or search_string] [,mode=<tt>FL_NONE</tt>]")
,JSDOCSTR("list files in the specified file directory, "
"optionally specifying a file specification (wildcards) or a description search string, "
"and <i>mode</i> (bitfield)")
,310
},
{"list_file_info", js_listfileinfo, 1, JSTYPE_NUMBER, JSDOCSTR("[directory=<i>current</i>] [,filespec=<tt>\"*.*\"</tt>] [,mode=<tt>FI_INFO</tt>]")
,JSDOCSTR("list extended file information for files in the specified file directory")
,310
},
{"post_msg", js_postmsg, 1, JSTYPE_BOOLEAN, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>WM_MODE</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>"
"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 (this argument added in v3.13)")
,313
},
{"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>)")
,310
},
{"cfg_msg_ptrs", js_msgscan_ptrs, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("change message scan pointer values")
,310
},
{"reinit_msg_ptrs", js_msgscan_reinit, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("re-initialize new message scan pointers")
,310
},
{"scan_subs", js_scansubs, 0, JSTYPE_VOID, JSDOCSTR("[mode=<tt>SCAN_NEW</tt>] [,all=<tt>false</tt>]")
,JSDOCSTR("scan sub-boards for messages")
,310
},
{"scan_dirs", js_scandirs, 0, JSTYPE_VOID, JSDOCSTR("[mode=<tt>FL_NONE</tt>] [,all=<tt>false</tt>]")
,JSDOCSTR("scan directories for files")
,310
},
{"scan_posts", js_scanposts, 1, JSTYPE_ALIAS },
{"scan_msgs", js_scanposts, 1, JSTYPE_BOOLEAN, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>SCAN_READ</tt>] [,string find]")
,JSDOCSTR("scan messages in the specified message sub-board (number or internal code), "
"optionally search for 'find' string (AKA scan_posts)")
,310
},
{"list_msgs", js_listmsgs, 1, JSTYPE_NUMBER, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>SCAN_READ</tt>] [,message_number=<tt>0</tt>] [,string find]")
,JSDOCSTR("list messages in the specified message sub-board (number or internal code), "
"optionally search for 'find' string, returns number of messages listed")
,314
{"menu", js_menu, 1, JSTYPE_VOID, JSDOCSTR("base_filename")
,JSDOCSTR("display a menu file from the text/menu directory")
,310
},
{"log_key", js_logkey, 1, JSTYPE_BOOLEAN, JSDOCSTR("key [,comma=<tt>false</tt>]")
,JSDOCSTR("log key to node.log (comma optional)")
,310
},
{"log_str", js_logstr, 1, JSTYPE_BOOLEAN, JSDOCSTR("text")
,JSDOCSTR("log string to node.log")
,310
},
{"finduser", js_finduser, 1, JSTYPE_NUMBER, JSDOCSTR("username_or_number")
,JSDOCSTR("find user name (partial name support), interactive")
,310
},
{"trashcan", js_trashcan, 2, JSTYPE_BOOLEAN, JSDOCSTR("base_filename, search_string")
,JSDOCSTR("search file for psuedo-regexp (search string) in trashcan file (text/base_filename.can)")
,310
},
{"exec", js_exec, 2, JSTYPE_NUMBER, JSDOCSTR("cmdline [,mode=<tt>EX_NONE</tt>] [,string startup_dir]")
,JSDOCSTR("execute a program, optionally changing current directory to <i>startup_dir</i> "
"(see <tt>EX_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> bits)")
,310
},
{"exec_xtrn", js_exec_xtrn, 1, JSTYPE_BOOLEAN, JSDOCSTR("xtrn_number_or_code")
,JSDOCSTR("execute external program by number or internal code")
,310
},
{"user_event", js_user_event, 1, JSTYPE_BOOLEAN, JSDOCSTR("event_type")
,JSDOCSTR("execute user event by event type "
"(see <tt>EVENT_*</tt> in <tt>sbbsdefs.js</tt> for valid values)")
,310
},
{"telnet_gate", js_telnet_gate, 1, JSTYPE_VOID, JSDOCSTR("address [,mode=<tt>TG_NONE</tt>]")
,JSDOCSTR("external telnet/rlogin gateway (see <tt>TG_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> bits)")
,310
},
{"check_syspass", js_chksyspass, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("prompt for and verify system password")
,310
{"good_password", js_chkpass, 1, JSTYPE_STRING, JSDOCSTR("password")
,JSDOCSTR("check if requested user password meets minimum password requirements "
"(length, uniqueness, etc.)")
,310
{"page_sysop", js_pagesysop, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("page the sysop for chat, returns <i>false</i> if the sysop could not be paged")
,310
},
{"page_guru", js_pageguru, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("page the guru for chat")
,310
},
{"multinode_chat", js_multinode_chat, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("enter multi-node chat")
,310
},
{"private_message", js_private_message, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("use the private inter-node message prompt")
,310
},
{"private_chat", js_private_chat, 0, JSTYPE_VOID, JSDOCSTR("[local=<i>false</i>]")
,JSDOCSTR("enter private inter-node chat, or local sysop chat (if <i>local</i>=<i>true</i>)")
,310
},
{"get_node_message",js_get_node_message,0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("receive and display an inter-node message")
,310
},
{"put_node_message",js_put_node_message,2, JSTYPE_BOOLEAN, JSDOCSTR("node_number, text")
,JSDOCSTR("send an inter-node message")
,310
},
{"get_telegram", js_get_telegram, 1, JSTYPE_VOID, JSDOCSTR("[user_number=<i>current</i>]")
,JSDOCSTR("receive and display waiting telegrams for specified (or current) user")
,310
},
{"put_telegram", js_put_telegram, 2, JSTYPE_BOOLEAN, JSDOCSTR("user_number, text")
,JSDOCSTR("send a telegram to a user")
,310
},
{"list_nodes", js_nodelist, 0, JSTYPE_VOID, JSDOCSTR("")
,310
},
{"whos_online", js_whos_online, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("list active nodes only (who's online)")
,310
},
{"spy", js_spy, 1, JSTYPE_VOID, JSDOCSTR("node_number")
,JSDOCSTR("spy on a node")
,310
},
/* misc */
{"cmdstr", js_cmdstr, 1, JSTYPE_STRING, JSDOCSTR("command_string [,string fpath=<tt>\"\"</tt>] [,string fspec=<tt>\"\"</tt>]")
,JSDOCSTR("return expanded command string using Synchronet command-line specifiers")
,310
},
/* input */
{"get_filespec", js_getfilespec, 0, JSTYPE_STRING, JSDOCSTR("")
,JSDOCSTR("returns a file specification input by the user (optionally with wildcards)")
,310
},
{"get_newscantime", js_getnstime, 1, JSTYPE_NUMBER, JSDOCSTR("time=<i>current</i>")
,JSDOCSTR("confirm or change a new-scan time, returns the new new-scan time value (<i>time_t</i> format)")
,310
},
{"select_shell", js_select_shell, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("prompt user to select a new command shell")
,310
{"select_editor", js_select_editor, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("prompt user to select a new external message editor")
,310
{"get_time_left", js_get_time_left, 0, JSTYPE_NUMBER, JSDOCSTR("")
,JSDOCSTR("check the user's available remaining time online and return the value, in seconds<br>"
"This method will inform (and disconnect) the user when they are out of time")
,31401
},
{"compare_ars", js_chk_ar, 1, JSTYPE_BOOLEAN, JSDOCSTR("string ars")
,JSDOCSTR("verify the current user online meets the specified Access Requirements String")
,315
},
static JSBool js_bbs_resolve(JSContext *cx, JSObject *obj, jsid id)
if(id != JSID_VOID && id != JSID_EMPTY) {
jsval idval;
JS_IdToValue(cx, id, &idval);
if(JSVAL_IS_STRING(idval)) {
JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL);
HANDLE_PENDING(cx);
}
ret=js_SyncResolve(cx, obj, name, js_bbs_properties, js_bbs_functions, NULL, 0);
if(name)
free(name);
return ret;
}
static JSBool js_bbs_enumerate(JSContext *cx, JSObject *obj)
{
static JSClass js_bbs_class = {
"BBS" /* name */
,0 /* flags */
,JS_PropertyStub /* addProperty */
,JS_PropertyStub /* delProperty */
,js_bbs_get /* getProperty */
,js_bbs_set /* setProperty */
,js_bbs_enumerate /* enumerate */
,js_bbs_resolve /* resolve */
,JS_ConvertStub /* convert */
,JS_FinalizeStub /* finalize */
};
JSObject* js_CreateBbsObject(JSContext* cx, JSObject* parent)
{
JSObject* obj;
JSObject* mods;
obj = JS_DefineObject(cx, parent, "bbs", &js_bbs_class, NULL
,JSPROP_ENUMERATE|JSPROP_READONLY);
if(obj==NULL)
return(NULL);
if((mods=JS_DefineObject(cx, obj, "mods", NULL, NULL ,JSPROP_ENUMERATE))==NULL)
return(NULL);
#ifdef BUILD_JSDOCS
js_DescribeSyncObject(cx,mods,"Global repository for 3rd party modifications",312);
js_DescribeSyncObject(cx,obj,"Controls the Telnet/SSH/RLogin BBS experience",310);
js_CreateArrayOfStrings(cx, obj, "_property_desc_list", bbs_prop_desc, JSPROP_READONLY);
#endif