|
|
1.1 root 1: /* exec.cpp */
2:
3: /* Synchronet command shell/module interpretter */
4:
1.1.1.2 ! root 5: /* $Id: exec.cpp,v 1.50 2004/05/30 06:47:52 deuce Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39: #include "cmdshell.h"
40:
41: char ** sbbs_t::getstrvar(csi_t *bin, long name)
42: {
43: uint i;
44:
45: if(sysvar_pi>=MAX_SYSVARS) sysvar_pi=0;
46: switch(name) {
47: case 0:
48: return((char **)&(bin->str));
49: case 0x490873f1:
50: sysvar_p[sysvar_pi]=(char*)useron.alias;
51: break;
52: case 0x5de44e8b:
53: sysvar_p[sysvar_pi]=(char*)useron.name;
54: break;
55: case 0x979ef1de:
56: sysvar_p[sysvar_pi]=(char*)useron.handle;
57: break;
58: case 0xc8cd5fb7:
59: sysvar_p[sysvar_pi]=(char*)useron.comp;
60: break;
61: case 0xcc7aca99:
62: sysvar_p[sysvar_pi]=(char*)useron.note;
63: break;
64: case 0xa842c43b:
65: sysvar_p[sysvar_pi]=(char*)useron.address;
66: break;
67: case 0x4ee1ff3a:
68: sysvar_p[sysvar_pi]=(char*)useron.location;
69: break;
70: case 0xf000aa78:
71: sysvar_p[sysvar_pi]=(char*)useron.zipcode;
72: break;
73: case 0xcdb7e4a9:
74: sysvar_p[sysvar_pi]=(char*)useron.pass;
75: break;
76: case 0x94d59a7a:
77: sysvar_p[sysvar_pi]=(char*)useron.birth;
78: break;
79: case 0xec2b8fb8:
80: sysvar_p[sysvar_pi]=(char*)useron.phone;
81: break;
82: case 0x08f65a2a:
83: sysvar_p[sysvar_pi]=(char*)useron.modem;
84: break;
85: case 0xc7e0e8ce:
86: sysvar_p[sysvar_pi]=(char*)useron.netmail;
87: break;
88: case 0xd3606303:
89: sysvar_p[sysvar_pi]=(char*)useron.tmpext;
90: break;
91: case 0x3178f9d6:
92: sysvar_p[sysvar_pi]=(char*)useron.comment;
93: break;
94:
95: case 0x41239e21:
96: sysvar_p[sysvar_pi]=(char*)connection;
97: break;
98: case 0x90fc82b4:
99: sysvar_p[sysvar_pi]=(char*)cid;
100: break;
101: case 0x15755030:
102: return((char **)&comspec);
1.1.1.2 ! root 103: case 0x5E049062:
! 104: sysvar_p[sysvar_pi]=question;
! 105: break;
1.1 root 106:
107: case 0xf19cd046:
108: sysvar_p[sysvar_pi]=(char*)wordwrap;
109: break;
110:
111: default:
112: if(bin->str_var && bin->str_var_name)
113: for(i=0;i<bin->str_vars;i++)
114: if(bin->str_var_name[i]==name)
115: return((char **)&(bin->str_var[i]));
116: if(global_str_var && global_str_var_name)
117: for(i=0;i<global_str_vars;i++)
118: if(global_str_var_name[i]==name)
119: return(&(global_str_var[i]));
120: return(NULL); }
121:
122: return((char **)&sysvar_p[sysvar_pi++]);
123: }
124:
125: long * sbbs_t::getintvar(csi_t *bin, long name)
126: {
127: uint i;
128:
129: if(sysvar_li>=MAX_SYSVARS) sysvar_li=0;
130: switch(name) {
131: case 0:
132: sysvar_l[sysvar_li]=strtol((char*)bin->str,0,0);
133: break;
134: case 0x908ece53:
135: sysvar_l[sysvar_li]=useron.number;
136: break;
137: case 0xdcedf626:
138: sysvar_l[sysvar_li]=useron.uls;
139: break;
140: case 0xc1093f61:
141: sysvar_l[sysvar_li]=useron.dls;
142: break;
143: case 0x2039a29f:
144: sysvar_l[sysvar_li]=useron.posts;
145: break;
146: case 0x4a9f3955:
147: sysvar_l[sysvar_li]=useron.emails;
148: break;
149: case 0x0c8dcf3b:
150: sysvar_l[sysvar_li]=useron.fbacks;
151: break;
152: case 0x9a13bf95:
153: sysvar_l[sysvar_li]=useron.etoday;
154: break;
155: case 0xc9082cbd:
156: sysvar_l[sysvar_li]=useron.ptoday;
157: break;
158: case 0x7c72376d:
159: sysvar_l[sysvar_li]=useron.timeon;
160: break;
161: case 0xac72c50b:
162: sysvar_l[sysvar_li]=useron.textra;
163: break;
164: case 0x04807a11:
165: sysvar_l[sysvar_li]=useron.logons;
166: break;
167: case 0x52996eab:
168: sysvar_l[sysvar_li]=useron.ttoday;
169: break;
170: case 0x098bdfcb:
171: sysvar_l[sysvar_li]=useron.tlast;
172: break;
173: case 0xbd1cee5d:
174: sysvar_l[sysvar_li]=useron.ltoday;
175: break;
176: case 0x07954570:
177: sysvar_l[sysvar_li]=useron.xedit;
178: break;
179: case 0xedf6aa98:
180: sysvar_l[sysvar_li]=useron.shell;
181: break;
182: case 0x328ed476:
183: sysvar_l[sysvar_li]=useron.level;
184: break;
185: case 0x9e70e855:
186: sysvar_l[sysvar_li]=useron.sex;
187: break;
188: case 0x094cc42c:
189: sysvar_l[sysvar_li]=useron.rows;
190: break;
191: case 0xabc4317e:
192: sysvar_l[sysvar_li]=useron.prot;
193: break;
194: case 0x7dd9aac0:
195: sysvar_l[sysvar_li]=useron.leech;
196: break;
197: case 0x7c602a37:
198: return((long *)&useron.misc);
199: case 0x61be0d36:
200: return((long *)&useron.qwk);
201: case 0x665ac227:
202: return((long *)&useron.chat);
203: case 0x951341ab:
204: return((long *)&useron.flags1);
205: case 0x0c1a1011:
206: return((long *)&useron.flags2);
207: case 0x7b1d2087:
208: return((long *)&useron.flags3);
209: case 0xe579b524:
210: return((long *)&useron.flags4);
211: case 0x12e7d6d2:
212: return((long *)&useron.exempt);
213: case 0xfed3115d:
214: return((long *)&useron.rest);
215: case 0xb65dd6d4:
216: return((long *)&useron.ulb);
217: case 0xabb91f93:
218: return((long *)&useron.dlb);
219: case 0x92fb364f:
220: return((long *)&useron.cdt);
221: case 0xd0a99c72:
222: return((long *)&useron.min);
223: case 0xd7ae3022:
224: return((long *)&useron.freecdt);
225: case 0x1ef214ef:
226: return((long *)&useron.firston);
227: case 0x0ea515b1:
228: return((long *)&useron.laston);
229: case 0x2aaf9bd3:
230: return((long *)&useron.expire);
231: case 0x89c91dc8:
232: return((long *)&useron.pwmod);
233: case 0x5b0d0c54:
234: return((long *)&useron.ns_time);
235:
236: case 0xae256560:
237: return((long *)&cur_rate);
238: case 0x2b3c257f:
239: return((long *)&cur_cps);
240: case 0x1c4455ee:
241: return((long *)&dte_rate);
242: case 0x7fbf958e:
243: return((long *)&lncntr);
244: case 0x5c1c1500:
245: return((long *)&tos);
246: case 0x613b690e:
247: return((long *)&rows);
248: case 0x205ace36:
249: return((long *)&autoterm);
250: case 0x7d0ed0d1:
251: return((long *)&console);
252: case 0xbf31a280:
253: return((long *)&answertime);
254: case 0x83aa2a6a:
255: return((long *)&logontime);
256: case 0xb50cb889:
257: return((long *)&ns_time);
258: case 0xae92d249:
259: return((long *)&last_ns_time);
260: case 0x97f99eef:
261: return((long *)&online);
262: case 0x381d3c2a:
263: return((long *)&sys_status);
264: case 0x7e29c819:
265: return((long *)&cfg.sys_misc);
266: case 0x11c83294:
267: return((long *)&cfg.sys_psnum);
268: case 0x02408dc5:
1.1.1.2 ! root 269: sysvar_l[sysvar_li]=sys_timezone(&cfg);
1.1 root 270: break;
271: case 0x78afeaf1:
272: sysvar_l[sysvar_li]=cfg.sys_pwdays;
273: break;
274: case 0xd859385f:
275: sysvar_l[sysvar_li]=cfg.sys_deldays;
276: break;
277: case 0x6392dc62:
278: sysvar_l[sysvar_li]=cfg.sys_autodel;
279: break;
280: case 0x698d59b4:
281: sysvar_l[sysvar_li]=cfg.sys_nodes;
282: break;
283: case 0x6fb1c46e:
284: sysvar_l[sysvar_li]=cfg.sys_exp_warn;
285: break;
286: case 0xdf391ca7:
287: sysvar_l[sysvar_li]=cfg.sys_lastnode;
288: break;
289: case 0xdd982780:
290: sysvar_l[sysvar_li]=cfg.sys_autonode;
291: break;
292: case 0xf53db6c7:
293: sysvar_l[sysvar_li]=cfg.node_scrnlen;
294: break;
295: case 0xa1f0fcb7:
296: sysvar_l[sysvar_li]=cfg.node_scrnblank;
297: break;
298: case 0x709c07da:
299: return((long *)&cfg.node_misc);
300: case 0xb17e7914:
301: sysvar_l[sysvar_li]=cfg.node_valuser;
302: break;
303: case 0xadae168a:
304: sysvar_l[sysvar_li]=cfg.node_ivt;
305: break;
306: case 0x2aa89801:
307: sysvar_l[sysvar_li]=cfg.node_swap;
308: break;
309: case 0x4f02623a:
310: sysvar_l[sysvar_li]=cfg.node_minbps;
311: break;
312: case 0xe7a7fb07:
313: sysvar_l[sysvar_li]=cfg.node_num;
314: break;
315: case 0x6c8e350a:
316: sysvar_l[sysvar_li]=cfg.new_level;
317: break;
318: case 0xccfe7c5d:
319: return((long *)&cfg.new_flags1);
320: case 0x55f72de7:
321: return((long *)&cfg.new_flags2);
322: case 0x22f01d71:
323: return((long *)&cfg.new_flags3);
324: case 0xbc9488d2:
325: return((long *)&cfg.new_flags4);
326: case 0x4b0aeb24:
327: return((long *)&cfg.new_exempt);
328: case 0x20cb6325:
329: return((long *)&cfg.new_rest);
330: case 0x31178ba2:
331: return((long *)&cfg.new_cdt);
332: case 0x7345219f:
333: return((long *)&cfg.new_min);
334: case 0xb3f64be4:
335: sysvar_l[sysvar_li]=cfg.new_shell;
336: break;
337: case 0xa278584f:
338: return((long *)&cfg.new_misc);
339: case 0x7342a625:
340: sysvar_l[sysvar_li]=cfg.new_expire;
341: break;
342: case 0x75dc4306:
343: sysvar_l[sysvar_li]=cfg.new_prot;
344: break;
345: case 0xfb394e27:
346: sysvar_l[sysvar_li]=cfg.expired_level;
347: break;
348: case 0x89b69753:
349: return((long *)&cfg.expired_flags1);
350: case 0x10bfc6e9:
351: return((long *)&cfg.expired_flags2);
352: case 0x67b8f67f:
353: return((long *)&cfg.expired_flags3);
354: case 0xf9dc63dc:
355: return((long *)&cfg.expired_flags4);
356: case 0x0e42002a:
357: return((long *)&cfg.expired_exempt);
358: case 0x4569c62e:
359: return((long *)&cfg.expired_rest);
360: case 0xfcf3542e:
361: sysvar_l[sysvar_li]=cfg.min_dspace;
362: break;
363: case 0xcf9ce02c:
364: sysvar_l[sysvar_li]=cfg.cdt_min_value;
365: break;
366: case 0xfcb5b274:
367: return((long *)&cfg.cdt_per_dollar);
368: case 0x4db200d2:
369: sysvar_l[sysvar_li]=cfg.leech_pct;
370: break;
371: case 0x9a7d9cca:
372: sysvar_l[sysvar_li]=cfg.leech_sec;
373: break;
374: case 0x396b7167:
375: return((long *)&cfg.netmail_cost);
376: case 0x5eeaff21:
377: sysvar_l[sysvar_li]=cfg.netmail_misc;
378: break;
379: case 0x82d9484e:
380: return((long *)&cfg.inetmail_cost);
381: case 0xe558c608:
382: return((long *)&cfg.inetmail_misc);
383:
384: case 0xc6e8539d:
385: return((long *)&logon_ulb);
386: case 0xdb0c9ada:
387: return((long *)&logon_dlb);
388: case 0xac58736f:
389: return((long *)&logon_uls);
390: case 0xb1bcba28:
391: return((long *)&logon_dls);
392: case 0x9c5051c9:
393: return((long *)&logon_posts);
394: case 0xc82ba467:
395: return((long *)&logon_emails);
396: case 0x8e395209:
397: return((long *)&logon_fbacks);
398: case 0x8b12ba9d:
399: return((long *)&posts_read);
400: case 0xe51c1956:
401: sysvar_l[sysvar_li]=(ulong)logfile_fp;
402: break;
403: case 0x5a22d4bd:
404: sysvar_l[sysvar_li]=(ulong)nodefile_fp;
405: break;
406: case 0x3a37c26b:
407: sysvar_l[sysvar_li]=(ulong)node_ext_fp;
408: break;
409:
410: case 0xeb6c9c73:
411: sysvar_l[sysvar_li]=errorlevel;
412: break;
413:
414: case 0x5aaccfc5:
415: sysvar_l[sysvar_li]=errno;
416: break;
417:
418: case 0x057e4cd4:
419: sysvar_l[sysvar_li]=timeleft;
420: break;
421:
422: case 0x1e5052a7:
423: return((long *)&cfg.max_minutes);
424: case 0xedc643f1:
425: return((long *)&cfg.max_qwkmsgs);
426:
427: case 0x430178ec:
428: return((long *)&cfg.uq);
429:
1.1.1.2 ! root 430: case 0x455CB929:
! 431: return(&bin->ftp_mode);
! 432:
! 433: case 0x2105D2B9:
! 434: return(&bin->socket_error);
! 435:
! 436: case 0xA0023A2E:
! 437: return((long *)&startup->options);
! 438:
! 439: case 0x16E2585F:
! 440: sysvar_l[sysvar_li]=client_socket;
! 441: break;
! 442:
1.1 root 443: default:
444: if(bin->int_var && bin->int_var_name)
445: for(i=0;i<bin->int_vars;i++)
446: if(bin->int_var_name[i]==name)
447: return(&bin->int_var[i]);
448: if(global_int_var && global_int_var_name)
449: for(i=0;i<global_int_vars;i++)
450: if(global_int_var_name[i]==name)
451: return(&global_int_var[i]);
452: return(NULL); }
453:
454: return(&sysvar_l[sysvar_li++]);
455: }
456:
457: void sbbs_t::clearvars(csi_t *bin)
458: {
459: bin->str_vars=0;
460: bin->str_var=NULL;
461: bin->str_var_name=NULL;
462: bin->int_vars=0;
463: bin->int_var=NULL;
464: bin->int_var_name=NULL;
465: bin->files=0;
1.1.1.2 ! root 466: bin->loops=0;
! 467: bin->sockets=0;
1.1 root 468: bin->retval=0;
469: }
470:
471: void sbbs_t::freevars(csi_t *bin)
472: {
473: uint i;
474:
475: if(bin->str_var) {
476: for(i=0;i<bin->str_vars;i++)
477: if(bin->str_var[i])
478: FREE(bin->str_var[i]);
479: FREE(bin->str_var);
480: }
481: if(bin->int_var)
482: FREE(bin->int_var);
483: if(bin->str_var_name)
484: FREE(bin->str_var_name);
485: if(bin->int_var_name)
486: FREE(bin->int_var_name);
487: for(i=0;i<bin->files;i++) {
488: if(bin->file[i]) {
489: fclose((FILE *)bin->file[i]);
490: bin->file[i]=0;
491: }
492: }
1.1.1.2 ! root 493: for(i=0;i<bin->sockets;i++) {
! 494: if(bin->socket[i]) {
! 495: close_socket((SOCKET)bin->socket[i]);
! 496: bin->socket[i]=0;
! 497: }
! 498: }
1.1 root 499: }
500:
501: /****************************************************************************/
502: /* Copies a new value (str) into the string variable pointed to by p */
503: /* re-allocating if necessary */
504: /****************************************************************************/
505: char * sbbs_t::copystrvar(csi_t *csi, char *p, char *str)
506: {
507: char *np; /* New pointer after realloc */
1.1.1.2 ! root 508: int i=0;
1.1 root 509:
510: if(p!=csi->str) {
511: if(p)
512: for(i=0;i<MAX_SYSVARS;i++)
513: if(p==sysvar_p[i])
514: break;
515: if(!p || i==MAX_SYSVARS) { /* Not system variable */
516: if((np=(char*)REALLOC(p,strlen(str)+1))==NULL)
517: errormsg(WHERE,ERR_ALLOC,"variable",strlen(str)+1);
518: else
519: p=np; } }
520: if(p)
521: strcpy(p,str);
522: return(p);
523: }
524:
1.1.1.2 ! root 525: #ifdef JAVASCRIPT
! 526:
! 527: static JSBool
! 528: js_BranchCallback(JSContext *cx, JSScript *script)
! 529: {
! 530: sbbs_t* sbbs;
! 531:
! 532: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
! 533: return(JS_FALSE);
! 534:
! 535: sbbs->js_branch.counter++;
! 536:
! 537: /* Terminated? */
! 538: if(sbbs->js_branch.auto_terminate && sbbs->terminated) {
! 539: JS_ReportError(cx,"Terminated");
! 540: sbbs->js_branch.counter=0;
! 541: return(JS_FALSE);
! 542: }
! 543: /* Infinite loop? */
! 544: if(sbbs->js_branch.limit && sbbs->js_branch.counter>sbbs->js_branch.limit) {
! 545: JS_ReportError(cx,"Infinite loop (%lu branches) detected",sbbs->js_branch.counter);
! 546: sbbs->js_branch.counter=0;
! 547: return(JS_FALSE);
! 548: }
! 549: /* Give up timeslices every once in a while */
! 550: if(sbbs->js_branch.yield_interval && (sbbs->js_branch.counter%sbbs->js_branch.yield_interval)==0)
! 551: YIELD();
! 552:
! 553: if(sbbs->js_branch.gc_interval && (sbbs->js_branch.counter%sbbs->js_branch.gc_interval)==0)
! 554: JS_MaybeGC(cx), sbbs->js_branch.gc_attempts++;
! 555:
! 556: return(JS_TRUE);
! 557: }
! 558:
! 559: static const char* js_ext(const char* fname)
! 560: {
! 561: if(strchr(fname,'.')==NULL)
! 562: return(".js");
! 563: return("");
! 564: }
! 565:
! 566: long sbbs_t::js_execfile(const char *cmd)
! 567: {
! 568: char* p;
! 569: char* args=NULL;
! 570: char* fname;
! 571: int argc=0;
! 572: char cmdline[MAX_PATH+1];
! 573: char path[MAX_PATH+1];
! 574: JSObject* js_scope=NULL;
! 575: JSScript* js_script=NULL;
! 576: jsval rval;
! 577: int32 result=0;
! 578:
! 579: if(js_cx==NULL) {
! 580: errormsg(WHERE,ERR_CHK,"JavaScript support",0);
! 581: errormsg(WHERE,ERR_EXEC,cmd,0);
! 582: return(-1);
! 583: }
! 584:
! 585: SAFECOPY(cmdline,cmd);
! 586: p=strchr(cmdline,' ');
! 587: if(p!=NULL) {
! 588: *p=0;
! 589: args=p+1;
! 590: }
! 591: fname=cmdline;
! 592:
! 593: if(strcspn(fname,"/\\")==strlen(fname)) {
! 594: sprintf(path,"%s%s%s",cfg.mods_dir,fname,js_ext(fname));
! 595: if(cfg.mods_dir[0]==0 || !fexistcase(path))
! 596: sprintf(path,"%s%s%s",cfg.exec_dir,fname,js_ext(fname));
! 597: } else
! 598: SAFECOPY(path,fname);
! 599:
! 600: if(!fexistcase(path)) {
! 601: errormsg(WHERE,ERR_OPEN,path,O_RDONLY);
! 602: return(-1);
! 603: }
! 604:
! 605: js_scope=JS_NewObject(js_cx, NULL, NULL, js_glob);
! 606:
! 607: if(js_scope!=NULL) {
! 608:
! 609: JSObject* argv=JS_NewArrayObject(js_cx, 0, NULL);
! 610:
! 611: JS_DefineProperty(js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
! 612: ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
! 613:
! 614: if(args!=NULL && argv!=NULL) {
! 615: while(*args) {
! 616: p=strchr(args,' ');
! 617: if(p!=NULL)
! 618: *p=0;
! 619: while(*args && *args==' ') args++; /* Skip spaces */
! 620: JSString* arg = JS_NewStringCopyZ(js_cx, args);
! 621: if(arg==NULL)
! 622: break;
! 623: jsval val=STRING_TO_JSVAL(arg);
! 624: if(!JS_SetElement(js_cx, argv, argc, &val))
! 625: break;
! 626: argc++;
! 627: if(p==NULL) /* last arg */
! 628: break;
! 629: args+=(strlen(args)+1);
! 630: }
! 631: }
! 632: JS_DefineProperty(js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
! 633: ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
! 634:
! 635: JS_ClearPendingException(js_cx);
! 636:
! 637: js_script=JS_CompileFile(js_cx, js_scope, path);
! 638: }
! 639:
! 640: if(js_scope==NULL || js_script==NULL) {
! 641: errormsg(WHERE,ERR_EXEC,path,0);
! 642: return(-1);
! 643: }
! 644:
! 645: js_branch.counter=0; // Reset loop counter
! 646:
! 647: JS_SetBranchCallback(js_cx, js_BranchCallback);
! 648:
! 649: JS_ExecuteScript(js_cx, js_scope, js_script, &rval);
! 650:
! 651: JS_GetProperty(js_cx, js_glob, "exit_code", &rval);
! 652:
! 653: JS_DestroyScript(js_cx, js_script);
! 654:
! 655: JS_ClearScope(js_cx, js_scope);
! 656:
! 657: JS_GC(js_cx);
! 658:
! 659: if(rval!=JSVAL_VOID)
! 660: JS_ValueToInt32(js_cx,rval,&result);
! 661:
! 662: return(result);
! 663: }
! 664: #endif
! 665:
1.1 root 666:
667: long sbbs_t::exec_bin(char *mod, csi_t *csi)
668: {
1.1.1.2 ! root 669: char str[MAX_PATH+1];
! 670: char modname[MAX_PATH+1];
1.1 root 671: int file;
672: csi_t bin;
673:
1.1.1.2 ! root 674: #ifdef JAVASCRIPT
! 675: if(cfg.mods_dir[0]) {
! 676: sprintf(str,"%s%s.js",cfg.mods_dir,mod);
! 677: if(fexistcase(str))
! 678: return(js_execfile(str));
! 679: }
! 680: sprintf(str,"%s%s.js",cfg.exec_dir,mod);
! 681: if(fexistcase(str))
! 682: return(js_execfile(str));
! 683: #endif
! 684:
1.1 root 685: memcpy(&bin,csi,sizeof(csi_t));
686: clearvars(&bin);
687:
1.1.1.2 ! root 688: SAFECOPY(modname,mod);
! 689: if(!strchr(modname,'.'))
! 690: strcat(modname,".bin");
! 691:
! 692: sprintf(str,"%s%s",cfg.mods_dir,modname);
! 693: if(cfg.mods_dir[0]==0 || !fexistcase(str)) {
! 694: sprintf(str,"%s%s",cfg.exec_dir,modname);
! 695: fexistcase(str);
! 696: }
1.1 root 697: if((file=nopen(str,O_RDONLY))==-1) {
698: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
1.1.1.2 ! root 699: return(-1);
! 700: }
1.1 root 701:
702: bin.length=filelength(file);
703: if((bin.cs=(uchar *)MALLOC(bin.length))==NULL) {
704: close(file);
705: errormsg(WHERE,ERR_ALLOC,str,bin.length);
1.1.1.2 ! root 706: return(-1);
! 707: }
1.1 root 708: if(lread(file,bin.cs,bin.length)!=bin.length) {
709: close(file);
710: errormsg(WHERE,ERR_READ,str,bin.length);
711: FREE(bin.cs);
1.1.1.2 ! root 712: return(-1);
! 713: }
1.1 root 714: close(file);
715:
716: bin.ip=bin.cs;
717: bin.rets=0;
718: bin.cmdrets=0;
719: bin.misc=0;
720:
721: while(exec(&bin)==0)
722: if(!(bin.misc&CS_OFFLINE_EXEC)) {
723: checkline();
724: if(!online)
1.1.1.2 ! root 725: break;
! 726: }
1.1 root 727:
728: freevars(&bin);
729: FREE(bin.cs);
730: csi->logic=bin.logic;
731: return(bin.retval);
732: }
733:
734: /****************************************************************************/
735: /* Skcsi->ip to a specific instruction */
736: /****************************************************************************/
737: void sbbs_t::skipto(csi_t *csi, uchar inst)
738: {
739: int i,j;
740:
741: while(csi->ip<csi->cs+csi->length && ((inst&0x80) || *csi->ip!=inst)) {
742:
743: if(*csi->ip==CS_IF_TRUE || *csi->ip==CS_IF_FALSE
744: || (*csi->ip>=CS_IF_GREATER && *csi->ip<=CS_IF_LESS_OR_EQUAL)) {
745: csi->ip++;
746: skipto(csi,CS_ENDIF);
747: csi->ip++;
748: continue; }
749:
750: if(inst==CS_ELSEORENDIF
751: && (*csi->ip==CS_ELSE || *csi->ip==CS_ENDIF))
752: break;
753:
754: if(inst==CS_NEXTCASE
755: && (*csi->ip==CS_CASE || *csi->ip==CS_DEFAULT
756: || *csi->ip==CS_END_SWITCH))
757: break;
758:
759: if(*csi->ip==CS_SWITCH) {
760: csi->ip++;
761: csi->ip+=4; /* Skip variable name */
762: skipto(csi,CS_END_SWITCH);
763: csi->ip++;
764: continue; }
765:
766: if(*csi->ip==CS_CASE) {
767: csi->ip++;
768: csi->ip+=4; /* Skip value */
769: skipto(csi,CS_NEXTCASE);
770: continue; }
771:
772: if(*csi->ip==CS_CMDKEY || *csi->ip==CS_CMDCHAR) {
773: csi->ip+=2;
774: skipto(csi,CS_END_CMD);
775: csi->ip++;
776: continue; }
777: if(*csi->ip==CS_CMDSTR || *csi->ip==CS_CMDKEYS) {
778: csi->ip++; /* skip inst */
779: while(*(csi->ip++)); /* skip string */
780: skipto(csi,CS_END_CMD);
781: csi->ip++;
782: continue; }
783:
784: if(*csi->ip>=CS_FUNCTIONS) {
785: csi->ip++;
786: continue; }
787:
788: if(*csi->ip>=CS_MISC) {
789: switch(*csi->ip) {
790: case CS_VAR_INSTRUCTION:
791: csi->ip++;
792: switch(*(csi->ip++)) {
793: case SHOW_VARS:
794: continue;
795: case PRINT_VAR:
796: case DEFINE_STR_VAR:
797: case DEFINE_INT_VAR:
798: case DEFINE_GLOBAL_STR_VAR:
799: case DEFINE_GLOBAL_INT_VAR:
800: case TIME_INT_VAR:
801: case STRUPR_VAR:
802: case STRLWR_VAR:
803: case TRUNCSP_STR_VAR:
804: case CHKFILE_VAR:
1.1.1.2 ! root 805: case COPY_CHAR:
1.1 root 806: case STRIP_CTRL_STR_VAR:
807: csi->ip+=4; /* Skip variable name */
808: continue;
809: case GETSTR_VAR:
810: case GETNAME_VAR:
811: case GETLINE_VAR:
812: case GETSTRUPR_VAR:
813: case SHIFT_STR_VAR:
814: case SEND_FILE_VIA_VAR:
815: case RECEIVE_FILE_VIA_VAR:
816: case COMPARE_FIRST_CHAR:
1.1.1.2 ! root 817: case SHIFT_TO_FIRST_CHAR:
! 818: case SHIFT_TO_LAST_CHAR:
1.1 root 819: csi->ip+=4; /* Skip variable name */
820: csi->ip++; /* Skip char */
821: continue;
822: case PRINTTAIL_VAR_MODE:
823: csi->ip++; /* Skip length */
824: case PRINTFILE_VAR_MODE:
825: case GETNUM_VAR:
826: csi->ip+=4; /* Skip variable name */
827: csi->ip+=2; /* Skip max num */
828: continue;
829: case STRNCMP_VAR:
830: csi->ip++; /* Skip length */
831: case SET_STR_VAR:
832: case COMPARE_STR_VAR:
833: case CAT_STR_VAR:
834: case STRSTR_VAR:
835: case TELNET_GATE_STR:
836: csi->ip+=4; /* Skip variable name */
837: while(*(csi->ip++)); /* skip string */
838: continue;
839: case FORMAT_TIME_STR:
840: csi->ip+=4; /* Skip destination variable */
841: while(*(csi->ip++)); /* Skip string */
842: csi->ip+=4; /* Skip int variable */
843: continue;
844: case FORMAT_STR_VAR: /* SPRINTF */
845: csi->ip+=4; /* Skip destination variable */
846: case VAR_PRINTF:
1.1.1.2 ! root 847: case VAR_PRINTF_LOCAL:
1.1 root 848: while(*(csi->ip++)); /* Skip string */
849: j=*(csi->ip++); /* Skip number of arguments */
850: for(i=0;i<j;i++)
851: csi->ip+=4; /* Skip arguments */
852: continue;
853: case SEND_FILE_VIA:
854: case RECEIVE_FILE_VIA:
855: csi->ip++; /* Skip prot */
856: while(*(csi->ip++)); /* Skip filepath */
857: continue;
858: case GETSTR_MODE:
859: case STRNCMP_VARS:
860: csi->ip++; /* Skip length */
861: default:
862: csi->ip+=8; /* Skip two variable names or var & val */
863: continue; }
864:
865: case CS_FIO_FUNCTION:
866: csi->ip++;
867: switch(*(csi->ip++)) {
868: case FIO_OPEN:
869: csi->ip+=4; /* File handle */
870: csi->ip+=2; /* Access */
871: while(*(csi->ip++)); /* path/filename */
872: continue;
873: case FIO_CLOSE:
874: case FIO_FLUSH:
875: case FIO_EOF:
876: case REMOVE_FILE:
877: case REMOVE_DIR:
878: case CHANGE_DIR:
879: case MAKE_DIR:
880: case REWIND_DIR:
881: case CLOSE_DIR:
882: csi->ip+=4; /* File handle */
883: continue;
884: case FIO_SET_ETX:
885: csi->ip++;
886: continue;
887: case FIO_PRINTF:
888: csi->ip+=4; /* File handle */
889: while(*(csi->ip++)); /* String */
890: j=*(csi->ip++); /* Number of arguments */
891: for(i=0;i<j;i++)
892: csi->ip+=4; /* Arguments */
893: continue;
894: case FIO_READ:
895: case FIO_WRITE:
896: case FIO_SEEK:
897: case FIO_SEEK_VAR:
898: case FIO_OPEN_VAR:
899: csi->ip+=4; /* File handle */
900: csi->ip+=4; /* Variable */
901: csi->ip+=2; /* Length/access */
902: continue;
903: case FIO_READ_VAR:
904: case FIO_WRITE_VAR:
905: csi->ip+=4; /* File handle */
906: csi->ip+=4; /* Buf Variable */
907: csi->ip+=4; /* Length Variable */
908: continue;
909: default:
910: csi->ip+=4; /* File handle */
911: csi->ip+=4; /* Variable */
912: continue; }
913:
1.1.1.2 ! root 914: case CS_NET_FUNCTION:
! 915: csi->ip++;
! 916: switch(*(csi->ip++)) {
! 917: case CS_SOCKET_CONNECT:
! 918: csi->ip+=4; /* socket */
! 919: csi->ip+=4; /* address */
! 920: csi->ip+=2; /* port */
! 921: continue;
! 922: case CS_SOCKET_NREAD:
! 923: csi->ip+=4; /* socket */
! 924: csi->ip+=4; /* intvar */
! 925: continue;
! 926: case CS_SOCKET_READ:
! 927: case CS_SOCKET_READLINE:
! 928: case CS_SOCKET_PEEK:
! 929: csi->ip+=4; /* socket */
! 930: csi->ip+=4; /* buffer */
! 931: csi->ip+=2; /* length */
! 932: continue;
! 933: case CS_SOCKET_WRITE:
! 934: csi->ip+=4; /* socket */
! 935: csi->ip+=4; /* strvar */
! 936: continue;
! 937:
! 938: case CS_FTP_LOGIN:
! 939: case CS_FTP_GET:
! 940: case CS_FTP_PUT:
! 941: case CS_FTP_RENAME:
! 942: csi->ip+=4; /* socket */
! 943: csi->ip+=4; /* username/path */
! 944: csi->ip+=4; /* password/path */
! 945: continue;
! 946: case CS_FTP_DIR:
! 947: case CS_FTP_CWD:
! 948: case CS_FTP_DELETE:
! 949: csi->ip+=4; /* socket */
! 950: csi->ip+=4; /* path */
! 951: continue;
! 952:
! 953: default:
! 954: csi->ip+=4; /* socket */
! 955: continue; }
! 956:
1.1 root 957: case CS_COMPARE_ARS:
958: csi->ip++;
959: csi->ip+=(*csi->ip);
960: csi->ip++;
961: break;
962: case CS_TOGGLE_USER_MISC:
963: case CS_COMPARE_USER_MISC:
964: case CS_TOGGLE_USER_CHAT:
965: case CS_COMPARE_USER_CHAT:
966: case CS_TOGGLE_USER_QWK:
967: case CS_COMPARE_USER_QWK:
968: csi->ip+=5;
969: break;
970: case CS_REPLACE_TEXT:
971: csi->ip+=3; /* skip inst and text # */
972: while(*(csi->ip++)); /* skip string */
973: break;
974: case CS_USE_INT_VAR:
975: csi->ip+=7; // inst, var, offset, len
976: break;
977: default:
978: csi->ip++; }
979: continue; }
980:
981: if(*csi->ip==CS_ONE_MORE_BYTE) {
1.1.1.2 ! root 982: if(inst==CS_END_LOOP && *(csi->ip+1)==CS_END_LOOP)
! 983: break;
! 984:
1.1 root 985: csi->ip++; /* skip extension */
986: csi->ip++; /* skip instruction */
1.1.1.2 ! root 987:
! 988: if(*(csi->ip-1)==CS_LOOP_BEGIN) { /* nested loop */
! 989: skipto(csi,CS_END_LOOP);
! 990: csi->ip+=2;
! 991: }
! 992:
1.1 root 993: continue; }
994:
995: if(*csi->ip==CS_TWO_MORE_BYTES) {
996: csi->ip++; /* skip extension */
997: csi->ip++; /* skip instruction */
998: csi->ip++; /* skip argument */
999: continue; }
1000:
1001: if(*csi->ip==CS_THREE_MORE_BYTES) {
1002: csi->ip++; /* skip extension */
1003: csi->ip++; /* skip instruction */
1004: csi->ip+=2; /* skip argument */
1005: continue; }
1006:
1007: if(*csi->ip==CS_STR_FUNCTION) {
1008: csi->ip++; /* skip extension */
1009: csi->ip++; /* skip instruction */
1010: while(*(csi->ip++)); /* skip string */
1011: continue; }
1012:
1013: if(*csi->ip>=CS_ASCIIZ) {
1014: csi->ip++; /* skip inst */
1015: while(*(csi->ip++)); /* skip string */
1016: continue; }
1017:
1018: if(*csi->ip>=CS_THREE_BYTE) {
1019: csi->ip+=3;
1020: continue; }
1021:
1022: if(*csi->ip>=CS_TWO_BYTE) {
1023: csi->ip+=2;
1024: continue; }
1025:
1026: csi->ip++; }
1027: }
1028:
1029:
1030: int sbbs_t::exec(csi_t *csi)
1031: {
1032: char str[256],*path;
1033: char tmp[512];
1034: uchar buf[1025],ch;
1035: int i,j,file;
1036: long l;
1037: FILE *stream;
1038:
1039: if(usrgrps)
1040: cursubnum=usrsub[curgrp][cursub[curgrp]]; /* Used for ARS */
1041: else
1042: cursubnum=INVALID_SUB;
1043: if(usrlibs) {
1044: curdirnum=usrdir[curlib][curdir[curlib]]; /* Used for ARS */
1045: path=cfg.dir[usrdir[curlib][curdir[curlib]]]->path; }
1046: else {
1047: curdirnum=INVALID_DIR;
1048: path=nulstr; }
1049: now=time(NULL);
1050:
1051: if(csi->ip>=csi->cs+csi->length)
1052: return(1);
1053:
1054: if(*csi->ip>=CS_FUNCTIONS)
1055: return(exec_function(csi));
1056:
1057: /**********************************************/
1058: /* Miscellaneous variable length instructions */
1059: /**********************************************/
1060:
1061: if(*csi->ip>=CS_MISC)
1062: return(exec_misc(csi,path));
1063:
1064: /********************************/
1065: /* ASCIIZ argument instructions */
1066: /********************************/
1067:
1068: if(*csi->ip>=CS_ASCIIZ) {
1069: switch(*(csi->ip++)) {
1070: case CS_STR_FUNCTION:
1071: switch(*(csi->ip++)) {
1072: case CS_LOGIN:
1073: csi->logic=login(csi->str,(char*)csi->ip);
1074: break;
1075: case CS_LOAD_TEXT:
1076: csi->logic=LOGIC_FALSE;
1077: for(i=0;i<TOTAL_TEXT;i++)
1078: if(text[i]!=text_sav[i]) {
1079: if(text[i]!=nulstr)
1080: FREE(text[i]);
1081: text[i]=text_sav[i]; }
1082: sprintf(str,"%s%s.dat"
1083: ,cfg.ctrl_dir,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1084: if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
1085: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
1086: break; }
1087: for(i=0;i<TOTAL_TEXT && !feof(stream);i++) {
1088: if((text[i]=readtext((long *)NULL,stream))==NULL) {
1089: i--;
1090: continue; }
1091: if(!strcmp(text[i],text_sav[i])) { /* If identical */
1092: FREE(text[i]); /* Don't alloc */
1093: text[i]=text_sav[i]; }
1094: else if(text[i][0]==0) {
1095: FREE(text[i]);
1096: text[i]=nulstr; } }
1097: if(i<TOTAL_TEXT) {
1098: fclose(stream);
1099: errormsg(WHERE,ERR_READ,str,TOTAL_TEXT);
1100: break; }
1101: fclose(stream);
1102: csi->logic=LOGIC_TRUE;
1103: break;
1104: default:
1105: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1106: break; }
1107: while(*(csi->ip++)); /* Find NULL */
1108: return(0);
1109: case CS_LOG:
1110: log(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1111: break;
1112: case CS_GETCMD:
1113: csi->cmd=(uchar)getkeys((char*)csi->ip,0);
1114: if((char)csi->cmd==-1)
1115: csi->cmd=3;
1116: break;
1117: case CS_CMDSTR:
1118: if(stricmp(csi->str,(char*)csi->ip)) {
1119: while(*(csi->ip++)); /* Find NULL */
1120: skipto(csi,CS_END_CMD);
1121: csi->ip++;
1122: return(0); }
1123: break;
1124: case CS_CMDKEYS:
1125: for(i=0;csi->ip[i];i++)
1126: if(csi->cmd==csi->ip[i])
1127: break;
1128: if(!csi->ip[i]) {
1129: while(*(csi->ip++)); /* Find NULL */
1130: skipto(csi,CS_END_CMD);
1131: csi->ip++;
1132: return(0); }
1133: break;
1134: case CS_GET_TEMPLATE:
1135: gettmplt(csi->str,(char*)csi->ip,K_LINE);
1136: if(sys_status&SS_ABORT)
1137: csi->str[0]=0;
1138: csi->cmd=csi->str[0];
1139: break;
1140: case CS_TRASHCAN:
1141: csi->logic=!trashcan(csi->str,(char*)csi->ip);
1142: break;
1143: case CS_CREATE_SIF:
1144: create_sif_dat((char*)csi->ip,csi->str);
1145: break;
1146: case CS_READ_SIF:
1147: read_sif_dat((char*)csi->ip,csi->str);
1148: break;
1149: case CS_MNEMONICS:
1150: mnemonics((char*)csi->ip);
1151: break;
1152: case CS_PRINT:
1153: putmsg(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR|P_NOABORT);
1154: break;
1155: case CS_PRINT_LOCAL:
1.1.1.2 ! root 1156: if(online==ON_LOCAL)
! 1157: eprintf(LOG_INFO,"%s",cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
! 1158: else
! 1159: lputs(LOG_INFO,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1.1 root 1160: break;
1161: case CS_PRINT_REMOTE:
1162: putcom(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1163: break;
1164: case CS_PRINTFILE:
1165: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1166: break;
1167: case CS_PRINTFILE_REMOTE:
1168: if(online!=ON_REMOTE || !(console&CON_R_ECHO))
1169: break;
1170: console&=~CON_L_ECHO;
1171: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1172: console|=CON_L_ECHO;
1173: break;
1174: case CS_PRINTFILE_LOCAL:
1175: if(!(console&CON_L_ECHO))
1176: break;
1177: console&=~CON_R_ECHO;
1178: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1179: console|=CON_R_ECHO;
1180: break;
1181: case CS_CHKFILE:
1.1.1.2 ! root 1182: csi->logic=!fexistcase(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1.1 root 1183: break;
1184: case CS_EXEC:
1185: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),0);
1186: break;
1187: case CS_EXEC_INT:
1188: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),EX_OUTR|EX_INR|EX_OUTL);
1189: break;
1190: case CS_EXEC_XTRN:
1191: for(i=0;i<cfg.total_xtrns;i++)
1192: if(!stricmp(cfg.xtrn[i]->code,(char*)csi->ip))
1193: break;
1194: if(i<cfg.total_xtrns)
1195: exec_xtrn(i);
1196: break;
1197: case CS_EXEC_BIN:
1198: exec_bin(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),csi);
1199: break;
1200: case CS_YES_NO:
1201: csi->logic=!yesno(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1202: break;
1203: case CS_NO_YES:
1204: csi->logic=!noyes(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1205: break;
1206: case CS_MENU:
1207: menu(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1208: break;
1209: case CS_SETSTR:
1210: strcpy(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1211: break;
1212: case CS_SET_MENU_DIR:
1213: cmdstr((char*)csi->ip,path,csi->str,menu_dir);
1214: break;
1215: case CS_SET_MENU_FILE:
1216: cmdstr((char*)csi->ip,path,csi->str,menu_file);
1217: break;
1218: case CS_COMPARE_STR:
1219: csi->logic=stricmp(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1220: break;
1221: case CS_COMPARE_KEYS:
1222: for(i=0;csi->ip[i];i++)
1223: if(csi->cmd==csi->ip[i])
1224: break;
1225: if(csi->ip[i])
1226: csi->logic=LOGIC_TRUE;
1227: else
1228: csi->logic=LOGIC_FALSE;
1229: break;
1230: case CS_COMPARE_WORD:
1231: csi->logic=strnicmp(csi->str,(char*)csi->ip,strlen((char*)csi->ip));
1232: break;
1233: default:
1234: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1235: break; }
1236: while(*(csi->ip++)); /* Find NULL */
1237: return(0); }
1238:
1239: if(*csi->ip>=CS_THREE_BYTE) {
1240: switch(*(csi->ip++)) {
1241: case CS_THREE_MORE_BYTES:
1242: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1243: return(0);
1244: case CS_GOTO:
1245: csi->ip=csi->cs+*((ushort *)(csi->ip));
1246: return(0);
1247: case CS_CALL:
1.1.1.2 ! root 1248: if(csi->rets<MAX_RETS) {
! 1249: csi->ret[csi->rets++]=csi->ip+2;
! 1250: csi->ip=csi->cs+*((ushort *)(csi->ip));
! 1251: }
1.1 root 1252: return(0);
1253: case CS_MSWAIT:
1254: mswait(*(ushort *)csi->ip);
1255: csi->ip+=2;
1256: return(0);
1257: case CS_TOGGLE_NODE_MISC:
1.1.1.2 ! root 1258: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
! 1259: thisnode.misc^=*(ushort *)csi->ip;
! 1260: putnodedat(cfg.node_num,&thisnode);
! 1261: }
1.1 root 1262: csi->ip+=2;
1263: return(0);
1264: case CS_COMPARE_NODE_MISC:
1265: getnodedat(cfg.node_num,&thisnode,0);
1266: if((thisnode.misc&*(ushort *)csi->ip)==*(ushort *)csi->ip)
1267: csi->logic=LOGIC_TRUE;
1268: else
1269: csi->logic=LOGIC_FALSE;
1270: csi->ip+=2;
1271: return(0);
1272: case CS_ADJUST_USER_CREDITS:
1273: i=*(short *)csi->ip;
1274: l=i*1024L;
1275: if(l<0)
1276: subtract_cdt(&cfg,&useron,-l);
1277: else
1278: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,l);
1279: csi->ip+=2;
1280: return(0);
1281: case CS_ADJUST_USER_MINUTES:
1282: i=*(short *)csi->ip;
1283: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,i);
1284: csi->ip+=2;
1285: return(0);
1286: case CS_GETNUM:
1287: i=*(short *)csi->ip;
1288: csi->ip+=2;
1289: l=getnum(i);
1290: if(l<=0) {
1291: csi->str[0]=0;
1292: csi->logic=LOGIC_FALSE; }
1293: else {
1294: sprintf(csi->str,"%lu",l);
1295: csi->logic=LOGIC_TRUE; }
1296: return(0);
1297:
1298: case CS_TOGGLE_USER_FLAG:
1299: i=*(csi->ip++);
1300: ch=*(csi->ip++);
1301: switch(i) {
1302: case '1':
1303: useron.flags1^=FLAG(ch);
1304: putuserrec(&cfg,useron.number,U_FLAGS1,8
1305: ,ultoa(useron.flags1,tmp,16));
1306: break;
1307: case '2':
1308: useron.flags2^=FLAG(ch);
1309: putuserrec(&cfg,useron.number,U_FLAGS2,8
1310: ,ultoa(useron.flags2,tmp,16));
1311: break;
1312: case '3':
1313: useron.flags3^=FLAG(ch);
1314: putuserrec(&cfg,useron.number,U_FLAGS3,8
1315: ,ultoa(useron.flags3,tmp,16));
1316: break;
1317: case '4':
1318: useron.flags4^=FLAG(ch);
1319: putuserrec(&cfg,useron.number,U_FLAGS4,8
1320: ,ultoa(useron.flags4,tmp,16));
1321: break;
1322: case 'R':
1323: useron.rest^=FLAG(ch);
1324: putuserrec(&cfg,useron.number,U_REST,8
1325: ,ultoa(useron.rest,tmp,16));
1326: break;
1327: case 'E':
1328: useron.exempt^=FLAG(ch);
1329: putuserrec(&cfg,useron.number,U_EXEMPT,8
1330: ,ultoa(useron.exempt,tmp,16));
1331: break;
1332: default:
1333: errormsg(WHERE,ERR_CHK,"user flag type",*(csi->ip-2));
1334: return(0); }
1335: return(0);
1336: case CS_REVERT_TEXT:
1337: i=*(ushort *)csi->ip;
1338: csi->ip+=2;
1339: if((ushort)i==0xffff) {
1340: for(i=0;i<TOTAL_TEXT;i++) {
1341: if(text[i]!=text_sav[i] && text[i]!=nulstr)
1342: FREE(text[i]);
1343: text[i]=text_sav[i]; }
1344: return(0); }
1345: i--;
1346: if(i>=TOTAL_TEXT) {
1347: errormsg(WHERE,ERR_CHK,"revert text #",i);
1348: return(0); }
1349: if(text[i]!=text_sav[i] && text[i]!=nulstr)
1350: FREE(text[i]);
1351: text[i]=text_sav[i];
1352: return(0);
1353: default:
1354: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1355: return(0); } }
1356:
1357: if(*csi->ip>=CS_TWO_BYTE) {
1358: switch(*(csi->ip++)) {
1359: case CS_TWO_MORE_BYTES:
1360: switch(*(csi->ip++)) {
1361: case CS_USER_EVENT:
1.1.1.2 ! root 1362: user_event((user_event_t)*(csi->ip++));
1.1 root 1363: return(0);
1364: }
1365: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1366: return(0);
1367: case CS_SETLOGIC:
1368: csi->logic=*csi->ip++;
1369: return(0);
1370: case CS_CMDKEY:
1371: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
1372: || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
1373: && isdigit(csi->cmd&0x7f))) {
1374: csi->ip++;
1375: return(0); }
1376: if(csi->cmd!=*csi->ip) {
1377: csi->ip++;
1378: skipto(csi,CS_END_CMD); } /* skip code */
1379: csi->ip++; /* skip key */
1380: return(0);
1381: case CS_CMDCHAR:
1382: if(csi->cmd!=*csi->ip) {
1383: csi->ip++;
1384: skipto(csi,CS_END_CMD); } /* skip code */
1385: csi->ip++; /* skip key */
1386: return(0);
1387: case CS_NODE_ACTION:
1388: action=*csi->ip++;
1389: return(0);
1390: case CS_NODE_STATUS:
1.1.1.2 ! root 1391: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
! 1392: thisnode.status=*csi->ip++;
! 1393: putnodedat(cfg.node_num,&thisnode);
! 1394: } else
! 1395: csi->ip++;
! 1396: return(0);
! 1397: case CS_MULTINODE_CHAT:
! 1398: multinodechat(*csi->ip++);
1.1 root 1399: return(0);
1400: case CS_GETSTR:
1401: csi->logic=LOGIC_TRUE;
1402: getstr(csi->str,*csi->ip++,0);
1403: if(sys_status&SS_ABORT) {
1404: csi->str[0]=0;
1405: csi->logic=LOGIC_FALSE; }
1406: if(csi->str[0]=='/' && csi->str[1])
1407: csi->cmd=csi->str[1]|0x80;
1408: else
1409: csi->cmd=csi->str[0];
1410: return(0);
1411: case CS_GETLINE:
1412: getstr(csi->str,*csi->ip++,K_LINE);
1413: if(sys_status&SS_ABORT)
1414: csi->str[0]=0;
1415: if(csi->str[0]=='/' && csi->str[1])
1416: csi->cmd=csi->str[1]|0x80;
1417: else
1418: csi->cmd=csi->str[0];
1419: return(0);
1420: case CS_GETSTRUPR:
1421: getstr(csi->str,*csi->ip++,K_UPPER);
1422: if(sys_status&SS_ABORT)
1423: csi->str[0]=0;
1424: if(csi->str[0]=='/' && csi->str[1])
1425: csi->cmd=csi->str[1]|0x80;
1426: else
1427: csi->cmd=csi->str[0];
1428: return(0);
1429: case CS_GETNAME:
1430: getstr(csi->str,*csi->ip++,K_UPRLWR);
1431: if(sys_status&SS_ABORT)
1432: csi->str[0]=0;
1433: return(0);
1434: case CS_SHIFT_STR:
1.1.1.2 ! root 1435: i=*(csi->ip++);
! 1436: j=strlen(csi->str);
! 1437: if(i>j)
! 1438: i=j;
! 1439: if(i)
! 1440: memmove(csi->str,csi->str+i,j+1);
1.1 root 1441: return(0);
1442: case CS_COMPARE_KEY:
1443: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
1444: || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
1445: && isdigit(csi->cmd&0x7f))) {
1446: csi->ip++;
1447: csi->logic=LOGIC_TRUE; }
1448: else {
1449: if(csi->cmd==*(csi->ip++))
1450: csi->logic=LOGIC_TRUE;
1451: else
1452: csi->logic=LOGIC_FALSE; }
1453: return(0);
1454: case CS_COMPARE_CHAR:
1455: if(csi->cmd==*(csi->ip++))
1456: csi->logic=LOGIC_TRUE;
1457: else
1458: csi->logic=LOGIC_FALSE;
1459: return(0);
1460: case CS_SET_USER_LEVEL:
1461: useron.level=*(csi->ip++);
1462: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1463: return(0);
1464: case CS_SET_USER_STRING:
1465: csi->logic=LOGIC_FALSE;
1466: if(!csi->str[0]) {
1467: csi->ip++;
1468: return(0); }
1469: switch(*(csi->ip++)) {
1470: case USER_STRING_ALIAS:
1471: if(!isalpha(csi->str[0]) || trashcan(csi->str,"name"))
1472: break;
1.1.1.2 ! root 1473: i=matchuser(&cfg,csi->str,TRUE /*sysop_alias*/);
1.1 root 1474: if(i && i!=useron.number)
1475: break;
1476: sprintf(useron.alias,"%.*s",LEN_ALIAS,csi->str);
1477: putuserrec(&cfg,useron.number,U_ALIAS,LEN_ALIAS,useron.alias);
1.1.1.2 ! root 1478: putusername(&cfg,useron.number,useron.alias);
1.1 root 1479: csi->logic=LOGIC_TRUE;
1480: break;
1481: case USER_STRING_REALNAME:
1482: if(trashcan(csi->str,"name"))
1483: break;
1484: if(cfg.uq&UQ_DUPREAL
1485: && userdatdupe(useron.number,U_NAME,LEN_NAME
1486: ,csi->str,0))
1487: break;
1488: sprintf(useron.name,"%.*s",LEN_NAME,csi->str);
1489: putuserrec(&cfg,useron.number,U_NAME,LEN_NAME
1490: ,useron.name);
1491: csi->logic=LOGIC_TRUE;
1492: break;
1493: case USER_STRING_HANDLE:
1494: if(trashcan(csi->str,"name"))
1495: break;
1496: if(cfg.uq&UQ_DUPHAND
1497: && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE
1498: ,csi->str,0))
1499: break;
1500: sprintf(useron.handle,"%.*s",LEN_HANDLE,csi->str);
1501: putuserrec(&cfg,useron.number,U_HANDLE,LEN_HANDLE
1502: ,useron.handle);
1503: csi->logic=LOGIC_TRUE;
1504: break;
1505: case USER_STRING_COMPUTER:
1506: sprintf(useron.comp,"%.*s",LEN_COMP,csi->str);
1507: putuserrec(&cfg,useron.number,U_COMP,LEN_COMP
1508: ,useron.comp);
1509: csi->logic=LOGIC_TRUE;
1510: break;
1511: case USER_STRING_NOTE:
1512: sprintf(useron.note,"%.*s",LEN_NOTE,csi->str);
1513: putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE
1514: ,useron.note);
1515: csi->logic=LOGIC_TRUE;
1516: break;
1517: case USER_STRING_ADDRESS:
1518: sprintf(useron.address,"%.*s",LEN_ADDRESS,csi->str);
1519: putuserrec(&cfg,useron.number,U_ADDRESS,LEN_ADDRESS
1520: ,useron.address);
1521: csi->logic=LOGIC_TRUE;
1522: break;
1523: case USER_STRING_LOCATION:
1524: sprintf(useron.location,"%.*s",LEN_LOCATION,csi->str);
1525: putuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION
1526: ,useron.location);
1527: csi->logic=LOGIC_TRUE;
1528: break;
1529: case USER_STRING_ZIPCODE:
1530: sprintf(useron.zipcode,"%.*s",LEN_ZIPCODE,csi->str);
1531: putuserrec(&cfg,useron.number,U_ZIPCODE,LEN_ZIPCODE
1532: ,useron.zipcode);
1533: csi->logic=LOGIC_TRUE;
1534: break;
1535: case USER_STRING_PASSWORD:
1536: sprintf(useron.pass,"%.*s",LEN_PASS,csi->str);
1537: putuserrec(&cfg,useron.number,U_PASS,LEN_PASS
1538: ,useron.pass);
1539: csi->logic=LOGIC_TRUE;
1540: break;
1541: case USER_STRING_BIRTHDAY:
1542: if(!getage(&cfg,csi->str))
1543: break;
1544: sprintf(useron.birth,"%.*s",LEN_BIRTH,csi->str);
1545: putuserrec(&cfg,useron.number,U_BIRTH,LEN_BIRTH
1546: ,useron.birth);
1547: csi->logic=LOGIC_TRUE;
1548: break;
1549: case USER_STRING_PHONE:
1550: if(trashcan(csi->str,"phone"))
1551: break;
1552: sprintf(useron.phone,"%.*s",LEN_PHONE,csi->str);
1553: putuserrec(&cfg,useron.number,U_PHONE,LEN_PHONE
1554: ,useron.phone);
1555: csi->logic=LOGIC_TRUE;
1556: break;
1557: case USER_STRING_MODEM:
1558: sprintf(useron.modem,"%.*s",LEN_MODEM,csi->str);
1559: putuserrec(&cfg,useron.number,U_MODEM,LEN_MODEM
1560: ,useron.phone);
1561: csi->logic=LOGIC_TRUE;
1562: break;
1563: case USER_STRING_COMMENT:
1564: sprintf(useron.comment,"%.*s",LEN_COMMENT,csi->str);
1565: putuserrec(&cfg,useron.number,U_COMMENT,LEN_COMMENT
1566: ,useron.comment);
1567: csi->logic=LOGIC_TRUE;
1568: break;
1569: case USER_STRING_NETMAIL:
1570: sprintf(useron.netmail,"%.*s",LEN_NETMAIL,csi->str);
1571: putuserrec(&cfg,useron.number,U_NETMAIL,LEN_NETMAIL
1572: ,useron.netmail);
1573: csi->logic=LOGIC_TRUE;
1574: break;
1575: default:
1576: errormsg(WHERE,ERR_CHK,"user string type",*(csi->ip-1));
1577: return(0); }
1578: return(0);
1579: default:
1580: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1581: return(0); } }
1582:
1583:
1584: /*********************************/
1585: /* Single Byte Instrcutions ONLY */
1586: /*********************************/
1587:
1588: switch(*(csi->ip++)) {
1589: case CS_ONE_MORE_BYTE: /* Just one MORE byte */
1590: switch(*(csi->ip++)) {
1591: case CS_OFFLINE:
1592: csi->misc|=CS_OFFLINE_EXEC;
1593: return(0);
1594: case CS_ONLINE:
1595: csi->misc&=~CS_OFFLINE_EXEC;
1596: return(0);
1597: case CS_NEWUSER:
1.1.1.2 ! root 1598: if(newuser())
! 1599: csi->logic=LOGIC_TRUE;
! 1600: else
! 1601: csi->logic=LOGIC_FALSE;
1.1 root 1602: return(0);
1603: case CS_LOGON:
1604: if(logon())
1605: csi->logic=LOGIC_TRUE;
1606: else
1607: csi->logic=LOGIC_FALSE;
1608: return(0);
1609: case CS_LOGOUT:
1610: logout();
1611: return(0);
1612: case CS_EXIT:
1613: return(1);
1.1.1.2 ! root 1614: case CS_LOOP_BEGIN:
! 1615: if(csi->loops<MAX_LOOPDEPTH)
! 1616: csi->loop_home[csi->loops++]=(csi->ip-1);
! 1617: return(0);
! 1618: case CS_BREAK_LOOP:
! 1619: if(csi->loops) {
! 1620: skipto(csi,CS_END_LOOP);
! 1621: csi->ip+=2;
! 1622: csi->loops--;
! 1623: }
! 1624: return(0);
! 1625: case CS_END_LOOP:
! 1626: case CS_CONTINUE_LOOP:
! 1627: if(csi->loops)
! 1628: csi->ip=csi->loop_home[csi->loops-1];
! 1629: return(0);
1.1 root 1630: default:
1631: errormsg(WHERE,ERR_CHK,"one byte extended function"
1632: ,*(csi->ip-1));
1633: return(0); }
1634: case CS_CRLF:
1635: CRLF;
1636: return(0);
1637: case CS_CLS:
1638: CLS;
1639: return(0);
1640: case CS_PAUSE:
1641: pause();
1642: return(0);
1643: case CS_PAUSE_RESET:
1644: lncntr=0;
1645: return(0);
1646: case CS_GETLINES:
1647: ansi_getlines();
1648: return(0);
1649: case CS_HANGUP:
1650: hangup();
1651: return(0);
1652: case CS_LOGKEY:
1653: logch(csi->cmd,0);
1654: return(0);
1655: case CS_LOGKEY_COMMA:
1656: logch(csi->cmd,1);
1657: return(0);
1658: case CS_LOGSTR:
1659: log(csi->str);
1660: return(0);
1661: case CS_CHKSYSPASS:
1.1.1.2 ! root 1662: csi->logic=!chksyspass();
1.1 root 1663: return(0);
1664: case CS_PUT_NODE:
1.1.1.2 ! root 1665: if(getnodedat(cfg.node_num,&thisnode,true)==0)
! 1666: putnodedat(cfg.node_num,&thisnode);
1.1 root 1667: return(0);
1668: case CS_SYNC:
1669: SYNC;
1670: return(0);
1671: case CS_ASYNC:
1672: ASYNC;
1673: return(0);
1.1.1.2 ! root 1674: #if 0 /* Removed 02/18/01 - never used, officially deprecated for INCHAR */
1.1 root 1675: case CS_RIOSYNC:
1676: RIOSYNC(0);
1677: return(0);
1.1.1.2 ! root 1678: #endif
1.1 root 1679: case CS_GETTIMELEFT:
1680: gettimeleft();
1681: return(0);
1682: case CS_RETURN:
1683: if(!csi->rets)
1684: return(1);
1685: csi->ip=csi->ret[--csi->rets];
1686: return(0);
1687: case CS_GETKEY:
1688: csi->cmd=getkey(K_UPPER);
1689: return(0);
1690: case CS_GETCHAR:
1.1.1.2 ! root 1691: csi->cmd=getkey(0);
1.1 root 1692: return(0);
1693: case CS_INKEY:
1.1.1.2 ! root 1694: csi->cmd=toupper(inkey(K_NONE,1));
! 1695: if(csi->cmd)
! 1696: csi->logic=LOGIC_TRUE;
! 1697: else
! 1698: csi->logic=LOGIC_FALSE;
! 1699: return(0);
! 1700: case CS_INCHAR:
! 1701: csi->cmd=inkey(K_NONE,1);
1.1 root 1702: if(csi->cmd)
1703: csi->logic=LOGIC_TRUE;
1704: else
1705: csi->logic=LOGIC_FALSE;
1706: return(0);
1707: case CS_GETKEYE:
1708: csi->cmd=getkey(K_UPPER);
1709: if(csi->cmd=='/') {
1710: outchar('/');
1711: csi->cmd=getkey(K_UPPER);
1712: csi->cmd|=0x80; }
1713: return(0);
1714: case CS_GETFILESPEC:
1715: if(getfilespec(csi->str))
1716: csi->logic=LOGIC_TRUE;
1717: else
1718: csi->logic=LOGIC_FALSE;
1719: return(0);
1720: case CS_SAVELINE:
1721: SAVELINE;
1722: return(0);
1723: case CS_RESTORELINE:
1724: RESTORELINE;
1725: return(0);
1726: case CS_SELECT_SHELL:
1.1.1.2 ! root 1727: csi->logic=select_shell() ? LOGIC_TRUE:LOGIC_FALSE;
1.1 root 1728: return(0);
1729: case CS_SET_SHELL:
1730: csi->logic=LOGIC_TRUE;
1731: for(i=0;i<cfg.total_shells;i++)
1732: if(!stricmp(csi->str,cfg.shell[i]->code)
1733: && chk_ar(cfg.shell[i]->ar,&useron))
1734: break;
1735: if(i<cfg.total_shells) {
1736: useron.shell=i;
1737: putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code); }
1738: else
1739: csi->logic=LOGIC_FALSE;
1740: return(0);
1741:
1742: case CS_SELECT_EDITOR:
1.1.1.2 ! root 1743: csi->logic=select_editor() ? LOGIC_TRUE:LOGIC_FALSE;
1.1 root 1744: return(0);
1745: case CS_SET_EDITOR:
1746: csi->logic=LOGIC_TRUE;
1747: for(i=0;i<cfg.total_xedits;i++)
1748: if(!stricmp(csi->str,cfg.xedit[i]->code)
1749: && chk_ar(cfg.xedit[i]->ar,&useron))
1750: break;
1751: if(i<cfg.total_xedits) {
1752: useron.xedit=i+1;
1753: putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code); }
1754: else
1755: csi->logic=LOGIC_FALSE;
1756: return(0);
1757:
1758: case CS_CLEAR_ABORT:
1759: sys_status&=~SS_ABORT;
1760: return(0);
1761: case CS_FINDUSER:
1762: i=finduser(csi->str);
1763: if(i) {
1764: csi->logic=LOGIC_TRUE;
1765: username(&cfg,i,csi->str); }
1766: else
1767: csi->logic=LOGIC_FALSE;
1768: return(0);
1769: case CS_UNGETKEY:
1770: ungetkey(csi->cmd&0x7f);
1771: return(0);
1772: case CS_UNGETSTR:
1773: j=strlen(csi->str);
1774: for(i=0;i<j;i++)
1775: ungetkey(csi->str[i]);
1776: return(0);
1777: case CS_PRINTKEY:
1.1.1.2 ! root 1778: if((csi->cmd&0x7f)>=' ')
1.1 root 1779: outchar(csi->cmd&0x7f);
1780: return(0);
1781: case CS_PRINTSTR:
1782: putmsg(csi->str,P_SAVEATR|P_NOABORT);
1783: return(0);
1784: case CS_CMD_HOME:
1.1.1.2 ! root 1785: if(csi->cmdrets<MAX_CMDRETS)
! 1786: csi->cmdret[csi->cmdrets++]=(csi->ip-1);
1.1 root 1787: return(0);
1788: case CS_END_CMD:
1789: if(csi->cmdrets)
1790: csi->ip=csi->cmdret[--csi->cmdrets];
1791: return(0);
1792: case CS_CMD_POP:
1793: if(csi->cmdrets)
1794: csi->cmdrets--;
1795: return(0);
1796: case CS_IF_TRUE:
1797: if(csi->logic!=LOGIC_TRUE) {
1798: skipto(csi,CS_ELSEORENDIF);
1799: csi->ip++; }
1800: return(0);
1801: case CS_IF_GREATER:
1802: if(csi->logic!=LOGIC_GREATER) {
1803: skipto(csi,CS_ELSEORENDIF);
1804: csi->ip++; }
1805: return(0);
1806: case CS_IF_GREATER_OR_EQUAL:
1807: if(csi->logic!=LOGIC_GREATER && csi->logic!=LOGIC_EQUAL) {
1808: skipto(csi,CS_ELSEORENDIF);
1809: csi->ip++; }
1810: return(0);
1811: case CS_IF_LESS:
1812: if(csi->logic!=LOGIC_LESS) {
1813: skipto(csi,CS_ELSEORENDIF);
1814: csi->ip++; }
1815: return(0);
1816: case CS_IF_LESS_OR_EQUAL:
1817: if(csi->logic!=LOGIC_LESS && csi->logic!=LOGIC_EQUAL) {
1818: skipto(csi,CS_ELSEORENDIF);
1819: csi->ip++; }
1820: return(0);
1821: case CS_IF_FALSE:
1822: if(csi->logic==LOGIC_TRUE) {
1823: skipto(csi,CS_ELSEORENDIF);
1824: csi->ip++; }
1825: return(0);
1826: case CS_ELSE:
1827: skipto(csi,CS_ENDIF);
1828: csi->ip++;
1829: return(0);
1830: case CS_END_CASE:
1831: skipto(csi,CS_END_SWITCH);
1832: csi->misc&=~CS_IN_SWITCH;
1833: csi->ip++;
1834: return(0);
1835: case CS_DEFAULT:
1836: case CS_END_SWITCH:
1837: csi->misc&=~CS_IN_SWITCH;
1838: return(0);
1839: case CS_ENDIF:
1840: return(0);
1841: default:
1842: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1843: return(0); }
1844: }
1845:
1.1.1.2 ! root 1846: bool sbbs_t::select_shell(void)
! 1847: {
! 1848: int i;
! 1849:
! 1850: for(i=0;i<cfg.total_shells;i++)
! 1851: uselect(1,i,"Command Shell",cfg.shell[i]->name,cfg.shell[i]->ar);
! 1852: if((i=uselect(0,useron.shell,0,0,0))>=0) {
! 1853: useron.shell=i;
! 1854: putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code);
! 1855: return(true);
! 1856: }
! 1857: return(false);
! 1858: }
! 1859:
! 1860: bool sbbs_t::select_editor(void)
! 1861: {
! 1862: int i;
! 1863:
! 1864: for(i=0;i<cfg.total_xedits;i++)
! 1865: uselect(1,i,"External Editor",cfg.xedit[i]->name,cfg.xedit[i]->ar);
! 1866: if(useron.xedit) useron.xedit--;
! 1867: if((i=uselect(0,useron.xedit,0,0,0))>=0) {
! 1868: useron.xedit=i+1;
! 1869: putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code);
! 1870: return(true);
! 1871: }
! 1872: return(false);
! 1873: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.