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
00044 u_string_t *vars_get_value_s(vars_t *vs, const char *name)
00045 {
00046 var_t *v = NULL;
00047
00048 dbg_err_if (vs == NULL);
00049 dbg_err_if (name == NULL);
00050
00051 dbg_err_if((v = vars_get(vs, name)) == NULL);
00052
00053 return var_get_value_s(v);
00054 err:
00055 return NULL;
00056 }
00057
00058 int vars_create(vars_t **pvs)
00059 {
00060 vars_t *vs = NULL;
00061
00062 dbg_err_if (pvs == NULL);
00063
00064 vs = u_zalloc(sizeof(vars_t));
00065 dbg_err_if(vs == NULL);
00066
00067 TAILQ_INIT(&vs->list);
00068
00069 *pvs = vs;
00070
00071 return 0;
00072 err:
00073 if(vs)
00074 vars_free(vs);
00075 return ~0;
00076 }
00077
00078 int vars_free(vars_t *vs)
00079 {
00080 var_t *v;
00081
00082 if(vs)
00083 {
00084
00085 while((v = TAILQ_FIRST(&vs->list)) != NULL)
00086 {
00087 vars_del(vs, v);
00088 var_free(v);
00089 }
00090 U_FREE(vs);
00091 }
00092
00093 return 0;
00094 }
00095
00096 int vars_add(vars_t *vs, var_t *v)
00097 {
00098 TAILQ_INSERT_TAIL(&vs->list, v, np);
00099 vs->count++;
00100
00101 return 0;
00102 }
00103
00104 int vars_del(vars_t *vs, var_t *v)
00105 {
00106 dbg_return_if (vs == NULL, ~0);
00107 dbg_return_if (v == NULL, ~0);
00108
00109 TAILQ_REMOVE(&vs->list, v, np);
00110 vs->count--;
00111
00112 return 0;
00113 }
00114
00125 var_t *vars_getn(vars_t *vs, size_t i)
00126 {
00127 var_t *v;
00128
00129 dbg_goto_if (vs == NULL, notfound);
00130 dbg_goto_if (i >= vs->count, notfound);
00131
00132 TAILQ_FOREACH(v, &vs->list, np)
00133 {
00134 if(i-- == 0)
00135 return v;
00136 }
00137
00138 notfound:
00139 return NULL;
00140 }
00141
00151 size_t vars_count(vars_t *vs)
00152 {
00153 dbg_return_if (vs == NULL, 0);
00154
00155 return vs->count;
00156 }
00157
00168 size_t vars_countn(vars_t *vs, const char *name)
00169 {
00170 var_t *v;
00171 size_t c = 0;
00172
00173 dbg_return_if (vs == NULL || name == NULL, 0);
00174
00175 TAILQ_FOREACH(v, &vs->list, np)
00176 {
00177 if(strcasecmp(u_string_c(v->sname), name) == 0)
00178 c++;
00179 }
00180
00181 return c;
00182 }
00183
00196 int vars_add_urlvar(vars_t *vs, const char *cstr, var_t **v)
00197 {
00198 enum { NAMESZ = 256, VALSZ = 4096 };
00199 char sname[NAMESZ], svalue[VALSZ];
00200 char *val, *str = NULL, *name = sname, *value = svalue;
00201 var_t *var = NULL;
00202 ssize_t vsz;
00203
00204 dbg_return_if (vs == NULL, ~0);
00205 dbg_return_if (cstr == NULL, ~0);
00206
00207
00208
00209 str = u_strdup(cstr);
00210 dbg_err_if(str == NULL);
00211
00212 val = strchr(str, '=');
00213 dbg_err_if(val == NULL);
00214
00215
00216 *val++ = 0;
00217
00218
00219 if(strlen(str) >= NAMESZ)
00220 dbg_err_if((name = u_zalloc(1 + strlen(str))) == NULL);
00221
00222
00223 if(strlen(val) >= VALSZ)
00224 dbg_err_if((value = u_zalloc(1 + strlen(val))) == NULL);
00225
00226
00227 dbg_err_if(u_urlncpy(name, str, strlen(str), URLCPY_DECODE) <= 0);
00228
00229
00230 dbg_err_if((vsz = u_urlncpy(value, val, strlen(val), URLCPY_DECODE)) <= 0);
00231
00232
00233
00234
00235 --vsz;
00236
00237 dbg_err_if(var_bin_create(name, value, vsz, &var));
00238
00239
00240 dbg_err_if(vars_add(vs, var));
00241
00242 if(v)
00243 *v = var;
00244
00245
00246 if(value && value != svalue)
00247 U_FREE(value);
00248
00249 if(name && name != sname)
00250 U_FREE(name);
00251
00252 U_FREE(str);
00253
00254 return 0;
00255 err:
00256 if(value && value != svalue)
00257 U_FREE(value);
00258 if(name && name != sname)
00259 U_FREE(name);
00260 if(cstr)
00261 dbg("%s", cstr);
00262 U_FREE(str);
00263 if(var)
00264 var_free(var);
00265 return ~0;
00266 }
00267
00268 int vars_add_strvar(vars_t *vs, const char *str)
00269 {
00270 char *eq, *dups = NULL;
00271 var_t *var = NULL;
00272
00273 dbg_err_if (vs == NULL);
00274 dbg_err_if (str == NULL);
00275
00276
00277 dups = u_strdup(str);
00278 dbg_err_if(dups == NULL);
00279
00280
00281 eq = strchr(dups, '=');
00282 dbg_err_if(eq == NULL);
00283 *eq = 0;
00284
00285
00286 dbg_err_if(var_create(dups, eq+1, &var));
00287
00288 U_FREE(dups);
00289
00290
00291 dbg_err_if(vars_add(vs, var));
00292
00293 return 0;
00294 err:
00295 U_FREE(dups);
00296 if(var)
00297 var_free(var);
00298 return ~0;
00299 }
00300
00314 var_t *vars_geti(vars_t *vs, const char *var_name, size_t i)
00315 {
00316 var_t *v;
00317
00318 dbg_goto_if (vs == NULL, notfound);
00319 dbg_goto_if (var_name == NULL, notfound);
00320
00321 TAILQ_FOREACH(v, &vs->list, np)
00322 {
00323 if(strcasecmp(u_string_c(v->sname), var_name) == 0)
00324 {
00325 if(i-- == 0)
00326 return v;
00327 }
00328 }
00329
00330 notfound:
00331 return NULL;
00332 }
00333
00346 var_t *vars_get(vars_t *vs, const char *var_name)
00347 {
00348 dbg_return_if (vs == NULL, NULL);
00349 dbg_return_if (var_name == NULL, NULL);
00350
00351 return vars_geti(vs, var_name, 0);
00352 }
00353
00368 int vars_geti_value_i(vars_t *vs, const char *name, size_t ith)
00369 {
00370 const char *v;
00371
00372 dbg_return_if (vs == NULL, 0);
00373 dbg_return_if (name == NULL, 0);
00374
00375 v = vars_geti_value(vs, name, ith);
00376 if(v == NULL)
00377 return 0;
00378 else
00379 return atoi(v);
00380 }
00381
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
00420 int vars_get_value_i(vars_t *vs, const char *name)
00421 {
00422 dbg_return_if (vs == NULL, 0);
00423 dbg_return_if (name == NULL, 0);
00424
00425 return vars_geti_value_i(vs, name, 0);
00426 }
00427
00442 const char *vars_geti_value(vars_t *vs, const char *name, size_t ith)
00443 {
00444 var_t *v;
00445
00446 dbg_return_if (vs == NULL, NULL);
00447 dbg_return_if (name == NULL, NULL);
00448
00449 v = vars_geti(vs, name, ith);
00450
00451 return v ? var_get_value(v) : NULL;
00452 }
00453
00466 const char *vars_get_value(vars_t *vs, const char *name)
00467 {
00468 dbg_return_if (vs == NULL, NULL);
00469 dbg_return_if (name == NULL, NULL);
00470
00471 return vars_geti_value(vs, name, 0);
00472 }
00473
00486 void vars_foreach(vars_t *vs, int (*cb)(var_t *, void *), void *arg)
00487 {
00488 var_t *v;
00489
00490 dbg_ifb (vs == NULL) return;
00491 dbg_ifb (cb == NULL) return;
00492
00493 TAILQ_FOREACH(v, &vs->list, np)
00494 {
00495 if(cb(v, arg))
00496 break;
00497 }
00498
00499 return;
00500 }
00501