00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <sys/param.h>
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014 #include <fcntl.h>
00015 #include <unistd.h>
00016 #include <u/libu.h>
00017 #include <klone/klog.h>
00018 #include <klone/klogprv.h>
00019
00020 static void klog_close_file (klog_t *klf);
00021 static int klog_file (klog_t *klf, int level, const char *fmt, va_list ap);
00022 static int klog_flush_file (klog_t *kl);
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 static void klog_free_file (klog_file_t *klf);
00052 static int klog_file_head_load (const char *base, klog_file_t **pklf);
00053 static int klog_file_head_dump (klog_file_t *klf);
00054 static int klog_file_head_new (const char *base, size_t npages, size_t nlines,
00055 size_t wpageid, size_t offset, klog_file_t **pklf);
00056 static void klog_file_head_free (klog_file_t *klf);
00057 static int klog_file_append (klog_file_t *klf, const char *id, int level,
00058 const char *ln);
00059 static int klog_file_open_page (klog_file_t *klf);
00060 static int klog_file_shift_page (klog_file_t *klf);
00061
00062 int klog_open_file (klog_t *kl, const char *base, size_t npages, size_t nlines)
00063 {
00064 klog_file_t *klf = NULL;
00065
00066 dbg_return_if (kl == NULL, ~0);
00067 dbg_return_if (base == NULL, ~0);
00068
00069
00070 if (klog_file_head_load(base, &klf))
00071 dbg_err_if (klog_file_head_new(base, npages, nlines, 0, 0, &klf));
00072 else
00073 {
00074
00075
00076 dbg_ifb (klf->npages != npages || klf->nlines != nlines)
00077 {
00078 klf->npages = npages;
00079 klf->nlines = nlines;
00080 klf->wpageid = 0;
00081 klf->offset = 0;
00082 }
00083 }
00084
00085
00086 dbg_err_if (klog_file_open_page(klf));
00087
00088
00089 kl->cb_log = klog_file;
00090 kl->cb_close = klog_close_file;
00091 kl->cb_getln = NULL;
00092 kl->cb_countln = NULL;
00093 kl->cb_clear = NULL;
00094 kl->cb_flush = klog_flush_file;
00095
00096 kl->u.f = klf, klf = NULL;
00097
00098 return 0;
00099 err:
00100 if (klf)
00101 klog_free_file(klf);
00102 return ~0;
00103 }
00104
00105 static void klog_free_file (klog_file_t *klf)
00106 {
00107 U_FREE(klf);
00108 }
00109
00110 static int klog_flush_file (klog_t *kl)
00111 {
00112 klog_file_t *klf;
00113
00114 dbg_return_if (kl == NULL, ~0);
00115 dbg_return_if (kl->type != KLOG_TYPE_FILE, ~0);
00116 dbg_return_if (kl->u.f == NULL, ~0);
00117
00118 klf = kl->u.f;
00119
00120 dbg_err_if (klf->wfp == NULL);
00121 dbg_err_sif (fflush(klf->wfp) != 0);
00122
00123 return 0;
00124 err:
00125 return ~0;
00126 }
00127
00128 static int klog_file (klog_t *kl, int level, const char *fmt, va_list ap)
00129 {
00130 klog_file_t *klf;
00131 char ln[KLOG_LN_SZ + 1];
00132
00133 dbg_return_if (kl == NULL, ~0);
00134 dbg_return_if (kl->type != KLOG_TYPE_FILE, ~0);
00135 dbg_return_if (kl->u.f == NULL, ~0);
00136 dbg_return_if (fmt == NULL, ~0);
00137
00138 klf = kl->u.f;
00139
00140
00141 vsnprintf(ln, sizeof ln, fmt, ap);
00142
00143 if (KLOG_PAGE_FULL(klf))
00144 dbg_err_if (klog_file_shift_page(klf));
00145
00146 dbg_err_if (klog_file_append(klf, kl->ident, level, ln));
00147
00148 return 0;
00149 err:
00150 return ~0;
00151 }
00152
00153 static int klog_file_append (klog_file_t *klf, const char *id, int level,
00154 const char *ln)
00155 {
00156 time_t now;
00157 char *ct;
00158
00159 dbg_return_if (ln == NULL, ~0);
00160 dbg_return_if (id == NULL, ~0);
00161 dbg_return_if (klf == NULL, ~0);
00162 dbg_return_if (klf->wfp == NULL, ~0);
00163
00164 dbg_err_if ((now = time(NULL)) == (time_t) -1);
00165 ct = ctime((const time_t *) &now);
00166 ct[24] = '\0';
00167
00168
00169 fprintf(klf->wfp, "[%s] %s <%s>: %s\n",
00170 klog_to_str(level), ct, id, ln);
00171 klf->offset += 1;
00172
00173 return 0;
00174 err:
00175 return ~0;
00176 }
00177
00178 static void klog_close_file (klog_t *kl)
00179 {
00180 klog_file_t *klf;
00181
00182 dbg_ifb (kl == NULL) return;
00183 dbg_ifb (kl->type != KLOG_TYPE_FILE) return;
00184 dbg_ifb (kl->u.f == NULL) return;
00185
00186 klf = kl->u.f;
00187
00188
00189 U_FCLOSE(klf->wfp);
00190
00191
00192 dbg_if (klog_file_head_dump(klf));
00193
00194
00195 klog_free_file(klf), kl->u.f = NULL;
00196
00197 return;
00198 }
00199
00200 static int klog_file_head_load (const char *base, klog_file_t **pklf)
00201 {
00202 FILE *hfp = NULL;
00203 char hf[U_FILENAME_MAX];
00204 klog_file_t hfs, *klf = NULL;
00205
00206 dbg_return_if (base == NULL, ~0);
00207 dbg_return_if (pklf == NULL, ~0);
00208
00209 dbg_err_if (u_path_snprintf(hf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s%s",
00210 base, ".head"));
00211 dbg_err_if ((hfp = fopen(hf, "r")) == NULL);
00212 dbg_err_if (fread(&hfs, sizeof hfs, 1, hfp) != 1);
00213 U_FCLOSE(hfp);
00214
00215 dbg_err_if (klog_file_head_new(base, hfs.npages, hfs.nlines,
00216 hfs.wpageid, hfs.offset, &klf));
00217 *pklf = klf;
00218
00219 return 0;
00220 err:
00221 if (klf)
00222 klog_file_head_free(klf);
00223 U_FCLOSE(hfp);
00224 return ~0;
00225 }
00226
00227 static int klog_file_head_dump (klog_file_t *klf)
00228 {
00229 FILE *hfp = NULL;
00230 char hf[U_FILENAME_MAX];
00231
00232 dbg_return_if (klf == NULL, ~0);
00233
00234 dbg_err_if (u_path_snprintf(hf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%s",
00235 klf->basename, "head"));
00236 dbg_err_if ((hfp = fopen(hf, "w")) == NULL);
00237 dbg_err_if (fwrite(klf, sizeof(klog_file_t), 1, hfp) != 1);
00238 U_FCLOSE(hfp);
00239
00240 return 0;
00241 err:
00242 U_FCLOSE(hfp);
00243 return ~0;
00244 }
00245
00246 static int klog_file_head_new (const char *base, size_t npages, size_t nlines,
00247 size_t wpageid, size_t offset, klog_file_t **pklf)
00248 {
00249 klog_file_t *klf = NULL;
00250
00251 klf = u_zalloc(sizeof(klog_file_t));
00252 dbg_err_if (klf == NULL);
00253
00254 u_sstrncpy(klf->basename, base, U_FILENAME_MAX - 1);
00255 klf->npages = npages;
00256 klf->nlines = nlines;
00257 klf->wpageid = wpageid;
00258 klf->offset = offset;
00259 klf->wfp = NULL;
00260
00261 *pklf = klf;
00262
00263 return 0;
00264 err:
00265 klog_file_head_free(klf);
00266 return ~0;
00267 }
00268
00269 static void klog_file_head_free (klog_file_t *klf)
00270 {
00271 if (klf == NULL)
00272 return;
00273
00274 U_FCLOSE(klf->wfp);
00275 U_FREE(klf);
00276
00277 return;
00278 }
00279
00280 static int klog_file_shift_page (klog_file_t *klf)
00281 {
00282 char wf[U_FILENAME_MAX];
00283
00284 dbg_return_if (klf == NULL, ~0);
00285
00286 U_FCLOSE(klf->wfp);
00287 dbg_err_if (u_path_snprintf(wf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%d",
00288 klf->basename, (klf->wpageid + 1)%klf->npages));
00289 dbg_err_if ((klf->wfp = fopen(wf, "w")) == NULL);
00290
00291 klf->offset = 0;
00292 klf->wpageid = ++(klf->wpageid)%klf->npages;
00293
00294 return 0;
00295 err:
00296 return ~0;
00297 }
00298
00299 static int klog_file_open_page (klog_file_t *klf)
00300 {
00301 char wf[U_FILENAME_MAX];
00302
00303 dbg_return_if (klf == NULL, ~0);
00304
00305 dbg_err_if (u_path_snprintf(wf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%d",
00306 klf->basename, klf->wpageid));
00307 dbg_err_if ((klf->wfp = fopen(wf, "a")) == NULL);
00308
00309 return 0;
00310 err:
00311 return ~0;
00312 }