home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / XTRN.C < prev   
Encoding:
C/C++ Source or Header  |  1997-04-13  |  12.6 KB  |  501 lines

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