00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <time.h>
00013 #include <u/libu.h>
00014 #include <klone/klog.h>
00015 #include <klone/klogprv.h>
00016
00017 static int klog_args_new (klog_args_t **pka);
00018 static int klog_args_check (klog_args_t *ka);
00019
00020 static int klog_type (const char *type);
00021 static int klog_facility (const char *fac);
00022 static int klog_threshold (const char *threshold);
00023 static int klog_logopt (const char *options);
00024
00025
00037 int klog_args (u_config_t *ls, klog_args_t **pka)
00038 {
00039 const char *cs;
00040 klog_args_t *ka = NULL;
00041
00042 dbg_return_if (ls == NULL, ~0);
00043 dbg_return_if (pka == NULL, ~0);
00044
00045
00046 dbg_err_if (klog_args_new(&ka));
00047
00048
00049 ka->type = klog_type(u_config_get_subkey_value(ls, "type"));
00050
00051 if ((cs = u_config_get_subkey_value(ls, "ident")) != NULL)
00052 ka->ident = u_strdup(cs);
00053
00054 ka->threshold = klog_threshold(u_config_get_subkey_value(ls, "threshold"));
00055
00056 if ((cs = u_config_get_subkey_value(ls, "memory.limit")) != NULL)
00057 ka->mlimit = atoi(cs);
00058
00059 if ((cs = u_config_get_subkey_value(ls, "file.basename")) != NULL)
00060 ka->fbasename = u_strdup(cs);
00061
00062 if ((cs = u_config_get_subkey_value(ls, "file.limit")) != NULL)
00063 ka->flimit = atoi(cs);
00064
00065 if ((cs = u_config_get_subkey_value(ls, "file.splits")) != NULL)
00066 ka->fsplits = atoi(cs);
00067
00068 #ifdef HAVE_SYSLOG
00069 ka->sfacility =
00070 klog_facility(u_config_get_subkey_value(ls, "syslog.facility"));
00071
00072 ka->soptions = klog_logopt(u_config_get_subkey_value(ls, "syslog.options"));
00073 #endif
00074
00075 dbg_return_if (klog_args_check(ka), ~0);
00076
00077 *pka = ka;
00078
00079 return 0;
00080 err:
00081 if (ka)
00082 klog_args_free(ka);
00083 return ~0;
00084 }
00085
00096 int klog_open (klog_args_t *ka, klog_t **pkl)
00097 {
00098 int rv;
00099 klog_t *kl = NULL;
00100
00101 dbg_return_if (pkl == NULL, ~0);
00102 dbg_return_if (ka == NULL, ~0);
00103
00104
00105
00106 dbg_err_if (klog_new(ka->type, ka->threshold, ka->ident, &kl));
00107
00108 switch (ka->type)
00109 {
00110 case KLOG_TYPE_MEM:
00111 rv = klog_open_mem(kl, ka->mlimit);
00112 break;
00113 case KLOG_TYPE_FILE:
00114 rv = klog_open_file(kl, ka->fbasename, ka->fsplits, ka->flimit);
00115 break;
00116 #ifdef HAVE_SYSLOG
00117 case KLOG_TYPE_SYSLOG:
00118 rv = klog_open_syslog(kl, ka->sfacility, ka->soptions);
00119 break;
00120 #endif
00121 default:
00122 return ~0;
00123 }
00124
00125 dbg_err_if (rv);
00126 *pkl = kl;
00127
00128 return 0;
00129 err:
00130 klog_close(kl);
00131 return ~0;
00132 }
00133
00149 int klog (klog_t *kl, int level, const char *fmt, ...)
00150 {
00151 va_list ap;
00152 int rv = 0;
00153
00154 dbg_return_if (kl == NULL, ~0);
00155 dbg_return_if (fmt == NULL, ~0);
00156 dbg_return_if (!IS_KLOG_TYPE(kl->type), ~0);
00157
00158 va_start(ap, fmt);
00159
00160
00161 dbg_goto_if (level < KLOG_DEBUG || level >= KLOG_LEVEL_UNKNOWN, end);
00162
00163
00164 if (level < kl->threshold)
00165 goto end;
00166
00167
00168 if (kl->cb_log)
00169 rv = kl->cb_log(kl, level, fmt, ap);
00170
00171 end:
00172 va_end(ap);
00173
00174 return rv;
00175 }
00176
00184 void klog_close (klog_t *kl)
00185 {
00186 if (kl == NULL)
00187 return;
00188 if (!IS_KLOG_TYPE(kl->type))
00189 return;
00190
00191
00192 if (kl->cb_close)
00193 kl->cb_close(kl);
00194
00195 U_FREE(kl);
00196
00197 return;
00198 }
00199
00212 int klog_getln (klog_t *kl, size_t nth, char ln[])
00213 {
00214 dbg_return_if (kl == NULL, ~0);
00215 dbg_return_if (!IS_KLOG_TYPE(kl->type), ~0);
00216
00217 if (kl->cb_getln)
00218 return kl->cb_getln(kl, nth, ln);
00219
00220 return 0;
00221 }
00222
00232 int klog_clear (klog_t *kl)
00233 {
00234 dbg_return_if (kl == NULL, ~0);
00235 dbg_return_if (!IS_KLOG_TYPE(kl->type), ~0);
00236
00237 if (kl->cb_clear)
00238 return kl->cb_clear(kl);
00239
00240 return ~0;
00241 }
00242
00250 ssize_t klog_countln (klog_t *kl)
00251 {
00252 dbg_return_if (kl == NULL, -1);
00253 dbg_return_if (!IS_KLOG_TYPE(kl->type), ~0);
00254
00255 if (kl->cb_countln)
00256 return kl->cb_countln(kl);
00257
00258 return -1;
00259 }
00260
00272 int klog_open_from_config(u_config_t *ls, klog_t **pkl)
00273 {
00274 klog_t *kl = NULL;
00275 klog_args_t *kargs = NULL;
00276
00277
00278 dbg_err_if(klog_args(ls, &kargs));
00279
00280
00281 dbg_err_if(klog_open(kargs, &kl));
00282
00283 klog_args_free(kargs);
00284 kargs = NULL;
00285
00286
00287 *pkl = kl;
00288
00289 return 0;
00290 err:
00291 if(kargs)
00292 klog_args_free(kargs);
00293 if(kl)
00294 klog_close(kl);
00295 return ~0;
00296 }
00297
00307 int klog_flush (klog_t *kl)
00308 {
00309 dbg_return_if (kl == NULL, ~0);
00310 dbg_return_if (!IS_KLOG_TYPE(kl->type), ~0);
00311
00312
00313 if (kl->cb_flush)
00314 return kl->cb_flush(kl);
00315
00316 return 0;
00317 }
00318
00319
00320
00321 void klog_args_print (FILE *fp, klog_args_t *ka)
00322 {
00323 dbg_ifb (ka == NULL) return;
00324 dbg_ifb (fp == NULL) return;
00325
00326 fprintf(fp, "ka->type: \t %d\n", ka->type);
00327 fprintf(fp, "ka->ident: \t %s\n", ka->ident);
00328 fprintf(fp, "ka->threshold: \t %d\n", ka->threshold);
00329 fprintf(fp, "ka->mlimit: \t %zd\n", ka->mlimit);
00330 fprintf(fp, "ka->fbasename: \t %s\n", ka->fbasename);
00331 fprintf(fp, "ka->fsplits: \t %zd\n", ka->fsplits);
00332 fprintf(fp, "ka->flimit: \t %zd\n", ka->flimit);
00333 fprintf(fp, "ka->soptions: \t %d\n", ka->soptions);
00334 fprintf(fp, "ka->sfacility: \t %d\n", ka->sfacility);
00335
00336 return;
00337 }
00338
00339 void klog_args_free (klog_args_t *ka)
00340 {
00341 U_FREE(ka->ident);
00342 U_FREE(ka->fbasename);
00343 U_FREE(ka);
00344 return;
00345 }
00346
00347
00348 static int klog_type (const char *type)
00349 {
00350 dbg_return_if (type == NULL, KLOG_TYPE_UNKNOWN);
00351
00352 if (!strcasecmp(type, "memory"))
00353 return KLOG_TYPE_MEM;
00354 else if (!strcasecmp(type, "file"))
00355 return KLOG_TYPE_FILE;
00356 else if (!strcasecmp(type, "syslog"))
00357 return KLOG_TYPE_SYSLOG;
00358 else
00359 return KLOG_TYPE_UNKNOWN;
00360 }
00361
00362
00363 static int klog_threshold (const char *threshold)
00364 {
00365 int i;
00366
00367 dbg_return_if (threshold == NULL, KLOG_LEVEL_UNKNOWN);
00368
00369 for (i = KLOG_DEBUG; i <= KLOG_EMERG; i++)
00370 if (!strcasecmp(threshold, kloglev[i]))
00371 return i;
00372
00373 warn("bad threshold value: \'%s\'", threshold);
00374 return KLOG_LEVEL_UNKNOWN;
00375 }
00376
00377 #ifdef HAVE_SYSLOG
00378
00379 static int klog_logopt (const char *options)
00380 {
00381 char *o2 = NULL;
00382 int i, logopt = 0;
00383 enum { NOPTS = 4 };
00384 char *optv[NOPTS + 1];
00385
00386 dbg_return_if (options == NULL, 0);
00387 dbg_return_if ((o2 = u_strdup(options)) == NULL, 0);
00388
00389 dbg_err_if (u_tokenize(o2, " \t", optv, NOPTS + 1));
00390
00391 for (i = 0; optv[i] != NULL; i++)
00392 {
00393 if (!strcasecmp(optv[i], "LOG_CONS"))
00394 logopt |= LOG_CONS;
00395 else if (!strcasecmp(optv[i], "LOG_NDELAY"))
00396 logopt |= LOG_NDELAY;
00397 else if (!strcasecmp(optv[i], "LOG_PERROR"))
00398 logopt |= LOG_PERROR;
00399 else if (!strcasecmp(optv[i], "LOG_PID"))
00400 logopt |= LOG_PID;
00401 else
00402 warn("bad log option: \'%s\'", optv[i]);
00403 }
00404
00405 U_FREE(o2);
00406 return logopt;
00407
00408 err:
00409 U_FREE(o2);
00410 return 0;
00411 }
00412 #endif
00413
00414
00415 static int klog_facility (const char *fac)
00416 {
00417 dbg_err_if (fac == NULL);
00418
00419 if (!strcasecmp(fac, "LOG_LOCAL0"))
00420 return LOG_LOCAL0;
00421 else if (!strcasecmp(fac, "LOG_LOCAL1"))
00422 return LOG_LOCAL1;
00423 else if (!strcasecmp(fac, "LOG_LOCAL2"))
00424 return LOG_LOCAL2;
00425 else if (!strcasecmp(fac, "LOG_LOCAL3"))
00426 return LOG_LOCAL3;
00427 else if (!strcasecmp(fac, "LOG_LOCAL4"))
00428 return LOG_LOCAL4;
00429 else if (!strcasecmp(fac, "LOG_LOCAL5"))
00430 return LOG_LOCAL5;
00431 else if (!strcasecmp(fac, "LOG_LOCAL6"))
00432 return LOG_LOCAL6;
00433 else if (!strcasecmp(fac, "LOG_LOCAL7"))
00434 return LOG_LOCAL7;
00435
00436 err:
00437 warn("bad facility value \'%s\'", fac);
00438 return KLOG_FACILITY_UNKNOWN;
00439 }
00440
00441 static int klog_args_new (klog_args_t **pka)
00442 {
00443 dbg_return_if (pka == NULL, ~0);
00444
00445 *pka = u_zalloc(sizeof(klog_args_t));
00446 dbg_return_if (*pka == NULL, ~0);
00447
00448 return 0;
00449 }
00450
00451 static int klog_args_check (klog_args_t *ka)
00452 {
00453 dbg_return_if (ka == NULL, ~0);
00454
00455 if (ka->type == KLOG_TYPE_UNKNOWN)
00456 warn_err("unknown log type");
00457
00458
00459 if (ka->threshold == KLOG_LEVEL_UNKNOWN)
00460 {
00461 warn("threshold unspecified: assuming lowest possible (DEBUG)");
00462 ka->threshold = KLOG_DEBUG;
00463 }
00464
00465 switch (ka->type)
00466 {
00467 case KLOG_TYPE_MEM:
00468 if (ka->mlimit == 0)
00469 ka->mlimit = KLOG_MLIMIT_DFL;
00470 break;
00471 case KLOG_TYPE_FILE:
00472 if (ka->fbasename == NULL)
00473 warn_err("log file path is mandatory !");
00474 if (ka->fsplits == 0)
00475 ka->fsplits = KLOG_FSPLITS_DFL;
00476 if (ka->flimit == 0)
00477 ka->flimit = KLOG_FLIMIT_DFL;
00478 break;
00479 case KLOG_TYPE_SYSLOG:
00480 if (ka->sfacility == KLOG_FACILITY_UNKNOWN)
00481 {
00482 warn("facility unspecified: defaults to LOG_LOCAL7");
00483 ka->sfacility = LOG_LOCAL7;
00484 }
00485 break;
00486 default:
00487 warn_err("what are you doing here ?");
00488 }
00489
00490 return 0;
00491 err:
00492 return ~0;
00493 }
00494
00495