home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / ci_c86 / bisicc / execf.c < prev   
Encoding:
C/C++ Source or Header  |  1985-06-26  |  4.4 KB  |  170 lines

  1. /*        execf.c        execute another program and return status */
  2.  
  3. #include <stdio.h>
  4.  
  5. struct {unsigned int ax,bx,cx,dx,si,di,ds,es;} r;
  6. unsigned char cline[128],*ep,*envfind();
  7. int status=-1;
  8.  
  9. #define NUMINTS 30
  10. static char *internals[] = {"copy","ren","rename","del","erase","chdir","cd",\
  11. "md","mkdir","dir","rd","rmdir","type","cls","ctty","date","time",\
  12. "path","prompt","set","ver","verify","vol","echo","rem","goto","if",\
  13. "shift","pause","for"};
  14.  
  15. fork(cmdl)                /* parses off name and cmdl for execf */
  16. char *cmdl;
  17. {
  18.     char *sp;
  19.     char *name;
  20.     char comlin[128];
  21.     int er;
  22.  
  23.     sp = strcpy(name,cmdl);
  24.     strcat(name," ");                    /* pad for find */
  25.     while(*++sp != ' ');                /* find 1st space */
  26.     *sp++ = '\0';                        /* term name str */
  27.     strcpy(comlin,sp);                /* get command line */
  28.     er= execf(name,comlin);
  29.     return(er);
  30. }
  31.  
  32. execf(name,cmdl)        /* executes name with command line cmdl */
  33. char *name;
  34. char *cmdl;
  35. {
  36.     int i,er;
  37.     char tp[255];
  38.     char *ts;
  39.     char *path;
  40.     char *findexecf();
  41.     char lcmdl[255];        /* local command line */
  42.     
  43.     lcmdl[0] = ' ';            /* tack on a space at the beginning */
  44.     strcpy(lcmdl+1,cmdl);    /* to keep DOS happy */
  45.     name = lower(name);        /* convert to lowercase for search */
  46.     for (i=0;i<NUMINTS;i++) {
  47.         if (!strcmp(name,internals[i]))    /* check for an internal command */
  48.             return (system(strcat(name,lcmdl)));    /* use c86 system() if internal */
  49.     }
  50.     /* it's not an internal command, process it */
  51.     
  52.     path = alloc(255);
  53.     curdrv(path);            /* get current drive */
  54.     getpath(path);        /* and path */
  55.     ep = envfind("PATH");
  56.     if (*ep != ';') strcat(path,";");    /* if none at beginning already */
  57.     strcat(path,ep);                            /* all one path string */
  58.     free(ep);
  59.     while (*path) {                            /* until we hit EOS */
  60.         strcpy(tp,path);
  61.         i = 0;
  62.         while (*path++ != ';') i++;        /* find end of path */
  63.         tp[i] = '\0';                            /* term path string */
  64.         if (tp[i-2] != '\\' || tp[i-2] != '/') strcat(tp,"/"); 
  65.         if ((ts=findexecf(tp,name))) {
  66.             er = _execf(ts,lcmdl);
  67.             if (!er) {
  68.                 r.ax = 0x4d00;
  69.                 sysint21(&r,&r);
  70.                 er = r.ax&0xff;
  71.             }
  72.             return(er);
  73.         }
  74.     }
  75.     return(-1);                                /* command not found, ret err */
  76. }
  77.  
  78. char *findexecf(path,name)                /* tries to find an execable name along path */
  79. char *path,*name;
  80. {
  81.     char tn[255];
  82.     char *first,*next;
  83.     static char *exet[] = {".COM",".EXE",".BAT"};
  84.     int i;
  85.  
  86.     name = upper(name);
  87.     strcpy(tn,path);
  88.     strcat(tn,name);
  89.     strcat(tn,".*");            /* add wildcard to find all */
  90.     first = filedir(tn,0);    /* look for all normal files */
  91.     strcpy(tn,name);
  92.     for (next=first;*next != '\0';) {
  93.         for (i=0;i<3;i++) {
  94.             if (!(strcmp(strcat(tn,exet[i]),next))) return(strcat(path,tn));
  95.             strcpy(tn,name);        /* nope, try again */
  96.         }
  97.         next += strlen(next)+1;        /* look at next name in list */
  98.     }
  99.     return(NULL);                        /* didn't find one */
  100. }
  101.  
  102. _execf(path,cmdl)                /* execs path(incl. name.ext) with cmdl */
  103. char *path,*cmdl;
  104. {
  105.     int er;
  106.     struct {
  107.         int env_seg;
  108.         char *line_off,*line_seg;
  109.         char *fcb1_off,*fcb1_seg;
  110.         char *fcb2_off,*fcb2_seg;
  111.     } ctrl;
  112.     
  113.     cline[0] = strlen(cmdl);        /* put in length */
  114.     strcpy(cline+1,cmdl);            /* copy in command line */
  115.     strcat(cline,"\r");                /* add a CR */
  116.     segread(&r.si);                    /* get current cs */
  117.     ctrl.env_seg=0;                    /* no environment to pass */
  118.     ctrl.line_off=cline;                /* offset of command line */
  119.     ctrl.line_seg=r.ds;                /* segment of command line */
  120.     er = loadexec(path,r.ds,&ctrl,r.ds,0);    /* launch! */
  121.     return(er);
  122. }
  123.  
  124. /* curdrv - get current default drive */
  125.  
  126. curdrv(sp)
  127. char *sp;
  128. {
  129.     struct { int ax, bx, cx;
  130.              char *dx, *si, *di, *ds, *es;
  131.            } r;
  132.  
  133.     r.ax = 0x1900;                            /* DOS interrupt 19 */
  134.     sysint(0x21, &r, &r);                /* gets current drive number */
  135.     *sp++ = r.ax + 'a';                    /* convert to symbolic drive name */
  136.     *sp++ = ':';
  137.     *sp++ = '\0';
  138.     sp--;
  139.     return;
  140. }
  141.  
  142. /* getpath - get path to directory on indicated drive */
  143.  
  144. getpath(sp)
  145. char *sp;
  146. {
  147.     struct { int ax, bx, cx, dx;
  148.              char *si;
  149.              int di, ds, es;
  150.            } r;
  151.     extern int _showds();
  152.  
  153.     strcat(sp, "/");                /* append root file symbol to drive name */
  154.     
  155.     r.ax = 0x4700;                    /* DOS interrupt 47 gets path string */
  156.     r.dx = *sp - '`';                /* convert drive name to index */
  157.     r.ds = _showds();
  158.     r.si = sp + 3;                    /* paste string after root symbol */
  159.     sysint(0x21, &r, &r);
  160.     return;
  161. }
  162.  
  163. _showds()
  164. {
  165.     struct{int cs, ss, ds, es;} r;
  166.  
  167.     segread(&r);
  168.     return(r.ds);
  169. }
  170.