1 /* @(#)alias.c	1.18 16/08/10 Copyright 1986-2016 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)alias.c	1.18 16/08/10 Copyright 1986-2016 J. Schilling";
6 #endif
7 /*
8  *	Copyright (c) 1986-2016 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 <schily/stdio.h>
25 #include "bsh.h"
26 #include "btab.h"
27 #include "abbrev.h"
28 #include "strsubs.h"
29 #include "str.h"
30 
31 extern	abidx_t	deftab;
32 
33 LOCAL	int	parselocal	__PR((const char *arg, void *valp, int *pac, char *const **pav, const char *opt));
34 EXPORT	void	balias		__PR((Argvec * vp, FILE ** std, int flag));
35 EXPORT	void	bunalias	__PR((Argvec * vp, FILE ** std, int flag));
36 
37 
38 /* ARGSUSED */
39 LOCAL int
parselocal(arg,valp,pac,pav,opt)40 parselocal(arg, valp, pac, pav, opt)
41 	const char	*arg;
42 	void		*valp;
43 	int		*pac;
44 	char	*const	**pav;
45 	const char	*opt;
46 {
47 	char	*op = *pav[0];
48 	char	c;
49 
50 	while ((c = *(++op)) != '\0') {
51 		if (c == 'l')
52 			*(int *)valp = TRUE;
53 		else if (c == 'g')
54 			*(int *)valp = FALSE;
55 	}
56 	return (1);
57 }
58 
59 
60 /*
61  * alias		list all
62  * alias name		list name
63  * alias name=value	push new alias
64  * alias -a		create non-begin type alias
65  * alias -p		list with "alias " prefix (bash/ksh93)
66  * alias -g		use .global aliases
67  * alias -l		use .local aliases
68  * alias -p -g		push .global aliases
69  * alias -p -l		push .local aliases
70  * alias -e		everlasting aliases ???
71  * alias -r		reload from .globals/.locals
72  * alias -R		list in raw mode
73  *
74  * alias -t		outdated ksh93
75  * alias -x		outdated ksh93
76  */
77 /* ARGSUSED */
78 EXPORT void
balias(vp,std,flag)79 balias(vp, std, flag)
80 	Argvec	*vp;
81 	FILE	*std[];
82 	int	flag;
83 {
84 	int	ac;
85 	char	* const *av;
86 	char	*opt	= "a,e,g~,l~,p,r,reload,R,raw";
87 	int	islocal = -1;
88 	BOOL	allflag = FALSE;	/* -a non-begin type alias (#a) */
89 	BOOL	persist = FALSE;	/* -e persistent (everlasing) macros */
90 	BOOL	doglobal = FALSE;	/* -g persistent global aliases */
91 	BOOL	dolocal = FALSE;	/* -l persistent local aliases */
92 	BOOL	pflag = FALSE;		/* -p push or list parsable */
93 	BOOL	doreload = FALSE;	/* -r reload from persistent definitions */
94 	BOOL	doraw = FALSE;		/* -R/-raw list in raw mode */
95 	abidx_t	tab;
96 	int	aflags = 0;		/* All (non-begin) type alias */
97 	int	lflags = 0;		/* List flags */
98 	int	pflags = 0;		/* List parseable flags */
99 
100 	ac = vp->av_ac - 1;		/* set values */
101 	av = &vp->av_av[1];
102 
103 	if (getargs(&ac, &av, opt, &allflag, &persist,
104 				parselocal, &islocal,
105 				parselocal, &islocal,
106 				&pflag,
107 				&doreload, &doreload,
108 				&doraw, &doraw) < 0) {
109 		if (av[0][0] == '-') {
110 			fprintf(std[2], ebadopt, vp->av_av[0], av[0]);
111 			fprintf(std[2], "%s", nl);
112 			busage(vp, std);
113 			ex_status = 1;
114 			return;
115 		}
116 	}
117 	if (islocal > 0)
118 		dolocal = TRUE;
119 	else if (islocal == 0)
120 		doglobal = TRUE;
121 	tab = dolocal?LOCAL_AB:GLOBAL_AB;
122 	if (!allflag)
123 		aflags = AB_BEGIN;
124 	lflags = (persist?AB_PERSIST:0) |
125 			(doraw?0:AB_POSIX) |
126 			(pflag?AB_PARSE|AB_ALL:0);
127 	if (pflag) {
128 		if (dolocal)
129 			pflags |= AB_PLOCAL;
130 		else
131 			pflags |= AB_PGLOBAL;
132 	}
133 
134 	if (doreload) {
135 		char	*fname;
136 
137 		if (ac > 0) {
138 			wrong_args(vp, std);
139 			return;
140 		}
141 		fname = ab_gname(tab);
142 		if (fname)
143 			ab_use(tab, fname);
144 		return;
145 	}
146 	if (ac == 0) {
147 		ab_dump(tab, std[1], lflags | pflags);
148 		return;
149 	}
150 	for (; ac > 0; ac--, av++) {
151 		char	*a1;
152 		char	*val;
153 
154 		a1 = av[0];
155 		val = strchr(a1, '=');
156 		if (val) {
157 			*val++ = '\0';
158 			if (pflag || (doglobal == 0 && dolocal == 0))
159 				ab_push(tab, makestr(a1), makestr(val), aflags);
160 			else
161 				ab_insert(tab, makestr(a1), makestr(val), aflags);
162 		} else {
163 			ab_list(tab, a1, std[1], lflags | pflags);
164 		}
165 	}
166 }
167 
168 /*
169  * unalias name		pop alias
170  * unalias -a		pop all aliases
171  * unalias -g		use .global aliases
172  * unalias -l		use .local aliases
173  * unalias -p -g	pop .global aliases
174  * unalias -p -l	pop .local aliases
175  * unalias -e		everlasting aliases ???
176  */
177 /* ARGSUSED */
178 EXPORT void
bunalias(vp,std,flag)179 bunalias(vp, std, flag)
180 	Argvec	*vp;
181 	FILE	*std[];
182 	int	flag;
183 {
184 	int	ac;
185 	char	* const *av;
186 	char	*opt	= "a,g~,l~,p";
187 	int	islocal = -1;
188 	BOOL	allflag = FALSE;	/* -a remove all aliases */
189 	BOOL	doglobal = FALSE;	/* -g persistent global aliases */
190 	BOOL	dolocal = FALSE;	/* -l persistent local aliases */
191 	BOOL	pflag = FALSE;		/* -p pop all (non-persistent) */
192 	abidx_t	tab;
193 
194 	ac = vp->av_ac - 1;		/* set values */
195 	av = &vp->av_av[1];
196 
197 	if (getargs(&ac, &av, opt, &allflag,
198 				parselocal, &islocal,
199 				parselocal, &islocal,
200 				&pflag) < 0) {
201 		fprintf(std[2], ebadopt, vp->av_av[0], av[0]);
202 		fprintf(std[2], "%s", nl);
203 		busage(vp, std);
204 		ex_status = 1;
205 		return;
206 	}
207 	if (islocal > 0)
208 		dolocal = TRUE;
209 	else if (islocal == 0)
210 		doglobal = TRUE;
211 	tab = dolocal?LOCAL_AB:GLOBAL_AB;
212 
213 	if (ac < 1) {
214 		if (allflag) {
215 			ab_deleteall(tab, AB_INTR | AB_POP);
216 			return;
217 		}
218 		wrong_args(vp, std);
219 		return;
220 	}
221 	if (allflag) {
222 		wrong_args(vp, std);
223 		return;
224 	}
225 	for (; ac > 0; ac--, av++) {
226 		char	*a1 = av[0];
227 
228 		if (pflag || (doglobal == 0 && dolocal == 0))
229 			ab_delete(tab, a1, AB_POP | AB_POPALL);
230 		else
231 			ab_delete(tab, a1, 0);
232 	}
233 }
234