|
|
1.1 root 1: /* exec.cpp */
2:
3: /* Synchronet command shell/module interpretter */
4:
5: /* $Id: exec.cpp,v 1.60 2006/11/16 20:41:06 rswindell Exp $ */
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: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
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);
103: case 0x5E049062:
104: sysvar_p[sysvar_pi]=question;
105: break;
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:
269: sysvar_l[sysvar_li]=sys_timezone(&cfg);
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:
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:
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;
466: bin->loops=0;
467: bin->sockets=0;
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: }
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: }
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 */
508: int i=0;
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:
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: if(sbbs->js_branch.auto_terminate && !sbbs->online) {
536: JS_ReportError(cx,"Disconnected");
537: sbbs->js_branch.counter=0;
538: return(JS_FALSE);
539: }
540:
541: return(js_CommonBranchCallback(cx,&sbbs->js_branch));
542: }
543:
544: static const char* js_ext(const char* fname)
545: {
546: if(strchr(fname,'.')==NULL)
547: return(".js");
548: return("");
549: }
550:
551: long sbbs_t::js_execfile(const char *cmd)
552: {
553: char* p;
554: char* args=NULL;
555: char* fname;
556: int argc=0;
557: char cmdline[MAX_PATH+1];
558: char path[MAX_PATH+1];
559: JSObject* js_scope=NULL;
560: JSScript* js_script=NULL;
561: jsval rval;
562: int32 result=0;
563:
564: if(js_cx==NULL) {
565: errormsg(WHERE,ERR_CHK,"JavaScript support",0);
566: errormsg(WHERE,ERR_EXEC,cmd,0);
567: return(-1);
568: }
569:
570: SAFECOPY(cmdline,cmd);
571: p=strchr(cmdline,' ');
572: if(p!=NULL) {
573: *p=0;
574: args=p+1;
575: }
576: fname=cmdline;
577:
578: if(strcspn(fname,"/\\")==strlen(fname)) {
579: sprintf(path,"%s%s%s",cfg.mods_dir,fname,js_ext(fname));
580: if(cfg.mods_dir[0]==0 || !fexistcase(path))
581: sprintf(path,"%s%s%s",cfg.exec_dir,fname,js_ext(fname));
582: } else
583: SAFECOPY(path,fname);
584:
585: if(!fexistcase(path)) {
586: errormsg(WHERE,ERR_OPEN,path,O_RDONLY);
587: return(-1);
588: }
589:
590: js_scope=JS_NewObject(js_cx, NULL, NULL, js_glob);
591:
592: if(js_scope!=NULL) {
593:
594: JSObject* argv=JS_NewArrayObject(js_cx, 0, NULL);
595:
596: JS_DefineProperty(js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
597: ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
598:
599: if(args!=NULL && argv!=NULL) {
600: while(*args) {
601: p=strchr(args,' ');
602: if(p!=NULL)
603: *p=0;
604: while(*args && *args==' ') args++; /* Skip spaces */
605: JSString* arg = JS_NewStringCopyZ(js_cx, args);
606: if(arg==NULL)
607: break;
608: jsval val=STRING_TO_JSVAL(arg);
609: if(!JS_SetElement(js_cx, argv, argc, &val))
610: break;
611: argc++;
612: if(p==NULL) /* last arg */
613: break;
614: args+=(strlen(args)+1);
615: }
616: }
617: JS_DefineProperty(js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
618: ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
619:
620: JS_ClearPendingException(js_cx);
621:
622: js_script=JS_CompileFile(js_cx, js_scope, path);
623: }
624:
625: if(js_scope==NULL || js_script==NULL) {
626: JS_ReportPendingException(js_cx); /* Added Feb-2-2006, rswindell */
627: errormsg(WHERE,"compiling",path,0);
628: return(-1);
629: }
630:
631: js_branch.counter=0; // Reset loop counter
632:
633: JS_SetBranchCallback(js_cx, js_BranchCallback);
634:
635: JS_ExecuteScript(js_cx, js_scope, js_script, &rval);
636:
637: JS_ReportPendingException(js_cx); /* Added Dec-4-2005, rswindell */
638:
639: js_EvalOnExit(js_cx, js_glob, &js_branch);
640:
641: JS_GetProperty(js_cx, js_glob, "exit_code", &rval);
642:
643: JS_DestroyScript(js_cx, js_script);
644:
645: JS_ClearScope(js_cx, js_scope);
646:
647: JS_GC(js_cx);
648:
649: if(rval!=JSVAL_VOID)
650: JS_ValueToInt32(js_cx,rval,&result);
651:
652: return(result);
653: }
654: #endif
655:
656: /* Important change as of Nov-16-2006, 'cmdline' may contain args */
657: long sbbs_t::exec_bin(const char *cmdline, csi_t *csi)
658: {
659: char str[MAX_PATH+1];
660: char mod[MAX_PATH+1];
661: char modname[MAX_PATH+1];
662: char* p;
663: int file;
664: csi_t bin;
665:
666: SAFECOPY(mod,cmdline);
667: p=mod;
668: FIND_CHAR(p,' ');
669: if(*p) {
670: *p=0; /* terminate 'mod' */
671: p++; /* skip space */
672: SKIP_CHAR(p,' '); /* skip more spaces */
673: }
674: strcpy(main_csi.str, p);
675:
676: #ifdef JAVASCRIPT
677: if((p=getfext(mod))!=NULL && stricmp(p,".js")==0)
678: return(js_execfile(cmdline));
679: if(cfg.mods_dir[0]) {
680: sprintf(str,"%s%s.js",cfg.mods_dir,mod);
681: if(fexistcase(str))
682: return(js_execfile(cmdline));
683: }
684: sprintf(str,"%s%s.js",cfg.exec_dir,mod);
685: if(fexistcase(str))
686: return(js_execfile(cmdline));
687: #endif
688:
689: memcpy(&bin,csi,sizeof(csi_t));
690: clearvars(&bin);
691:
692: SAFECOPY(modname,mod);
693: if(!strchr(modname,'.'))
694: strcat(modname,".bin");
695:
696: sprintf(str,"%s%s",cfg.mods_dir,modname);
697: if(cfg.mods_dir[0]==0 || !fexistcase(str)) {
698: sprintf(str,"%s%s",cfg.exec_dir,modname);
699: fexistcase(str);
700: }
701: if((file=nopen(str,O_RDONLY))==-1) {
702: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
703: return(-1);
704: }
705:
706: bin.length=filelength(file);
707: if((bin.cs=(uchar *)malloc(bin.length))==NULL) {
708: close(file);
709: errormsg(WHERE,ERR_ALLOC,str,bin.length);
710: return(-1);
711: }
712: if(lread(file,bin.cs,bin.length)!=bin.length) {
713: close(file);
714: errormsg(WHERE,ERR_READ,str,bin.length);
715: free(bin.cs);
716: return(-1);
717: }
718: close(file);
719:
720: bin.ip=bin.cs;
721: bin.rets=0;
722: bin.cmdrets=0;
723: bin.misc=0;
724:
725: while(exec(&bin)==0)
726: if(!(bin.misc&CS_OFFLINE_EXEC)) {
727: checkline();
728: if(!online)
729: break;
730: }
731:
732: freevars(&bin);
733: free(bin.cs);
734: csi->logic=bin.logic;
735: return(bin.retval);
736: }
737:
738: /****************************************************************************/
739: /* Skcsi->ip to a specific instruction */
740: /****************************************************************************/
741: void sbbs_t::skipto(csi_t *csi, uchar inst)
742: {
743: int i,j;
744:
745: while(csi->ip<csi->cs+csi->length && ((inst&0x80) || *csi->ip!=inst)) {
746:
747: if(*csi->ip==CS_IF_TRUE || *csi->ip==CS_IF_FALSE
748: || (*csi->ip>=CS_IF_GREATER && *csi->ip<=CS_IF_LESS_OR_EQUAL)) {
749: csi->ip++;
750: skipto(csi,CS_ENDIF);
751: csi->ip++;
752: continue; }
753:
754: if(inst==CS_ELSEORENDIF
755: && (*csi->ip==CS_ELSE || *csi->ip==CS_ENDIF))
756: break;
757:
758: if(inst==CS_NEXTCASE
759: && (*csi->ip==CS_CASE || *csi->ip==CS_DEFAULT
760: || *csi->ip==CS_END_SWITCH))
761: break;
762:
763: if(*csi->ip==CS_SWITCH) {
764: csi->ip++;
765: csi->ip+=4; /* Skip variable name */
766: skipto(csi,CS_END_SWITCH);
767: csi->ip++;
768: continue; }
769:
770: if(*csi->ip==CS_CASE) {
771: csi->ip++;
772: csi->ip+=4; /* Skip value */
773: skipto(csi,CS_NEXTCASE);
774: continue; }
775:
776: if(*csi->ip==CS_CMDKEY || *csi->ip==CS_CMDCHAR) {
777: csi->ip+=2;
778: skipto(csi,CS_END_CMD);
779: csi->ip++;
780: continue; }
781: if(*csi->ip==CS_CMDSTR || *csi->ip==CS_CMDKEYS) {
782: csi->ip++; /* skip inst */
783: while(*(csi->ip++)); /* skip string */
784: skipto(csi,CS_END_CMD);
785: csi->ip++;
786: continue; }
787:
788: if(*csi->ip>=CS_FUNCTIONS) {
789: csi->ip++;
790: continue; }
791:
792: if(*csi->ip>=CS_MISC) {
793: switch(*csi->ip) {
794: case CS_VAR_INSTRUCTION:
795: csi->ip++;
796: switch(*(csi->ip++)) {
797: case SHOW_VARS:
798: continue;
799: case PRINT_VAR:
800: case DEFINE_STR_VAR:
801: case DEFINE_INT_VAR:
802: case DEFINE_GLOBAL_STR_VAR:
803: case DEFINE_GLOBAL_INT_VAR:
804: case TIME_INT_VAR:
805: case STRUPR_VAR:
806: case STRLWR_VAR:
807: case TRUNCSP_STR_VAR:
808: case CHKFILE_VAR:
809: case COPY_CHAR:
810: case STRIP_CTRL_STR_VAR:
811: csi->ip+=4; /* Skip variable name */
812: continue;
813: case GETSTR_VAR:
814: case GETNAME_VAR:
815: case GETLINE_VAR:
816: case GETSTRUPR_VAR:
817: case SHIFT_STR_VAR:
818: case SEND_FILE_VIA_VAR:
819: case RECEIVE_FILE_VIA_VAR:
820: case COMPARE_FIRST_CHAR:
821: case SHIFT_TO_FIRST_CHAR:
822: case SHIFT_TO_LAST_CHAR:
823: csi->ip+=4; /* Skip variable name */
824: csi->ip++; /* Skip char */
825: continue;
826: case PRINTTAIL_VAR_MODE:
827: csi->ip++; /* Skip length */
828: case PRINTFILE_VAR_MODE:
829: case GETNUM_VAR:
830: csi->ip+=4; /* Skip variable name */
831: csi->ip+=2; /* Skip max num */
832: continue;
833: case STRNCMP_VAR:
834: csi->ip++; /* Skip length */
835: case SET_STR_VAR:
836: case COMPARE_STR_VAR:
837: case CAT_STR_VAR:
838: case STRSTR_VAR:
839: case TELNET_GATE_STR:
840: csi->ip+=4; /* Skip variable name */
841: while(*(csi->ip++)); /* skip string */
842: continue;
843: case FORMAT_TIME_STR:
844: csi->ip+=4; /* Skip destination variable */
845: while(*(csi->ip++)); /* Skip string */
846: csi->ip+=4; /* Skip int variable */
847: continue;
848: case FORMAT_STR_VAR: /* SPRINTF */
849: csi->ip+=4; /* Skip destination variable */
850: case VAR_PRINTF:
851: case VAR_PRINTF_LOCAL:
852: while(*(csi->ip++)); /* Skip string */
853: j=*(csi->ip++); /* Skip number of arguments */
854: for(i=0;i<j;i++)
855: csi->ip+=4; /* Skip arguments */
856: continue;
857: case SEND_FILE_VIA:
858: case RECEIVE_FILE_VIA:
859: csi->ip++; /* Skip prot */
860: while(*(csi->ip++)); /* Skip filepath */
861: continue;
862: case GETSTR_MODE:
863: case STRNCMP_VARS:
864: csi->ip++; /* Skip length */
865: default:
866: csi->ip+=8; /* Skip two variable names or var & val */
867: continue; }
868:
869: case CS_FIO_FUNCTION:
870: csi->ip++;
871: switch(*(csi->ip++)) {
872: case FIO_OPEN:
873: csi->ip+=4; /* File handle */
874: csi->ip+=2; /* Access */
875: while(*(csi->ip++)); /* path/filename */
876: continue;
877: case FIO_CLOSE:
878: case FIO_FLUSH:
879: case FIO_EOF:
880: case REMOVE_FILE:
881: case REMOVE_DIR:
882: case CHANGE_DIR:
883: case MAKE_DIR:
884: case REWIND_DIR:
885: case CLOSE_DIR:
886: csi->ip+=4; /* File handle */
887: continue;
888: case FIO_SET_ETX:
889: csi->ip++;
890: continue;
891: case FIO_PRINTF:
892: csi->ip+=4; /* File handle */
893: while(*(csi->ip++)); /* String */
894: j=*(csi->ip++); /* Number of arguments */
895: for(i=0;i<j;i++)
896: csi->ip+=4; /* Arguments */
897: continue;
898: case FIO_READ:
899: case FIO_WRITE:
900: case FIO_SEEK:
901: case FIO_SEEK_VAR:
902: case FIO_OPEN_VAR:
903: csi->ip+=4; /* File handle */
904: csi->ip+=4; /* Variable */
905: csi->ip+=2; /* Length/access */
906: continue;
907: case FIO_READ_VAR:
908: case FIO_WRITE_VAR:
909: csi->ip+=4; /* File handle */
910: csi->ip+=4; /* Buf Variable */
911: csi->ip+=4; /* Length Variable */
912: continue;
913: default:
914: csi->ip+=4; /* File handle */
915: csi->ip+=4; /* Variable */
916: continue; }
917:
918: case CS_NET_FUNCTION:
919: csi->ip++;
920: switch(*(csi->ip++)) {
921: case CS_SOCKET_CONNECT:
922: csi->ip+=4; /* socket */
923: csi->ip+=4; /* address */
924: csi->ip+=2; /* port */
925: continue;
926: case CS_SOCKET_NREAD:
927: csi->ip+=4; /* socket */
928: csi->ip+=4; /* intvar */
929: continue;
930: case CS_SOCKET_READ:
931: case CS_SOCKET_READLINE:
932: case CS_SOCKET_PEEK:
933: csi->ip+=4; /* socket */
934: csi->ip+=4; /* buffer */
935: csi->ip+=2; /* length */
936: continue;
937: case CS_SOCKET_WRITE:
938: csi->ip+=4; /* socket */
939: csi->ip+=4; /* strvar */
940: continue;
941:
942: case CS_FTP_LOGIN:
943: case CS_FTP_GET:
944: case CS_FTP_PUT:
945: case CS_FTP_RENAME:
946: csi->ip+=4; /* socket */
947: csi->ip+=4; /* username/path */
948: csi->ip+=4; /* password/path */
949: continue;
950: case CS_FTP_DIR:
951: case CS_FTP_CWD:
952: case CS_FTP_DELETE:
953: csi->ip+=4; /* socket */
954: csi->ip+=4; /* path */
955: continue;
956:
957: default:
958: csi->ip+=4; /* socket */
959: continue; }
960:
961: case CS_COMPARE_ARS:
962: csi->ip++;
963: csi->ip+=(*csi->ip);
964: csi->ip++;
965: break;
966: case CS_TOGGLE_USER_MISC:
967: case CS_COMPARE_USER_MISC:
968: case CS_TOGGLE_USER_CHAT:
969: case CS_COMPARE_USER_CHAT:
970: case CS_TOGGLE_USER_QWK:
971: case CS_COMPARE_USER_QWK:
972: csi->ip+=5;
973: break;
974: case CS_REPLACE_TEXT:
975: csi->ip+=3; /* skip inst and text # */
976: while(*(csi->ip++)); /* skip string */
977: break;
978: case CS_USE_INT_VAR:
979: csi->ip+=7; // inst, var, offset, len
980: break;
981: default:
982: csi->ip++; }
983: continue; }
984:
985: if(*csi->ip==CS_ONE_MORE_BYTE) {
986: if(inst==CS_END_LOOP && *(csi->ip+1)==CS_END_LOOP)
987: break;
988:
989: csi->ip++; /* skip extension */
990: csi->ip++; /* skip instruction */
991:
992: if(*(csi->ip-1)==CS_LOOP_BEGIN) { /* nested loop */
993: skipto(csi,CS_END_LOOP);
994: csi->ip+=2;
995: }
996:
997: continue; }
998:
999: if(*csi->ip==CS_TWO_MORE_BYTES) {
1000: csi->ip++; /* skip extension */
1001: csi->ip++; /* skip instruction */
1002: csi->ip++; /* skip argument */
1003: continue; }
1004:
1005: if(*csi->ip==CS_THREE_MORE_BYTES) {
1006: csi->ip++; /* skip extension */
1007: csi->ip++; /* skip instruction */
1008: csi->ip+=2; /* skip argument */
1009: continue; }
1010:
1011: if(*csi->ip==CS_STR_FUNCTION) {
1012: csi->ip++; /* skip extension */
1013: csi->ip++; /* skip instruction */
1014: while(*(csi->ip++)); /* skip string */
1015: continue; }
1016:
1017: if(*csi->ip>=CS_ASCIIZ) {
1018: csi->ip++; /* skip inst */
1019: while(*(csi->ip++)); /* skip string */
1020: continue; }
1021:
1022: if(*csi->ip>=CS_THREE_BYTE) {
1023: csi->ip+=3;
1024: continue; }
1025:
1026: if(*csi->ip>=CS_TWO_BYTE) {
1027: csi->ip+=2;
1028: continue; }
1029:
1030: csi->ip++; }
1031: }
1032:
1033:
1034: int sbbs_t::exec(csi_t *csi)
1035: {
1036: char str[256],*path;
1037: char tmp[512];
1038: uchar buf[1025],ch;
1039: int i,j,file;
1040: long l;
1041: FILE *stream;
1042:
1043: if(usrgrps)
1044: cursubnum=usrsub[curgrp][cursub[curgrp]]; /* Used for ARS */
1045: else
1046: cursubnum=INVALID_SUB;
1047: if(usrlibs) {
1048: curdirnum=usrdir[curlib][curdir[curlib]]; /* Used for ARS */
1049: path=cfg.dir[usrdir[curlib][curdir[curlib]]]->path; }
1050: else {
1051: curdirnum=INVALID_DIR;
1052: path=nulstr; }
1053: now=time(NULL);
1054:
1055: if(csi->ip>=csi->cs+csi->length)
1056: return(1);
1057:
1058: if(*csi->ip>=CS_FUNCTIONS)
1059: return(exec_function(csi));
1060:
1061: /**********************************************/
1062: /* Miscellaneous variable length instructions */
1063: /**********************************************/
1064:
1065: if(*csi->ip>=CS_MISC)
1066: return(exec_misc(csi,path));
1067:
1068: /********************************/
1069: /* ASCIIZ argument instructions */
1070: /********************************/
1071:
1072: if(*csi->ip>=CS_ASCIIZ) {
1073: switch(*(csi->ip++)) {
1074: case CS_STR_FUNCTION:
1075: switch(*(csi->ip++)) {
1076: case CS_LOGIN:
1077: csi->logic=login(csi->str,(char*)csi->ip);
1078: break;
1079: case CS_LOAD_TEXT:
1080: csi->logic=LOGIC_FALSE;
1081: for(i=0;i<TOTAL_TEXT;i++)
1082: if(text[i]!=text_sav[i]) {
1083: if(text[i]!=nulstr)
1084: free(text[i]);
1085: text[i]=text_sav[i]; }
1086: sprintf(str,"%s%s.dat"
1087: ,cfg.ctrl_dir,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1088: if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
1089: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
1090: break; }
1091: for(i=0;i<TOTAL_TEXT && !feof(stream);i++) {
1092: if((text[i]=readtext((long *)NULL,stream))==NULL) {
1093: i--;
1094: continue; }
1095: if(!strcmp(text[i],text_sav[i])) { /* If identical */
1096: free(text[i]); /* Don't alloc */
1097: text[i]=text_sav[i]; }
1098: else if(text[i][0]==0) {
1099: free(text[i]);
1100: text[i]=nulstr; } }
1101: if(i<TOTAL_TEXT) {
1102: fclose(stream);
1103: errormsg(WHERE,ERR_READ,str,TOTAL_TEXT);
1104: break; }
1105: fclose(stream);
1106: csi->logic=LOGIC_TRUE;
1107: break;
1108: default:
1109: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1110: break; }
1111: while(*(csi->ip++)); /* Find NULL */
1112: return(0);
1113: case CS_LOG:
1114: log(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1115: break;
1116: case CS_GETCMD:
1117: csi->cmd=(uchar)getkeys((char*)csi->ip,0);
1118: if((char)csi->cmd==-1)
1119: csi->cmd=3;
1120: break;
1121: case CS_CMDSTR:
1122: if(stricmp(csi->str,(char*)csi->ip)) {
1123: while(*(csi->ip++)); /* Find NULL */
1124: skipto(csi,CS_END_CMD);
1125: csi->ip++;
1126: return(0); }
1127: break;
1128: case CS_CMDKEYS:
1129: for(i=0;csi->ip[i];i++)
1130: if(csi->cmd==csi->ip[i])
1131: break;
1132: if(!csi->ip[i]) {
1133: while(*(csi->ip++)); /* Find NULL */
1134: skipto(csi,CS_END_CMD);
1135: csi->ip++;
1136: return(0); }
1137: break;
1138: case CS_GET_TEMPLATE:
1139: gettmplt(csi->str,(char*)csi->ip,K_LINE);
1140: if(sys_status&SS_ABORT)
1141: csi->str[0]=0;
1142: csi->cmd=csi->str[0];
1143: break;
1144: case CS_TRASHCAN:
1145: csi->logic=!trashcan(csi->str,(char*)csi->ip);
1146: break;
1147: case CS_CREATE_SIF:
1148: create_sif_dat((char*)csi->ip,csi->str);
1149: break;
1150: case CS_READ_SIF:
1151: read_sif_dat((char*)csi->ip,csi->str);
1152: break;
1153: case CS_MNEMONICS:
1154: mnemonics((char*)csi->ip);
1155: break;
1156: case CS_PRINT:
1157: putmsg(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR|P_NOABORT);
1158: break;
1159: case CS_PRINT_LOCAL:
1160: if(online==ON_LOCAL)
1161: eprintf(LOG_INFO,"%s",cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1162: else
1163: lputs(LOG_INFO,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1164: break;
1165: case CS_PRINT_REMOTE:
1166: putcom(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1167: break;
1168: case CS_PRINTFILE:
1169: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1170: break;
1171: case CS_PRINTFILE_REMOTE:
1172: if(online!=ON_REMOTE || !(console&CON_R_ECHO))
1173: break;
1174: console&=~CON_L_ECHO;
1175: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1176: console|=CON_L_ECHO;
1177: break;
1178: case CS_PRINTFILE_LOCAL:
1179: if(!(console&CON_L_ECHO))
1180: break;
1181: console&=~CON_R_ECHO;
1182: printfile(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),P_SAVEATR);
1183: console|=CON_R_ECHO;
1184: break;
1185: case CS_CHKFILE:
1186: csi->logic=!fexistcase(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1187: break;
1188: case CS_EXEC:
1189: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),0);
1190: break;
1191: case CS_EXEC_INT:
1192: external(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),EX_OUTR|EX_INR|EX_OUTL);
1193: break;
1194: case CS_EXEC_XTRN:
1195: for(i=0;i<cfg.total_xtrns;i++)
1196: if(!stricmp(cfg.xtrn[i]->code,(char*)csi->ip))
1197: break;
1198: if(i<cfg.total_xtrns)
1199: exec_xtrn(i);
1200: break;
1201: case CS_EXEC_BIN:
1202: exec_bin(cmdstr((char*)csi->ip,path,csi->str,(char*)buf),csi);
1203: break;
1204: case CS_YES_NO:
1205: csi->logic=!yesno(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1206: break;
1207: case CS_NO_YES:
1208: csi->logic=!noyes(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1209: break;
1210: case CS_MENU:
1211: menu(cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1212: break;
1213: case CS_SETSTR:
1214: strcpy(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1215: break;
1216: case CS_SET_MENU_DIR:
1217: cmdstr((char*)csi->ip,path,csi->str,menu_dir);
1218: break;
1219: case CS_SET_MENU_FILE:
1220: cmdstr((char*)csi->ip,path,csi->str,menu_file);
1221: break;
1222: case CS_COMPARE_STR:
1223: csi->logic=stricmp(csi->str,cmdstr((char*)csi->ip,path,csi->str,(char*)buf));
1224: break;
1225: case CS_COMPARE_KEYS:
1226: for(i=0;csi->ip[i];i++)
1227: if(csi->cmd==csi->ip[i])
1228: break;
1229: if(csi->ip[i])
1230: csi->logic=LOGIC_TRUE;
1231: else
1232: csi->logic=LOGIC_FALSE;
1233: break;
1234: case CS_COMPARE_WORD:
1235: csi->logic=strnicmp(csi->str,(char*)csi->ip,strlen((char*)csi->ip));
1236: break;
1237: default:
1238: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1239: break; }
1240: while(*(csi->ip++)); /* Find NULL */
1241: return(0); }
1242:
1243: if(*csi->ip>=CS_THREE_BYTE) {
1244: switch(*(csi->ip++)) {
1245: case CS_THREE_MORE_BYTES:
1246: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1247: return(0);
1248: case CS_GOTO:
1249: csi->ip=csi->cs+*((ushort *)(csi->ip));
1250: return(0);
1251: case CS_CALL:
1252: if(csi->rets<MAX_RETS) {
1253: csi->ret[csi->rets++]=csi->ip+2;
1254: csi->ip=csi->cs+*((ushort *)(csi->ip));
1255: }
1256: return(0);
1257: case CS_MSWAIT:
1258: mswait(*(ushort *)csi->ip);
1259: csi->ip+=2;
1260: return(0);
1261: case CS_TOGGLE_NODE_MISC:
1262: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
1263: thisnode.misc^=*(ushort *)csi->ip;
1264: putnodedat(cfg.node_num,&thisnode);
1265: }
1266: csi->ip+=2;
1267: return(0);
1268: case CS_COMPARE_NODE_MISC:
1269: getnodedat(cfg.node_num,&thisnode,0);
1270: if((thisnode.misc&*(ushort *)csi->ip)==*(ushort *)csi->ip)
1271: csi->logic=LOGIC_TRUE;
1272: else
1273: csi->logic=LOGIC_FALSE;
1274: csi->ip+=2;
1275: return(0);
1276: case CS_ADJUST_USER_CREDITS:
1277: i=*(short *)csi->ip;
1278: l=i*1024L;
1279: if(l<0)
1280: subtract_cdt(&cfg,&useron,-l);
1281: else
1282: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,l);
1283: csi->ip+=2;
1284: return(0);
1285: case CS_ADJUST_USER_MINUTES:
1286: i=*(short *)csi->ip;
1287: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,i);
1288: csi->ip+=2;
1289: return(0);
1290: case CS_GETNUM:
1291: i=*(short *)csi->ip;
1292: csi->ip+=2;
1293: l=getnum(i);
1294: if(l<=0) {
1295: csi->str[0]=0;
1296: csi->logic=LOGIC_FALSE; }
1297: else {
1298: sprintf(csi->str,"%lu",l);
1299: csi->logic=LOGIC_TRUE; }
1300: return(0);
1301:
1302: case CS_TOGGLE_USER_FLAG:
1303: i=*(csi->ip++);
1304: ch=*(csi->ip++);
1305: switch(i) {
1306: case '1':
1307: useron.flags1^=FLAG(ch);
1308: putuserrec(&cfg,useron.number,U_FLAGS1,8
1309: ,ultoa(useron.flags1,tmp,16));
1310: break;
1311: case '2':
1312: useron.flags2^=FLAG(ch);
1313: putuserrec(&cfg,useron.number,U_FLAGS2,8
1314: ,ultoa(useron.flags2,tmp,16));
1315: break;
1316: case '3':
1317: useron.flags3^=FLAG(ch);
1318: putuserrec(&cfg,useron.number,U_FLAGS3,8
1319: ,ultoa(useron.flags3,tmp,16));
1320: break;
1321: case '4':
1322: useron.flags4^=FLAG(ch);
1323: putuserrec(&cfg,useron.number,U_FLAGS4,8
1324: ,ultoa(useron.flags4,tmp,16));
1325: break;
1326: case 'R':
1327: useron.rest^=FLAG(ch);
1328: putuserrec(&cfg,useron.number,U_REST,8
1329: ,ultoa(useron.rest,tmp,16));
1330: break;
1331: case 'E':
1332: useron.exempt^=FLAG(ch);
1333: putuserrec(&cfg,useron.number,U_EXEMPT,8
1334: ,ultoa(useron.exempt,tmp,16));
1335: break;
1336: default:
1337: errormsg(WHERE,ERR_CHK,"user flag type",*(csi->ip-2));
1338: return(0); }
1339: return(0);
1340: case CS_REVERT_TEXT:
1341: i=*(ushort *)csi->ip;
1342: csi->ip+=2;
1343: if((ushort)i==0xffff) {
1344: for(i=0;i<TOTAL_TEXT;i++) {
1345: if(text[i]!=text_sav[i] && text[i]!=nulstr)
1346: free(text[i]);
1347: text[i]=text_sav[i]; }
1348: return(0); }
1349: i--;
1350: if(i>=TOTAL_TEXT) {
1351: errormsg(WHERE,ERR_CHK,"revert text #",i);
1352: return(0); }
1353: if(text[i]!=text_sav[i] && text[i]!=nulstr)
1354: free(text[i]);
1355: text[i]=text_sav[i];
1356: return(0);
1357: default:
1358: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1359: return(0); } }
1360:
1361: if(*csi->ip>=CS_TWO_BYTE) {
1362: switch(*(csi->ip++)) {
1363: case CS_TWO_MORE_BYTES:
1364: switch(*(csi->ip++)) {
1365: case CS_USER_EVENT:
1366: user_event((user_event_t)*(csi->ip++));
1367: return(0);
1368: }
1369: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1370: return(0);
1371: case CS_SETLOGIC:
1372: csi->logic=*csi->ip++;
1373: return(0);
1374: case CS_CMDKEY:
1375: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
1376: || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
1377: && isdigit(csi->cmd&0x7f))) {
1378: csi->ip++;
1379: return(0); }
1380: if(csi->cmd!=*csi->ip) {
1381: csi->ip++;
1382: skipto(csi,CS_END_CMD); } /* skip code */
1383: csi->ip++; /* skip key */
1384: return(0);
1385: case CS_CMDCHAR:
1386: if(csi->cmd!=*csi->ip) {
1387: csi->ip++;
1388: skipto(csi,CS_END_CMD); } /* skip code */
1389: csi->ip++; /* skip key */
1390: return(0);
1391: case CS_NODE_ACTION:
1392: action=*csi->ip++;
1393: return(0);
1394: case CS_NODE_STATUS:
1395: if(getnodedat(cfg.node_num,&thisnode,true)==0) {
1396: thisnode.status=*csi->ip++;
1397: putnodedat(cfg.node_num,&thisnode);
1398: } else
1399: csi->ip++;
1400: return(0);
1401: case CS_MULTINODE_CHAT:
1402: multinodechat(*csi->ip++);
1403: return(0);
1404: case CS_GETSTR:
1405: csi->logic=LOGIC_TRUE;
1406: getstr(csi->str,*csi->ip++,0);
1407: if(sys_status&SS_ABORT) {
1408: csi->str[0]=0;
1409: csi->logic=LOGIC_FALSE; }
1410: if(csi->str[0]=='/' && csi->str[1])
1411: csi->cmd=csi->str[1]|0x80;
1412: else
1413: csi->cmd=csi->str[0];
1414: return(0);
1415: case CS_GETLINE:
1416: getstr(csi->str,*csi->ip++,K_LINE);
1417: if(sys_status&SS_ABORT)
1418: csi->str[0]=0;
1419: if(csi->str[0]=='/' && csi->str[1])
1420: csi->cmd=csi->str[1]|0x80;
1421: else
1422: csi->cmd=csi->str[0];
1423: return(0);
1424: case CS_GETSTRUPR:
1425: getstr(csi->str,*csi->ip++,K_UPPER);
1426: if(sys_status&SS_ABORT)
1427: csi->str[0]=0;
1428: if(csi->str[0]=='/' && csi->str[1])
1429: csi->cmd=csi->str[1]|0x80;
1430: else
1431: csi->cmd=csi->str[0];
1432: return(0);
1433: case CS_GETNAME:
1434: getstr(csi->str,*csi->ip++,K_UPRLWR);
1435: if(sys_status&SS_ABORT)
1436: csi->str[0]=0;
1437: return(0);
1438: case CS_SHIFT_STR:
1439: i=*(csi->ip++);
1440: j=strlen(csi->str);
1441: if(i>j)
1442: i=j;
1443: if(i)
1444: memmove(csi->str,csi->str+i,j+1);
1445: return(0);
1446: case CS_COMPARE_KEY:
1447: if( ((*csi->ip)==CS_DIGIT && isdigit(csi->cmd))
1448: || ((*csi->ip)==CS_EDIGIT && csi->cmd&0x80
1449: && isdigit(csi->cmd&0x7f))) {
1450: csi->ip++;
1451: csi->logic=LOGIC_TRUE; }
1452: else {
1453: if(csi->cmd==*(csi->ip++))
1454: csi->logic=LOGIC_TRUE;
1455: else
1456: csi->logic=LOGIC_FALSE; }
1457: return(0);
1458: case CS_COMPARE_CHAR:
1459: if(csi->cmd==*(csi->ip++))
1460: csi->logic=LOGIC_TRUE;
1461: else
1462: csi->logic=LOGIC_FALSE;
1463: return(0);
1464: case CS_SET_USER_LEVEL:
1465: useron.level=*(csi->ip++);
1466: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1467: return(0);
1468: case CS_SET_USER_STRING:
1469: csi->logic=LOGIC_FALSE;
1470: if(!csi->str[0]) {
1471: csi->ip++;
1472: return(0); }
1473: switch(*(csi->ip++)) {
1474: case USER_STRING_ALIAS:
1475: if(!isalpha(csi->str[0]) || trashcan(csi->str,"name"))
1476: break;
1477: i=matchuser(&cfg,csi->str,TRUE /*sysop_alias*/);
1478: if(i && i!=useron.number)
1479: break;
1480: sprintf(useron.alias,"%.*s",LEN_ALIAS,csi->str);
1481: putuserrec(&cfg,useron.number,U_ALIAS,LEN_ALIAS,useron.alias);
1482: putusername(&cfg,useron.number,useron.alias);
1483: csi->logic=LOGIC_TRUE;
1484: break;
1485: case USER_STRING_REALNAME:
1486: if(trashcan(csi->str,"name"))
1487: break;
1488: if(cfg.uq&UQ_DUPREAL
1489: && userdatdupe(useron.number,U_NAME,LEN_NAME
1490: ,csi->str,0))
1491: break;
1492: sprintf(useron.name,"%.*s",LEN_NAME,csi->str);
1493: putuserrec(&cfg,useron.number,U_NAME,LEN_NAME
1494: ,useron.name);
1495: csi->logic=LOGIC_TRUE;
1496: break;
1497: case USER_STRING_HANDLE:
1498: if(trashcan(csi->str,"name"))
1499: break;
1500: if(cfg.uq&UQ_DUPHAND
1501: && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE
1502: ,csi->str,0))
1503: break;
1504: sprintf(useron.handle,"%.*s",LEN_HANDLE,csi->str);
1505: putuserrec(&cfg,useron.number,U_HANDLE,LEN_HANDLE
1506: ,useron.handle);
1507: csi->logic=LOGIC_TRUE;
1508: break;
1509: case USER_STRING_COMPUTER:
1510: sprintf(useron.comp,"%.*s",LEN_COMP,csi->str);
1511: putuserrec(&cfg,useron.number,U_COMP,LEN_COMP
1512: ,useron.comp);
1513: csi->logic=LOGIC_TRUE;
1514: break;
1515: case USER_STRING_NOTE:
1516: sprintf(useron.note,"%.*s",LEN_NOTE,csi->str);
1517: putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE
1518: ,useron.note);
1519: csi->logic=LOGIC_TRUE;
1520: break;
1521: case USER_STRING_ADDRESS:
1522: sprintf(useron.address,"%.*s",LEN_ADDRESS,csi->str);
1523: putuserrec(&cfg,useron.number,U_ADDRESS,LEN_ADDRESS
1524: ,useron.address);
1525: csi->logic=LOGIC_TRUE;
1526: break;
1527: case USER_STRING_LOCATION:
1528: sprintf(useron.location,"%.*s",LEN_LOCATION,csi->str);
1529: putuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION
1530: ,useron.location);
1531: csi->logic=LOGIC_TRUE;
1532: break;
1533: case USER_STRING_ZIPCODE:
1534: sprintf(useron.zipcode,"%.*s",LEN_ZIPCODE,csi->str);
1535: putuserrec(&cfg,useron.number,U_ZIPCODE,LEN_ZIPCODE
1536: ,useron.zipcode);
1537: csi->logic=LOGIC_TRUE;
1538: break;
1539: case USER_STRING_PASSWORD:
1540: sprintf(useron.pass,"%.*s",LEN_PASS,csi->str);
1541: putuserrec(&cfg,useron.number,U_PASS,LEN_PASS
1542: ,useron.pass);
1543: csi->logic=LOGIC_TRUE;
1544: break;
1545: case USER_STRING_BIRTHDAY:
1546: if(!getage(&cfg,csi->str))
1547: break;
1548: sprintf(useron.birth,"%.*s",LEN_BIRTH,csi->str);
1549: putuserrec(&cfg,useron.number,U_BIRTH,LEN_BIRTH
1550: ,useron.birth);
1551: csi->logic=LOGIC_TRUE;
1552: break;
1553: case USER_STRING_PHONE:
1554: if(trashcan(csi->str,"phone"))
1555: break;
1556: sprintf(useron.phone,"%.*s",LEN_PHONE,csi->str);
1557: putuserrec(&cfg,useron.number,U_PHONE,LEN_PHONE
1558: ,useron.phone);
1559: csi->logic=LOGIC_TRUE;
1560: break;
1561: case USER_STRING_MODEM:
1562: sprintf(useron.modem,"%.*s",LEN_MODEM,csi->str);
1563: putuserrec(&cfg,useron.number,U_MODEM,LEN_MODEM
1564: ,useron.phone);
1565: csi->logic=LOGIC_TRUE;
1566: break;
1567: case USER_STRING_COMMENT:
1568: sprintf(useron.comment,"%.*s",LEN_COMMENT,csi->str);
1569: putuserrec(&cfg,useron.number,U_COMMENT,LEN_COMMENT
1570: ,useron.comment);
1571: csi->logic=LOGIC_TRUE;
1572: break;
1573: case USER_STRING_NETMAIL:
1574: sprintf(useron.netmail,"%.*s",LEN_NETMAIL,csi->str);
1575: putuserrec(&cfg,useron.number,U_NETMAIL,LEN_NETMAIL
1576: ,useron.netmail);
1577: csi->logic=LOGIC_TRUE;
1578: break;
1579: default:
1580: errormsg(WHERE,ERR_CHK,"user string type",*(csi->ip-1));
1581: return(0); }
1582: return(0);
1583: default:
1584: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1585: return(0); } }
1586:
1587:
1588: /*********************************/
1589: /* Single Byte Instrcutions ONLY */
1590: /*********************************/
1591:
1592: switch(*(csi->ip++)) {
1593: case CS_ONE_MORE_BYTE: /* Just one MORE byte */
1594: switch(*(csi->ip++)) {
1595: case CS_OFFLINE:
1596: csi->misc|=CS_OFFLINE_EXEC;
1597: return(0);
1598: case CS_ONLINE:
1599: csi->misc&=~CS_OFFLINE_EXEC;
1600: return(0);
1601: case CS_NEWUSER:
1602: if(newuser())
1603: csi->logic=LOGIC_TRUE;
1604: else
1605: csi->logic=LOGIC_FALSE;
1606: return(0);
1607: case CS_LOGON:
1608: if(logon())
1609: csi->logic=LOGIC_TRUE;
1610: else
1611: csi->logic=LOGIC_FALSE;
1612: return(0);
1613: case CS_LOGOUT:
1614: logout();
1615: return(0);
1616: case CS_EXIT:
1617: return(1);
1618: case CS_LOOP_BEGIN:
1619: if(csi->loops<MAX_LOOPDEPTH)
1620: csi->loop_home[csi->loops++]=(csi->ip-1);
1621: return(0);
1622: case CS_BREAK_LOOP:
1623: if(csi->loops) {
1624: skipto(csi,CS_END_LOOP);
1625: csi->ip+=2;
1626: csi->loops--;
1627: }
1628: return(0);
1629: case CS_END_LOOP:
1630: case CS_CONTINUE_LOOP:
1631: if(csi->loops)
1632: csi->ip=csi->loop_home[csi->loops-1];
1633: return(0);
1634: default:
1635: errormsg(WHERE,ERR_CHK,"one byte extended function"
1636: ,*(csi->ip-1));
1637: return(0); }
1638: case CS_CRLF:
1639: CRLF;
1640: return(0);
1641: case CS_CLS:
1642: CLS;
1643: return(0);
1644: case CS_PAUSE:
1645: pause();
1646: return(0);
1647: case CS_PAUSE_RESET:
1648: lncntr=0;
1649: return(0);
1650: case CS_GETLINES:
1651: ansi_getlines();
1652: return(0);
1653: case CS_HANGUP:
1654: hangup();
1655: return(0);
1656: case CS_LOGKEY:
1657: logch(csi->cmd,0);
1658: return(0);
1659: case CS_LOGKEY_COMMA:
1660: logch(csi->cmd,1);
1661: return(0);
1662: case CS_LOGSTR:
1663: log(csi->str);
1664: return(0);
1665: case CS_CHKSYSPASS:
1666: csi->logic=!chksyspass();
1667: return(0);
1668: case CS_PUT_NODE:
1669: if(getnodedat(cfg.node_num,&thisnode,true)==0)
1670: putnodedat(cfg.node_num,&thisnode);
1671: return(0);
1672: case CS_SYNC:
1673: SYNC;
1674: return(0);
1675: case CS_ASYNC:
1676: ASYNC;
1677: return(0);
1678: case CS_GETTIMELEFT:
1679: gettimeleft();
1680: return(0);
1681: case CS_RETURN:
1682: if(!csi->rets)
1683: return(1);
1684: csi->ip=csi->ret[--csi->rets];
1685: return(0);
1686: case CS_GETKEY:
1687: csi->cmd=getkey(K_UPPER);
1688: return(0);
1689: case CS_GETCHAR:
1690: csi->cmd=getkey(0);
1691: return(0);
1692: case CS_INKEY:
1693: csi->cmd=toupper(inkey(K_NONE,1));
1694: if(csi->cmd)
1695: csi->logic=LOGIC_TRUE;
1696: else
1697: csi->logic=LOGIC_FALSE;
1698: return(0);
1699: case CS_INCHAR:
1700: csi->cmd=inkey(K_NONE,1);
1701: if(csi->cmd)
1702: csi->logic=LOGIC_TRUE;
1703: else
1704: csi->logic=LOGIC_FALSE;
1705: return(0);
1706: case CS_GETKEYE:
1707: csi->cmd=getkey(K_UPPER);
1708: if(csi->cmd=='/') {
1709: outchar('/');
1710: csi->cmd=getkey(K_UPPER);
1711: csi->cmd|=0x80; }
1712: return(0);
1713: case CS_GETFILESPEC:
1714: if(getfilespec(csi->str))
1715: csi->logic=LOGIC_TRUE;
1716: else
1717: csi->logic=LOGIC_FALSE;
1718: return(0);
1719: case CS_SAVELINE:
1720: SAVELINE;
1721: return(0);
1722: case CS_RESTORELINE:
1723: RESTORELINE;
1724: return(0);
1725: case CS_SELECT_SHELL:
1726: csi->logic=select_shell() ? LOGIC_TRUE:LOGIC_FALSE;
1727: return(0);
1728: case CS_SET_SHELL:
1729: csi->logic=LOGIC_TRUE;
1730: for(i=0;i<cfg.total_shells;i++)
1731: if(!stricmp(csi->str,cfg.shell[i]->code)
1732: && chk_ar(cfg.shell[i]->ar,&useron))
1733: break;
1734: if(i<cfg.total_shells) {
1735: useron.shell=i;
1736: putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code); }
1737: else
1738: csi->logic=LOGIC_FALSE;
1739: return(0);
1740:
1741: case CS_SELECT_EDITOR:
1742: csi->logic=select_editor() ? LOGIC_TRUE:LOGIC_FALSE;
1743: return(0);
1744: case CS_SET_EDITOR:
1745: csi->logic=LOGIC_TRUE;
1746: for(i=0;i<cfg.total_xedits;i++)
1747: if(!stricmp(csi->str,cfg.xedit[i]->code)
1748: && chk_ar(cfg.xedit[i]->ar,&useron))
1749: break;
1750: if(i<cfg.total_xedits) {
1751: useron.xedit=i+1;
1752: putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code); }
1753: else
1754: csi->logic=LOGIC_FALSE;
1755: return(0);
1756:
1757: case CS_CLEAR_ABORT:
1758: sys_status&=~SS_ABORT;
1759: return(0);
1760: case CS_FINDUSER:
1761: i=finduser(csi->str);
1762: if(i) {
1763: csi->logic=LOGIC_TRUE;
1764: username(&cfg,i,csi->str); }
1765: else
1766: csi->logic=LOGIC_FALSE;
1767: return(0);
1768: case CS_UNGETKEY:
1769: ungetkey(csi->cmd&0x7f);
1770: return(0);
1771: case CS_UNGETSTR:
1772: j=strlen(csi->str);
1773: for(i=0;i<j;i++)
1774: ungetkey(csi->str[i]);
1775: return(0);
1776: case CS_PRINTKEY:
1777: if((csi->cmd&0x7f)>=' ')
1778: outchar(csi->cmd&0x7f);
1779: return(0);
1780: case CS_PRINTSTR:
1781: putmsg(csi->str,P_SAVEATR|P_NOABORT|P_NOATCODES);
1782: return(0);
1783: case CS_CMD_HOME:
1784: if(csi->cmdrets<MAX_CMDRETS)
1785: csi->cmdret[csi->cmdrets++]=(csi->ip-1);
1786: return(0);
1787: case CS_END_CMD:
1788: if(csi->cmdrets)
1789: csi->ip=csi->cmdret[--csi->cmdrets];
1790: return(0);
1791: case CS_CMD_POP:
1792: if(csi->cmdrets)
1793: csi->cmdrets--;
1794: return(0);
1795: case CS_IF_TRUE:
1796: if(csi->logic!=LOGIC_TRUE) {
1797: skipto(csi,CS_ELSEORENDIF);
1798: csi->ip++; }
1799: return(0);
1800: case CS_IF_GREATER:
1801: if(csi->logic!=LOGIC_GREATER) {
1802: skipto(csi,CS_ELSEORENDIF);
1803: csi->ip++; }
1804: return(0);
1805: case CS_IF_GREATER_OR_EQUAL:
1806: if(csi->logic!=LOGIC_GREATER && csi->logic!=LOGIC_EQUAL) {
1807: skipto(csi,CS_ELSEORENDIF);
1808: csi->ip++; }
1809: return(0);
1810: case CS_IF_LESS:
1811: if(csi->logic!=LOGIC_LESS) {
1812: skipto(csi,CS_ELSEORENDIF);
1813: csi->ip++; }
1814: return(0);
1815: case CS_IF_LESS_OR_EQUAL:
1816: if(csi->logic!=LOGIC_LESS && csi->logic!=LOGIC_EQUAL) {
1817: skipto(csi,CS_ELSEORENDIF);
1818: csi->ip++; }
1819: return(0);
1820: case CS_IF_FALSE:
1821: if(csi->logic==LOGIC_TRUE) {
1822: skipto(csi,CS_ELSEORENDIF);
1823: csi->ip++; }
1824: return(0);
1825: case CS_ELSE:
1826: skipto(csi,CS_ENDIF);
1827: csi->ip++;
1828: return(0);
1829: case CS_END_CASE:
1830: skipto(csi,CS_END_SWITCH);
1831: csi->misc&=~CS_IN_SWITCH;
1832: csi->ip++;
1833: return(0);
1834: case CS_DEFAULT:
1835: case CS_END_SWITCH:
1836: csi->misc&=~CS_IN_SWITCH;
1837: return(0);
1838: case CS_ENDIF:
1839: return(0);
1840: default:
1841: errormsg(WHERE,ERR_CHK,"shell instruction",*(csi->ip-1));
1842: return(0); }
1843: }
1844:
1845: bool sbbs_t::select_shell(void)
1846: {
1847: int i;
1848:
1849: for(i=0;i<cfg.total_shells;i++)
1850: uselect(1,i,"Command Shell",cfg.shell[i]->name,cfg.shell[i]->ar);
1851: if((i=uselect(0,useron.shell,0,0,0))>=0) {
1852: useron.shell=i;
1853: putuserrec(&cfg,useron.number,U_SHELL,8,cfg.shell[i]->code);
1854: return(true);
1855: }
1856: return(false);
1857: }
1858:
1859: bool sbbs_t::select_editor(void)
1860: {
1861: int i;
1862:
1863: for(i=0;i<cfg.total_xedits;i++)
1864: uselect(1,i,"External Editor",cfg.xedit[i]->name,cfg.xedit[i]->ar);
1865: if(useron.xedit) useron.xedit--;
1866: if((i=uselect(0,useron.xedit,0,0,0))>=0) {
1867: useron.xedit=i+1;
1868: putuserrec(&cfg,useron.number,U_XEDIT,8,cfg.xedit[i]->code);
1869: return(true);
1870: }
1871: return(false);
1872: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.