logger.c revision 1.1
1/* $KAME: logger.c,v 1.9 2002/09/03 14:37:03 itojun Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include "config.h" 33 34#include <sys/types.h> 35#include <sys/param.h> 36 37#include <stdlib.h> 38#include <stdio.h> 39#include <string.h> 40#include <errno.h> 41#ifdef HAVE_STDARG_H 42#include <stdarg.h> 43#else 44#include <varargs.h> 45#endif 46#if TIME_WITH_SYS_TIME 47# include <sys/time.h> 48# include <time.h> 49#else 50# if HAVE_SYS_TIME_H 51# include <sys/time.h> 52# else 53# include <time.h> 54# endif 55#endif 56 57#include "logger.h" 58#include "var.h" 59#include "gcmalloc.h" 60 61struct log * 62log_open(siz, fname) 63 size_t siz; 64 char *fname; 65{ 66 struct log *p; 67 68 p = (struct log *)racoon_malloc(sizeof(*p)); 69 if (p == NULL) 70 return NULL; 71 memset(p, 0, sizeof(*p)); 72 73 p->buf = (char **)racoon_malloc(sizeof(char *) * siz); 74 if (p->buf == NULL) { 75 racoon_free(p); 76 return NULL; 77 } 78 memset(p->buf, 0, sizeof(char *) * siz); 79 80 p->tbuf = (time_t *)racoon_malloc(sizeof(time_t *) * siz); 81 if (p->tbuf == NULL) { 82 racoon_free(p->buf); 83 racoon_free(p); 84 return NULL; 85 } 86 memset(p->tbuf, 0, sizeof(time_t *) * siz); 87 88 p->siz = siz; 89 if (fname) 90 p->fname = strdup(fname); 91 92 return p; 93} 94 95/* 96 * append string to ring buffer. 97 * string must be \n-terminated (since we add timestamps). 98 * even if not, we'll add \n to avoid formatting mistake (see log_close()). 99 */ 100void 101log_add(p, str) 102 struct log *p; 103 char *str; 104{ 105 /* syslog if p->fname == NULL? */ 106 if (p->buf[p->head]) 107 racoon_free(p->buf[p->head]); 108 p->buf[p->head] = strdup(str); 109 p->tbuf[p->head] = time(NULL); 110 p->head++; 111 p->head %= p->siz; 112} 113 114/* 115 * write out string to the log file, as is. 116 * \n-termination is up to the caller. if you don't add \n, the file 117 * format may be broken. 118 */ 119int 120log_print(p, str) 121 struct log *p; 122 char *str; 123{ 124 FILE *fp; 125 126 if (p->fname == NULL) 127 return -1; /*XXX syslog?*/ 128 fp = fopen(p->fname, "a"); 129 if (fp == NULL) 130 return -1; 131 fprintf(fp, "%s", str); 132 fclose(fp); 133 134 return 0; 135} 136 137int 138log_vprint(struct log *p, const char *fmt, ...) 139{ 140 va_list ap; 141 142 FILE *fp; 143 144 if (p->fname == NULL) 145 return -1; /*XXX syslog?*/ 146 fp = fopen(p->fname, "a"); 147 if (fp == NULL) 148 return -1; 149 va_start(ap, fmt); 150 vfprintf(fp, fmt, ap); 151 va_end(ap); 152 153 fclose(fp); 154 155 return 0; 156} 157 158int 159log_vaprint(struct log *p, const char *fmt, va_list ap) 160{ 161 FILE *fp; 162 163 if (p->fname == NULL) 164 return -1; /*XXX syslog?*/ 165 fp = fopen(p->fname, "a"); 166 if (fp == NULL) 167 return -1; 168 vfprintf(fp, fmt, ap); 169 fclose(fp); 170 171 return 0; 172} 173 174/* 175 * write out content of ring buffer, and reclaim the log structure 176 */ 177int 178log_close(p) 179 struct log *p; 180{ 181 FILE *fp; 182 int i, j; 183 char ts[256]; 184 struct tm *tm; 185 186 if (p->fname == NULL) 187 goto nowrite; 188 fp = fopen(p->fname, "a"); 189 if (fp == NULL) 190 goto nowrite; 191 192 for (i = 0; i < p->siz; i++) { 193 j = (p->head + i) % p->siz; 194 if (p->buf[j]) { 195 tm = localtime(&p->tbuf[j]); 196 strftime(ts, sizeof(ts), "%B %d %T", tm); 197 fprintf(fp, "%s: %s\n", ts, p->buf[j]); 198 if (*(p->buf[j] + strlen(p->buf[j]) - 1) != '\n') 199 fprintf(fp, "\n"); 200 } 201 } 202 fclose(fp); 203 204nowrite: 205 log_free(p); 206 return 0; 207} 208 209void 210log_free(p) 211 struct log *p; 212{ 213 int i; 214 215 for (i = 0; i < p->siz; i++) 216 racoon_free(p->buf[i]); 217 racoon_free(p->buf); 218 racoon_free(p->tbuf); 219 if (p->fname) 220 racoon_free(p->fname); 221 racoon_free(p); 222} 223 224#ifdef TEST 225struct log *l; 226 227void 228vatest(const char *fmt, ...) 229{ 230 va_list ap; 231 va_start(ap, fmt); 232 log_vaprint(l, fmt, ap); 233 va_end(ap); 234} 235 236int 237main(argc, argv) 238 int argc; 239 char **argv; 240{ 241 int i; 242 243 l = log_open(30, "/tmp/hoge"); 244 if (l == NULL) 245 errx(1, "hoge"); 246 247 for (i = 0; i < 50; i++) { 248 log_add(l, "foo"); 249 log_add(l, "baa"); 250 log_add(l, "baz"); 251 } 252 log_print(l, "hoge\n"); 253 log_vprint(l, "hoge %s\n", "this is test"); 254 vatest("%s %s\n", "this is", "vprint test"); 255 abort(); 256 log_free(l); 257} 258 259#endif 260 261