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"
85195609SmpRCSID("$tcsh: ma.setp.c,v 1.19 2007/11/20 20:03:51 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
135167465Smpstatic int initpaths	(char **);
136167465Smpstatic void savepaths	(char **);
137167465Smpstatic void freepaths	(void);
138195609Smpstatic void tcsh_rcmd	(char *);
139167465Smpstatic void icmd	(char *, char *);
140167465Smpstatic void iacmd	(char *, char *);
141167465Smpstatic void ibcmd	(char *, char *);
142167465Smpstatic void incmd	(char *, int);
143167465Smpstatic void insert	(struct pelem *, int, char *);
144167465Smpstatic void dcmd	(char *);
145167465Smpstatic void dncmd	(int);
146167465Smpstatic void delete	(struct pelem *, int);
147167465Smpstatic void ccmd	(char *, char *);
148167465Smpstatic void cncmd	(char *, int);
149167465Smpstatic void change	(struct pelem *, int, char *);
150167465Smpstatic int locate	(struct pelem *, char *);
15159243Sobrien
15259243Sobrien
15359243Sobrien
15459243Sobrienint
155167465Smpsetpath(char **paths, char **cmds, char *localsyspath, int dosuffix,
156167465Smp	int printerrors)
15759243Sobrien{
158145479Smp    char *cmd, *cmd1, *cmd2;
159145479Smp    int ncmd;
16059243Sobrien
16159243Sobrien    sflag = dosuffix;
16259243Sobrien    eflag = printerrors;
16359243Sobrien    if (initpaths(paths) < 0)
16459243Sobrien	return(-1);
16559243Sobrien    if (npaths == 0)
16659243Sobrien	return(0);
16759243Sobrien    for (ncmd = 0; cmd = cmds[ncmd]; ncmd++) {
16859243Sobrien	if (cmd[0] != '-')
16959243Sobrien	    INVALID;
17059243Sobrien	cmd1 = cmds[ncmd+1];
17159243Sobrien	cmd2 = cmds[ncmd+2];
17259243Sobrien	switch (cmd[1]) {
17359243Sobrien	case 'r':
17459243Sobrien	    if (cmd[2] != '\0')
17559243Sobrien		INVALID;
176195609Smp	    tcsh_rcmd(localsyspath);
17759243Sobrien	    break;
17859243Sobrien	case 'i':
17959243Sobrien	    if (cmd[2] == '\0') {
18059243Sobrien		ncmd++;
18159243Sobrien		if (cmd1 == NULL) TOOFEW;
18259243Sobrien		icmd(cmd1, localsyspath);
18359243Sobrien	    } else if (isdigit(cmd[2])) {
18459243Sobrien		ncmd++;
18559243Sobrien		if (cmd1 == NULL) TOOFEW;
18659243Sobrien		incmd(cmd1, atoi(cmd+2));
18759243Sobrien	    } else if (cmd[3] != '\0' || (cmd[2] != 'a' && cmd[2] != 'b')) {
18859243Sobrien		INVALID;
18959243Sobrien	    } else {
19059243Sobrien		ncmd += 2;
19159243Sobrien		if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
19259243Sobrien		if (cmd[2] == 'a')
19359243Sobrien		    iacmd(cmd1, cmd2);
19459243Sobrien		else
19559243Sobrien		    ibcmd(cmd1, cmd2);
19659243Sobrien	    }
19759243Sobrien	    break;
19859243Sobrien	case 'd':
19959243Sobrien	    if (cmd[2] == '\0') {
20059243Sobrien		ncmd++;
20159243Sobrien		if (cmd1 == NULL) TOOFEW;
20259243Sobrien		dcmd(cmd1);
20359243Sobrien	    } else if (isdigit(cmd[2]))
20459243Sobrien		dncmd(atoi(cmd+2));
20559243Sobrien	    else {
20659243Sobrien		INVALID;
20759243Sobrien	    }
20859243Sobrien	    break;
20959243Sobrien	case 'c':
21059243Sobrien	    if (cmd[2] == '\0') {
21159243Sobrien		ncmd += 2;
21259243Sobrien		if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
21359243Sobrien		ccmd(cmd1, cmd2);
21459243Sobrien	    } else if (isdigit(cmd[2])) {
21559243Sobrien		ncmd++;
21659243Sobrien		if (cmd1 == NULL) TOOFEW;
21759243Sobrien		cncmd(cmd1, atoi(cmd+2));
21859243Sobrien	    } else {
21959243Sobrien		INVALID;
22059243Sobrien	    }
22159243Sobrien	    break;
22259243Sobrien	default:
22359243Sobrien	    INVALID;
22459243Sobrien	}
22559243Sobrien    }
22659243Sobrien    savepaths(paths);
22759243Sobrien    freepaths();
22859243Sobrien    return(0);
22959243Sobrien}
23059243Sobrien
23159243Sobrienstatic int
232167465Smpinitpaths(char **paths)
23359243Sobrien{
234145479Smp    char *path, *val, *p, *q;
235145479Smp    int i, done;
236145479Smp    struct pelem *pe, *pathend;
23759243Sobrien
23859243Sobrien    freepaths();
23959243Sobrien    for (npaths = 0; path = paths[npaths]; npaths++) {
24059243Sobrien	val = index(path, '=');
24159243Sobrien	if (val == NULL) {
24259243Sobrien	    if (eflag)
24359243Sobrien		xprintf(CGETS(10, 3,
24459243Sobrien			      "setpath: value missing in path '%s'\n"), path);
24559243Sobrien	    freepaths();
24659243Sobrien	    return(-1);
24759243Sobrien	}
24859243Sobrien	*val++ = '\0';
249167465Smp	pe = xmalloc(sizeof(struct pelem));
250167465Smp	setzero(pe, sizeof(struct pelem));
25159243Sobrien	if (pathhead == NULL)
25259243Sobrien	    pathhead = pathend = pe;
25359243Sobrien	else {
25459243Sobrien	    pathend->pnext = pe;
25559243Sobrien	    pathend = pe;
25659243Sobrien	}
25759243Sobrien	p = strsave(path);
25859243Sobrien	pe->pname = p;
25959243Sobrien	pe->psuf = "";
26059243Sobrien	pe->pdef = "";
26159243Sobrien	for (i = 0; syspath[i].name; i++)
26259243Sobrien	    if (strcmp(pe->pname, syspath[i].name) == 0) {
26359243Sobrien		pe->psuf = syspath[i].suffix;
26459243Sobrien		pe->pdef = syspath[i].defalt;
26559243Sobrien		break;
26659243Sobrien	    }
26759243Sobrien	q = val;
26859243Sobrien	for (;;) {
26959243Sobrien	    q = index(p = q, ':');
27059243Sobrien	    done = (q == NULL);
27159243Sobrien	    if (!done)
27259243Sobrien		*q++ = '\0';
27359243Sobrien	    p = strsave(p);
27459243Sobrien	    pe->pdir[pe->pdirs] = p;
27559243Sobrien	    pe->pdirs++;
27659243Sobrien	    if (done)
27759243Sobrien		break;
27859243Sobrien	}
27959243Sobrien    }
28059243Sobrien    return(0);
28159243Sobrien}
28259243Sobrien
28359243Sobrienstatic void
284167465Smpsavepaths(char **paths)
28559243Sobrien{
286145479Smp    char *p, *q;
287145479Smp    int npath, i, len;
288145479Smp    struct pelem *pe;
28959243Sobrien
29059243Sobrien    for (npath = 0, pe = pathhead; pe; npath++, pe = pe->pnext) {
29159243Sobrien	len = strlen(pe->pname) + 1;
29259243Sobrien	if (pe->pdirs == 0)
29359243Sobrien	    len++;
29459243Sobrien	else for (i = 0; i < pe->pdirs; i++)
29559243Sobrien	    len += strlen(pe->pdir[i]) + 1;
29659243Sobrien	p = xmalloc((unsigned)len);
29759243Sobrien	paths[npath] = p;
29859243Sobrien	for (q = pe->pname; *p = *q; p++, q++);
29959243Sobrien	*p++ = '=';
30059243Sobrien	if (pe->pdirs != 0) {
30159243Sobrien	    for (i = 0; i < pe->pdirs; i++) {
30259243Sobrien		for (q = pe->pdir[i]; *p = *q; p++, q++);
30359243Sobrien		*p++ = ':';
30459243Sobrien	    }
30559243Sobrien	    p--;
30659243Sobrien	}
30759243Sobrien	*p = '\0';
30859243Sobrien    }
30959243Sobrien}
31059243Sobrien
31159243Sobrienstatic void
312167465Smpfreepaths(void)
31359243Sobrien{
314145479Smp    char *p;
315145479Smp    int i;
316145479Smp    struct pelem *pe;
31759243Sobrien
31859243Sobrien    if (npaths == 0 || pathhead == NULL)
31959243Sobrien	return;
32059243Sobrien    while (pe = pathhead) {
32159243Sobrien	if (pe->pname) {
32259243Sobrien	    for (i = 0; i < pe->pdirs; i++) {
32359243Sobrien		if (pe->pdir[i] == NULL)
32459243Sobrien		    continue;
32559243Sobrien		p = pe->pdir[i];
32659243Sobrien		pe->pdir[i] = NULL;
32759243Sobrien		xfree((ptr_t) p);
32859243Sobrien	    }
32959243Sobrien	    pe->pdirs = 0;
33059243Sobrien	    p = pe->pname;
33159243Sobrien	    pe->pname = NULL;
33259243Sobrien	    xfree((ptr_t) p);
33359243Sobrien	}
33459243Sobrien	pathhead = pe->pnext;
33559243Sobrien	xfree((ptr_t) pe);
33659243Sobrien    }
33759243Sobrien    npaths = 0;
33859243Sobrien}
33959243Sobrien
34059243Sobrien/***********************************************
34159243Sobrien ***    R E S E T   A   P A T H N A M E    ***
34259243Sobrien ***********************************************/
34359243Sobrien
34459243Sobrienstatic void
345195609Smptcsh_rcmd(char *localsyspath)	/* reset path with localsyspath */
34659243Sobrien{
347145479Smp    int n, done;
348145479Smp    char *new, *p;
349145479Smp    struct pelem *pe;
350167465Smp    char newbuf[MAXPATHLEN+1];/*FIXBUF*/
35159243Sobrien
35259243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
35359243Sobrien	new = newbuf;
35459243Sobrien	*new = '\0';
35559243Sobrien	if (localsyspath != NULL) {
35659243Sobrien	    *new = ':';
35759243Sobrien	    (void) strcpy(new + 1, localsyspath);
35859243Sobrien	    (void) strcat(new, pe->psuf);
35959243Sobrien	}
36059243Sobrien	(void) strcat(new, pe->pdef);
36159243Sobrien	for (n = 0; n < pe->pdirs; n++) {
36259243Sobrien	    if (pe->pdir[n] == NULL)
36359243Sobrien		continue;
36459243Sobrien	    p = pe->pdir[n];
36559243Sobrien	    pe->pdir[n] = NULL;
36659243Sobrien	    xfree((ptr_t) p);
36759243Sobrien	}
36859243Sobrien	pe->pdirs = 0;
36959243Sobrien	for (;;) {
37059243Sobrien	    new = index(p = new, ':');
37159243Sobrien	    done = (new == NULL);
37259243Sobrien	    if (!done)
37359243Sobrien		*new++ = '\0';
37459243Sobrien	    p = strsave(p);
37559243Sobrien	    pe->pdir[pe->pdirs] = p;
37659243Sobrien	    pe->pdirs++;
37759243Sobrien	    if (done)
37859243Sobrien		break;
37959243Sobrien	}
38059243Sobrien    }
38159243Sobrien}
38259243Sobrien
38359243Sobrien/***********************************************
38459243Sobrien ***    I N S E R T   A   P A T H N A M E    ***
38559243Sobrien ***********************************************/
38659243Sobrien
38759243Sobrienstatic void
388167465Smpicmd(char *path, char *localsyspath)	/* insert path before localsyspath */
38959243Sobrien{
390145479Smp    int n;
391145479Smp    char *new;
392145479Smp    struct pelem *pe;
393167465Smp    char newbuf[MAXPATHLEN+1];/*FIXBUF*/
39459243Sobrien
39559243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
39659243Sobrien	if (sflag)
39759243Sobrien	    new = localsyspath;
39859243Sobrien	else {
39959243Sobrien	    new = newbuf;
40059243Sobrien	    (void) strcpy(new, localsyspath);
40159243Sobrien	    (void) strcat(new, pe->psuf);
40259243Sobrien	}
40359243Sobrien	n = locate(pe, new);
40459243Sobrien	if (n >= 0)
40559243Sobrien	    insert(pe, n, path);
40659243Sobrien	else
40759243Sobrien	    insert(pe, 0, path);
40859243Sobrien    }
40959243Sobrien}
41059243Sobrien
41159243Sobrienstatic void
412167465Smpiacmd(char *inpath, char *path)	/* insert path after inpath */
41359243Sobrien{
414145479Smp    int n;
415145479Smp    struct pelem *pe;
41659243Sobrien
41759243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
41859243Sobrien	n = locate(pe, inpath);
41959243Sobrien	if (n >= 0)
42059243Sobrien	    insert(pe, n + 1, path);
42159243Sobrien	else
42259243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
42359243Sobrien		    inpath, pe->pname);
42459243Sobrien    }
42559243Sobrien}
42659243Sobrien
42759243Sobrienstatic void
428167465Smpibcmd(char *inpath, char *path)	/* insert path before inpath */
42959243Sobrien{
430145479Smp    int n;
431145479Smp    struct pelem *pe;
43259243Sobrien
43359243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
43459243Sobrien	n = locate(pe, inpath);
43559243Sobrien	if (n >= 0)
43659243Sobrien	    insert(pe, n, path);
43759243Sobrien	else
438131962Smp	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
439131962Smp		    inpath, pe->pname);
44059243Sobrien    }
44159243Sobrien}
44259243Sobrien
44359243Sobrienstatic void
444167465Smpincmd(char *path, int n)	/* insert path at position n */
44559243Sobrien{
446145479Smp    struct pelem *pe;
44759243Sobrien
44859243Sobrien    for (pe = pathhead; pe; pe = pe->pnext)
44959243Sobrien	insert(pe, n, path);
45059243Sobrien}
45159243Sobrien
45259243Sobrienstatic void
453167465Smpinsert(struct pelem *pe, int loc, char *key)
45459243Sobrien{
455145479Smp    int i;
456145479Smp    char *new;
457167465Smp    char newbuf[2000];/*FIXBUF*/
45859243Sobrien
45959243Sobrien    if (sflag) {		/* add suffix */
46059243Sobrien	new = newbuf;
46159243Sobrien	(void) strcpy(new, key);
46259243Sobrien	(void) strcat(new, pe->psuf);
46359243Sobrien    } else
46459243Sobrien	new = key;
46559243Sobrien    new = strsave(new);
46659243Sobrien    for (i = pe->pdirs; i > loc; --i)
46759243Sobrien	pe->pdir[i] = pe->pdir[i-1];
46859243Sobrien    if (loc > pe->pdirs)
46959243Sobrien	loc = pe->pdirs;
47059243Sobrien    pe->pdir[loc] = new;
47159243Sobrien    pe->pdirs++;
47259243Sobrien}
47359243Sobrien
47459243Sobrien/***********************************************
47559243Sobrien ***    D E L E T E   A   P A T H N A M E    ***
47659243Sobrien ***********************************************/
47759243Sobrien
47859243Sobrienstatic void
479167465Smpdcmd(char *path)		/* delete path */
48059243Sobrien{
481145479Smp    int n;
482145479Smp    struct pelem *pe;
48359243Sobrien
48459243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
48559243Sobrien	n = locate(pe, path);
48659243Sobrien	if (n >= 0)
48759243Sobrien	    delete(pe, n);
48859243Sobrien	else
48959243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
49059243Sobrien		    path, pe->pname);
49159243Sobrien    }
49259243Sobrien}
49359243Sobrien
49459243Sobrienstatic void
495167465Smpdncmd(int n)			/* delete at position n */
49659243Sobrien{
497145479Smp    struct pelem *pe;
49859243Sobrien
49959243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
50059243Sobrien	if (n < pe->pdirs)
50159243Sobrien	    delete(pe, n);
50259243Sobrien	else
50359243Sobrien	    xprintf(CGETS(10, 5,
50459243Sobrien			    "setpath: %d not valid position in %s\n"),
50559243Sobrien		    n, pe->pname);
50659243Sobrien    }
50759243Sobrien}
50859243Sobrien
50959243Sobrienstatic void
510167465Smpdelete(struct pelem *pe, int n)
51159243Sobrien{
512145479Smp    int d;
51359243Sobrien
51459243Sobrien    xfree((ptr_t) (pe->pdir[n]));
51559243Sobrien    for (d = n; d < pe->pdirs - 1; d++)
51659243Sobrien	pe->pdir[d] = pe->pdir[d+1];
51759243Sobrien    --pe->pdirs;
51859243Sobrien}
51959243Sobrien
52059243Sobrien/***********************************************
52159243Sobrien ***    C H A N G E   A   P A T H N A M E    ***
52259243Sobrien ***********************************************/
52359243Sobrien
52459243Sobrienstatic void
525167465Smpccmd(char *inpath, char *path)	/* change inpath to path */
52659243Sobrien{
527145479Smp    int n;
528145479Smp    struct pelem *pe;
52959243Sobrien
53059243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
53159243Sobrien	n = locate(pe, inpath);
53259243Sobrien	if (n >= 0)
53359243Sobrien	    change(pe, n, path);
53459243Sobrien	else
53559243Sobrien	    xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
53659243Sobrien		    inpath, pe->pname);
53759243Sobrien    }
53859243Sobrien}
53959243Sobrien
54059243Sobrienstatic void
541167465Smpcncmd(char *path, int n)	/* change at position n to path */
54259243Sobrien{
543145479Smp    struct pelem *pe;
54459243Sobrien
54559243Sobrien    for (pe = pathhead; pe; pe = pe->pnext) {
54659243Sobrien	if (n < pe->pdirs)
54759243Sobrien	    change(pe, n, path);
54859243Sobrien	else
54959243Sobrien	    xprintf(CGETS(10, 5,
55059243Sobrien			    "setpath: %d not valid position in %s\n"),
55159243Sobrien		    n, pe->pname);
55259243Sobrien    }
55359243Sobrien}
55459243Sobrien
55559243Sobrienstatic void
556167465Smpchange(struct pelem *pe, int loc, char *key)
55759243Sobrien{
558145479Smp    char *new;
559167465Smp    char newbuf[MAXPATHLEN+1];/*FIXBUF*/
56059243Sobrien
56159243Sobrien    if (sflag) {		/* append suffix */
56259243Sobrien	new = newbuf;
56359243Sobrien	(void) strcpy(new, key);
56459243Sobrien	(void) strcat(new, pe->psuf);
56559243Sobrien    } else
56659243Sobrien	new = key;
56759243Sobrien    new = strsave(new);
56859243Sobrien    xfree((ptr_t) (pe->pdir[loc]));
56959243Sobrien    pe->pdir[loc] = new;
57059243Sobrien}
57159243Sobrien
57259243Sobrien/***************************************
57359243Sobrien ***    F I N D   P A T H N A M E    ***
57459243Sobrien ***************************************/
57559243Sobrien
57659243Sobrienstatic int
577167465Smplocate(struct pelem *pe, char *key)
57859243Sobrien{
579145479Smp    int i;
580145479Smp    char *realkey;
581167465Smp    char keybuf[MAXPATHLEN+1];/*FIXBUF*/
58259243Sobrien
58359243Sobrien    if (sflag) {
58459243Sobrien	realkey = keybuf;
58559243Sobrien	(void) strcpy(realkey, key);
58659243Sobrien	(void) strcat(realkey, pe->psuf);
58759243Sobrien    } else
58859243Sobrien	realkey = key;
58959243Sobrien    for (i = 0; i < pe->pdirs; i++)
59059243Sobrien	if (strcmp(pe->pdir[i], realkey) == 0)
59159243Sobrien	    break;
59259243Sobrien    return((i < pe->pdirs) ? i : -1);
59359243Sobrien}
59459243Sobrien#endif
595