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