1 /* @(#)alias.c	1.13 18/07/07 Copyright 1986-2018 J. Schilling */
2 #include <schily/mconfig.h>
3 static	UConst char sccsid[] =
4 	"@(#)alias.c	1.13 18/07/07 Copyright 1986-2018 J. Schilling";
5 /*
6  *	The built-in commands "alias" and "unalias".
7  *
8  *	Copyright (c) 1986-2018 J. Schilling
9  */
10 /*
11  * The contents of this file are subject to the terms of the
12  * Common Development and Distribution License, Version 1.0 only
13  * (the "License").  You may not use this file except in compliance
14  * with the License.
15  *
16  * See the file CDDL.Schily.txt in this distribution for details.
17  * A copy of the CDDL is also available via the Internet at
18  * http://www.opensource.org/licenses/cddl1.txt
19  *
20  * When distributing Covered Code, include this CDDL HEADER in each
21  * file and include the License file CDDL.Schily.txt from this distribution.
22  */
23 
24 #include "defs.h"
25 #include "abbrev.h"
26 
27 #undef	tab
28 #define	LOCAL	static
29 
30 void
sysalias(argc,argv)31 sysalias(argc, argv)
32 	int	argc;
33 	unsigned char	**argv;
34 {
35 	struct optv optv;
36 	int	c;
37 	int	ret = 1;
38 	int	badflag = 0;	/* -g/-l with {local!global}aliases disabled */
39 	int	allflag = 0;	/* -a non-begin type alias (#a) */
40 	int	persist = 0;	/* -e persistent (everlasing) macros */
41 	int	doglobal = 0;	/* -g persistent global aliases */
42 	int	dolocal = 0;	/* -l persistent local aliases */
43 	int	pflag = 0;	/* -p push or list parsable */
44 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
45 	int	doreload = 0;	/* -r reload from persistent definitions */
46 #endif
47 	int	doraw = 0;	/* -R/-raw list in raw mode */
48 	abidx_t	tab;
49 	int	aflags = 0;	/* All (non-begin) type alias */
50 	int	lflags = 0;	/* List flags */
51 	int	pflags = 0;	/* List parseable flags */
52 	unsigned char	*a1;
53 	unsigned char	o[3];
54 
55 	optinit(&optv);
56 	o[0] = '-';
57 	o[2] = '\0';
58 	while ((c = optget(argc, argv, &optv,
59 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
60 			    "()aeglprR(raw)")) != -1) {
61 #else
62 			    "()aepR(raw)")) != -1) {
63 #endif
64 		switch (c) {
65 		case 'a':
66 			allflag++;
67 			break;
68 		case 'e':
69 			persist++;
70 			break;
71 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
72 		case 'g':
73 			if ((flags2 & globalaliasflg) == 0) {
74 				o[1] = c;
75 				badflag++;
76 				goto err;
77 			}
78 			dolocal = 0;
79 			doglobal++;
80 			break;
81 		case 'l':
82 			if ((flags2 & localaliasflg) == 0) {
83 				o[1] = c;
84 				badflag++;
85 				goto err;
86 			}
87 			doglobal = 0;
88 			dolocal++;
89 			break;
90 		case 'r':
91 			doreload++;
92 			break;
93 #endif
94 		case 'p':
95 			pflag++;
96 			break;
97 		case 'R':
98 			doraw++;
99 			break;
100 		case '?':
101 			gfailure((unsigned char *)usage, aliasuse);
102 			goto err;
103 		}
104 	}
105 	ret = 0;
106 	c = optv.optind;
107 err:
108 	if (badflag) {
109 		failure(o, badopt);
110 		return;
111 	}
112 	if (ret)
113 		return;
114 
115 	tab = dolocal?LOCAL_AB:GLOBAL_AB;
116 	if (!allflag)
117 		aflags = AB_BEGIN;
118 	lflags = (persist?AB_PERSIST:0) |
119 			(doraw?0:AB_POSIX) |
120 			(pflag?AB_PARSE|AB_ALL:0);
121 	if (pflag) {
122 		if (dolocal)
123 			pflags |= AB_PLOCAL;
124 		else if ((flags2 & globalaliasflg) != 0)
125 			pflags |= AB_PGLOBAL;
126 	}
127 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
128 	if (doreload) {
129 		char	*fname;
130 
131 		if (c < argc) {
132 			failure(argv[0], toomanyargs);
133 			return;
134 		}
135 		fname = ab_gname(tab);
136 		ab_use(tab, fname);
137 		return;
138 	}
139 #endif
140 	if (c >= argc) {
141 		/*
142 		 * Just list everysthing, never fail.
143 		 */
144 		ab_dump(tab, 1, lflags | pflags);
145 		return;
146 	}
147 	for (; c < argc; c++) {
148 		unsigned char *val;
149 
150 		a1 = argv[c];
151 		val = UC strchr((char *)a1, '=');
152 		if (val) {
153 			*val++ = '\0';
154 			if (pflag || (doglobal == 0 && dolocal == 0)) {
155 				if (!ab_push(tab,
156 						(char *)make(a1),
157 						(char *)make(val),
158 						aflags)) {
159 					failure(a1, "cannot push alias");
160 				}
161 
162 			} else {
163 				if (!ab_insert(tab,
164 						(char *)make(a1),
165 						(char *)make(val),
166 						aflags)) {
167 					failure(a1, "cannot define alias");
168 				}
169 			}
170 		} else {
171 			if (!ab_list(tab, (char *)a1, 1, lflags | pflags))
172 				failure(a1, "alias not found");
173 		}
174 	}
175 }
176 
177 void
sysunalias(argc,argv)178 sysunalias(argc, argv)
179 	int	argc;
180 	unsigned char	**argv;
181 {
182 	struct optv optv;
183 	int	c;
184 	int	ret = 1;
185 	int	badflag = 0;	/* -g/-l with {local!global}aliases disabled */
186 	int	allflag = 0;	/* -a remove all aliases */
187 	int	doglobal = 0;	/* -g persistent global aliases */
188 	int	dolocal = 0;	/* -l persistent local aliases */
189 	int	pflag = 0;	/* -p pop all (non-persistent) */
190 
191 	abidx_t	tab;
192 	unsigned char	*a1;
193 	unsigned char	o[3];
194 
195 	optinit(&optv);
196 	o[0] = '-';
197 	o[2] = '\0';
198 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
199 	while ((c = optget(argc, argv, &optv, "aglp")) != -1) {
200 #else
201 	while ((c = optget(argc, argv, &optv, "ap")) != -1) {
202 #endif
203 		switch (c) {
204 		case 'a':
205 			allflag++;
206 			break;
207 #if	defined(DO_GLOBALALIASES) || defined(DO_LOCALALIASES)
208 		case 'g':
209 			if ((flags2 & globalaliasflg) == 0) {
210 				o[1] = c;
211 				badflag++;
212 				goto err;
213 			}
214 			dolocal = 0;
215 			doglobal++;
216 			break;
217 		case 'l':
218 			if ((flags2 & localaliasflg) == 0) {
219 				o[1] = c;
220 				badflag++;
221 				goto err;
222 			}
223 			doglobal = 0;
224 			dolocal++;
225 			break;
226 #endif
227 		case 'p':
228 			pflag++;
229 			break;
230 		case '?':
231 			gfailure((unsigned char *)usage, unaliasuse);
232 			goto err;
233 		}
234 	}
235 	ret = 0;
236 	c = optv.optind;
237 err:
238 	if (badflag) {
239 		failure(o, badopt);
240 		return;
241 	}
242 	if (ret)
243 		return;
244 
245 	tab = dolocal?LOCAL_AB:GLOBAL_AB;
246 	if (c >= argc) {
247 		if (allflag) {
248 			ab_deleteall(tab, AB_INTR | AB_POP);
249 			return;
250 		}
251 		gfailure((unsigned char *)usage, unaliasuse);
252 		return;
253 	}
254 	for (; c < argc; c++) {
255 		BOOL	r;
256 
257 		a1 = argv[c];
258 		if (pflag || (doglobal == 0 && dolocal == 0))
259 			r = ab_delete(tab, (char *)a1, AB_POP | AB_POPALL);
260 		else
261 			r = ab_delete(tab, (char *)a1, 0);
262 		if (!r)
263 			failure(a1, "alias not found");
264 	}
265 }
266