version 0.9.6
[rofl0r-htun.git] / src / log.c
blob4e9db8b3dcbf27fb0511449e9946595fb0fc5cf0
1 /* -------------------------------------------------------------------------
2 * log.c - htun logging functions
3 * Copyright (C) 2002 Moshe Jacobson <moshe@runslinux.net>,
4 * Ola NordstrÖm <ola@triblock.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * -------------------------------------------------------------------------
21 /* $Id: log.c,v 2.5 2005/04/27 20:11:26 jehsom Exp $ */
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <semaphore.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <time.h>
31 #include <pthread.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
36 #include "log.h"
37 #include "util.h"
39 /* Allows printf()-like interface to file descriptors without the
40 * complications that arise from mixing stdio and low level calls
41 * FIXME: Needs date and time before logfile entries.
43 int lprintf_real( const char *func, log_t *log, unsigned int level, char *fmt, ... ) {
44 int fd;
45 int rc;
46 va_list ap;
47 time_t now;
48 char date[50];
49 static char line[LOGLINE_MAX];
50 static char threadnum[10];
51 int cnt;
52 static char *levels[6] = { "[(bad)] ",
53 "[debug] ",
54 "[info ] ",
55 "[warn ] ",
56 "[error] ",
57 "[fatal] " };
59 if(!log) return -1;
61 /* If this is debug info, and we're not logging it, return */
62 if( !(log->flags&LOG_DEBUG) && level == DEBUG ) return 0;
64 fd=log->fd;
66 /* Prepare the date string */
67 if( !(log->flags&LOG_NODATE) ) {
68 now=time(NULL);
69 strcpy(date,ctime(&now));
70 date[strlen(date)-6]=' ';
71 date[strlen(date)-5]='\0';
74 if( !(log->flags&LOG_NOTID) ) {
75 sprintf(threadnum, "(%lu) ", pthread_self());
78 cnt = snprintf(line, sizeof(line), "%s%s%s%s%s",
79 log->flags&LOG_NODATE ? "" : date,
80 log->flags&LOG_NOLVL ? "" :
81 (level > FATAL ? levels[0] : levels[level]),
82 log->flags&LOG_NOTID ? "" : threadnum,
83 log->flags&LOG_FUNC ? func : "",
84 log->flags&LOG_FUNC ? ": " : "");
86 va_start(ap, fmt);
87 vsnprintf(line+cnt, sizeof(line)-cnt, fmt, ap);
88 va_end(ap);
90 line[sizeof(line)-1] = '\0';
92 if( !(log->flags&LOG_NOLF) ) {
93 chomp(line);
94 strcpy(line+strlen(line), "\n");
97 sem_wait(&log->sem);
98 rc = write(fd, line, strlen(line));
99 sem_post(&log->sem);
101 if( !rc ) errno = 0;
102 return rc;
105 log_t *log_open( char *fname, int flags ) {
106 log_t *log = malloc(sizeof(log_t));
108 if(!log) {
109 fprintf(stderr, "log_open: Unable to malloc()");
110 goto log_open_a;
112 log->flags=flags;
113 if( !strcmp(fname,"-") ) {
114 log->fd = 2;
115 } else {
116 log->fd = open(fname, O_WRONLY|O_CREAT|O_NOCTTY |
117 (flags&LOG_TRUNC ? O_TRUNC : O_APPEND) , 0666);
120 if( log->fd == -1 ) {
121 fprintf(stderr, "log_open: Opening logfile %s: %s",
122 fname, strerror(errno));
123 goto log_open_b;
125 if( sem_init(&log->sem, 0, 1) == -1 ) {
126 fprintf(stderr, "log_open: Could not initialize log semaphore.");
127 goto log_open_c;
129 return log;
131 log_open_c:
132 close(log->fd);
133 log_open_b:
134 free(log);
135 log_open_a:
136 return NULL;
139 void log_close( log_t *log ) {
140 sem_wait(&log->sem);
141 sem_destroy(&log->sem);
142 close(log->fd);
143 free(log);
144 return;