home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / rc / part06 / execve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-30  |  1.8 KB  |  62 lines

  1. /* execve.c: an execve() for geriatric unices without #! */
  2.  
  3. /*
  4.    NOTE: this file depends on a hack in footobar.c which places two free spots before
  5.    av[][] so that execve does not have to call malloc.
  6. */
  7.  
  8. #include <errno.h>
  9. #include "rc.h"
  10.  
  11. #define giveupif(x) { if (x) goto fail; }
  12.  
  13. extern int my_execve(const char *path, const char **av, const char **ev) {
  14.     int fd, len, fst, snd, end;
  15.     bool noarg;
  16.     char pb[256]; /* arbitrary but generous limit */
  17.     execve(path, av, ev);
  18.     if (errno != ENOEXEC)
  19.         return -1;
  20.     fd = rc_open(path, rFrom);
  21.     giveupif(fd < 0);
  22.     len = read(fd, pb, sizeof pb);
  23.     close(fd);
  24.     /* reject scripts which don't begin with #! */
  25.     giveupif(len <= 0 || pb[0] != '#' || pb[1] != '!');
  26.     for (fst = 2; fst < len && (pb[fst] == ' ' || pb[fst] == '\t'); fst++)
  27.         ; /* skip leading whitespace */
  28.     giveupif(fst == len);
  29.     for (snd = fst; snd < len && pb[snd] != ' ' && pb[snd] != '\t' && pb[snd] != '\n'; snd++)
  30.         ; /* skip first arg */
  31.     giveupif(snd == len);
  32.     noarg = (pb[snd] == '\n');
  33.     pb[snd++] = '\0'; /* null terminate the first arg */
  34.     if (!noarg) {
  35.         while (snd < len && (pb[snd] == ' ' || pb[snd] == '\t'))
  36.             snd++; /* skip whitespace to second arg */
  37.         giveupif(snd == len);
  38.         noarg = (pb[snd] == '\n'); /* could have trailing whitespace after only one arg */
  39.         if (!noarg) {
  40.             for (end = snd; end < len && pb[end] != ' ' && pb[end] != '\t' && pb[end] != '\n'; end++)
  41.                 ; /* skip to the end of the second arg */
  42.             giveupif(end == len);
  43.             if (pb[end] == '\n') {
  44.                 pb[end] = '\0'; /* null terminate the first arg */
  45.             } else {        /* else check for a spurious third arg */
  46.                 pb[end++] = '\0';
  47.                 while (end < len && (pb[end] == ' ' || pb[end] == '\t'))
  48.                     end++;
  49.                 giveupif(end == len || pb[end] != '\n');
  50.             }
  51.         }
  52.     }
  53.     *av = path;
  54.     if (!noarg)
  55.         *--av = pb + snd;
  56.     *--av = pb + fst;
  57.     execve(*av, av, ev);
  58.     return -1;
  59. fail:    errno = ENOEXEC;
  60.     return -1;
  61. }
  62.