|
|
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.