diff options
author | obrien <obrien@FreeBSD.org> | 2000-04-15 04:41:27 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-04-15 04:41:27 +0000 |
commit | 4ad28cefef28ce6bdb44a0532cfe20a2076bc694 (patch) | |
tree | 7679c440a91912ee9586cee3ebab24596c0fe1c4 /contrib/tcsh/ma.setp.c | |
download | FreeBSD-src-4ad28cefef28ce6bdb44a0532cfe20a2076bc694.zip FreeBSD-src-4ad28cefef28ce6bdb44a0532cfe20a2076bc694.tar.gz |
Import the latest version of the 44BSD C-shell -- tcsh-6.09.
Diffstat (limited to 'contrib/tcsh/ma.setp.c')
-rw-r--r-- | contrib/tcsh/ma.setp.c | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/contrib/tcsh/ma.setp.c b/contrib/tcsh/ma.setp.c new file mode 100644 index 0000000..d515d0f --- /dev/null +++ b/contrib/tcsh/ma.setp.c @@ -0,0 +1,618 @@ +/* + * Copyright (c) 1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT + * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Users of this software agree to return to Carnegie Mellon any + * improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * Export of this software is permitted only after complying with the + * regulations of the U.S. Deptartment of Commerce relating to the + * Export of Technical Data. + */ +/* + * setpath --- smart interface for setting path variables + * + * usage: setpath(paths, cmds, localsyspath, dosuffix, printerrors) + * char **paths, **cmds, *localsyspath; + * int dosuffix, printerrors; + * + * The 'paths' argument is a list of pointers to path lists of the + * form "name=value" where name is the name of the path and value + * is a colon separated list of directories. There can never be + * more than MAXDIRS (64) directories in a path. + * + * The 'cmds' argument may be a sequence of any of the following: + * -r reset path to default + * -i newpath insert newpath before localsyspath + * -ia oldpath newpath insert newpath after oldpath + * -ib oldpath newpath insert newpath before oldpath + * -i# newpath insert newpath at position # + * -d oldpath delete oldpath + * -d# delete path at position # + * -c oldpath newpath change oldpath to newpath + * -c# newpath change position # to newpath + * + * The "-i newpath" command is equivilent to "-ib 'localsyspath' newpath". + * + * If 'dosuffix' is true, the appropriate suffix will be added to + * all command operands for any system path in 'paths'. + * + * Both of the 'paths' and 'cmds' lists are terminated by a NULL + * entry. + * + * if 'printerrors' is true, setpath will printf error diagnostics. + * + * WARNING !!!: Under no circumstances should anyone change this + * module without fully understanding the impact on the C shell. + * The C shell has it's own malloc and printf routines and this + * module was carefully written taking that into account. Do not + * use any stdio routines from this module except printf. + * + ********************************************************************** + * HISTORY + * + * Revision 1.4 90/12/11 17:58:44 mja + * Add copyright/disclaimer for distribution. + * + * 05-Jun-88 Glenn Marcy (gm0w) at Carnegie-Mellon University + * Make all non-entry points static. + * + * 30-Apr-88 Glenn Marcy (gm0w) at Carnegie-Mellon University + * Added -r switch to reset paths to their default values. + * + * 06-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University + * Created from old setpath program for the shell. + * + ********************************************************************** + */ +#include "sh.h" +RCSID("$Id: ma.setp.c,v 1.12 1996/04/26 19:18:36 christos Exp $") + +#ifdef MACH + +#define MAXDIRS 64 /* max directories on a path */ +#ifndef NULL +# define NULL 0 +#endif + +static int npaths; /* # pathlist arguments */ + +static struct pelem { + struct pelem *pnext; /* pointer to next path */ + char *pname; /* name of pathlist */ + char *psuf; /* suffix for pathlist */ + char *pdef; /* default for pathlist */ + int pdirs; /* # directories on each pathlist */ + char *pdir[MAXDIRS]; /* directory names for each pathlist */ +} *pathhead = NULL; + +static struct { + char *name; + char *suffix; + char *defalt; +} syspath[] = { + "PATH", "/bin", ":/usr/ucb:/bin:/usr/bin", + "CPATH", "/include", ":/usr/include", + "LPATH", "/lib", ":/lib:/usr/lib", + "MPATH", "/man", ":/usr/man", + "EPATH", "/maclib", "", + 0, 0, 0 +}; + +static int sflag; +static int eflag; + +#define INVALID { \ + if (eflag) xprintf(CGETS(10, 1, \ + "setpath: invalid command '%s'.\n"), cmd); \ + freepaths(); \ + return(-1); \ +} + +#define TOOFEW { \ + if (eflag) xprintf(CGETS(10, 2, \ + "setpath: insufficient arguments to command '%s'.\n"), cmd); \ + freepaths(); \ + return(-1); \ +} + +static int initpaths __P((char **)); +static void savepaths __P((char **)); +static void freepaths __P((void)); +static void rcmd __P((char *)); +static void icmd __P((char *, char *)); +static void iacmd __P((char *, char *)); +static void ibcmd __P((char *, char *)); +static void incmd __P((char *, int)); +static void insert __P((struct pelem *, int, char *)); +static void dcmd __P((char *)); +static void dncmd __P((int)); +static void delete __P((struct pelem *, int)); +static void ccmd __P((char *, char *)); +static void cncmd __P((char *, int)); +static void change __P((struct pelem *, int, char *)); +static int locate __P((struct pelem *, char *)); + + + +int +setpath(paths, cmds, localsyspath, dosuffix, printerrors) +register char **paths, **cmds, *localsyspath; +int dosuffix, printerrors; +{ + register char *cmd, *cmd1, *cmd2; + register int ncmd; + + sflag = dosuffix; + eflag = printerrors; + if (initpaths(paths) < 0) + return(-1); + if (npaths == 0) + return(0); + for (ncmd = 0; cmd = cmds[ncmd]; ncmd++) { + if (cmd[0] != '-') + INVALID; + cmd1 = cmds[ncmd+1]; + cmd2 = cmds[ncmd+2]; + switch (cmd[1]) { + case 'r': + if (cmd[2] != '\0') + INVALID; + rcmd(localsyspath); + break; + case 'i': + if (cmd[2] == '\0') { + ncmd++; + if (cmd1 == NULL) TOOFEW; + icmd(cmd1, localsyspath); + } else if (isdigit(cmd[2])) { + ncmd++; + if (cmd1 == NULL) TOOFEW; + incmd(cmd1, atoi(cmd+2)); + } else if (cmd[3] != '\0' || (cmd[2] != 'a' && cmd[2] != 'b')) { + INVALID; + } else { + ncmd += 2; + if (cmd1 == NULL || cmd2 == NULL) TOOFEW; + if (cmd[2] == 'a') + iacmd(cmd1, cmd2); + else + ibcmd(cmd1, cmd2); + } + break; + case 'd': + if (cmd[2] == '\0') { + ncmd++; + if (cmd1 == NULL) TOOFEW; + dcmd(cmd1); + } else if (isdigit(cmd[2])) + dncmd(atoi(cmd+2)); + else { + INVALID; + } + break; + case 'c': + if (cmd[2] == '\0') { + ncmd += 2; + if (cmd1 == NULL || cmd2 == NULL) TOOFEW; + ccmd(cmd1, cmd2); + } else if (isdigit(cmd[2])) { + ncmd++; + if (cmd1 == NULL) TOOFEW; + cncmd(cmd1, atoi(cmd+2)); + } else { + INVALID; + } + break; + default: + INVALID; + } + } + savepaths(paths); + freepaths(); + return(0); +} + +static int +initpaths(paths) +register char **paths; +{ + register char *path, *val, *p, *q; + register int i, done; + register struct pelem *pe, *pathend; + + freepaths(); + for (npaths = 0; path = paths[npaths]; npaths++) { + val = index(path, '='); + if (val == NULL) { + if (eflag) + xprintf(CGETS(10, 3, + "setpath: value missing in path '%s'\n"), path); + freepaths(); + return(-1); + } + *val++ = '\0'; + pe = (struct pelem *)xmalloc((unsigned)(sizeof(struct pelem))); + setzero((char *) pe, sizeof(struct pelem)); + if (pathhead == NULL) + pathhead = pathend = pe; + else { + pathend->pnext = pe; + pathend = pe; + } + p = strsave(path); + pe->pname = p; + pe->psuf = ""; + pe->pdef = ""; + for (i = 0; syspath[i].name; i++) + if (strcmp(pe->pname, syspath[i].name) == 0) { + pe->psuf = syspath[i].suffix; + pe->pdef = syspath[i].defalt; + break; + } + q = val; + for (;;) { + q = index(p = q, ':'); + done = (q == NULL); + if (!done) + *q++ = '\0'; + p = strsave(p); + pe->pdir[pe->pdirs] = p; + pe->pdirs++; + if (done) + break; + } + } + return(0); +} + +static void +savepaths(paths) +register char **paths; +{ + register char *p, *q; + register int npath, i, len; + register struct pelem *pe; + + for (npath = 0, pe = pathhead; pe; npath++, pe = pe->pnext) { + len = strlen(pe->pname) + 1; + if (pe->pdirs == 0) + len++; + else for (i = 0; i < pe->pdirs; i++) + len += strlen(pe->pdir[i]) + 1; + p = xmalloc((unsigned)len); + paths[npath] = p; + for (q = pe->pname; *p = *q; p++, q++); + *p++ = '='; + if (pe->pdirs != 0) { + for (i = 0; i < pe->pdirs; i++) { + for (q = pe->pdir[i]; *p = *q; p++, q++); + *p++ = ':'; + } + p--; + } + *p = '\0'; + } +} + +static void +freepaths() +{ + register char *p; + register int i; + register struct pelem *pe; + + if (npaths == 0 || pathhead == NULL) + return; + while (pe = pathhead) { + if (pe->pname) { + for (i = 0; i < pe->pdirs; i++) { + if (pe->pdir[i] == NULL) + continue; + p = pe->pdir[i]; + pe->pdir[i] = NULL; + xfree((ptr_t) p); + } + pe->pdirs = 0; + p = pe->pname; + pe->pname = NULL; + xfree((ptr_t) p); + } + pathhead = pe->pnext; + xfree((ptr_t) pe); + } + npaths = 0; +} + +/*********************************************** + *** R E S E T A P A T H N A M E *** + ***********************************************/ + +static void +rcmd(localsyspath) /* reset path with localsyspath */ +char *localsyspath; +{ + register int n, done; + register char *new, *p; + register struct pelem *pe; + char newbuf[MAXPATHLEN+1]; + + for (pe = pathhead; pe; pe = pe->pnext) { + new = newbuf; + *new = '\0'; + if (localsyspath != NULL) { + *new = ':'; + (void) strcpy(new + 1, localsyspath); + (void) strcat(new, pe->psuf); + } + (void) strcat(new, pe->pdef); + for (n = 0; n < pe->pdirs; n++) { + if (pe->pdir[n] == NULL) + continue; + p = pe->pdir[n]; + pe->pdir[n] = NULL; + xfree((ptr_t) p); + } + pe->pdirs = 0; + for (;;) { + new = index(p = new, ':'); + done = (new == NULL); + if (!done) + *new++ = '\0'; + p = strsave(p); + pe->pdir[pe->pdirs] = p; + pe->pdirs++; + if (done) + break; + } + } +} + +/*********************************************** + *** I N S E R T A P A T H N A M E *** + ***********************************************/ + +static void +icmd(path, localsyspath) /* insert path before localsyspath */ +char *path, *localsyspath; +{ + register int n; + register char *new; + register struct pelem *pe; + char newbuf[MAXPATHLEN+1]; + + for (pe = pathhead; pe; pe = pe->pnext) { + if (sflag) + new = localsyspath; + else { + new = newbuf; + (void) strcpy(new, localsyspath); + (void) strcat(new, pe->psuf); + } + n = locate(pe, new); + if (n >= 0) + insert(pe, n, path); + else + insert(pe, 0, path); + } +} + +static void +iacmd(inpath, path) /* insert path after inpath */ +char *inpath, *path; +{ + register int n; + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + n = locate(pe, inpath); + if (n >= 0) + insert(pe, n + 1, path); + else + xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"), + inpath, pe->pname); + } +} + +static void +ibcmd(inpath, path) /* insert path before inpath */ +char *inpath, *path; +{ + register int n; + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + n = locate(pe, inpath); + if (n >= 0) + insert(pe, n, path); + else + xprintf(CGETS(10, 4, "setpath: %s not found in %s\n", + inpath, pe->pname)); + } +} + +static void +incmd(path, n) /* insert path at position n */ +char *path; +int n; +{ + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) + insert(pe, n, path); +} + +static void +insert(pe, loc, key) +register struct pelem *pe; +register int loc; +register char *key; +{ + register int i; + register char *new; + char newbuf[2000]; + + if (sflag) { /* add suffix */ + new = newbuf; + (void) strcpy(new, key); + (void) strcat(new, pe->psuf); + } else + new = key; + new = strsave(new); + for (i = pe->pdirs; i > loc; --i) + pe->pdir[i] = pe->pdir[i-1]; + if (loc > pe->pdirs) + loc = pe->pdirs; + pe->pdir[loc] = new; + pe->pdirs++; +} + +/*********************************************** + *** D E L E T E A P A T H N A M E *** + ***********************************************/ + +static void +dcmd(path) /* delete path */ +char *path; +{ + register int n; + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + n = locate(pe, path); + if (n >= 0) + delete(pe, n); + else + xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"), + path, pe->pname); + } +} + +static void +dncmd(n) /* delete at position n */ +int n; +{ + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + if (n < pe->pdirs) + delete(pe, n); + else + xprintf(CGETS(10, 5, + "setpath: %d not valid position in %s\n"), + n, pe->pname); + } +} + +static void +delete(pe, n) +register struct pelem *pe; +int n; +{ + register int d; + + xfree((ptr_t) (pe->pdir[n])); + for (d = n; d < pe->pdirs - 1; d++) + pe->pdir[d] = pe->pdir[d+1]; + --pe->pdirs; +} + +/*********************************************** + *** C H A N G E A P A T H N A M E *** + ***********************************************/ + +static void +ccmd(inpath, path) /* change inpath to path */ +char *inpath, *path; +{ + register int n; + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + n = locate(pe, inpath); + if (n >= 0) + change(pe, n, path); + else + xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"), + inpath, pe->pname); + } +} + +static void +cncmd(path, n) /* change at position n to path */ +char *path; +int n; +{ + register struct pelem *pe; + + for (pe = pathhead; pe; pe = pe->pnext) { + if (n < pe->pdirs) + change(pe, n, path); + else + xprintf(CGETS(10, 5, + "setpath: %d not valid position in %s\n"), + n, pe->pname); + } +} + +static void +change(pe, loc, key) +register struct pelem *pe; +register int loc; +register char *key; +{ + register char *new; + char newbuf[MAXPATHLEN+1]; + + if (sflag) { /* append suffix */ + new = newbuf; + (void) strcpy(new, key); + (void) strcat(new, pe->psuf); + } else + new = key; + new = strsave(new); + xfree((ptr_t) (pe->pdir[loc])); + pe->pdir[loc] = new; +} + +/*************************************** + *** F I N D P A T H N A M E *** + ***************************************/ + +static int +locate(pe, key) +register struct pelem *pe; +register char *key; +{ + register int i; + register char *realkey; + char keybuf[MAXPATHLEN+1]; + + if (sflag) { + realkey = keybuf; + (void) strcpy(realkey, key); + (void) strcat(realkey, pe->psuf); + } else + realkey = key; + for (i = 0; i < pe->pdirs; i++) + if (strcmp(pe->pdir[i], realkey) == 0) + break; + return((i < pe->pdirs) ? i : -1); +} +#endif |