#ifndef lint static char *rcsid = "$Id: execit.c,v 1.3 90/02/17 07:18:39 jdpeek Exp $"; #endif /* execit - run a program; use a different name * * Usage: progname [arguments] * * Some programs, especially MH programs, check the name they're * invoked with (from their argv[0]) and change the way they work. * The easiest way to do this with system programs is to make a new * link (symbolic or "hard") to the program's executable code, like this: * % ln /usr/local/bin/folder /usr/myhome/bin/folders * Then, you can run "folder" with the name "folders". * * The problems with that are: You can only make hard links (ln) if * you have access to a directory on the same filesystem as the system * executables. And some systems don't have symbolic links (ln -s). * That's when you need "execit". This "execit" program lets you * define a table of system commands and the names you want to run them * with. Then, you make a link to "execit" with the name of the program * you want to run. It invokes the system program with the name you use. * This way, you get fast execution of a system program with your own name. * And, if you make new hard links to "execit", defining new program names * doesn't take any more filesystem space. * * Here's an example of how to set up "execit" so it will run the program * "/usr/local/mh/repl", but make "repl" think its name is "replx": * * 1) Edit the file "execit.include" and add a new line like this: * "replx", "/usr/local/mh/repl", * (the second string should be where repl is located on your system!) * Be sure to make the line look just like that -- quotes and commas. * This file is read into the xref structure at compile time. * * 2) Recompile this program, something like this: * % cc -o execit execit.c * * 3) If there were no errors, make a link to "execit" named "replx": * % ln execit replx * Then, use "ls -li" to be sure previous links to "execit" still exist: * % ls -li execit replx tscan * 2379 -rwx------ 3 jdpeek 35982 Feb 10 22:14 execit * 2379 -rwx------ 3 jdpeek 35982 Feb 10 22:14 replx * 2379 -rwx------ 3 jdpeek 35982 Feb 10 22:14 tscan * ^^^^ ^ ^^^^^^^^^^^^ * SAME SAME TODAY'S * i-NUMS LINK COUNT DATE AND TIME * * (Delete any old links and re-link to the new "execit" with "ln".) * * 4) Now, assuming the directory is in your shell's search path, * (and, for MH programs, you may want a line in .mh_profile like this: * replx: -switches -go -here * ) you can run "replx" and pass the switch "-query" to it this way: * % replx -query * * Placed in the public domain by its author, Jerry Peek, 12 February 1990. * (jdpeek@rodan.acs.syr.edu) Use at your own risk. Suggestions welcome! */ #include /* Table of command name user wants to run as, * and full pathname of actual system program to run. * Edit the "execit.include" file to add more entries to the structure below; * then recompile and re-link this code with the new name. */ struct xref { char *runas, *torun; } xrefs[] = { "EDIT_ME", "/YOUR/PATH/NAME/HERE", #include "execit.include" "tscan", "/usr/local/mh/scan" }; main(argc, argv, envp) int argc; char **argv, **envp; { char *myname, *p; int ret, index, bogus; int numcmds = sizeof(xrefs) / sizeof(struct xref); /* Get basename of this program by stepping past final '/': */ myname = p = *argv; while (*p) if (*p++ == '/') myname = p; /* Find program to run (xrefs[index].torun) from lookup table: */ bogus = 1; for (index = 0; index < numcmds; index++) { if (strcmp(myname, xrefs[index].runas) == 0) { bogus = 0; /* found it */ break; } } if (bogus) { fprintf(stderr, "%s: Can't run myself! Fix execit.include and/or run execit.link.\n", argv[0]); exit(1); } /* Set fake program name in argv[0], then try to run real program. * If exec succeeds, return program's exit status. * Otherwise, print errno message and return -1. */ argv[0] = xrefs[index].runas; if ((ret = execve(xrefs[index].torun, argv, envp)) != -1) exit(ret); else { perror(xrefs[index].torun); exit(-1); } }