Subversion Repositories HelenOS

Rev

Rev 2714 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2714 cejka 1
/*  $NetBSD: alias.c,v 1.10 1998/05/20 00:27:56 christos Exp $  */
2
 
3
/*-
4
 * Copyright (c) 1993
5
 *  The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software contributed to Berkeley by
8
 * Kenneth Almquist.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. All advertising materials mentioning features or use of this software
19
 *    must display the following acknowledgement:
20
 *  This product includes software developed by the University of
21
 *  California, Berkeley and its contributors.
22
 * 4. Neither the name of the University nor the names of its contributors
23
 *    may be used to endorse or promote products derived from this software
24
 *    without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36
 * SUCH DAMAGE.
37
 */
38
 
39
//#include <sys/cdefs.h>
40
#ifndef lint
41
#if 0
42
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
43
#else
44
__RCSID("$NetBSD: alias.c,v 1.10 1998/05/20 00:27:56 christos Exp $");
45
#endif
46
#endif /* not lint */
47
 
48
#include <stdlib.h>
49
#include "shell.h"
50
#include "input.h"
51
#include "output.h"
52
#include "error.h"
53
#include "memalloc.h"
54
#include "mystring.h"
55
#include "alias.h"
56
#include "options.h"    /* XXX for argptr (should remove?) */
57
 
58
#define ATABSIZE 39
59
 
60
struct alias *atab[ATABSIZE];
61
 
62
STATIC void setalias (char *, char *);
63
STATIC int unalias (char *);
64
STATIC struct alias **hashalias (char *);
65
 
66
STATIC
67
void
68
setalias(char *name, char *val)
69
{
70
    struct alias *ap, **app;
71
 
72
    app = hashalias(name);
73
    for (ap = *app; ap; ap = ap->next) {
74
        if (equal(name, ap->name)) {
75
            INTOFF;
76
            ckfree(ap->val);
77
            ap->val = savestr(val);
78
            INTON;
79
            return;
80
        }
81
    }
82
    /* not found */
83
    INTOFF;
84
    ap = ckmalloc(sizeof (struct alias));
85
    ap->name = savestr(name);
86
    /*
87
     * XXX - HACK: in order that the parser will not finish reading the
88
     * alias value off the input before processing the next alias, we
89
     * dummy up an extra space at the end of the alias.  This is a crock
90
     * and should be re-thought.  The idea (if you feel inclined to help)
91
     * is to avoid alias recursions.  The mechanism used is: when
92
     * expanding an alias, the value of the alias is pushed back on the
93
     * input as a string and a pointer to the alias is stored with the
94
     * string.  The alias is marked as being in use.  When the input
95
     * routine finishes reading the string, it markes the alias not
96
     * in use.  The problem is synchronization with the parser.  Since
97
     * it reads ahead, the alias is marked not in use before the
98
     * resulting token(s) is next checked for further alias sub.  The
99
     * H A C K is that we add a little fluff after the alias value
100
     * so that the string will not be exhausted.  This is a good
101
     * idea ------- ***NOT***
102
     */
103
#ifdef notyet
104
    ap->val = savestr(val);
105
#else /* hack */
106
    {
107
    int len = strlen(val);
108
    ap->val = ckmalloc(len + 2);
109
    memcpy(ap->val, val, len);
110
    ap->val[len] = ' '; /* fluff */
111
    ap->val[len+1] = '\0';
112
    }
113
#endif
114
    ap->next = *app;
115
    *app = ap;
116
    INTON;
117
}
118
 
119
STATIC int
120
unalias(name)
121
    char *name;
122
    {
123
    struct alias *ap, **app;
124
 
125
    app = hashalias(name);
126
 
127
    for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
128
        if (equal(name, ap->name)) {
129
            /*
130
             * if the alias is currently in use (i.e. its
131
             * buffer is being used by the input routine) we
132
             * just null out the name instead of freeing it.
133
             * We could clear it out later, but this situation
134
             * is so rare that it hardly seems worth it.
135
             */
136
            if (ap->flag & ALIASINUSE)
137
                *ap->name = '\0';
138
            else {
139
                INTOFF;
140
                *app = ap->next;
141
                ckfree(ap->name);
142
                ckfree(ap->val);
143
                ckfree(ap);
144
                INTON;
145
            }
146
            return (0);
147
        }
148
    }
149
 
150
    return (1);
151
}
152
 
153
#ifdef mkinit
154
MKINIT void rmaliases (void);
155
 
156
SHELLPROC {
157
    rmaliases();
158
}
159
#endif
160
 
161
void
162
rmaliases() {
163
    struct alias *ap, *tmp;
164
    int i;
165
 
166
    INTOFF;
167
    for (i = 0; i < ATABSIZE; i++) {
168
        ap = atab[i];
169
        atab[i] = NULL;
170
        while (ap) {
171
            ckfree(ap->name);
172
            ckfree(ap->val);
173
            tmp = ap;
174
            ap = ap->next;
175
            ckfree(tmp);
176
        }
177
    }
178
    INTON;
179
}
180
 
181
struct alias *
182
lookupalias(name, check)
183
    char *name;
184
    int check;
185
{
186
    struct alias *ap = *hashalias(name);
187
 
188
    for (; ap; ap = ap->next) {
189
        if (equal(name, ap->name)) {
190
            if (check && (ap->flag & ALIASINUSE))
191
                return (NULL);
192
            return (ap);
193
        }
194
    }
195
 
196
    return (NULL);
197
}
198
 
199
/*
200
 * TODO - sort output
201
 */
202
int
203
aliascmd(argc, argv)
204
    int argc;
205
    char **argv;
206
{
207
    char *n, *v;
208
    int ret = 0;
209
    struct alias *ap;
210
 
211
    if (argc == 1) {
212
        int i;
213
 
214
        for (i = 0; i < ATABSIZE; i++)
215
            for (ap = atab[i]; ap; ap = ap->next) {
216
                if (*ap->name != '\0')
217
                    out1fmt("alias %s=%s\n", ap->name, ap->val);
218
            }
219
        return (0);
220
    }
221
    while ((n = *++argv) != NULL) {
222
        if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
223
            if ((ap = lookupalias(n, 0)) == NULL) {
224
                outfmt(out2, "alias: %s not found\n", n);
225
                ret = 1;
226
            } else
227
                out1fmt("alias %s=%s\n", n, ap->val);
228
        }
229
        else {
230
            *v++ = '\0';
231
            setalias(n, v);
232
        }
233
    }
234
 
235
    return (ret);
236
}
237
 
238
int
239
unaliascmd(argc, argv)
240
    int argc;
241
    char **argv;
242
{
243
    int i;
244
 
245
    while ((i = nextopt("a")) != '\0') {
246
        if (i == 'a') {
247
            rmaliases();
248
            return (0);
249
        }
250
    }
251
    for (i = 0; *argptr; argptr++)
252
        i = unalias(*argptr);
253
 
254
    return (i);
255
}
256
 
257
STATIC struct alias **
258
hashalias(p)
259
    char *p;
260
    {
261
    unsigned int hashval;
262
 
263
    hashval = *p << 4;
264
    while (*p)
265
        hashval+= *p++;
266
    return &atab[hashval % ATABSIZE];
267
}