#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 <stdio.h>

/* 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);
	}
}
