1 /*************************************************************
2  *  $Id: alias.c,v 1.5 2003/05/24 15:26:32 marcolz Exp $
3  *
4  *  alias.c
5  *
6  *  Maintain the user aliases.
7  *
8  */
9 /*******************************************************
10  *  Copyright (C) Doug Hay, 1991.
11  *  Permission to use and abuse this code, as long
12  *  as this copyright notice stays intact and with the
13  *  code.  No warranty implied.  This code supplied as is.
14  *******************************************************/
15 
16 #include	"config.h"
17 
18 #include	<ctype.h>
19 #include	<stdio.h>
20 #ifdef	HAVE_STRING_H
21 #include	<string.h>
22 #endif				/* HAVE_STRING_H */
23 #ifdef	HAVE_STRINGS_H
24 #include	<strings.h>
25 #endif				/* HAVE_STRINGS_H */
26 
27 #ifdef	HAVE_STDLIB_H
28 #include	<stdlib.h>
29 #else				/* not HAVE_STDLIB_H */
30 #ifdef	HAVE_MALLOC_H
31 #include	<malloc.h>
32 #else				/* not HAVE_MALLOC_H */
33 char		*calloc();
34 #endif				/* not HAVE_MALLOC_H */
35 #endif				/* not HAVE_STDLIB_H */
36 
37 #include	"alias.h"
38 #include	"print.h"
39 
40 static alias_t *alias_list;
41 static int	numaliases = 0;
42 static int	maxaliases = 0;
43 
44 static alias_t *find_alias_loc(const char *buf);
45 
46 /***********************************
47  * clear_alias_marks
48  *
49  * Clear the alias marks so they can be reused.
50  */
51 void
clear_alias_marks()52 clear_alias_marks()
53 {
54 	alias_t		*ap;
55 	int		i;
56 
57 	for (ap = alias_list, i = 0; (ap && i < numaliases); ap++, i++)
58 		ap->mark = 0;
59 }
60 
61 /***********************************
62  * find_alias_loc
63  *
64  * Find the matching alias, if it exists.
65  */
66 static alias_t *
find_alias_loc(buf)67 find_alias_loc(buf)
68 	const char	*buf;
69 {
70 	alias_t		*ap;
71 	int		i;
72 
73 	for (ap = alias_list, i = 0; ap && i < numaliases; ap++, i++) {
74 		if (ap->alias && !strcmp(ap->alias, buf))
75 			return (ap);
76 	}
77 	return ((alias_t *) 0);
78 }
79 
80 /***********************************
81  * find_alias
82  *
83  * Find the alias, if it exists, and return a
84  * pointer to it's command, if it hasn't been
85  * marked as being used before.
86  */
87 char	*
find_alias(buf)88 find_alias(buf)
89 	const char	*buf;
90 {
91 	alias_t		*ap;
92 
93 	if ((ap = find_alias_loc(buf)) && !ap->mark) {
94 		ap->mark = 1;
95 		return (ap->command);
96 	}
97 	return ((char *)0);
98 }
99 
100 
101 /***********************************
102  * cmd_alias
103  *
104  * The alias command.
105  */
106 void
cmd_alias(alias,sub)107 cmd_alias(alias, sub)
108 	const char	*alias;
109 	int sub		__attribute__((unused));
110 {
111 	char		com_buf[1024];
112 	char		*command;
113 	char		*cp;
114 	alias_t		*ap;
115 	int		i;
116 
117 	/* Skip over trailing space. */
118 	while (isspace(*alias))
119 		alias++;
120 
121 	/* If no alias is specified, print all the aliases. */
122 	if (!*alias) {
123 		if (!numaliases)
124 			prt("No aliases defined.\n");
125 		else
126 			for (ap = alias_list, i = 0; ap && i < numaliases; ap++, i++)
127 				prt("alias %s \"%s\"\n", ap->alias, ap->command);
128 		return;
129 	}
130 	strncpy(com_buf, alias, sizeof(com_buf));
131 	command = com_buf;
132 	while (*command && !isspace(*command))
133 		command++;
134 	if (*command) {
135 		*command++ = '\0';
136 		while (isspace(*command))
137 			command++;
138 		/* String "'s from the command */
139 		if ('\"' == *command) {
140 			cp = ++command;
141 			while (*cp)
142 			{
143 				if ('\\' == *cp)
144 				{
145 					if (!*++cp)
146 						break;
147 				} else if ('\"' == *cp)
148 					break;
149 
150 				cp++;
151 			}
152 			if ('"' == *cp)
153 				*cp = '\0';
154 		}
155 	}
156 	/* We prevent certain keywords from being aliased. */
157 	/* Like, alias, unalias */
158 	if (!strcmp(com_buf, "alias") || !strcmp(com_buf, "unalias")) {
159 		eprt("Too dangerous to allow that\n");
160 		return;
161 	}
162 	/* If we find a matching alias, either print it or replace it. */
163 	if ((ap = find_alias_loc(com_buf))) {
164 		if (*command) {
165 			free(ap->command);
166 		} else {
167 			prt("alias %s \"%s\"\n", ap->alias, ap->command);
168 			return;
169 		}
170 	} else {
171 		if (!*command) {
172 			prt("%s undefined.\n", com_buf);
173 			return;
174 		}
175 		numaliases++;
176 		if (numaliases >= maxaliases) {
177 			alias_t         *tp;
178 
179 			maxaliases += 10;
180 			if (!(tp = (alias_t *) calloc((unsigned)maxaliases,
181 							sizeof(alias_t))))
182 				exit(1);
183 			if (alias_list)
184 				bcopy((char *)alias_list, (char *)tp,
185 					((numaliases - 1) * sizeof(alias_t)));
186 			free((char *)alias_list);
187 			alias_list = tp;
188 		}
189 		ap = &alias_list[numaliases - 1];
190 		ap->alias = strdup(com_buf);
191 	}
192 	ap->command = strdup(command);
193 	return;
194 }
195 
196 /***********************************
197  * cmd_unalias
198  *
199  * The unalias command.
200  */
201 void
cmd_unalias(buf,sub)202 cmd_unalias(buf, sub)
203 	const char	*buf;
204 	int sub		__attribute__((unused));
205 {
206 	char		*cp, a_buf[1024];
207 	char		*alias;
208 	alias_t		*ap, *bp;
209 	int		i;
210 
211 	strncpy(a_buf, buf, sizeof(a_buf));
212 	alias = a_buf;
213 
214 	/* Skip over trailing space. */
215 	while (isspace(*alias))
216 		alias++;
217 
218 	if (!*alias) {
219 		eprt("Expecting alias to remove.\n");
220 		return;
221 	}
222 	cp = alias;
223 	while (!isspace(*cp))
224 		cp++;
225 	*cp = '\0';
226 
227 	if ('*' == *alias && !*(alias + 1)) {
228 		for (ap = alias_list, i = 0; (ap && i < numaliases); ap++, i++) {
229 			free(ap->alias);
230 			free(ap->command);
231 			ap->alias = (char *)0;
232 		}
233 		numaliases = 0;
234 		prt("All aliases removed.\n");
235 		return;
236 	}
237 	if (!(ap = find_alias_loc(alias))) {
238 		eprt("Alias '%s' not found.\n", alias);
239 		return;
240 	}
241 	free(ap->alias);
242 	free(ap->command);
243 	bp = ap++;
244 	while (ap->alias) {
245 		bp->alias = ap->alias;
246 		bp->command = ap->command;
247 		bp = ap++;
248 	}
249 	bp->alias = (char *)0;
250 
251 	prt("Alias '%s' deleted.\n", alias);
252 	numaliases--;
253 	return;
254 }
255 
256 /* vim:ts=8:ai:sw=8:syntax=c
257  */
258