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 fflush(klf->wfp);
00174
00175 return 0;
00176 err:
00177 return ~0;
00178 }
00179
00180 static void klog_close_file (klog_t *kl)
00181 {
00182 klog_file_t *klf;
00183
00184 dbg_ifb (kl == NULL) return;
00185 dbg_ifb (kl->type != KLOG_TYPE_FILE) return;
00186 dbg_ifb (kl->u.f == NULL) return;
00187
00188 klf = kl->u.f;
00189
00190
00191 U_FCLOSE(klf->wfp);
00192
00193
00194 dbg_if (klog_file_head_dump(klf));
00195
00196
00197 klog_free_file(klf), kl->u.f = NULL;
00198
00199 return;
00200 }
00201
00202 static int klog_file_head_load (const char *base, klog_file_t **pklf)
00203 {
00204 FILE *hfp = NULL;
00205 char hf[U_FILENAME_MAX];
00206 klog_file_t hfs, *klf = NULL;
00207
00208 dbg_return_if (base == NULL, ~0);
00209 dbg_return_if (pklf == NULL, ~0);
00210
00211 dbg_err_if (u_path_snprintf(hf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s%s",
00212 base, ".head"));
00213 dbg_err_if ((hfp = fopen(hf, "r")) == NULL);
00214 dbg_err_if (fread(&hfs, sizeof hfs, 1, hfp) != 1);
00215 U_FCLOSE(hfp);
00216
00217 dbg_err_if (klog_file_head_new(base, hfs.npages, hfs.nlines,
00218 hfs.wpageid, hfs.offset, &klf));
00219 *pklf = klf;
00220
00221 return 0;
00222 err:
00223 if (klf)
00224 klog_file_head_free(klf);
00225 U_FCLOSE(hfp);
00226 return ~0;
00227 }
00228
00229 static int klog_file_head_dump (klog_file_t *klf)
00230 {
00231 FILE *hfp = NULL;
00232 char hf[U_FILENAME_MAX];
00233
00234 dbg_return_if (klf == NULL, ~0);
00235
00236 dbg_err_if (u_path_snprintf(hf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%s",
00237 klf->basename, "head"));
00238 dbg_err_if ((hfp = fopen(hf, "w")) == NULL);
00239 dbg_err_if (fwrite(klf, sizeof(klog_file_t), 1, hfp) != 1);
00240 U_FCLOSE(hfp);
00241
00242 return 0;
00243 err:
00244 U_FCLOSE(hfp);
00245 return ~0;
00246 }
00247
00248 static int klog_file_head_new (const char *base, size_t npages, size_t nlines,
00249 size_t wpageid, size_t offset, klog_file_t **pklf)
00250 {
00251 klog_file_t *klf = NULL;
00252
00253 klf = u_zalloc(sizeof(klog_file_t));
00254 dbg_err_if (klf == NULL);
00255
00256 u_strlcpy(klf->basename, base, sizeof klf->basename);
00257 klf->npages = npages;
00258 klf->nlines = nlines;
00259 klf->wpageid = wpageid;
00260 klf->offset = offset;
00261 klf->wfp = NULL;
00262
00263 *pklf = klf;
00264
00265 return 0;
00266 err:
00267 klog_file_head_free(klf);
00268 return ~0;
00269 }
00270
00271 static void klog_file_head_free (klog_file_t *klf)
00272 {
00273 if (klf == NULL)
00274 return;
00275
00276 U_FCLOSE(klf->wfp);
00277 U_FREE(klf);
00278
00279 return;
00280 }
00281
00282 static int klog_file_shift_page (klog_file_t *klf)
00283 {
00284 char wf[U_FILENAME_MAX];
00285
00286 dbg_return_if (klf == NULL, ~0);
00287
00288 U_FCLOSE(klf->wfp);
00289 dbg_err_if (u_path_snprintf(wf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%d",
00290 klf->basename, (klf->wpageid + 1)%klf->npages));
00291 dbg_err_if ((klf->wfp = fopen(wf, "w")) == NULL);
00292
00293 klf->offset = 0;
00294 klf->wpageid = ++(klf->wpageid)%klf->npages;
00295
00296 return 0;
00297 err:
00298 return ~0;
00299 }
00300
00301 static int klog_file_open_page (klog_file_t *klf)
00302 {
00303 char wf[U_FILENAME_MAX];
00304
00305 dbg_return_if (klf == NULL, ~0);
00306
00307 dbg_err_if (u_path_snprintf(wf, U_FILENAME_MAX, U_PATH_SEPARATOR, "%s.%d",
00308 klf->basename, klf->wpageid));
00309 dbg_err_if ((klf->wfp = fopen(wf, "a")) == NULL);
00310
00311 return 0;
00312 err:
00313 return ~0;
00314 }