nfs-ganesha 1.4

shell_vars.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  * ---------------------------------------
00024  */
00025 
00051 #ifdef HAVE_CONFIG_H
00052 #include "config.h"
00053 #endif
00054 
00055 #include <HashTable.h>
00056 #include <strings.h>
00057 #include <stdlib.h>
00058 #include <string.h>
00059 #include "shell_vars.h"
00060 #include "abstract_mem.h"
00061 
00062 /* variable struct */
00063 typedef struct shell_variable__
00064 {
00065   char var_name[MAX_VAR_LEN];
00066   char *var_value;              /* mallocated */
00067   int datalen;
00068   struct shell_variable__ *next;
00069   struct shell_variable__ *prev;
00070 } shell_variable_t;
00071 
00072 /* threads keys */
00073 static pthread_key_t thread_key;
00074 static pthread_once_t once_key = PTHREAD_ONCE_INIT;
00075 
00076 /* init pthtread_key for current thread */
00077 
00078 static void init_keys(void)
00079 {
00080   if(pthread_key_create(&thread_key, NULL) == -1)
00081     printf("Error %d creating pthread key for thread %p : %s\n",
00082            errno, (caddr_t) pthread_self(), strerror(errno));
00083 
00084   return;
00085 }                               /* init_keys */
00086 
00090 static shell_variable_t *GetVarTable()
00091 {
00092 
00093   /* first, we init the keys if this is the first time */
00094   if(pthread_once(&once_key, init_keys) != 0)
00095     {
00096       printf("Error %d calling pthread_once for thread %p : %s\n",
00097              errno, (caddr_t) pthread_self(), strerror(errno));
00098       return NULL;
00099     }
00100 
00101   return (shell_variable_t *) pthread_getspecific(thread_key);
00102 
00103 }                               /* GetVarTable */
00104 
00105 void SetVarTable(shell_variable_t * var_table)
00106 {
00107   /* set the specific value */
00108   pthread_setspecific(thread_key, var_table);
00109 
00110 }
00111 
00115 void print_varlist(FILE * output, int is_dlen)
00116 {
00117   shell_variable_t *current = GetVarTable();
00118   while(current)
00119     {
00120       if(is_dlen)
00121         fprintf(output, "\t%s (%d Bytes)\n", current->var_name, current->datalen - 1);
00122       else
00123         fprintf(output, "\t%s\n", current->var_name);
00124       current = current->next;
00125     }
00126   return;
00127 }
00128 
00129 static shell_variable_t *find_var(char *str)
00130 {
00131   shell_variable_t *current = GetVarTable();
00132   while(current)
00133     {
00134       if(!strncmp(current->var_name, str, MAX_VAR_LEN))
00135         return current;
00136       current = current->next;
00137     }
00138   return NULL;
00139 }
00140 
00141 static shell_variable_t *create_var(char *str)
00142 {
00143 
00144   shell_variable_t *var_table = GetVarTable();
00145 
00146   /* remembers name */
00147   shell_variable_t *new_item = gsh_calloc(1, sizeof(shell_variable_t));
00148 
00149   strncpy(new_item->var_name, str, MAX_VAR_LEN);
00150 
00151   new_item->var_value = NULL;
00152   new_item->datalen = 0;
00153 
00154   /* inserting */
00155   if(var_table)
00156     var_table->prev = new_item;
00157   new_item->next = var_table;
00158   new_item->prev = NULL;
00159   SetVarTable(new_item);
00160 
00161   return new_item;
00162 }
00163 
00164 static void set_var(shell_variable_t * var, char *value)
00165 {
00166 
00167   int dlen;
00168 
00169   /* clears old value, if any */
00170   if(var->var_value)
00171     {
00172       gsh_free(var->var_value);
00173       var->var_value = NULL;
00174       var->datalen = 0;
00175     }
00176 
00177   /* alloc and set new value */
00178   dlen = strlen(value) + 1;
00179   var->datalen = dlen;
00180   var->var_value = gsh_malloc(dlen);
00181   strncpy(var->var_value, value, dlen);
00182 
00183 }
00184 
00185 static void del_var(shell_variable_t * var)
00186 {
00187 
00188   /* remove from the list */
00189 
00190   if(var->prev)
00191     {
00192       var->prev->next = var->next;
00193     }
00194   else
00195     {
00196       SetVarTable(var->next);
00197     }
00198 
00199   if(var->next)
00200     {
00201       var->next->prev = var->prev;
00202     }
00203 
00204   /* free */
00205   if(var->var_value)
00206     gsh_free(var->var_value);
00207 
00208   gsh_free(var);
00209 
00210 }
00211 
00212 #define IS_LETTER(_c_) (((_c_) >= 'a') && ((_c_) <= 'z'))
00213 #define IS_LETTER_CAP(_c_) (((_c_) >= 'A') && ((_c_) <= 'Z'))
00214 #define IS_NUMERIC(_c_) (((_c_) >= '0') && ((_c_) <= '9'))
00215 
00219 int is_authorized_varname(char *str)
00220 {
00221 
00222   int len = 0;
00223 
00224   /* special var $? */
00225   if(!strcmp(str, "?"))
00226     return 1;
00227 
00228   while(str[len])
00229     {
00230       char c = str[len];
00231       if(!IS_LETTER(c) &&
00232          !IS_LETTER_CAP(c) && !IS_NUMERIC(c) && (c != '.') && (c != '_') && (c != ':'))
00233         {
00234           return 0;
00235         }
00236 
00237       len++;
00238       if(len > MAX_VAR_LEN)
00239         return 0;
00240     }
00241 
00242   return 1;
00243 
00244 }
00245 
00249 char *get_var_value(char *varname)
00250 {
00251   shell_variable_t *var;
00252   if((var = find_var(varname)))
00253     {
00254       return var->var_value;
00255     }
00256   else
00257     {
00258       return NULL;
00259     }
00260 }
00261 
00265 int set_var_value(char *varname, char *var_value)
00266 {
00267   shell_variable_t *var;
00268   /* if the value doesn't exist, create it */
00269   if(!(var = find_var(varname)))
00270     {
00271       var = create_var(varname);
00272     }
00273   if(!var)
00274     return 1;
00275   set_var(var, var_value);
00276 
00277   return 0;
00278 
00279 }
00280 
00283 int free_var(char *varname)
00284 {
00285 
00286   shell_variable_t *var;
00287   /* if the value doesn't exist, error */
00288   if(!(var = find_var(varname)))
00289     {
00290       return 1;
00291     }
00292 
00293   del_var(var);
00294   return 0;
00295 
00296 }