00001
00002
00003
00004
00005
00006
00007
00008
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 struct var_list_s list;
00024 size_t count;
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 TAILQ_INIT(&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_free(vars_t *vs)
00074 {
00075 var_t *v;
00076
00077 if(vs)
00078 {
00079
00080 while((v = TAILQ_FIRST(&vs->list)) != NULL)
00081 {
00082 vars_del(vs, v);
00083 var_free(v);
00084 }
00085 U_FREE(vs);
00086 }
00087
00088 return 0;
00089 }
00090
00091 int vars_add(vars_t *vs, var_t *v)
00092 {
00093 TAILQ_INSERT_TAIL(&vs->list, v, np);
00094 vs->count++;
00095
00096 return 0;
00097 }
00098
00099 int vars_del(vars_t *vs, var_t *v)
00100 {
00101 dbg_return_if (vs == NULL, ~0);
00102 dbg_return_if (v == NULL, ~0);
00103
00104 TAILQ_REMOVE(&vs->list, v, np);
00105 vs->count--;
00106
00107 return 0;
00108 }
00109
00121 var_t *vars_getn(vars_t *vs, size_t i)
00122 {
00123 var_t *v;
00124
00125 dbg_goto_if (vs == NULL, notfound);
00126 dbg_goto_if (i >= vs->count, notfound);
00127
00128 TAILQ_FOREACH(v, &vs->list, np)
00129 {
00130 if(i-- == 0)
00131 return v;
00132 }
00133
00134 notfound:
00135 return NULL;
00136 }
00137
00148 size_t vars_count(vars_t *vs)
00149 {
00150 dbg_return_if (vs == NULL, 0);
00151
00152 return vs->count;
00153 }
00154
00166 size_t vars_countn(vars_t *vs, const char *name)
00167 {
00168 var_t *v;
00169 size_t c = 0;
00170
00171 dbg_return_if (vs == NULL || name == NULL, 0);
00172
00173 TAILQ_FOREACH(v, &vs->list, np)
00174 {
00175 if(strcasecmp(u_string_c(v->sname), name) == 0)
00176 c++;
00177 }
00178
00179 return c;
00180 }
00181
00195 int vars_add_urlvar(vars_t *vs, const char *cstr, var_t **v)
00196 {
00197 enum { NAMESZ = 256, VALSZ = 4096 };
00198 char sname[NAMESZ], svalue[VALSZ];
00199 char *val, *str = NULL, *name = sname, *value = svalue;
00200 var_t *var = NULL;
00201 ssize_t vsz;
00202
00203 dbg_return_if (vs == NULL, ~0);
00204 dbg_return_if (cstr == NULL, ~0);
00205
00206
00207
00208 str = u_strdup(cstr);
00209 dbg_err_if(str == NULL);
00210
00211 val = strchr(str, '=');
00212 dbg_err_if(val == NULL);
00213
00214
00215 *val++ = 0;
00216
00217
00218 if(strlen(str) >= NAMESZ)
00219 dbg_err_if((name = u_zalloc(1 + strlen(str))) == NULL);
00220
00221
00222 if(strlen(val) >= VALSZ)
00223 dbg_err_if((value = u_zalloc(1 + strlen(val))) == NULL);
00224
00225
00226 dbg_err_if(u_urlncpy(name, str, strlen(str), URLCPY_DECODE) <= 0);
00227
00228
00229 dbg_err_if((vsz = u_urlncpy(value, val, strlen(val), URLCPY_DECODE)) <= 0);
00230
00231
00232
00233 dbg_err_if(var_bin_create(name, value, vsz, &var));
00234
00235
00236 dbg_err_if(vars_add(vs, var));
00237
00238 if(v)
00239 *v = var;
00240
00241
00242 if(value && value != svalue)
00243 U_FREE(value);
00244
00245 if(name && name != sname)
00246 U_FREE(name);
00247
00248 U_FREE(str);
00249
00250 return 0;
00251 err:
00252 if(value && value != svalue)
00253 U_FREE(value);
00254 if(name && name != sname)
00255 U_FREE(name);
00256 if(cstr)
00257 dbg("%s", cstr);
00258 U_FREE(str);
00259 if(var)
00260 var_free(var);
00261 return ~0;
00262 }
00263
00264 int vars_add_strvar(vars_t *vs, const char *str)
00265 {
00266 char *eq, *dups = NULL;
00267 var_t *var = NULL;
00268
00269 dbg_err_if (vs == NULL);
00270 dbg_err_if (str == NULL);
00271
00272
00273 dups = u_strdup(str);
00274 dbg_err_if(dups == NULL);
00275
00276
00277 eq = strchr(dups, '=');
00278 dbg_err_if(eq == NULL);
00279 *eq = 0;
00280
00281
00282 dbg_err_if(var_create(dups, eq+1, &var));
00283
00284 U_FREE(dups);
00285
00286
00287 dbg_err_if(vars_add(vs, var));
00288
00289 return 0;
00290 err:
00291 U_FREE(dups);
00292 if(var)
00293 var_free(var);
00294 return ~0;
00295 }
00296
00311 var_t *vars_geti(vars_t *vs, const char *var_name, size_t i)
00312 {
00313 var_t *v;
00314
00315 dbg_goto_if (vs == NULL, notfound);
00316 dbg_goto_if (var_name == NULL, notfound);
00317
00318 TAILQ_FOREACH(v, &vs->list, np)
00319 {
00320 if(strcasecmp(u_string_c(v->sname), var_name) == 0)
00321 {
00322 if(i-- == 0)
00323 return v;
00324 }
00325 }
00326
00327 notfound:
00328 return NULL;
00329 }
00330
00344 var_t *vars_get(vars_t *vs, const char *var_name)
00345 {
00346 dbg_return_if (vs == NULL, NULL);
00347 dbg_return_if (var_name == NULL, NULL);
00348
00349 return vars_geti(vs, var_name, 0);
00350 }
00351
00367 int vars_geti_value_i(vars_t *vs, const char *name, size_t ith)
00368 {
00369 const char *v;
00370
00371 dbg_return_if (vs == NULL, 0);
00372 dbg_return_if (name == NULL, 0);
00373
00374 v = vars_geti_value(vs, name, ith);
00375 if(v == NULL)
00376 return 0;
00377 else
00378 return atoi(v);
00379 }
00380
00394 u_string_t *vars_geti_value_s(vars_t *vs, const char *name, size_t ith)
00395 {
00396 var_t *v = NULL;
00397
00398 dbg_err_if (vs == NULL);
00399 dbg_err_if (name == NULL);
00400
00401 dbg_err_if((v = vars_geti(vs, name, ith)) == NULL);
00402
00403 return var_get_value_s(v);
00404 err:
00405 return NULL;
00406 }
00407
00421 int vars_get_value_i(vars_t *vs, const char *name)
00422 {
00423 dbg_return_if (vs == NULL, 0);
00424 dbg_return_if (name == NULL, 0);
00425
00426 return vars_geti_value_i(vs, name, 0);
00427 }
00428
00444 const char *vars_geti_value(vars_t *vs, const char *name, size_t ith)
00445 {
00446 var_t *v;
00447
00448 dbg_return_if (vs == NULL, NULL);
00449 dbg_return_if (name == NULL, NULL);
00450
00451 v = vars_geti(vs, name, ith);
00452
00453 return v ? var_get_value(v) : NULL;
00454 }
00455
00469 const char *vars_get_value(vars_t *vs, const char *name)
00470 {
00471 dbg_return_if (vs == NULL, NULL);
00472 dbg_return_if (name == NULL, NULL);
00473
00474 return vars_geti_value(vs, name, 0);
00475 }
00476
00490 void vars_foreach(vars_t *vs, int (*cb)(var_t *, void *), void *arg)
00491 {
00492 var_t *v;
00493
00494 dbg_ifb (vs == NULL) return;
00495 dbg_ifb (cb == NULL) return;
00496
00497 TAILQ_FOREACH(v, &vs->list, np)
00498 {
00499 if(cb(v, arg))
00500 break;
00501 }
00502
00503 return;
00504 }