Kernel part of bluetooth stack ported by Dmitry Komissaroff. Very much work
[dragonfly.git] / contrib / tcsh / ma.setp.c
blobd515d0f5c1e3d813095f641902b1d7c2b0d0e820
1 /*
2 * Copyright (c) 1990 Carnegie Mellon University
3 * All Rights Reserved.
4 *
5 * Permission to use, copy, modify and distribute this software and its
6 * documentation is hereby granted, provided that both the copyright
7 * notice and this permission notice appear in all copies of the
8 * software, derivative works or modified versions, and any portions
9 * thereof, and that both notices appear in supporting documentation.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY
12 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
14 * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT,
15 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
16 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
17 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * Users of this software agree to return to Carnegie Mellon any
21 * improvements or extensions that they make and grant Carnegie the
22 * rights to redistribute these changes.
24 * Export of this software is permitted only after complying with the
25 * regulations of the U.S. Deptartment of Commerce relating to the
26 * Export of Technical Data.
29 * setpath --- smart interface for setting path variables
31 * usage: setpath(paths, cmds, localsyspath, dosuffix, printerrors)
32 * char **paths, **cmds, *localsyspath;
33 * int dosuffix, printerrors;
35 * The 'paths' argument is a list of pointers to path lists of the
36 * form "name=value" where name is the name of the path and value
37 * is a colon separated list of directories. There can never be
38 * more than MAXDIRS (64) directories in a path.
40 * The 'cmds' argument may be a sequence of any of the following:
41 * -r reset path to default
42 * -i newpath insert newpath before localsyspath
43 * -ia oldpath newpath insert newpath after oldpath
44 * -ib oldpath newpath insert newpath before oldpath
45 * -i# newpath insert newpath at position #
46 * -d oldpath delete oldpath
47 * -d# delete path at position #
48 * -c oldpath newpath change oldpath to newpath
49 * -c# newpath change position # to newpath
51 * The "-i newpath" command is equivilent to "-ib 'localsyspath' newpath".
53 * If 'dosuffix' is true, the appropriate suffix will be added to
54 * all command operands for any system path in 'paths'.
56 * Both of the 'paths' and 'cmds' lists are terminated by a NULL
57 * entry.
59 * if 'printerrors' is true, setpath will printf error diagnostics.
61 * WARNING !!!: Under no circumstances should anyone change this
62 * module without fully understanding the impact on the C shell.
63 * The C shell has it's own malloc and printf routines and this
64 * module was carefully written taking that into account. Do not
65 * use any stdio routines from this module except printf.
67 **********************************************************************
68 * HISTORY
70 * Revision 1.4 90/12/11 17:58:44 mja
71 * Add copyright/disclaimer for distribution.
73 * 05-Jun-88 Glenn Marcy (gm0w) at Carnegie-Mellon University
74 * Make all non-entry points static.
76 * 30-Apr-88 Glenn Marcy (gm0w) at Carnegie-Mellon University
77 * Added -r switch to reset paths to their default values.
79 * 06-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
80 * Created from old setpath program for the shell.
82 **********************************************************************
84 #include "sh.h"
85 RCSID("$Id: ma.setp.c,v 1.12 1996/04/26 19:18:36 christos Exp $")
87 #ifdef MACH
89 #define MAXDIRS 64 /* max directories on a path */
90 #ifndef NULL
91 # define NULL 0
92 #endif
94 static int npaths; /* # pathlist arguments */
96 static struct pelem {
97 struct pelem *pnext; /* pointer to next path */
98 char *pname; /* name of pathlist */
99 char *psuf; /* suffix for pathlist */
100 char *pdef; /* default for pathlist */
101 int pdirs; /* # directories on each pathlist */
102 char *pdir[MAXDIRS]; /* directory names for each pathlist */
103 } *pathhead = NULL;
105 static struct {
106 char *name;
107 char *suffix;
108 char *defalt;
109 } syspath[] = {
110 "PATH", "/bin", ":/usr/ucb:/bin:/usr/bin",
111 "CPATH", "/include", ":/usr/include",
112 "LPATH", "/lib", ":/lib:/usr/lib",
113 "MPATH", "/man", ":/usr/man",
114 "EPATH", "/maclib", "",
115 0, 0, 0
118 static int sflag;
119 static int eflag;
121 #define INVALID { \
122 if (eflag) xprintf(CGETS(10, 1, \
123 "setpath: invalid command '%s'.\n"), cmd); \
124 freepaths(); \
125 return(-1); \
128 #define TOOFEW { \
129 if (eflag) xprintf(CGETS(10, 2, \
130 "setpath: insufficient arguments to command '%s'.\n"), cmd); \
131 freepaths(); \
132 return(-1); \
135 static int initpaths __P((char **));
136 static void savepaths __P((char **));
137 static void freepaths __P((void));
138 static void rcmd __P((char *));
139 static void icmd __P((char *, char *));
140 static void iacmd __P((char *, char *));
141 static void ibcmd __P((char *, char *));
142 static void incmd __P((char *, int));
143 static void insert __P((struct pelem *, int, char *));
144 static void dcmd __P((char *));
145 static void dncmd __P((int));
146 static void delete __P((struct pelem *, int));
147 static void ccmd __P((char *, char *));
148 static void cncmd __P((char *, int));
149 static void change __P((struct pelem *, int, char *));
150 static int locate __P((struct pelem *, char *));
155 setpath(paths, cmds, localsyspath, dosuffix, printerrors)
156 register char **paths, **cmds, *localsyspath;
157 int dosuffix, printerrors;
159 register char *cmd, *cmd1, *cmd2;
160 register int ncmd;
162 sflag = dosuffix;
163 eflag = printerrors;
164 if (initpaths(paths) < 0)
165 return(-1);
166 if (npaths == 0)
167 return(0);
168 for (ncmd = 0; cmd = cmds[ncmd]; ncmd++) {
169 if (cmd[0] != '-')
170 INVALID;
171 cmd1 = cmds[ncmd+1];
172 cmd2 = cmds[ncmd+2];
173 switch (cmd[1]) {
174 case 'r':
175 if (cmd[2] != '\0')
176 INVALID;
177 rcmd(localsyspath);
178 break;
179 case 'i':
180 if (cmd[2] == '\0') {
181 ncmd++;
182 if (cmd1 == NULL) TOOFEW;
183 icmd(cmd1, localsyspath);
184 } else if (isdigit(cmd[2])) {
185 ncmd++;
186 if (cmd1 == NULL) TOOFEW;
187 incmd(cmd1, atoi(cmd+2));
188 } else if (cmd[3] != '\0' || (cmd[2] != 'a' && cmd[2] != 'b')) {
189 INVALID;
190 } else {
191 ncmd += 2;
192 if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
193 if (cmd[2] == 'a')
194 iacmd(cmd1, cmd2);
195 else
196 ibcmd(cmd1, cmd2);
198 break;
199 case 'd':
200 if (cmd[2] == '\0') {
201 ncmd++;
202 if (cmd1 == NULL) TOOFEW;
203 dcmd(cmd1);
204 } else if (isdigit(cmd[2]))
205 dncmd(atoi(cmd+2));
206 else {
207 INVALID;
209 break;
210 case 'c':
211 if (cmd[2] == '\0') {
212 ncmd += 2;
213 if (cmd1 == NULL || cmd2 == NULL) TOOFEW;
214 ccmd(cmd1, cmd2);
215 } else if (isdigit(cmd[2])) {
216 ncmd++;
217 if (cmd1 == NULL) TOOFEW;
218 cncmd(cmd1, atoi(cmd+2));
219 } else {
220 INVALID;
222 break;
223 default:
224 INVALID;
227 savepaths(paths);
228 freepaths();
229 return(0);
232 static int
233 initpaths(paths)
234 register char **paths;
236 register char *path, *val, *p, *q;
237 register int i, done;
238 register struct pelem *pe, *pathend;
240 freepaths();
241 for (npaths = 0; path = paths[npaths]; npaths++) {
242 val = index(path, '=');
243 if (val == NULL) {
244 if (eflag)
245 xprintf(CGETS(10, 3,
246 "setpath: value missing in path '%s'\n"), path);
247 freepaths();
248 return(-1);
250 *val++ = '\0';
251 pe = (struct pelem *)xmalloc((unsigned)(sizeof(struct pelem)));
252 setzero((char *) pe, sizeof(struct pelem));
253 if (pathhead == NULL)
254 pathhead = pathend = pe;
255 else {
256 pathend->pnext = pe;
257 pathend = pe;
259 p = strsave(path);
260 pe->pname = p;
261 pe->psuf = "";
262 pe->pdef = "";
263 for (i = 0; syspath[i].name; i++)
264 if (strcmp(pe->pname, syspath[i].name) == 0) {
265 pe->psuf = syspath[i].suffix;
266 pe->pdef = syspath[i].defalt;
267 break;
269 q = val;
270 for (;;) {
271 q = index(p = q, ':');
272 done = (q == NULL);
273 if (!done)
274 *q++ = '\0';
275 p = strsave(p);
276 pe->pdir[pe->pdirs] = p;
277 pe->pdirs++;
278 if (done)
279 break;
282 return(0);
285 static void
286 savepaths(paths)
287 register char **paths;
289 register char *p, *q;
290 register int npath, i, len;
291 register struct pelem *pe;
293 for (npath = 0, pe = pathhead; pe; npath++, pe = pe->pnext) {
294 len = strlen(pe->pname) + 1;
295 if (pe->pdirs == 0)
296 len++;
297 else for (i = 0; i < pe->pdirs; i++)
298 len += strlen(pe->pdir[i]) + 1;
299 p = xmalloc((unsigned)len);
300 paths[npath] = p;
301 for (q = pe->pname; *p = *q; p++, q++);
302 *p++ = '=';
303 if (pe->pdirs != 0) {
304 for (i = 0; i < pe->pdirs; i++) {
305 for (q = pe->pdir[i]; *p = *q; p++, q++);
306 *p++ = ':';
308 p--;
310 *p = '\0';
314 static void
315 freepaths()
317 register char *p;
318 register int i;
319 register struct pelem *pe;
321 if (npaths == 0 || pathhead == NULL)
322 return;
323 while (pe = pathhead) {
324 if (pe->pname) {
325 for (i = 0; i < pe->pdirs; i++) {
326 if (pe->pdir[i] == NULL)
327 continue;
328 p = pe->pdir[i];
329 pe->pdir[i] = NULL;
330 xfree((ptr_t) p);
332 pe->pdirs = 0;
333 p = pe->pname;
334 pe->pname = NULL;
335 xfree((ptr_t) p);
337 pathhead = pe->pnext;
338 xfree((ptr_t) pe);
340 npaths = 0;
343 /***********************************************
344 *** R E S E T A P A T H N A M E ***
345 ***********************************************/
347 static void
348 rcmd(localsyspath) /* reset path with localsyspath */
349 char *localsyspath;
351 register int n, done;
352 register char *new, *p;
353 register struct pelem *pe;
354 char newbuf[MAXPATHLEN+1];
356 for (pe = pathhead; pe; pe = pe->pnext) {
357 new = newbuf;
358 *new = '\0';
359 if (localsyspath != NULL) {
360 *new = ':';
361 (void) strcpy(new + 1, localsyspath);
362 (void) strcat(new, pe->psuf);
364 (void) strcat(new, pe->pdef);
365 for (n = 0; n < pe->pdirs; n++) {
366 if (pe->pdir[n] == NULL)
367 continue;
368 p = pe->pdir[n];
369 pe->pdir[n] = NULL;
370 xfree((ptr_t) p);
372 pe->pdirs = 0;
373 for (;;) {
374 new = index(p = new, ':');
375 done = (new == NULL);
376 if (!done)
377 *new++ = '\0';
378 p = strsave(p);
379 pe->pdir[pe->pdirs] = p;
380 pe->pdirs++;
381 if (done)
382 break;
387 /***********************************************
388 *** I N S E R T A P A T H N A M E ***
389 ***********************************************/
391 static void
392 icmd(path, localsyspath) /* insert path before localsyspath */
393 char *path, *localsyspath;
395 register int n;
396 register char *new;
397 register struct pelem *pe;
398 char newbuf[MAXPATHLEN+1];
400 for (pe = pathhead; pe; pe = pe->pnext) {
401 if (sflag)
402 new = localsyspath;
403 else {
404 new = newbuf;
405 (void) strcpy(new, localsyspath);
406 (void) strcat(new, pe->psuf);
408 n = locate(pe, new);
409 if (n >= 0)
410 insert(pe, n, path);
411 else
412 insert(pe, 0, path);
416 static void
417 iacmd(inpath, path) /* insert path after inpath */
418 char *inpath, *path;
420 register int n;
421 register struct pelem *pe;
423 for (pe = pathhead; pe; pe = pe->pnext) {
424 n = locate(pe, inpath);
425 if (n >= 0)
426 insert(pe, n + 1, path);
427 else
428 xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
429 inpath, pe->pname);
433 static void
434 ibcmd(inpath, path) /* insert path before inpath */
435 char *inpath, *path;
437 register int n;
438 register struct pelem *pe;
440 for (pe = pathhead; pe; pe = pe->pnext) {
441 n = locate(pe, inpath);
442 if (n >= 0)
443 insert(pe, n, path);
444 else
445 xprintf(CGETS(10, 4, "setpath: %s not found in %s\n",
446 inpath, pe->pname));
450 static void
451 incmd(path, n) /* insert path at position n */
452 char *path;
453 int n;
455 register struct pelem *pe;
457 for (pe = pathhead; pe; pe = pe->pnext)
458 insert(pe, n, path);
461 static void
462 insert(pe, loc, key)
463 register struct pelem *pe;
464 register int loc;
465 register char *key;
467 register int i;
468 register char *new;
469 char newbuf[2000];
471 if (sflag) { /* add suffix */
472 new = newbuf;
473 (void) strcpy(new, key);
474 (void) strcat(new, pe->psuf);
475 } else
476 new = key;
477 new = strsave(new);
478 for (i = pe->pdirs; i > loc; --i)
479 pe->pdir[i] = pe->pdir[i-1];
480 if (loc > pe->pdirs)
481 loc = pe->pdirs;
482 pe->pdir[loc] = new;
483 pe->pdirs++;
486 /***********************************************
487 *** D E L E T E A P A T H N A M E ***
488 ***********************************************/
490 static void
491 dcmd(path) /* delete path */
492 char *path;
494 register int n;
495 register struct pelem *pe;
497 for (pe = pathhead; pe; pe = pe->pnext) {
498 n = locate(pe, path);
499 if (n >= 0)
500 delete(pe, n);
501 else
502 xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
503 path, pe->pname);
507 static void
508 dncmd(n) /* delete at position n */
509 int n;
511 register struct pelem *pe;
513 for (pe = pathhead; pe; pe = pe->pnext) {
514 if (n < pe->pdirs)
515 delete(pe, n);
516 else
517 xprintf(CGETS(10, 5,
518 "setpath: %d not valid position in %s\n"),
519 n, pe->pname);
523 static void
524 delete(pe, n)
525 register struct pelem *pe;
526 int n;
528 register int d;
530 xfree((ptr_t) (pe->pdir[n]));
531 for (d = n; d < pe->pdirs - 1; d++)
532 pe->pdir[d] = pe->pdir[d+1];
533 --pe->pdirs;
536 /***********************************************
537 *** C H A N G E A P A T H N A M E ***
538 ***********************************************/
540 static void
541 ccmd(inpath, path) /* change inpath to path */
542 char *inpath, *path;
544 register int n;
545 register struct pelem *pe;
547 for (pe = pathhead; pe; pe = pe->pnext) {
548 n = locate(pe, inpath);
549 if (n >= 0)
550 change(pe, n, path);
551 else
552 xprintf(CGETS(10, 4, "setpath: %s not found in %s\n"),
553 inpath, pe->pname);
557 static void
558 cncmd(path, n) /* change at position n to path */
559 char *path;
560 int n;
562 register struct pelem *pe;
564 for (pe = pathhead; pe; pe = pe->pnext) {
565 if (n < pe->pdirs)
566 change(pe, n, path);
567 else
568 xprintf(CGETS(10, 5,
569 "setpath: %d not valid position in %s\n"),
570 n, pe->pname);
574 static void
575 change(pe, loc, key)
576 register struct pelem *pe;
577 register int loc;
578 register char *key;
580 register char *new;
581 char newbuf[MAXPATHLEN+1];
583 if (sflag) { /* append suffix */
584 new = newbuf;
585 (void) strcpy(new, key);
586 (void) strcat(new, pe->psuf);
587 } else
588 new = key;
589 new = strsave(new);
590 xfree((ptr_t) (pe->pdir[loc]));
591 pe->pdir[loc] = new;
594 /***************************************
595 *** F I N D P A T H N A M E ***
596 ***************************************/
598 static int
599 locate(pe, key)
600 register struct pelem *pe;
601 register char *key;
603 register int i;
604 register char *realkey;
605 char keybuf[MAXPATHLEN+1];
607 if (sflag) {
608 realkey = keybuf;
609 (void) strcpy(realkey, key);
610 (void) strcat(realkey, pe->psuf);
611 } else
612 realkey = key;
613 for (i = 0; i < pe->pdirs; i++)
614 if (strcmp(pe->pdir[i], realkey) == 0)
615 break;
616 return((i < pe->pdirs) ? i : -1);
618 #endif