home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / icont / ixhdr.c next >
C/C++ Source or Header  |  1996-03-22  |  7KB  |  277 lines

  1. /*
  2.  * ixhdr.c -- bootstrap header for icode files
  3.  */
  4.  
  5. #include "::h:gsupport.h"
  6. #include "tproto.h"
  7.  
  8. #if UNIX
  9.  
  10. #ifdef Header
  11. #include "::h:header.h"
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15.  
  16. /*
  17.  * Prototypes.
  18.  */
  19.  
  20. hidden    novalue    doiconx        Params((char **s, char *t));
  21. hidden    novalue    hsyserr        Params((char *av, char *file));
  22.  
  23. #if IntBits == 16
  24. #undef strlen            /* short versions used here */
  25. #endif                    /* IntBits == 16 */
  26.  
  27. static char patchpath[MaxPath+18] = "%PatchStringHere->";
  28. static char *refpath = RefPath;
  29.  
  30. novalue main(argc, argv)
  31. int argc;
  32. char **argv;
  33.    {
  34.    char fullpath[256];
  35.    char *name;
  36.    char *argvx[1000];
  37.  
  38.    /*
  39.     * Abort if we've been invoked with setuid or setgid privileges.
  40.     *  Allowing such usage would open a huge security hole, because
  41.     *  there is no way to ensure that the right iconx will interpret
  42.     *  the right user program.
  43.     */
  44.    if (getuid() != geteuid() || getgid() != getegid())
  45.       hsyserr(argv[0], ": cannot run an Icon program setuid/setgid");
  46.  
  47.    name = argv[0];            /* name of icode file */
  48.  
  49.    do 
  50.       argvx[argc+1] = argv[argc];
  51.    while (argc--);
  52.    argv = argvx;
  53.  
  54.    /*
  55.     * If the name contains any slashes, execute the file as named.
  56.     *  Otherwise, search the path to find out where the file really is.
  57.     */
  58.    if (index(name, '/'))
  59.       doiconx(argv, name);
  60.    else if (findcmd(fullpath, name, "PATH"))
  61.       doiconx(argv, fullpath);
  62.    else
  63.       hsyserr("iconx: icode file not found: ", fullpath);
  64.    }
  65.  
  66. /*
  67.  * doiconx(argv, file) - execute iconx, passing file as argv[1].
  68.  *
  69.  *  To find the interpreter, first check the environment variable ICONX.
  70.  *  If it defines a path, it had better work, else we abort.
  71.  *
  72.  *  If there's no $ICONX, but there's a hardwired path, try that.
  73.  *  If THAT doesn't work, try searching $PATH for an "iconx" program.
  74.  *  If nothing works, abort.
  75.  */
  76. static novalue doiconx(argv, file)
  77. char **argv;
  78. char *file;
  79.    {
  80.    char xcmd[256];
  81.  
  82. #ifdef HardWiredPaths
  83.    static char hardpath[MaxPath];
  84.  
  85.    if ((int)(strlen(refpath) + 6) > MaxPath)
  86.       hsyserr("path to iconx too long","");
  87.    strcpy(hardpath, refpath);
  88.    strcat(hardpath, "iconx");
  89.  
  90.    if ((int)strlen(patchpath) > 18)
  91.       strcpy(hardpath, patchpath+18);
  92. #endif                    /* HardWiredPaths */
  93.  
  94.    argv[1] = file;
  95.  
  96.    if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  97.       execv(argv[0], argv);        /* exec file specified by $ICONX */
  98.       hsyserr("cannot execute $ICONX: ", argv[0]);
  99.       }
  100.  
  101. #ifdef HardWiredPaths
  102.    argv[0] = hardpath;            /* try predefined file */
  103.    execv(hardpath, argv);
  104. #endif                    /* HardWiredPaths */
  105.  
  106.    if (findcmd(xcmd, "iconx", "PATH")) {
  107.       argv[0] = xcmd;
  108.       execv(xcmd, argv);    /* if no path, search path for "iconx" */
  109.       hsyserr("cannot execute ", xcmd);
  110.       }
  111.  
  112. #ifdef HardWiredPaths
  113.    hsyserr("cannot execute ", hardpath);
  114. #else                    /* HardWiredPaths */
  115.    hsyserr("cannot find iconx", "");
  116. #endif                    /* HardWiredPaths */
  117.    }
  118.  
  119. /*
  120.  * hsyserr(s1, s2) - print s1 and s2 on stderr, then abort.
  121.  */
  122. hidden novalue hsyserr(s1, s2)
  123. char *s1, *s2;
  124.    {
  125.    char s[100];
  126.    /*
  127.     * Low-level I/O is used here to avoid sucking in a lot of stuff
  128.     *  that would make iconx.hdr much larger.
  129.     */
  130.    strcpy(s, s1);
  131.    if (s2)
  132.       strcat(s, s2);
  133.    strcat(s, "\n");
  134.    write(2, s, strlen(s));
  135.    _exit(ErrorExit);
  136.    }
  137.  
  138. /*
  139.  * This function searches all the directories in the path style environment
  140.  * variable (pvar) for a command with the base name (cnam).  If the command
  141.  * is found its full name is stored in the pointer passed (cmd) and 1 is
  142.  * returned.  If the command isn't found 0 is returned.
  143.  */
  144.  
  145. int    findcmd(cmd,cnam,pvar)
  146. register
  147. char    *cmd,
  148.     *cnam,
  149.     *pvar;
  150. {
  151.     register
  152.     char    *path;
  153.  
  154.     char    pbuf[1024],
  155.         *getdir(),
  156.         *getenv();
  157.  
  158. /*    if the environment variable isn't defined give up */
  159.     if (! (path = getenv(pvar))) return 0;
  160.  
  161. /*    copy the path to a temporary path buffer and point at the buffer
  162.  *    (this is necessary because we can diddle its contents in getdir) */
  163.     strcpy(pbuf,path);
  164.     path = pbuf;
  165.  
  166. /*    loop through all the path variable directories and check for
  167.  *    the command in each */
  168.     while (path = getdir(cmd,path)) {
  169.         strcat(cmd,cnam);
  170.         if (chkcmd(cmd)) return 1;
  171.     }
  172.  
  173.     return 0;
  174. }
  175.  
  176. /*
  177.  * This function returns the next directory in the directory string passed
  178.  * in path.  This directory string is similar to the PATH environment
  179.  * variable.  A pointer to the remaining directory string is returned so
  180.  * that the entire string can be scanned by the calling function.
  181.  */
  182.  
  183. char    *getdir(dir,path)
  184. register
  185. char    *dir,    /* the command directory buffer */
  186.     *path;    /* the string of directories */
  187. {
  188.     register
  189.     char    *dp;    /* the original directory pointer */
  190.  
  191. /*    if there is nothing left return null */
  192.     if (! *path) return (char *) 0;
  193.  
  194. /*    save the original directory pointer */
  195.     dp = dir;
  196.  
  197. /*    copy up to the next separator or the end of path */
  198.     while (*path && *path != ':') *dir++ = *path++;
  199.  
  200. /*    if dir is still empty use a dot (the current directory */
  201.     if (dp == dir) *dir++ = '.';
  202.  
  203. /*    if the directory isn't terminated with a slash tack one on */
  204.     if (*(dir-1) != '/') *dir++ = '/';
  205.  
  206. /*    null terminate the directory */
  207.     *dir = 0;
  208.  
  209. /*    if there's still a colon in path */
  210.     if (*path) {
  211.  
  212. /*        if there's something after the colon skip the colon */
  213.         if (*(path+1)) path++;
  214.  
  215. /*        otherwise terminate path with a dot (the current directory) */
  216.         else *path = '.';
  217.     }
  218.  
  219.     return path;
  220. }
  221.  
  222. /*
  223.  * This function checks to see if the file name passed exists and is
  224.  * executable.
  225.  */
  226.  
  227. #ifndef    S_IFMT        /* defined in <sys/stat.h> */
  228. #include <sys/types.h>
  229. #include <sys/stat.h>
  230. #endif                    /* S_IFMT */
  231.  
  232. int    chkcmd(file)
  233. register
  234. char    *file;
  235. {
  236.     register
  237.     unsigned
  238.     short    gid, uid;
  239.  
  240.     struct    stat s;
  241.  
  242. /*    if the file can't be "stat"ed fail */
  243.     if (stat(file,&s) < 0) return 0;
  244.  
  245. /*    get the effective group and user ids for this user */
  246.     gid = getegid();
  247.     uid = geteuid();
  248.  
  249. /*    if this is a "regular" file AND */
  250.     if ((s.st_mode & 0100000) &&
  251.  
  252. /*    the execute bit is set for "other" and the group id and user id
  253.  *    don't match OR */
  254.        (((s.st_mode & 0000001) && s.st_gid != gid && s.st_uid != uid) ||
  255.  
  256. /*    the execute bit is set for "group" and the group id matches and
  257.  *    the user id doesn't OR */
  258.         ((s.st_mode & 0000010) && s.st_gid == gid && s.st_uid != uid) ||
  259.  
  260. /*    the execute bit is set for "user" and the user id matches THEN */
  261.         ((s.st_mode & 0000100) && s.st_uid == uid)))
  262.  
  263. /*        succeed */
  264.         return 1;
  265.  
  266. /*    otherwise fail */
  267.     return 0;
  268. }
  269.  
  270. #else                    /* Header */
  271. main() {}
  272. #endif                    /* Header */
  273.  
  274. #else                    /* UNIX */
  275. main() {}
  276. #endif                    /* UNIX */
  277.