Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / usr / bin / sh / var.c @ 03e9c04a

History | View | Annotate | Download (4.18 KB)

1 03e9c04a Brad Neuman
/*
2
 * Copyright (c) 2009, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include <unistd.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <stdio.h>
34
#include <errno.h>
35
36
extern char **environ;
37
38
/*
39
 * Shell variables.
40
 */
41
42
#define VTABSIZE        20
43
#define MAXVARNAME        32
44
45
struct var {
46
        char        *name;
47
        char        *val;
48
};
49
50
static struct var vartab[VTABSIZE];
51
52
static int
53
is_name(char c)
54
{
55
56
        if ((c >= 'a' && c <= 'z') ||
57
            (c >= 'A' && c <= 'Z') || c == '_')
58
                return 1;
59
        return 0;
60
}
61
62
static int
63
is_validname(char *name)
64
{
65
        char *p;
66
67
        for (p = name; *p != '\0'; p++) {
68
                if (!is_name(*p))
69
                        return 0;
70
        }
71
        return 1;
72
}
73
74
static struct var *
75
lookupvar(char *name)
76
{
77
        struct var *var;
78
        int i;
79
80
        var = &vartab[0];
81
        for (i = 0; i < VTABSIZE; i++) {
82
                if (var->name != NULL && !strcmp(var->name, name))
83
                        return var;
84
                var++;
85
        }
86
        return NULL;
87
}
88
89
void
90
setvar(char *name, char *val)
91
{
92
        struct var *var, *free;
93
        int i;
94
95
        /*
96
         * Lookup existing name in variable table.
97
         */
98
        var = lookupvar(name);
99
100
        if (var == NULL) {
101
                /*
102
                 * Not found. Find empty slot.
103
                 */
104
                free = NULL;
105
                var = &vartab[0];
106
                for (i = 0; i < VTABSIZE; i++) {
107
                        if (var->name == NULL) {
108
                                free = var;
109
                                break;
110
                        }
111
                        var++;
112
                }
113
                if (free == NULL) {
114
                        fprintf(stderr, "too many variables\n");
115
                        return;
116
                }
117
                var = free;
118
        }
119
120
        if (!is_validname(name)) {
121
                fprintf(stderr, "%s: bad vairable name\n", name);
122
                return;
123
        }
124
        if ((var->name = strdup(name)) == NULL) {
125
                fprintf(stderr, "out of memory\n");
126
                return;
127
        }
128
        var->val = strdup(val);
129
}
130
131
void
132
unsetvar(char *name)
133
{
134
        struct var *var;
135
136
        /* Find target slot in variable table */
137
        var = lookupvar(name);
138
        if (var == NULL)
139
                return;
140
141
        free(var->name);
142
        free(var->val);
143
        var->name = NULL;
144
        var->val = NULL;
145
}
146
147
void
148
setvareq(char *str)
149
{
150
        char name[MAXVARNAME];
151
        char *p, *s;
152
        int i;
153
154
        s = str;
155
        p = name;
156
        for (i = 0; i < MAXVARNAME - 1; i++) {
157
                *p++ = *s++;
158
                if (*s == '=')
159
                        break;
160
        }
161
        *p = '\0';
162
        p = strchr(str, '=');
163
        setvar(name, p + 1);
164
}
165
166
int
167
cmd_showvars(int argc, char *argv[])
168
{
169
        struct var *var;
170
        int i;
171
172
        var = &vartab[0];
173
        for (i = 0; i < VTABSIZE; i++) {
174
                if (var->name != NULL)
175
                        printf("%s=%s\n", var->name, var->val);
176
                var++;
177
        }
178
        return 0;
179
}
180
181
int
182
cmd_unsetvar(int argc, char *argv[])
183
{
184
185
        if (argc != 2) {
186
                fprintf(stderr, "usage: unset name\n");
187
                return 0;
188
        }
189
190
        unsetvar(argv[1]);
191
        return 0;
192
}
193
194
int
195
cmd_export(int argc, char *argv[])
196
{
197
        struct var *var;
198
        int i;
199
200
        if (argc == 1) {
201
                fprintf(stderr, "usage: export name\n");
202
                return 0;
203
        }
204
        for (i = 1; i < argc; i++) {
205
                var = lookupvar(argv[i]);
206
                if (var != NULL)
207
                        setenv(var->name, var->val, 1);
208
        }
209
        return 0;
210
}
211
212
void
213
initvar(void)
214
{
215
        char **envp;
216
        int i;
217
218
        for (i = 0; i < VTABSIZE; i++)
219
                vartab[i].name = NULL;
220
221
        for (envp = environ; *envp; envp++) {
222
                if (strchr(*envp, '='))
223
                        setvareq(*envp);
224
        }
225
}