KLone APIs | Modules | Data Structures | File List | Data Fields | Globals

vars.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, 2006 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_goto_if (vs == NULL, notfound);
00146 
00147     dbg_goto_if (i >= u_list_count(vs->list), notfound); /* out of bounds */
00148 
00149     return u_list_get_n(vs->list, i);
00150 notfound:
00151     return NULL;
00152 }
00153 
00164 size_t vars_count(vars_t *vs)
00165 {
00166     dbg_return_if (vs == NULL, 0);
00167 
00168     return u_list_count(vs->list);
00169 }
00170 
00182 size_t vars_countn(vars_t *vs, const char *name)
00183 {
00184     var_t *v;
00185     size_t c = 0;
00186     int t;
00187 
00188     dbg_return_if (vs == NULL || name == NULL, 0);
00189 
00190     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00191     {
00192         if(strcasecmp(u_string_c(v->sname), name) == 0)
00193             c++;
00194     }
00195 
00196     return c;
00197 }
00198 
00212 int vars_add_urlvar(vars_t *vs, const char *cstr, var_t **pv)
00213 {
00214     enum { NAMESZ = 256, VALSZ = 4096 };
00215     char sname[NAMESZ], svalue[VALSZ];
00216     char *val, *str = NULL, *name = sname, *value = svalue;
00217     var_t *var = NULL;
00218     ssize_t vsz;
00219     size_t val_len;
00220 
00221     dbg_return_if (vs == NULL, ~0);
00222     dbg_return_if (cstr == NULL, ~0);
00223     /* v may be NULL */
00224         
00225     /* dup the string so we can modify it */
00226     str = u_strdup(cstr);
00227     dbg_err_if(str == NULL);
00228 
00229     val = strchr(str, '=');
00230     dbg_err_if(val == NULL);
00231 
00232     /* zero-term the name part and set the value pointer */
00233     *val++ = 0; 
00234 
00235     val_len = strlen(val);
00236 
00237     /* if the buffer on the stack is too small alloc a bigger one */
00238     if(strlen(str) >= NAMESZ)
00239         dbg_err_if((name = u_zalloc(1 + strlen(str))) == NULL);
00240 
00241     /* if the buffer on the stack is too small alloc a bigger one */
00242     if(val_len >= VALSZ)
00243         dbg_err_if((value = u_zalloc(1 + val_len)) == NULL);
00244 
00245     /* url-decode var name */
00246     dbg_err_if(u_urlncpy(name, str, strlen(str), URLCPY_DECODE) <= 0);
00247 
00248     /* url-decode var value */
00249     if(val_len)
00250     {
00251         dbg_err_if((
00252             vsz = u_urlncpy(value, val, val_len, URLCPY_DECODE)) <= 0);
00253     } else {
00254         /* an empty value */
00255         value[0] = 0;
00256         vsz = 1;
00257     }
00258 
00259     /* dbg("name: [%s]  value: [%s]", name, value); */
00260 
00261     dbg_err_if(var_bin_create(name, value, vsz, &var));
00262 
00263     /* push into the var list */
00264     dbg_err_if(vars_add(vs, var));
00265 
00266     if(pv)
00267         *pv = var;
00268 
00269     /* if the buffer has been alloc'd on the heap then free it */
00270     if(value && value != svalue)
00271         U_FREE(value);
00272 
00273     if(name && name != sname)
00274         U_FREE(name);
00275 
00276     U_FREE(str);
00277 
00278     return 0;
00279 err:
00280     if(value && value != svalue)
00281         U_FREE(value);
00282     if(name && name != sname)
00283         U_FREE(name);
00284     U_FREE(str);
00285     if(var)
00286         var_free(var);
00287     return ~0;
00288 }
00289 
00290 int vars_add_strvar(vars_t *vs, const char *str)
00291 {
00292     char *eq, *dups = NULL;
00293     var_t *var = NULL;
00294 
00295     dbg_err_if (vs == NULL);
00296     dbg_err_if (str == NULL);
00297 
00298     /* dup the string (str is const) */
00299     dups = u_strdup(str);
00300     dbg_err_if(dups == NULL);
00301 
00302     /* search the '=' and replace it with a '\0' */
00303     eq = strchr(dups, '=');
00304     dbg_err_if(eq == NULL);
00305     *eq = 0;
00306 
00307     /* create a new var obj */
00308     dbg_err_if(var_create(dups, eq+1, &var));
00309 
00310     U_FREE(dups);
00311 
00312     /* push into the cookie list */
00313     dbg_err_if(vars_add(vs, var));
00314 
00315     return 0;
00316 err:
00317     U_FREE(dups);
00318     if(var)
00319         var_free(var);
00320     return ~0;
00321 }
00322 
00337 var_t *vars_geti(vars_t *vs, const char *var_name, size_t i)
00338 {
00339     var_t *v;
00340     int t;
00341 
00342     dbg_goto_if (vs == NULL, notfound);
00343     dbg_goto_if (var_name == NULL, notfound);
00344 
00345     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00346     {
00347         if(strcasecmp(u_string_c(v->sname), var_name) == 0)
00348         {
00349             if(i-- == 0)
00350                 return v;
00351         }
00352     }
00353 
00354 notfound:
00355     return NULL;
00356 }
00357 
00371 var_t *vars_get(vars_t *vs, const char *var_name)
00372 {
00373     dbg_return_if (vs == NULL, NULL);
00374     dbg_return_if (var_name == NULL, NULL);
00375 
00376     return vars_geti(vs, var_name, 0);
00377 }
00378 
00394 int vars_geti_value_i(vars_t *vs, const char *name, size_t ith)
00395 {
00396     const char *v;
00397 
00398     dbg_return_if (vs == NULL, 0);
00399     dbg_return_if (name == NULL, 0);
00400 
00401     v = vars_geti_value(vs, name, ith);
00402     if(v == NULL)
00403         return 0;
00404     else
00405         return atoi(v);
00406 }
00407 
00421 u_string_t *vars_geti_value_s(vars_t *vs, const char *name, size_t ith)
00422 {
00423     var_t *v = NULL;
00424 
00425     dbg_err_if (vs == NULL);
00426     dbg_err_if (name == NULL);
00427 
00428     dbg_err_if((v = vars_geti(vs, name, ith)) == NULL);
00429 
00430     return var_get_value_s(v);
00431 err:
00432     return NULL;
00433 }
00434 
00448 int vars_get_value_i(vars_t *vs, const char *name)
00449 {
00450     dbg_return_if (vs == NULL, 0);
00451     dbg_return_if (name == NULL, 0);
00452 
00453     return vars_geti_value_i(vs, name, 0);
00454 }
00455 
00471 const char *vars_geti_value(vars_t *vs, const char *name, size_t ith)
00472 {
00473     var_t *v;
00474 
00475     dbg_return_if (vs == NULL, NULL);
00476     dbg_return_if (name == NULL, NULL);
00477     
00478     v = vars_geti(vs, name, ith);
00479 
00480     return  v ? var_get_value(v) : NULL;
00481 }
00482 
00496 const char *vars_get_value(vars_t *vs, const char *name)
00497 {
00498     dbg_return_if (vs == NULL, NULL);
00499     dbg_return_if (name == NULL, NULL);
00500 
00501     return vars_geti_value(vs, name, 0);
00502 }
00503 
00517 void vars_foreach(vars_t *vs, int (*cb)(var_t *, void *), void *arg)
00518 {
00519     var_t *v;
00520     int t;
00521 
00522     dbg_ifb (vs == NULL) return;
00523     dbg_ifb (cb == NULL) return;
00524 
00525     for(t = 0; (v = u_list_get_n(vs->list, t)) != NULL; ++t)
00526     {
00527         if(cb(v, arg))
00528             break;
00529     }
00530 
00531     return;
00532 }
00533