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_mem_msg_new (const char *s, int level, klog_mem_msg_t **pmmsg);
00018 static int klog_mem_msg_push (klog_mem_t *klm, klog_mem_msg_t *mmsg);
00019 static void klog_mem_msg_free (klog_mem_msg_t *mmsg);
00020 static void klog_mem_msgs_free (klog_mem_t *klm);
00021 static void klog_free_mem (klog_mem_t *klm);
00022
00023 static int klog_mem (klog_t *kl, int level, const char *fmt, va_list ap);
00024 static int klog_getln_mem (klog_t *kl, size_t nth, char ln[]);
00025 static ssize_t klog_countln_mem (klog_t *kl);
00026 static void klog_close_mem (klog_t *kl);
00027 static int klog_clear_mem (klog_t *kl);
00028
00029
00030 int klog_open_mem (klog_t *kl, size_t ln_max)
00031 {
00032 klog_mem_t *klm = NULL;
00033
00034 dbg_return_if (kl == NULL, ~0);
00035
00036
00037 klm = u_zalloc(sizeof(klog_mem_t));
00038 dbg_err_if (klm == NULL);
00039
00040
00041 klm->bound = ln_max ? ln_max : 1;
00042 klm->nmsgs = 0;
00043 TAILQ_INIT(&klm->msgs);
00044
00045
00046 kl->cb_log = klog_mem;
00047 kl->cb_close = klog_close_mem;
00048 kl->cb_getln = klog_getln_mem;
00049 kl->cb_countln = klog_countln_mem;
00050 kl->cb_clear = klog_clear_mem;
00051 kl->cb_flush = NULL;
00052
00053
00054 kl->u.m = klm, klm = NULL;
00055
00056 return 0;
00057 err:
00058 if (klm)
00059 klog_free_mem(klm);
00060 return ~0;
00061 }
00062
00063
00064 static int klog_mem (klog_t *kl, int level, const char *fmt, va_list ap)
00065 {
00066 klog_mem_t *klm;
00067 char ln[KLOG_LN_SZ + 1];
00068 klog_mem_msg_t *mmsg = NULL;
00069
00070 dbg_return_if (kl == NULL, ~0);
00071 dbg_return_if (kl->type != KLOG_TYPE_MEM, ~0);
00072 dbg_return_if (kl->u.m == NULL, ~0);
00073 dbg_return_if (fmt == NULL, ~0);
00074
00075 klm = kl->u.m;
00076
00077
00078 vsnprintf(ln, sizeof ln, fmt, ap);
00079 dbg_err_if (klog_mem_msg_new(ln, level, &mmsg));
00080 dbg_err_if (klog_mem_msg_push(klm, mmsg));
00081 mmsg = NULL;
00082
00083 return 0;
00084 err:
00085 if (mmsg)
00086 klog_mem_msg_free(mmsg);
00087 return ~0;
00088 }
00089
00090
00091 static int klog_getln_mem (klog_t *kl, size_t nth, char ln[])
00092 {
00093 size_t i = nth;
00094 klog_mem_msg_t *cur;
00095 char *ct;
00096 klog_mem_t *klm;
00097
00098 dbg_return_if (kl == NULL, ~0);
00099 dbg_return_if (kl->type != KLOG_TYPE_MEM, ~0);
00100 dbg_return_if (kl->u.m == NULL, ~0);
00101 nop_return_if (nth > kl->u.m->nmsgs, ~0);
00102 dbg_return_if (nth == 0, ~0);
00103
00104 klm = kl->u.m;
00105
00106 TAILQ_FOREACH (cur, &klm->msgs, next)
00107 {
00108 if (i-- == 1)
00109 break;
00110 }
00111
00112 ct = ctime((const time_t *) &cur->timestamp);
00113 ct[24] = '\0';
00114
00115
00116
00117
00118
00119 snprintf(ln, KLOG_LN_SZ + 1, "[%s] %s <%s>: %s",
00120 klog_to_str(cur->level), ct, kl->ident, cur->line);
00121
00122 return 0;
00123 }
00124
00125 static ssize_t klog_countln_mem (klog_t *kl)
00126 {
00127 dbg_return_if (kl == NULL, -1);
00128 dbg_return_if (kl->type != KLOG_TYPE_MEM, -1);
00129 dbg_return_if (kl->u.m == NULL, -1);
00130
00131 return kl->u.m->nmsgs;
00132 }
00133
00134 static void klog_close_mem (klog_t *kl)
00135 {
00136 if (kl == NULL || kl->type != KLOG_TYPE_MEM || kl->u.m == NULL)
00137 return;
00138
00139 klog_free_mem(kl->u.m), kl->u.m = NULL;
00140
00141 return;
00142 }
00143
00144 static void klog_free_mem (klog_mem_t *klm)
00145 {
00146 if (klm == NULL)
00147 return;
00148 klog_mem_msgs_free(klm);
00149 U_FREE(klm);
00150 return;
00151 }
00152
00153
00154 static int klog_clear_mem (klog_t *kl)
00155 {
00156 klog_mem_t *klm;
00157
00158 dbg_return_if (kl == NULL, ~0);
00159 dbg_return_if (kl->type != KLOG_TYPE_MEM, ~0);
00160 dbg_return_if (kl->u.m == NULL, ~0);
00161
00162 klm = kl->u.m;
00163
00164
00165 klog_mem_msgs_free(klm);
00166
00167
00168 klm->nmsgs = 0;
00169 TAILQ_INIT(&klm->msgs);
00170
00171 return 0;
00172 }
00173
00174 static void klog_mem_msgs_free (klog_mem_t *klm)
00175 {
00176 klog_mem_msg_t *mmsg;
00177
00178 dbg_ifb (klm == NULL) return;
00179
00180 while((mmsg = TAILQ_FIRST(&klm->msgs)) != NULL)
00181 {
00182 TAILQ_REMOVE(&klm->msgs, mmsg, next);
00183 klm->nmsgs--;
00184 klog_mem_msg_free(mmsg);
00185 }
00186
00187 return;
00188 }
00189
00190 static int klog_mem_msg_new (const char *s, int level, klog_mem_msg_t **pmmsg)
00191 {
00192 klog_mem_msg_t *mmsg = NULL;
00193
00194 dbg_return_if (s == NULL, ~0);
00195 dbg_return_if (pmmsg == NULL, ~0);
00196
00197 mmsg = u_zalloc(sizeof(klog_mem_msg_t));
00198 dbg_err_if (mmsg == NULL);
00199
00200 mmsg->line = u_strndup(s, KLOG_LN_SZ);
00201 mmsg->timestamp = time(NULL);
00202 mmsg->level = level;
00203
00204 *pmmsg = mmsg;
00205
00206 return 0;
00207
00208 err:
00209 if (mmsg)
00210 klog_mem_msg_free(mmsg);
00211 return ~0;
00212 }
00213
00214 static int klog_mem_msg_push (klog_mem_t *klm, klog_mem_msg_t *mmsg)
00215 {
00216 dbg_return_if (klm == NULL, ~0);
00217 dbg_return_if (mmsg == NULL, ~0);
00218
00219
00220 if (KLOG_MEM_FULL(klm))
00221 {
00222 klog_mem_msg_t *last = TAILQ_LAST(&klm->msgs, mh);
00223
00224
00225 if (last != NULL)
00226 {
00227 TAILQ_REMOVE(&klm->msgs, last, next);
00228 klog_mem_msg_free(last);
00229 klm->nmsgs--;
00230 }
00231 }
00232
00233 TAILQ_INSERT_HEAD(&klm->msgs, mmsg, next);
00234 klm->nmsgs++;
00235
00236 return 0;
00237 }
00238
00239 static void klog_mem_msg_free (klog_mem_msg_t *mmsg)
00240 {
00241 dbg_ifb (mmsg == NULL) return;
00242
00243 U_FREE(mmsg->line);
00244 U_FREE(mmsg);
00245
00246 return;
00247 }
00248