home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / MN321SRC.ZIP / exec.c < prev    next >
C/C++ Source or Header  |  2004-07-13  |  6KB  |  271 lines

  1. /** Warning! This is still PD, but had a minor change by Michael Karcher **/
  2. /*
  3.    EXEC.C: EXEC function with memory swap - Prepare parameters.
  4.  
  5.    Public domain software by
  6.  
  7.    Thomas Wagner
  8.    Ferrari electronic GmbH
  9.    Beusselstrasse 27
  10.    D-1000 Berlin 21
  11.    Germany
  12.  
  13.    BIXname: twagner
  14.  */
  15.  
  16. /* $Id: exec.c,v 1.3 2004/07/13 04:42:54 ozzmosis Exp $ */
  17.  
  18. #include <stdio.h> 
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/stat.h>
  22. #include <malloc.h>
  23. #include <ctype.h>
  24. #include <dos.h>
  25. #include <io.h>
  26. #include "fileutil.h"
  27. #include "exec.h"
  28. #include "os.h"
  29. #include "spawn.h"
  30.  
  31. #define SWAP_FILENAME "$makenl.swp"
  32.  
  33. #ifndef __TURBOC__
  34. #define stpcpy(d,s)     (strcpy (d, s), d + strlen (s))
  35. #endif
  36.  
  37. /** Modification by Michael Karcher - added get_tempdir, find_executable and
  38.     search into this source file **/
  39. static void get_tempdir(char *tempdir)
  40. {
  41.     char *env;
  42.     int len;
  43.     char drive[MYMAXDRIVE];
  44.     char ext[MYMAXEXT];
  45.     struct SREGS sr;
  46.     char name[MYMAXFILE];
  47.     union REGS r;
  48.     struct stat stbuf;
  49.     char dir[MYMAXDIR];
  50.  
  51.     tempdir[0] = 0;
  52.     if ((env = getenv("TMP")) == NULL && (env = getenv("TEMP")) == NULL)
  53.         return;
  54.  
  55.     strcpy(tempdir, env);
  56.     if ((len = strlen(tempdir)) == 0)
  57.         return;
  58.  
  59.     if (tempdir[len - 1] == '/' || tempdir[len - 1] == '\\')
  60.         tempdir[--len] = 0;
  61.  
  62.     myfnsplit(tempdir, drive, dir, name, ext);
  63.     if (drive[0] != 0)
  64.     {
  65.         r.h.dl = toupper(drive[0]) - 'A' + 1;
  66.         r.h.ah = 0x1C;
  67.         intdosx(&r, &r, &sr);
  68.         if (r.h.ah == 0xFF)
  69.         {
  70.             tempdir[0] = 0;
  71.             return;
  72.         }
  73.     }
  74.     if ((name[0] == 0 && dir[0] == 0) ||
  75.         (stat(tempdir, &stbuf) == 0 && stbuf.st_mode & S_IWRITE
  76.          && stbuf.st_mode & S_IEXEC))
  77.     {
  78.         tempdir[len] = '\\';
  79.         tempdir[len + 1] = 0;
  80.         return;
  81.     }
  82.  
  83. }
  84.  
  85.  
  86. static int find_executable(char *name)
  87. {
  88.     char *p = strchr(name, '\0');
  89.  
  90.     strcpy(p, ".COM");
  91.     if (access(name, 0) == 0)
  92.         return 1;
  93.  
  94.     strcpy(p, ".EXE");
  95.     if (access(name, 0) == 0)
  96.         return 1;
  97.  
  98.     strcpy(p, ".BAT");
  99.     if (access(name, 0) == 0)
  100.     {
  101.         char tmp[MYMAXDIR];
  102.  
  103.         strcpy(tmp, getenv("COMSPEC"));
  104.         strcat(tmp, " /c ");
  105.         strcat(tmp, name);
  106.         strcpy(name, tmp);
  107.         return 1;
  108.     }
  109.  
  110.     *p = '\0';
  111.     return 0;
  112. }
  113.  
  114.  
  115. static int search(char *prgname)
  116. {
  117.     char *pathelement;
  118.     int found;
  119.     char drive[MYMAXDRIVE];
  120.     char ext[MYMAXEXT];
  121.     char name[MYMAXFILE];
  122.     char dir[MYMAXDIR];
  123.     char pathstr[256];
  124.  
  125.     if (prgname[0] == 0)
  126.         strcpy(prgname, getenv("COMSPEC"));
  127.  
  128.     myfnsplit(prgname, drive, dir, name, ext);
  129.     if (ext[0])
  130.         found = access(prgname, 0) == 0;
  131.     else
  132.         found = find_executable(prgname);
  133.  
  134.     if (found || drive[0] != 0 || dir[0] != 0)
  135.         return found;
  136.  
  137.     strcpy(pathstr, getenv("PATH"));
  138.     pathelement = strtok(pathstr, ";");
  139.     while (!found)
  140.     {
  141.         if (!pathelement)
  142.             break;
  143.  
  144.         myfnmerge(prgname, drive, pathelement, name, ext);
  145.         if (ext[0] != 0)
  146.             found = access(prgname, 0) == 0;
  147.         else
  148.             found = find_executable(prgname);
  149.  
  150.         pathelement = strtok(NULL, ";");
  151.     }
  152.  
  153.     return found;
  154. }
  155.  
  156. int
  157. do_exec(const char *exfn, const char *epars, int spwn, unsigned needed,
  158.         char **envp)
  159. {
  160.     char swapfn[82];
  161.     char execfn[82];
  162.     unsigned avail;
  163.     union REGS regs;
  164.     unsigned envlen;
  165.     int rc;
  166.     int idx;
  167.     char **env;
  168.     char *ep, *envptr, *envbuf;
  169.     int swapping;
  170.  
  171.     strcpy(execfn, exfn);
  172.  
  173.     if (!search(execfn))
  174.         return RC_NOFILE;
  175.  
  176.     /* Now create a copy of the environment if the user wants it. */
  177.  
  178.     envlen = 0;
  179.     envptr = envbuf = NULL;
  180.  
  181.     if (envp != NULL)
  182.         for (env = envp; *env != NULL; env++)
  183.             envlen += strlen(*env) + 1;
  184.  
  185.     if (envlen)
  186.     {
  187.         /* round up to paragraph, and alloc another paragraph leeway */
  188.         envlen = (envlen + 32) & 0xfff0;
  189.         envbuf = (char *)malloc(envlen);
  190.         if (envbuf == NULL)
  191.             return RC_ENVERR;
  192.  
  193.         /* align to paragraph */
  194.         envptr = envbuf;
  195.         if (FP_OFF(envptr) & 0x0f)
  196.             envptr += 16 - (FP_OFF(envptr) & 0x0f);
  197.         ep = envptr;
  198.  
  199.         for (env = envp; *env != NULL; env++)
  200.         {
  201.             ep = stpcpy(ep, *env) + 1;
  202.         }
  203.         *ep = 0;
  204.     }
  205.  
  206.     if (!spwn)
  207.         swapping = -1;
  208.     else
  209.     {
  210.         /* Determine amount of free memory */
  211.  
  212.         regs.x.ax = 0x4800;
  213.         regs.x.bx = 0xffff;
  214.         intdos(®s, ®s);
  215.         avail = regs.x.bx;
  216.  
  217.         /* No swapping if available memory > needed */
  218.  
  219.         if (needed < avail)
  220.             swapping = 0;
  221.         else
  222.         {
  223.             /* Swapping necessary, use 'TMP' or 'TEMP' environment
  224.                variable to determine swap file path if defined. */
  225.  
  226.             swapping = spwn;
  227.             if (spwn & USE_FILE)
  228.             {
  229.                 get_tempdir(swapfn);
  230.  
  231.                 if (_osmajor >= 3)
  232.                     swapping |= CREAT_TEMP;
  233.                 else
  234.                 {
  235.                     strcat(swapfn, SWAP_FILENAME);
  236.                     idx = strlen(swapfn) - 1;
  237.                     while (access(swapfn, 0) == 0)
  238.                     {
  239.                         if (swapfn[idx] == 'Z')
  240.                             idx--;
  241.                         if (swapfn[idx] == '.')
  242.                             idx--;
  243.                         swapfn[idx]++;
  244.                     }
  245.                 }
  246.             }
  247.         }
  248.     }
  249.  
  250.     /* All set up, ready to go. */
  251.  
  252.     if (swapping > 0)
  253.     {
  254.         if (!envlen)
  255.             swapping |= DONT_SWAP_ENV;
  256.  
  257.         rc = prep_swap(swapping, swapfn);
  258.         if (rc < 0)
  259.             return RC_PREPERR | -rc;
  260.     }
  261.  
  262.     rc = do_spawn(swapping, execfn, epars, envlen, envptr);
  263.  
  264.     /* Free the environment buffer if it was allocated. */
  265.  
  266.     if (envlen)
  267.         free(envbuf);
  268.  
  269.     return rc;
  270. }
  271.