ma.setp.c revision 59243
159243Sobrien/*
259243Sobrien * Copyright (c) 1990 Carnegie Mellon University
359243Sobrien * All Rights Reserved.
459243Sobrien *
559243Sobrien * Permission to use, copy, modify and distribute this software and its
659243Sobrien * documentation is hereby granted, provided that both the copyright
759243Sobrien * notice and this permission notice appear in all copies of the
859243Sobrien * software, derivative works or modified versions, and any portions
959243Sobrien * thereof, and that both notices appear in supporting documentation.
1059243Sobrien *
1159243Sobrien * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY
1259243Sobrien * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
1359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT
1459243Sobrien * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT,
1559243Sobrien * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
1659243Sobrien * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
1759243Sobrien * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
1859243Sobrien * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1959243Sobrien *
2059243Sobrien * Users of this software agree to return to Carnegie Mellon any
2159243Sobrien * improvements or extensions that they make and grant Carnegie the
2259243Sobrien * rights to redistribute these changes.
2359243Sobrien *
2459243Sobrien * Export of this software is permitted only after complying with the
2559243Sobrien * regulations of the U.S. Deptartment of Commerce relating to the
2659243Sobrien * Export of Technical Data.
2759243Sobrien */
2859243Sobrien/*
2959243Sobrien *  setpath --- smart interface for setting path variables
3059243Sobrien *
3159243Sobrien *  usage:	setpath(paths, cmds, localsyspath, dosuffix, printerrors)
3259243Sobrien *		char **paths, **cmds, *localsyspath;
3359243Sobrien *		int dosuffix, printerrors;
3459243Sobrien *
3559243Sobrien *  The 'paths' argument is a list of pointers to path lists of the
3659243Sobrien *  form "name=value" where name is the name of the path and value
3759243Sobrien *  is a colon separated list of directories.  There can never be
3859243Sobrien *  more than MAXDIRS (64) directories in a path.
3959243Sobrien *
4059243Sobrien *  The 'cmds' argument may be a sequence of any of the following:
4159243Sobrien *	-r			reset path to default
4259243Sobrien *	-i newpath		insert newpath before localsyspath
4359243Sobrien *	-ia oldpath newpath	insert newpath after oldpath
4459243Sobrien *	-ib oldpath newpath	insert newpath before oldpath
4559243Sobrien *	-i# newpath		insert newpath at position #
4659243Sobrien *	-d oldpath		delete oldpath
4759243Sobrien *	-d#			delete path at position #
4859243Sobrien *	-c oldpath newpath	change oldpath to newpath
4959243Sobrien *	-c# newpath		change position # to newpath
5059243Sobrien *
5159243Sobrien *  The "-i newpath" command is equivilent to "-ib 'localsyspath' newpath".
5259243Sobrien *
5359243Sobrien *  If 'dosuffix' is true, the appropriate suffix will be added to
5459243Sobrien *  all command operands for any system path in 'paths'.
5559243Sobrien *
5659243Sobrien *  Both of the 'paths' and 'cmds' lists are terminated by a NULL
5759243Sobrien *  entry.
5859243Sobrien *
5959243Sobrien *  if 'printerrors' is true, setpath will printf error diagnostics.
6059243Sobrien *
6159243Sobrien *  WARNING !!!: Under no circumstances should anyone change this
6259243Sobrien *  module without fully understanding the impact on the C shell.
6359243Sobrien *  The C shell has it's own malloc and printf routines and this
6459243Sobrien *  module was carefully written taking that into account.  Do not
6559243Sobrien *  use any stdio routines from this module except printf.
6659243Sobrien *
6759243Sobrien **********************************************************************
6859243Sobrien * HISTORY
6959243Sobrien *
7059243Sobrien * Revision 1.4  90/12/11  17:58:44  mja
7159243Sobrien * 	Add copyright/disclaimer for distribution.
7259243Sobrien *
7359243Sobrien * 05-Jun-88  Glenn Marcy (gm0w) at Carnegie-Mellon University
7459243Sobrien *	Make all non-entry points static.
7559243Sobrien *
7659243Sobrien * 30-Apr-88  Glenn Marcy (gm0w) at Carnegie-Mellon University
7759243Sobrien *	Added -r switch to reset paths to their default values.
7859243Sobrien *
7959243Sobrien * 06-Jan-86  Glenn Marcy (gm0w) at Carnegie-Mellon University
8059243Sobrien *	Created from old setpath program for the shell.
8159243Sobrien *
8259243Sobrien **********************************************************************
8359243Sobrien */
8459243Sobrien#include "sh.h"
8559243SobrienRCSID("$Id: ma.setp.c,v 1.12 1996/04/26 19:18:36 christos Exp $")
8659243Sobrien
8759243Sobrien#ifdef MACH
8859243Sobrien
8959243Sobrien#define MAXDIRS 64		/* max directories on a path */
9059243Sobrien#ifndef NULL
9159243Sobrien# define NULL 0
9259243Sobrien#endif
9359243Sobrien
9459243Sobrienstatic int npaths;		/* # pathlist arguments */
9559243Sobrien
9659243Sobrienstatic struct pelem {
9759243Sobrien    struct pelem *pnext;	/* pointer to next path */
9859243Sobrien    char *pname;		/* name of pathlist */
9959243Sobrien    char *psuf;			/* suffix for pathlist */
10059243Sobrien    char *pdef;			/* default for pathlist */
10159243Sobrien    int pdirs;			/* # directories on each pathlist */
10259243Sobrien    char *pdir[MAXDIRS];	/* directory names for each pathlist */
10359243Sobrien} *pathhead = NULL;
10459243Sobrien
10559243Sobrienstatic struct {
10659243Sobrien    char *name;
10759243Sobrien    char *suffix;
10859243Sobrien    char *defalt;
10959243Sobrien} syspath[] = {
11059243Sobrien    "PATH",	"/bin",		":/usr/ucb:/bin:/usr/bin",
11159243Sobrien    "CPATH",	"/include",	":/usr/include",
11259243Sobrien    "LPATH",	"/lib",		":/lib:/usr/lib",
11359243Sobrien    "MPATH",	"/man",		":/usr/man",
11459243Sobrien    "EPATH",	"/maclib",	"",
11559243Sobrien    0, 0, 0
11659243Sobrien};
11759243Sobrien
11859243Sobrienstatic int sflag;
11959243Sobrienstatic int eflag;
12059243Sobrien
12159243Sobrien#define INVALID { \
12259243Sobrien	if (eflag) xprintf(CGETS(10, 1, \
12359243Sobrien				 "setpath: invalid command '%s'.\n"), cmd); \
12459243Sobrien	freepaths(); \
12559243Sobrien	return(-1); \
12659243Sobrien}
12759243Sobrien
12859243Sobrien#define TOOFEW { \
12959243Sobrien	if (eflag) xprintf(CGETS(10, 2, \
13059243Sobrien		 "setpath: insufficient arguments to command '%s'.\n"), cmd); \
13159243Sobrien	freepaths(); \
13259243Sobrien	return(-1); \
13359243Sobrien}
13459243Sobrien
13559243Sobrienstatic int initpaths	__P((char **));
13659243Sobrienstatic void savepaths	__P((char **));
13759243Sobrienstatic void freepaths	__P((void));
13859243Sobrienstatic void rcmd	__P((char *));
13959243Sobrienstatic void icmd	__P((char *, char *));
14059243Sobrienstatic void iacmd	__P((char *, char *));
14159243Sobrienstatic void ibcmd	__P((char *, char *));
14259243Sobrienstatic void incmd	__P((char *, int));
14359243Sobrienstatic void insert	__P((struct pelem *, int, char *));
14459243Sobrienstatic void dcmd	__P((char *));
14559243Sobrienstatic void dncmd	__P((int));
14659243Sobrienstatic void delete	__P((struct pelem *, int));
14759243Sobrienstatic void ccmd	__P((char *, char *));
14859243Sobrienstatic void cncmd	__P((char *, int));
14959243Sobrienstatic void change	__P((struct pelem *, int, char *));
15059243Sobrienstatic int locate	__P((struct pelem *, char *));
15159243Sobrien
15259243Sobrien
15359243Sobrien
15459243Sobrienint
15559243Sobriensetpath(paths, cmds, localsyspath, dosuffix, printerrors)
15659243Sobrienregister char **paths, **cmds, *localsyspath;
15759243Sobrienint dosuffix, printerrors;
15859243Sobrien{
15959243Sobrien    register char *cmd, *cmd1, *cmd2;
16059243Sobrien    register int ncmd;
16159243Sobrien
16259243Sobrien    sflag = dosuffix;
16359243Sobrien    eflag = printerrors;
16459243Sobrien    if (initpaths(paths) < 0)
16559243Sobrien	return(-1);
16659243Sobrien    if (npaths == 0)
16759243Sobrien	return(0);
16859243Sobrien    for (ncmd = 0; cmd = cmds[ncmd]; ncmd++) {
16959243Sobrien	if (cmd[0] != '-')
17059243Sobrien	    INVALID;
17159243Sobrien	cmd1 = cmds[ncmd+1];
17259243Sobrien	cmd2 = cmds[ncmd+2];
17359243Sobrien	switch (cmd[1]) {
17459243Sobrien	case 'r':
17559243Sobrien	    if (cmd[2] != '\0')
17659243Sobrien		INVALID;
17759243Sobrien	    rcmd(localsyspath);
17859243Sobrien	    break;
17959243Sobrien	case 'i':
18059243Sobrien	    if (cmd[2] == '\0') {
18159243Sobrien		ncmd++;
18259243Sobrien		if (cmd1 == NULL) TOOFEW;
18359243Sobrien		icmd(cmd1, localsyspath);
18459243Sobrien	    } else if (isdigit(cmd[2])) {
18559243Sobrien		ncmd++;
18659243Sobrien		if (cmd1 == NULL) TOOFEW;
18759243Sobrien		incmd(cmd1, atoi(cmd+2));
18859243Sobrien	    } else if (cmd[3] != '\0' || (cmd[2] != 'a' && cmd[2] != 'b')) {
18959243Sobrien		INVALID;
19059243Sobrien	    } else {
19159243Sobrien		ncmd += 2;
19259243Sobrien		if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
19359243Sobrien		if (cmd[2] == 'a')
19459243Sobrien		    iacmd(cmd1, cmd2);
19559243Sobrien		else
19659243Sobrien		    ibcmd(cmd1, cmd2);
19759243Sobrien	    }
19859243Sobrien	    break;
19959243Sobrien	case 'd':
20059243Sobrien	    if (cmd[2] == '\0') {
20159243Sobrien		ncmd++;
20259243Sobrien		if (cmd1 == NULL) TOOFEW;
20359243Sobrien		dcmd(cmd1);
20459243Sobrien	    } else if (isdigit(cmd[2]))
20559243Sobrien		dncmd(atoi(cmd+2));
20659243Sobrien	    else {
20759243Sobrien		INVALID;
20859243Sobrien	    }
20959243Sobrien	    break;
21059243Sobrien	case 'c':
21159243Sobrien	    if (cmd[2] == '\0') {
21259243Sobrien		ncmd += 2;
21359243Sobrien		if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
21459243Sobrien		ccmd(cmd1, cmd2);
21559243Sobrien	    } else if (isdigit(cmd[2])) {
21659243Sobrien		ncmd++;
21759243Sobrien		if (cmd1 == NULL) TOOFEW;
21859243Sobrien		cncmd(cmd1, atoi(cmd+2));
21959243Sobrien	    } else {
22059243Sobrien		INVALID;
22159243Sobrien	    }
22259243Sobrien	    break;
22359243Sobrien	default:
22459243Sobrien	    INVALID;
22559243Sobrien	}
22659243Sobrien    }
22759243Sobrien    savepaths(paths);
22859243Sobrien    freepaths();
22959243Sobrien    return(0);
23059243Sobrien}
23159243Sobrien
23259243Sobrienstatic int
23359243Sobrieninitpaths(paths)
23459243Sobrienregister char **paths;
23559243Sobrien{
23659243Sobrien    register char *path, *val, *p, *q;
23759243Sobrien    register int i, done;
23859243Sobrien    register struct pelem *pe, *pathend;
23959243Sobrien
24059243Sobrien    freepaths();
24159243Sobrien    for (npaths = 0; path = paths[npaths]; npaths++) {
24259243Sobrien	val = index(path, '=');
24359243Sobrien	if (val == NULL) {
24459243Sobrien	    if (eflag)
24559243Sobrien		xprintf(CGETS(10, 3,
24659243Sobrien			      "setpath: value missing in path '%s'\n"), path);
24759243Sobrien	    freepaths();
24859243Sobrien	    return(-1);
24959243Sobrien	}
25059243Sobrien	*val++ = '\0';
25159243Sobrien	pe = (struct pelem *)xmalloc((unsigned)(sizeof(struct pelem)));
25259243Sobrien	setzero((char *) pe, sizeof(struct pelem));
25359243Sobrien	if (pathhead == NULL)
25459243Sobrien	    pathhead = pathend = pe;
25559243Sobrien	else {
25659243Sobrien	    pathend->pnext = pe;
25759243Sobrien	    pathend = pe;
25859243Sobrien	}
25959243Sobrien	p = strsave(path);
26059243Sobrien	pe->pname = p;
26159243Sobrien	pe->psuf = "";
26259243Sobrien	pe->pdef = "";
26359243Sobrien	for (i = 0; syspath[i].name; i++)
26459243Sobrien	    if (strcmp(pe->pname, syspath[i].name) == 0) {
26559243Sobrien		pe->psuf = syspath[i].suffix;
26659243Sobrien		pe->pdef = syspath[i].defalt;
26759243Sobrien		break;
26859243Sobrien	    }
26959243Sobrien	q = val;
27059243Sobrien	for (;;) {
27159243Sobrien	    q = index(p = q, ':');
27259243Sobrien	    done = (q == NULL);
27359243Sobrien	    if (!done)
27459243Sobrien		*q++ = '\0';
27559243Sobrien	    p = strsave(p);
27659243Sobrien	    pe->pdir[pe->pdirs] = p;
27759243Sobrien	    pe->pdirs++;
27859243Sobrien	    if (done)
27959243Sobrien		break;
28059243Sobrien	}
28159243Sobrien    }
28259243Sobrien    return(0);
28359243Sobrien}
28459243Sobrien
28559243Sobrienstatic void
28659243Sobriensavepaths(paths)
28759243Sobrienregister char **paths;
28859243Sobrien{
28959243Sobrien    register char *p, *q;
29059243Sobrien    register int npath, i, len;
29159243Sobrien    register struct pelem *pe;
29259243Sobrien
29359243Sobrien    for (npath = 0, pe = pathhead; pe; npath++, pe = pe->pnext) {
29459243Sobrien	len = strlen(pe->pname) + 1;
29559243Sobrien	if (pe->pdirs == 0)
29659243Sobrien	    len++;
29759243Sobrien	else for (i = 0; i < pe->pdirs; i++)
29859243Sobrien	    len += strlen(pe->pdir[i]) + 1;
29959243Sobrien	p = xmalloc((unsigned)len);
30059243Sobrien	paths[npath] = p;
30159243Sobrien	for (q = pe->pname; *p = *q; p++, q++);
30259243Sobrien	*p++ = '=';
30359243Sobrien	if (pe->pdirs != 0) {
30459243Sobrien	    for (i = 0; i < pe->pdirs; i++) {
30559243Sobrien		for (q = pe->pdir[i]; *p = *q; p++, q++);
30659243Sobrien		*p++ = ':';
30759243Sobrien	    }
30859243Sobrien	    p--;
30959243Sobrien	}
31059243Sobrien	*p = '\0';
31159243Sobrien    }
31259243Sobrien}
31359243Sobrien
31459243Sobrienstatic void
31559243Sobrienfreepaths()
31659243Sobrien{
31759243Sobrien    register char *p;
31859243Sobrien    register int i;
31959243Sobrien    register struct pelem *pe;
32059243Sobrien
32159243Sobrien    if (npaths == 0 || pathhead == NULL)
32259243Sobrien	return;
32359243Sobrien    while (pe = pathhead) {
32459243Sobrien	if (pe->pname) {
32559243Sobrien	    for (i = 0; i < pe->pdirs; i++) {
32659243Sobrien		if (pe->pdir[i] == NULL)
32759243Sobrien		    continue;
32859243Sobrien		p = pe->pdir[i];
32959243Sobrien		pe->pdir[i] = NULL;
33059243Sobrien		xfree((ptr_t) p);
33159243Sobrien	    }
33259243Sobrien	    pe->pdirs = 0;
33359243Sobrien	    p = pe->pname;
33459243Sobrien	    pe->pname = NULL;
33559243Sobrien	    xfree((ptr_t) p);
33659243Sobrien	}
33759243Sobrien	pathhead = pe->pnext;
33859243Sobrien	xfree((ptr_t) pe);
33959243Sobrien    }
34059243Sobrien    npaths = 0;
34159243Sobrien}
34259243Sobrien
34359243Sobrien/***********************************************
34459243Sobrien ***    R E S E T   A   P A T H N A M E    ***
34559243Sobrien ***********************************************/
34659243Sobrien
34759243Sobrienstatic void
34859243Sobrienrcmd(localsyspath)		/* reset path with localsyspath */
34959243Sobrienchar *localsyspath;
35059243Sobrien{
35159243Sobrien    register int n, done;
35259243Sobrien    register char *new, *p;
35359243Sobrien    register struct pelem *pe;
35459243Sobrien    char newbuf[MAXPATHLEN+1];
35559243Sobrien
35659243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
35759243Sobrien	new = newbuf;
35859243Sobrien	*new = '\0';
35959243Sobrien	if (localsyspath != NULL) {
36059243Sobrien	    *new = ':';
36159243Sobrien	    (void) strcpy(new + 1, localsyspath);
36259243Sobrien	    (void) strcat(new, pe->psuf);
36359243Sobrien	}
36459243Sobrien	(void) strcat(new, pe->pdef);
36559243Sobrien	for (n = 0; n < pe->pdirs; n++) {
36659243Sobrien	    if (pe->pdir[n] == NULL)
36759243Sobrien		continue;
36859243Sobrien	    p = pe->pdir[n];
36959243Sobrien	    pe->pdir[n] = NULL;
37059243Sobrien	    xfree((ptr_t) p);
37159243Sobrien	}
37259243Sobrien	pe->pdirs = 0;
37359243Sobrien	for (;;) {
37459243Sobrien	    new = index(p = new, ':');
37559243Sobrien	    done = (new == NULL);
37659243Sobrien	    if (!done)
37759243Sobrien		*new++ = '\0';
37859243Sobrien	    p = strsave(p);
37959243Sobrien	    pe->pdir[pe->pdirs] = p;
38059243Sobrien	    pe->pdirs++;
38159243Sobrien	    if (done)
38259243Sobrien		break;
38359243Sobrien	}
38459243Sobrien    }
38559243Sobrien}
38659243Sobrien
38759243Sobrien/***********************************************
38859243Sobrien ***    I N S E R T   A   P A T H N A M E    ***
38959243Sobrien ***********************************************/
39059243Sobrien
39159243Sobrienstatic void
39259243Sobrienicmd(path, localsyspath)	/* insert path before localsyspath */
39359243Sobrienchar *path, *localsyspath;
39459243Sobrien{
39559243Sobrien    register int n;
39659243Sobrien    register char *new;
39759243Sobrien    register struct pelem *pe;
39859243Sobrien    char newbuf[MAXPATHLEN+1];
39959243Sobrien
40059243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
40159243Sobrien	if (sflag)
40259243Sobrien	    new = localsyspath;
40359243Sobrien	else {
40459243Sobrien	    new = newbuf;
40559243Sobrien	    (void) strcpy(new, localsyspath);
40659243Sobrien	    (void) strcat(new, pe->psuf);
40759243Sobrien	}
40859243Sobrien	n = locate(pe, new);
40959243Sobrien	if (n >= 0)
41059243Sobrien	    insert(pe, n, path);
41159243Sobrien	else
41259243Sobrien	    insert(pe, 0, path);
41359243Sobrien    }
41459243Sobrien}
41559243Sobrien
41659243Sobrienstatic void
41759243Sobrieniacmd(inpath, path)		/* insert path after inpath */
41859243Sobrienchar *inpath, *path;
41959243Sobrien{
42059243Sobrien    register int n;
42159243Sobrien    register struct pelem *pe;
42259243Sobrien
42359243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
42459243Sobrien	n = locate(pe, inpath);
42559243Sobrien	if (n >= 0)
42659243Sobrien	    insert(pe, n + 1, path);
42759243Sobrien	else
42859243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
42959243Sobrien		    inpath, pe->pname);
43059243Sobrien    }
43159243Sobrien}
43259243Sobrien
43359243Sobrienstatic void
43459243Sobrienibcmd(inpath, path)		/* insert path before inpath */
43559243Sobrienchar *inpath, *path;
43659243Sobrien{
43759243Sobrien    register int n;
43859243Sobrien    register struct pelem *pe;
43959243Sobrien
44059243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
44159243Sobrien	n = locate(pe, inpath);
44259243Sobrien	if (n >= 0)
44359243Sobrien	    insert(pe, n, path);
44459243Sobrien	else
44559243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n",
44659243Sobrien		    inpath, pe->pname));
44759243Sobrien    }
44859243Sobrien}
44959243Sobrien
45059243Sobrienstatic void
45159243Sobrienincmd(path, n)			/* insert path at position n */
45259243Sobrienchar *path;
45359243Sobrienint n;
45459243Sobrien{
45559243Sobrien    register struct pelem *pe;
45659243Sobrien
45759243Sobrien    for (pe = pathhead; pe; pe = pe->pnext)
45859243Sobrien	insert(pe, n, path);
45959243Sobrien}
46059243Sobrien
46159243Sobrienstatic void
46259243Sobrieninsert(pe, loc, key)
46359243Sobrienregister struct pelem *pe;
46459243Sobrienregister int loc;
46559243Sobrienregister char *key;
46659243Sobrien{
46759243Sobrien    register int i;
46859243Sobrien    register char *new;
46959243Sobrien    char newbuf[2000];
47059243Sobrien
47159243Sobrien    if (sflag) {		/* add suffix */
47259243Sobrien	new = newbuf;
47359243Sobrien	(void) strcpy(new, key);
47459243Sobrien	(void) strcat(new, pe->psuf);
47559243Sobrien    } else
47659243Sobrien	new = key;
47759243Sobrien    new = strsave(new);
47859243Sobrien    for (i = pe->pdirs; i > loc; --i)
47959243Sobrien	pe->pdir[i] = pe->pdir[i-1];
48059243Sobrien    if (loc > pe->pdirs)
48159243Sobrien	loc = pe->pdirs;
48259243Sobrien    pe->pdir[loc] = new;
48359243Sobrien    pe->pdirs++;
48459243Sobrien}
48559243Sobrien
48659243Sobrien/***********************************************
48759243Sobrien ***    D E L E T E   A   P A T H N A M E    ***
48859243Sobrien ***********************************************/
48959243Sobrien
49059243Sobrienstatic void
49159243Sobriendcmd(path)			/* delete path */
49259243Sobrienchar *path;
49359243Sobrien{
49459243Sobrien    register int n;
49559243Sobrien    register struct pelem *pe;
49659243Sobrien
49759243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
49859243Sobrien	n = locate(pe, path);
49959243Sobrien	if (n >= 0)
50059243Sobrien	    delete(pe, n);
50159243Sobrien	else
50259243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
50359243Sobrien		    path, pe->pname);
50459243Sobrien    }
50559243Sobrien}
50659243Sobrien
50759243Sobrienstatic void
50859243Sobriendncmd(n)			/* delete at position n */
50959243Sobrienint n;
51059243Sobrien{
51159243Sobrien    register struct pelem *pe;
51259243Sobrien
51359243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
51459243Sobrien	if (n < pe->pdirs)
51559243Sobrien	    delete(pe, n);
51659243Sobrien	else
51759243Sobrien	    xprintf(CGETS(10, 5,
51859243Sobrien			    "setpath: %d not valid position in %s\n"),
51959243Sobrien		    n, pe->pname);
52059243Sobrien    }
52159243Sobrien}
52259243Sobrien
52359243Sobrienstatic void
52459243Sobriendelete(pe, n)
52559243Sobrienregister struct pelem *pe;
52659243Sobrienint n;
52759243Sobrien{
52859243Sobrien    register int d;
52959243Sobrien
53059243Sobrien    xfree((ptr_t) (pe->pdir[n]));
53159243Sobrien    for (d = n; d < pe->pdirs - 1; d++)
53259243Sobrien	pe->pdir[d] = pe->pdir[d+1];
53359243Sobrien    --pe->pdirs;
53459243Sobrien}
53559243Sobrien
53659243Sobrien/***********************************************
53759243Sobrien ***    C H A N G E   A   P A T H N A M E    ***
53859243Sobrien ***********************************************/
53959243Sobrien
54059243Sobrienstatic void
54159243Sobrienccmd(inpath, path)		/* change inpath to path */
54259243Sobrienchar *inpath, *path;
54359243Sobrien{
54459243Sobrien    register int n;
54559243Sobrien    register struct pelem *pe;
54659243Sobrien
54759243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
54859243Sobrien	n = locate(pe, inpath);
54959243Sobrien	if (n >= 0)
55059243Sobrien	    change(pe, n, path);
55159243Sobrien	else
55259243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
55359243Sobrien		    inpath, pe->pname);
55459243Sobrien    }
55559243Sobrien}
55659243Sobrien
55759243Sobrienstatic void
55859243Sobriencncmd(path, n)		/* change at position n to path */
55959243Sobrienchar *path;
56059243Sobrienint n;
56159243Sobrien{
56259243Sobrien    register struct pelem *pe;
56359243Sobrien
56459243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
56559243Sobrien	if (n < pe->pdirs)
56659243Sobrien	    change(pe, n, path);
56759243Sobrien	else
56859243Sobrien	    xprintf(CGETS(10, 5,
56959243Sobrien			    "setpath: %d not valid position in %s\n"),
57059243Sobrien		    n, pe->pname);
57159243Sobrien    }
57259243Sobrien}
57359243Sobrien
57459243Sobrienstatic void
57559243Sobrienchange(pe, loc, key)
57659243Sobrienregister struct pelem *pe;
57759243Sobrienregister int loc;
57859243Sobrienregister char *key;
57959243Sobrien{
58059243Sobrien    register char *new;
58159243Sobrien    char newbuf[MAXPATHLEN+1];
58259243Sobrien
58359243Sobrien    if (sflag) {		/* append suffix */
58459243Sobrien	new = newbuf;
58559243Sobrien	(void) strcpy(new, key);
58659243Sobrien	(void) strcat(new, pe->psuf);
58759243Sobrien    } else
58859243Sobrien	new = key;
58959243Sobrien    new = strsave(new);
59059243Sobrien    xfree((ptr_t) (pe->pdir[loc]));
59159243Sobrien    pe->pdir[loc] = new;
59259243Sobrien}
59359243Sobrien
59459243Sobrien/***************************************
59559243Sobrien ***    F I N D   P A T H N A M E    ***
59659243Sobrien ***************************************/
59759243Sobrien
59859243Sobrienstatic int
59959243Sobrienlocate(pe, key)
60059243Sobrienregister struct pelem *pe;
60159243Sobrienregister char *key;
60259243Sobrien{
60359243Sobrien    register int i;
60459243Sobrien    register char *realkey;
60559243Sobrien    char keybuf[MAXPATHLEN+1];
60659243Sobrien
60759243Sobrien    if (sflag) {
60859243Sobrien	realkey = keybuf;
60959243Sobrien	(void) strcpy(realkey, key);
61059243Sobrien	(void) strcat(realkey, pe->psuf);
61159243Sobrien    } else
61259243Sobrien	realkey = key;
61359243Sobrien    for (i = 0; i < pe->pdirs; i++)
61459243Sobrien	if (strcmp(pe->pdir[i], realkey) == 0)
61559243Sobrien	    break;
61659243Sobrien    return((i < pe->pdirs) ? i : -1);
61759243Sobrien}
61859243Sobrien#endif
619