|
|
1.1 root 1: #line 1 "XTRN.C"
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: /***************************************************************************/
6: /* Functions that pertain to external programs (other EXE or COM programs) */
7: /***************************************************************************/
8:
9: #include "sbbs.h"
10: #include "cmdshell.h"
11:
12: #ifndef __FLAT__
13:
14: #include "spawno.h"
15:
16: void interrupt (*oldfunc)(void);
17:
18: /*****************************************************************************/
19: /* Interrupt routine to expand WWIV Ctrl-C# codes into ANSI escape sequences */
20: /*****************************************************************************/
21: void interrupt wwiv_expand()
22: {
23: char str[256],al;
24: static int ctrl_c;
25: int i,j;
26:
27: al=_AL;
28: if(al!=3 && !ctrl_c)
29: oldfunc();
30: else if(al!=3 && ctrl_c) {
31: ctrl_c=0;
32: if(useron.misc&ANSI) {
33: switch(al) {
34: default:
35: strcpy(str,"\x1b[0m"); /* low grey */
36: break;
37: case '1':
38: strcpy(str,"\x1b[0;1;36m"); /* high cyan */
39: break;
40: case '2':
41: strcpy(str,"\x1b[0;1;33m"); /* high yellow */
42: break;
43: case '3':
44: strcpy(str,"\x1b[0;35m"); /* low magenta */
45: break;
46: case '4':
47: strcpy(str,"\x1b[0;1;44m"); /* white on blue */
48: break;
49: case '5':
50: strcpy(str,"\x1b[0;32m"); /* low green */
51: break;
52: case '6':
53: strcpy(str,"\x1b[0;1;5;31m"); /* high blinking red */
54: break;
55: case '7':
56: strcpy(str,"\x1b[0;1;34m"); /* high blue */
57: break;
58: case '8':
59: strcpy(str,"\x1b[0;34m"); /* low blue */
60: break;
61: case '9':
62: strcpy(str,"\x1b[0;36m"); /* low cyan */
63: break; }
64: j=strlen(str);
65: for(i=0;i<j;i++) {
66: _AL=str[i];
67: oldfunc(); } } }
68: else
69: ctrl_c=1;
70: }
71: #endif
72:
73: /****************************************************************************/
74: /* Runs an external program directly using spawnvp */
75: /****************************************************************************/
76: int external(char *cmdline,char mode)
77: {
78: char c,d,cmdlen,*arg[30],str[256],str2[256],fname[128],*p,x,y;
79: int i,file,rmode=0;
80: long l;
81: FILE *fp;
82: #ifdef __OS2__
83: RESULTCODES rc;
84: #endif
85:
86: if(cmdline[0]=='*') { /* Baja module */
87: strcpy(str,cmdline+1);
88: p=strchr(str,SP);
89: if(p) {
90: strcpy(main_csi.str,p+1);
91: *p=0; }
92: return(exec_bin(str,&main_csi)); }
93:
94: #ifdef __MSDOS__
95: nosound(); /* if page is on, turn off sound */
96: #endif
97: attr(LIGHTGRAY); /* set attributes to normal text */
98:
99: strcpy(str,cmdline); /* Set str to program name only */
100: p=strchr(str,SP);
101: if(p) *p=0;
102: strcpy(fname,str);
103:
104:
105: if(!(mode&EX_CC)) {
106: if(strcspn(cmdline,"<>|")!=strlen(cmdline))
107: mode|=EX_CC; /* DOS I/O redirection; so, use command.com */
108: else {
109: i=strlen(str);
110: if(i>4 && !stricmp(str+(i-4),".BAT")) /* specified .BAT file */
111: mode|=EX_CC;
112: else {
113: strcat(str,".BAT");
114: if(fexist(str)) /* and it's a .BAT file */
115: mode|=EX_CC; } } }
116:
117: p=strrchr(fname,'\\');
118: if(!p) p=strchr(fname,':');
119: if(!p) p=fname;
120: else p++;
121:
122: #ifndef __FLAT__
123:
124: for(i=0;i<total_swaps;i++)
125: if(!stricmp(p,swap[i]->cmd))
126: break;
127: if(i<total_swaps)
128: mode|=EX_SWAP;
129:
130: #else
131:
132: for(i=0;i<total_os2pgms;i++)
133: if(!stricmp(p,os2pgm[i]->name))
134: break;
135: if(i<total_os2pgms) {
136: mode|=EX_OS2;
137: if(os2pgm[i]->misc&OS2_POPEN)
138: mode|=EX_POPEN; }
139:
140: #endif
141:
142: #ifndef __FLAT__
143:
144: if(node_swap&SWAP_NONE || mode&EX_WWIV)
145: mode&=~EX_SWAP;
146:
147: if(mode&EX_SWAP) {
148: if(lclwy()>1 || lclwx()>1)
149: lputs(crlf);
150: lputs("Swapping...\r\n"); }
151:
152: #endif
153:
154:
155: if(!(mode&EX_OS2) && mode&EX_CC)
156: sprintf(str,"%s /C %s",
157: #ifdef __OS2__
158: node_comspec // Only used node_comspec for OS/2 ver
159: #else
160: comspec
161: #endif
162: ,cmdline);
163:
164: else strcpy(str,cmdline);
165: if(!(mode&EX_OS2) && strlen(str)>126) {
166: errormsg(WHERE,ERR_LEN,str,strlen(str));
167: errorlevel=-1;
168: return(-1); }
169:
170: #ifndef __FLAT__
171:
172: arg[0]=str; /* point to the beginning of the string */
173: cmdlen=strlen(str);
174: for(c=0,d=1;c<cmdlen;c++) /* Break up command line */
175: if(str[c]==SP) {
176: str[c]=0; /* insert nulls */
177: arg[d++]=str+c+1; } /* point to the beginning of the next arg */
178: arg[d]=0;
179:
180: #endif
181:
182: if(mode&EX_OUTR && (console&CON_R_ECHO))
183: rmode|=INT29R;
184: if(mode&EX_OUTL)
185: rmode|=INT29L;
186: if(mode&EX_INR && (console&CON_R_INPUT))
187: rmode|=INT16;
188:
189: #ifndef __FLAT__
190:
191: if(rmode)
192: ivhctl(rmode); /* set DOS output interception vectors */
193:
194: if(mode&EX_WWIV) { /* WWIV code expansion */
195: rioctl(CPTOFF); /* turn off ctrl-p translation */
196: oldfunc=getvect(0x29);
197: setvect(0x29,wwiv_expand); }
198:
199: if(com_port && sys_status&SS_COMISR && !(mode&(EX_OUTR|EX_INR))) {
200: riosync(0);
201: rioini(0,0);
202: sys_status&=~SS_COMISR; }
203:
204: if(!rmode) { /* clear the status line */
205: lclini(node_scrnlen);
206: x=lclwx();
207: y=lclwy();
208: STATUSLINE;
209: lclxy(1,node_scrnlen);
210: lputc(CLREOL);
211: TEXTWINDOW;
212: lclxy(x,y); }
213:
214: if(mode&EX_SWAP) { /* set the resident size */
215: if(rmode)
216: __spawn_resident=7000; /* was 6000 */
217: else
218: __spawn_resident=0;
219: i=spawnvpeo(node_swapdir,arg[0],(const char **)arg
220: ,(const char **)environ); }
221: else
222: i=spawnvpe(P_WAIT,arg[0],arg,environ);
223:
224: #else //lif defined(__OS2__)
225:
226: if(com_port && !(mode&EX_POPEN)
227: && sys_status&SS_COMISR) { /* Uninstall COM routines */
228: riosync(0);
229: rioini(0,0);
230: sys_status&=~SS_COMISR; }
231:
232: textattr(LIGHTGRAY); // Redundant
233: if(!(mode&EX_OS2)) { /* DOS pgm */
234: if(lclwy()>1 || lclwx()>1)
235: lputs(crlf);
236: lprintf("Executing DOS program: %s\r\n",str);
237: sprintf(str2,"%sEXECDOS.DAT",node_dir);
238: if((file=nopen(str2,O_WRONLY|O_TRUNC|O_CREAT))!=-1) {
239: sprintf(str2,"V1.00\r\n%X\r\n%lu\r\n%u\r\n%X\r\n%X\r\n%lX\r\n%u\r\n"
240: "%s\r\n"
241: ,online==ON_REMOTE ? com_base:0
242: ,com_irq,dte_rate,rmode,mode,useron.misc,node_num,str);
243: write(file,str2,strlen(str2));
244: sprintf(str2,"%u\r\nDSZLOG=%s\r\n"
245: ,1 /* Total env vars to setup */
246: ,getenv("DSZLOG"));
247: write(file,str2,strlen(str2));
248: if(online) {
249: sprintf(str2,"%s\r\n%s\r\n%u\r\n%u\r\n%c\r\n%s\r\n%s\r\n"
250: ,useron.alias
251: ,useron.name
252: ,useron.level
253: ,getage(useron.birth)
254: ,useron.sex
255: ,useron.phone
256: ,useron.location);
257: write(file,str2,strlen(str2)); }
258: close(file); }
259:
260: sprintf(str,"%sEXECDOS.EXE %s",exec_dir,node_dir);
261:
262: x=wherex();
263: y=wherey();
264: i=system(str);
265: gotoxy(x,y); }
266: else { /* OS/2 pgm */
267: window(1,1,80,node_scrnlen);
268: x=lclwx();
269: y=lclwy();
270: lclxy(1,node_scrnlen);
271: lputc(CLREOL);
272: lclxy(x,y);
273: i=system(cmdline);
274: lputs(crlf);
275: lputs(crlf);
276: lclxy(1,node_scrnlen-1);
277: }
278:
279: #ifdef __OS2__
280: fixkbdmode();
281: #endif
282: textattr(LIGHTGRAY);
283:
284: #endif
285:
286: #ifndef __WIN32__
287: while(lkbrd(0)) /* suck up any chars in the keyboard buffer */
288: ;
289: #endif
290:
291: #ifdef __MSDOS__
292: setcbrk(0);
293:
294: lclatr(LIGHTGRAY);
295: c=wherey();
296: if(c>=node_scrnlen)
297: c=node_scrnlen-1;
298: lclxy(wherex(),c); /* put the cursor where BIOS thinks it is */
299:
300: #endif
301:
302: if(com_port && !(mode&EX_POPEN)
303: #ifndef __OS2__
304: && !(mode&(EX_OUTR|EX_INR))
305: #endif
306: ) {
307: comini();
308: setrate();
309: rioctl(IOSM|PAUSE|ABORT); }
310:
311: rioctl(CPTON); /* turn on ctrl-p translation */
312:
313: #ifndef __FLAT__
314: if(mode&EX_WWIV)
315: setvect(0x29,oldfunc);
316:
317: if(rmode)
318: ivhctl(0); /* replace DOS output interrupt vectors */
319: #endif
320:
321: setdisk(node_disk);
322: strcpy(str,node_dir);
323: str[strlen(str)-1]=0;
324: if(chdir(str))
325: errormsg(WHERE,ERR_CHDIR,str,0);
326:
327: #ifndef __FLAT__
328: lclini(node_scrnlen-1);
329: #endif
330:
331: lncntr=0;
332: if(online)
333: statusline(); /* Replace status line after calling external program */
334: errorlevel=i;
335: return(i);
336: }
337:
338: #ifndef __FLAT__
339: extern uint riobp;
340: extern mswtyp;
341: #endif
342:
343: uint fakeriobp=0xffff;
344:
345: /*****************************************************************************/
346: /* Returns command line generated from instr with %c replacments */
347: /*****************************************************************************/
348: char *cmdstr(char *instr, char *fpath, char *fspec, char *outstr)
349: {
350: static char static_cmd[128];
351: char str[256],str2[128],*cmd;
352: int i,j,len;
353:
354: if(outstr==NULL)
355: cmd=static_cmd;
356: else
357: cmd=outstr;
358: len=strlen(instr);
359: for(i=j=0;i<len && j<128;i++) {
360: if(instr[i]=='%') {
361: i++;
362: cmd[j]=0;
363: switch(toupper(instr[i])) {
364: case 'A': /* User alias */
365: strcat(cmd,useron.alias);
366: break;
367: case 'B': /* Baud (DTE) Rate */
368: strcat(cmd,ultoa(dte_rate,str,10));
369: break;
370: case 'C': /* Connect Description */
371: strcat(cmd,connection);
372: break;
373: case 'D': /* Connect (DCE) Rate */
374: strcat(cmd,ultoa((ulong)cur_rate,str,10));
375: break;
376: case 'E': /* Estimated Rate */
377: strcat(cmd,ultoa((ulong)cur_cps*10,str,10));
378: break;
379: case 'F': /* File path */
380: strcat(cmd,fpath);
381: break;
382: case 'G': /* Temp directory */
383: strcat(cmd,temp_dir);
384: break;
385: case 'H': /* Port Handle or Hardware Flow Control */
386: #ifdef __OS2__
387: strcat(cmd,itoa(rio_handle,str,10));
388: #else
389: if(mdm_misc&MDM_CTS)
390: strcat(cmd,"Y");
391: else
392: strcat(cmd,"N");
393: #endif
394: break;
395: case 'I': /* UART IRQ Line */
396: strcat(cmd,itoa(com_irq,str,10));
397: break;
398: case 'J':
399: strcat(cmd,data_dir);
400: break;
401: case 'K':
402: strcat(cmd,ctrl_dir);
403: break;
404: case 'L': /* Lines per message */
405: strcat(cmd,itoa(level_linespermsg[useron.level],str,10));
406: break;
407: case 'M': /* Minutes (credits) for user */
408: strcat(cmd,ultoa(useron.min,str,10));
409: break;
410: case 'N': /* Node Directory (same as SBBSNODE environment var) */
411: strcat(cmd,node_dir);
412: break;
413: case 'O': /* SysOp */
414: strcat(cmd,sys_op);
415: break;
416: case 'P': /* COM Port */
417: strcat(cmd,itoa(online==ON_LOCAL ? 0:com_port,str,10));
418: break;
419: case 'Q': /* QWK ID */
420: strcat(cmd,sys_id);
421: break;
422: case 'R': /* Rows */
423: strcat(cmd,itoa(rows,str,10));
424: break;
425: case 'S': /* File Spec */
426: strcat(cmd,fspec);
427: break;
428: case 'T': /* Time left in seconds */
429: gettimeleft();
430: strcat(cmd,itoa(timeleft,str,10));
431: break;
432: case 'U': /* UART I/O Address (in hex) */
433: strcat(cmd,itoa(com_base,str,16));
434: break;
435: case 'V': /* Synchronet Version */
436: sprintf(str,"%s%c",VERSION,REVISION);
437: break;
438: case 'W': /* Time-slice API type (mswtype) */
439: #ifndef __FLAT__
440: strcat(cmd,itoa(mswtyp,str,10));
441: #endif
442: break;
443: case 'X':
444: strcat(cmd,shell[useron.shell]->code);
445: break;
446: case '&': /* Address of msr */
447: #ifndef __FLAT__
448: sprintf(str,"%lu",sys_status&SS_DCDHIGH ? &fakeriobp
449: : online==ON_REMOTE ? &riobp-1 : 0);
450: strcat(cmd,str);
451: #else
452: strcat(cmd,"%&");
453: #endif
454: break;
455: case 'Y':
456: strcat(cmd,
457: #ifdef __OS2__
458: node_comspec
459: #else
460: comspec
461: #endif
462: );
463: break;
464: case 'Z':
465: strcat(cmd,text_dir);
466: break;
467: case '!': /* EXEC Directory */
468: strcat(cmd,exec_dir);
469: break;
470: case '#': /* Node number (same as SBBSNNUM environment var) */
471: sprintf(str,"%d",node_num);
472: strcat(cmd,str);
473: break;
474: case '*':
475: sprintf(str,"%03d",node_num);
476: strcat(cmd,str);
477: break;
478: case '$': /* Credits */
479: strcat(cmd,ultoa(useron.cdt+useron.freecdt,str,10));
480: break;
481: case '%': /* %% for percent sign */
482: strcat(cmd,"%");
483: break;
484: default: /* unknown specification */
485: if(isdigit(instr[i])) {
486: sprintf(str,"%0*d",instr[i]&0xf,useron.number);
487: strcat(cmd,str); }
488: /*
489: else
490: errormsg(WHERE,ERR_CHK,instr,i);
491: */
492: break; }
493: j=strlen(cmd); }
494: else
495: cmd[j++]=instr[i]; }
496: cmd[j]=0;
497:
498: return(cmd);
499: }
500:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.