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