vars.c

00001 /*
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: vars.c,v 1.32 2008/05/16 15:04:47 tat Exp $
00009  */
00010 
00011 #include "klone_conf.h"
00012 #include <sys/types.h>
00013 #include <stdlib.h>
00014 #include <u/libu.h>
00015 #include <klone/vars.h>
00016 #include <klone/varprv.h>
00017 #include <klone/utils.h>
00018 
00019 TAILQ_HEAD(var_list_s, var_s);
00020 
00021 struct vars_s
00022 {
00023     u_list_t *list;              /* list of variables (var_t) */
00024     int flags;
00025 };
00026 
00039 u_string_t *vars_get_value_s(vars_t *vs, const char *name)
00040 {
00041     var_t *v = NULL;
00042 
00043     dbg_err_if (vs == NULL);
00044     dbg_err_if (name == NULL);
00045 
00046     dbg_err_if((v = vars_get(vs, name)) == NULL);
00047 
00048     return var_get_value_s(v);
00049 err:
00050     return NULL;
00051 }
00052 
00053 int vars_create(vars_t **pvs)
00054 {
00055     vars_t *vs = NULL;
00056 
00057     dbg_err_if (pvs == NULL);
00058 
00059     vs = u_zalloc(sizeof(vars_t));
00060     dbg_err_if(vs == NULL);
00061 
00062     dbg_err_if(u_list_create(&vs->list));
00063 
00064     *pvs = vs;
00065 
00066     return 0;
00067 err:
00068     if(vs)
00069         vars_free(vs);
00070     return ~0;
00071 }
00072 
00073 int vars_set_flags(vars_t *vs, int flags)
00074 {
00075     dbg_err_if (vs == NULL);
00076 
00077     vs->flags = flags;
00078 
00079     return 0;
00080 err:
00081     return ~0;
00082 }
00083 
00084 int vars_free(vars_t *vs)
00085 {
00086     var_t *v;
00087     int t;
00088 
00089     if(vs)
00090     {
00091         /* if the var_t objects are owned by this vars_t then free them all */
00092         if((vs->flags & VARS_FLAG_FOREIGN) == 0)
00093         {
00094             /* free all variables */
00095             for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00096                 var_free(v);
00097         }
00098 
00099         if(vs->list)
00100             u_list_free(vs->list);
00101 
00102         U_FREE(vs);
00103     }
00104 
00105     return 0;
00106 }
00107 
00108 int vars_add(vars_t *vs, var_t *v)
00109 {
00110     dbg_err_if(vs == NULL);
00111     dbg_err_if(v == NULL);
00112 
00113     dbg_err_if(u_list_add(vs->list, v));
00114 
00115     return 0;
00116 err:
00117     return ~0;
00118 }
00119 
00120 int vars_del(vars_t *vs, var_t *v)
00121 {
00122     dbg_err_if(vs == NULL);
00123     dbg_err_if(v == NULL);
00124    
00125     dbg_err_if(u_list_del(vs->list, v));
00126 
00127     return 0;
00128 err:
00129     return ~0;
00130 }
00131 
00143 var_t *vars_getn(vars_t *vs, size_t i)
00144 {
00145     dbg_return_if (vs == NULL, NULL);
00146     nop_return_if (i >= u_list_count(vs->list), NULL);
00147 
00148     return u_list_get_n(vs->list, i);
00149 }
00150 
00161 size_t vars_count(vars_t *vs)
00162 {
00163     dbg_return_if (vs == NULL, 0);
00164 
00165     return u_list_count(vs->list);
00166 }
00167 
00179 size_t vars_countn(vars_t *vs, const char *name)
00180 {
00181     var_t *v;
00182     size_t c = 0;
00183     int t;
00184 
00185     dbg_return_if (vs == NULL || name == NULL, 0);
00186 
00187     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00188     {
00189         if(strcasecmp(u_string_c(v->sname), name) == 0)
00190             c++;
00191     }
00192 
00193     return c;
00194 }
00195 
00209 int vars_add_urlvar(vars_t *vs, const char *cstr, var_t **pv)
00210 {
00211     enum { NAMESZ = 256, VALSZ = 4096 };
00212     char sname[NAMESZ], svalue[VALSZ];
00213     char *val, *str = NULL, *name = sname, *value = svalue;
00214     var_t *var = NULL;
00215     ssize_t vsz;
00216     size_t val_len, nam_len;
00217 
00218     dbg_return_if (vs == NULL, ~0);
00219     dbg_return_if (cstr == NULL, ~0);
00220     /* pv may be NULL */
00221         
00222     /* dup the string so we can modify it */
00223     dbg_err_sif ((str = u_strdup(cstr)) == NULL);
00224 
00225     /* zero-term the name part and set the value pointer */
00226     dbg_err_if ((val = strchr(str, '=')) == NULL);
00227     *val++ = '\0'; 
00228 
00229     val_len = strlen(val);
00230     nam_len = strlen(str);
00231 
00232     /* if the buffer on the stack is too small alloc a bigger one */
00233     if (nam_len >= NAMESZ)
00234         dbg_err_if ((name = u_zalloc(1 + nam_len)) == NULL);
00235 
00236     /* if the buffer on the stack is too small alloc a bigger one */
00237     if (val_len >= VALSZ)
00238         dbg_err_if ((value = u_zalloc(1 + val_len)) == NULL);
00239 
00240     /* url-decode var name */
00241     dbg_err_if (u_urlncpy(name, str, nam_len, URLCPY_DECODE) <= 0);
00242 
00243     /* url-decode var value */
00244     if (val_len)
00245         dbg_err_if ((vsz = u_urlncpy(value, val, val_len, URLCPY_DECODE)) <= 0);
00246     else 
00247     {
00248         /* an empty value */
00249         value[0] = '\0';
00250         vsz = 1;
00251     }
00252 
00253     /* u_dbg("name: [%s]  value: [%s]", name, value); */
00254 
00255     dbg_err_if (var_bin_create(name, (unsigned char *) value, vsz, &var));
00256 
00257     /* push into the var list */
00258     dbg_err_if (vars_add(vs, var));
00259 
00260     if (pv)
00261         *pv = var;
00262 
00263     /* if the buffer has been alloc'd on the heap then free it */
00264     if (value && value != svalue)
00265         u_free(value);
00266 
00267     if (name && name != sname)
00268         u_free(name);
00269 
00270     u_free(str);
00271 
00272     return 0;
00273 err:
00274     if (value && value != svalue)
00275         u_free(value);
00276     if (name && name != sname)
00277         u_free(name);
00278     u_free(str);
00279     if (var)
00280         var_free(var);
00281     return ~0;
00282 }
00283 
00284 int vars_add_strvar(vars_t *vs, const char *str)
00285 {
00286     char *eq, *dups = NULL;
00287     var_t *var = NULL;
00288 
00289     dbg_err_if (vs == NULL);
00290     dbg_err_if (str == NULL);
00291 
00292     /* dup the string (str is const) */
00293     dups = u_strdup(str);
00294     dbg_err_if(dups == NULL);
00295 
00296     /* search the '=' and replace it with a '\0' */
00297     eq = strchr(dups, '=');
00298     dbg_err_if(eq == NULL);
00299     *eq = 0;
00300 
00301     /* create a new var obj */
00302     dbg_err_if(var_create(dups, eq+1, &var));
00303 
00304     U_FREE(dups);
00305 
00306     /* push into the cookie list */
00307     dbg_err_if(vars_add(vs, var));
00308 
00309     return 0;
00310 err:
00311     U_FREE(dups);
00312     if(var)
00313         var_free(var);
00314     return ~0;
00315 }
00316 
00331 var_t *vars_geti(vars_t *vs, const char *var_name, size_t i)
00332 {
00333     var_t *v;
00334     int t;
00335 
00336     dbg_goto_if (vs == NULL, notfound);
00337     dbg_goto_if (var_name == NULL, notfound);
00338 
00339     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00340     {
00341         if(strcasecmp(u_string_c(v->sname), var_name) == 0)
00342         {
00343             if(i-- == 0)
00344                 return v;
00345         }
00346     }
00347 
00348 notfound:
00349     return NULL;
00350 }
00351 
00365 var_t *vars_get(vars_t *vs, const char *var_name)
00366 {
00367     dbg_return_if (vs == NULL, NULL);
00368     dbg_return_if (var_name == NULL, NULL);
00369 
00370     return vars_geti(vs, var_name, 0);
00371 }
00372 
00388 int vars_geti_value_i(vars_t *vs, const char *name, size_t ith)
00389 {
00390     const char *v;
00391 
00392     dbg_return_if (vs == NULL, 0);
00393     dbg_return_if (name == NULL, 0);
00394 
00395     v = vars_geti_value(vs, name, ith);
00396     if(v == NULL)
00397         return 0;
00398     else
00399         return atoi(v);
00400 }
00401 
00415 u_string_t *vars_geti_value_s(vars_t *vs, const char *name, size_t ith)
00416 {
00417     var_t *v = NULL;
00418 
00419     dbg_err_if (vs == NULL);
00420     dbg_err_if (name == NULL);
00421 
00422     dbg_err_if((v = vars_geti(vs, name, ith)) == NULL);
00423 
00424     return var_get_value_s(v);
00425 err:
00426     return NULL;
00427 }
00428 
00442 int vars_get_value_i(vars_t *vs, const char *name)
00443 {
00444     dbg_return_if (vs == NULL, 0);
00445     dbg_return_if (name == NULL, 0);
00446 
00447     return vars_geti_value_i(vs, name, 0);
00448 }
00449 
00465 const char *vars_geti_value(vars_t *vs, const char *name, size_t ith)
00466 {
00467     var_t *v;
00468 
00469     dbg_return_if (vs == NULL, NULL);
00470     dbg_return_if (name == NULL, NULL);
00471     
00472     v = vars_geti(vs, name, ith);
00473 
00474     return  v ? var_get_value(v) : NULL;
00475 }
00476 
00490 const char *vars_get_value(vars_t *vs, const char *name)
00491 {
00492     dbg_return_if (vs == NULL, NULL);
00493     dbg_return_if (name == NULL, NULL);
00494 
00495     return vars_geti_value(vs, name, 0);
00496 }
00497 
00511 void vars_foreach(vars_t *vs, int (*cb)(var_t *, void *), void *arg)
00512 {
00513     var_t *v;
00514     int t;
00515 
00516     dbg_ifb (vs == NULL) return;
00517     dbg_ifb (cb == NULL) return;
00518 
00519     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00520     {
00521         if(cb(v, arg))
00522             break;
00523     }
00524 
00525     return;
00526 }
00527 

←Products
Copyright © 2005-2012 - KoanLogic S.r.l. - All rights reserved