Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/bin/sh/var.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_name
  2. is_validname
  3. lookupvar
  4. setvar
  5. unsetvar
  6. setvareq
  7. cmd_showvars
  8. cmd_unsetvar
  9. cmd_export
  10. initvar

   1 /*
   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 }

/* [<][>][^][v][top][bottom][index][help] */