Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
accesslog.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * accesslog.c - implement access logging functions
59  *
60  * see accesslog.h.
61  *
62  * Kalle Marjola 2000 for Project Kannel
63  */
64 
65 
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <errno.h>
69 #include <time.h>
70 #include <stdarg.h>
71 #include <string.h>
72 
73 #include "gwlib.h"
74 
75 static FILE *file = NULL;
76 static char filename[FILENAME_MAX + 1]; /* to allow re-open */
77 static int use_localtime;
78 static int markers = 1; /* can be turned-off by 'access-log-clean = yes' */
79 
80 /*
81  * Reopen/rotate lock.
82  */
83 static List *writers = NULL;
84 
85 void alog_reopen(void)
86 {
87  if (file == NULL)
88  return;
89 
90  if (markers)
91  alog("Log ends");
92 
93  gwlist_lock(writers);
94  /* wait for writers to complete */
95  gwlist_consume(writers);
96 
97  fclose(file);
98  file = fopen(filename, "a");
99 
100  gwlist_unlock(writers);
101 
102  if (file == NULL) {
103  error(errno, "Couldn't re-open access logfile `%s'.", filename);
104  }
105  else if (markers) {
106  alog("Log begins");
107  }
108 }
109 
110 
111 void alog_close(void)
112 {
113 
114  if (file != NULL) {
115  if (markers)
116  alog("Log ends");
117  gwlist_lock(writers);
118  /* wait for writers to complete */
119  gwlist_consume(writers);
120  fclose(file);
121  file = NULL;
122  gwlist_unlock(writers);
123  gwlist_destroy(writers, NULL);
124  writers = NULL;
125  }
126 }
127 
128 
129 void alog_open(char *fname, int use_localtm, int use_markers)
130 {
131  FILE *f;
132 
133  use_localtime = use_localtm;
134  markers = use_markers;
135 
136  if (file != NULL) {
137  warning(0, "Opening an already opened access log");
138  alog_close();
139  }
140  if (strlen(fname) > FILENAME_MAX) {
141  error(0, "Access Log filename too long: `%s', cannot open.", fname);
142  return;
143  }
144 
145  if (writers == NULL)
146  writers = gwlist_create();
147 
148  f = fopen(fname, "a");
149  if (f == NULL) {
150  error(errno, "Couldn't open logfile `%s'.", fname);
151  return;
152  }
153  file = f;
154  strcpy(filename, fname);
155  info(0, "Started access logfile `%s'.", filename);
156  if (markers)
157  alog("Log begins");
158 }
159 
160 
162 {
163  use_localtime = 1;
164 }
165 
166 
167 void alog_use_gmtime(void)
168 {
169  use_localtime = 0;
170 }
171 
172 
173 #define FORMAT_SIZE (10*1024)
174 static void format(char *buf, const char *fmt)
175 {
176  time_t t;
177  struct tm tm;
178  char *p, prefix[1024];
179 
180  p = prefix;
181 
182  if (markers) {
183  time(&t);
184  if (use_localtime)
185  tm = gw_localtime(t);
186  else
187  tm = gw_gmtime(t);
188 
189  sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d ",
190  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
191  tm.tm_hour, tm.tm_min, tm.tm_sec);
192  } else {
193  *p = '\0';
194  }
195 
196  if (strlen(prefix) + strlen(fmt) > FORMAT_SIZE / 2) {
197  sprintf(buf, "%s <OUTPUT message too long>\n", prefix);
198  return;
199  }
200  sprintf(buf, "%s%s\n", prefix, fmt);
201 }
202 
203 
204 /* XXX should we also log automatically into main log, too? */
205 
206 void alog(const char *fmt, ...)
207 {
208  char buf[FORMAT_SIZE + 1];
209  va_list args;
210 
211  if (file == NULL)
212  return;
213 
214  format(buf, fmt);
215  va_start(args, fmt);
216 
217  gwlist_lock(writers);
218  gwlist_add_producer(writers);
219  gwlist_unlock(writers);
220 
221  vfprintf(file, buf, args);
222  fflush(file);
223 
224  gwlist_remove_producer(writers);
225 
226  va_end(args);
227 }
228 
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
static int markers
Definition: accesslog.c:78
struct tm gw_gmtime(time_t t)
Definition: protected.c:137
#define FORMAT_SIZE
Definition: accesslog.c:173
static char filename[FILENAME_MAX+1]
Definition: accesslog.c:76
static void format(char *buf, const char *fmt)
Definition: accesslog.c:174
static int use_localtime
Definition: accesslog.c:77
void gwlist_unlock(List *list)
Definition: list.c:354
void alog_use_gmtime(void)
Definition: accesslog.c:167
void gwlist_remove_producer(List *list)
Definition: list.c:401
void alog_use_localtime(void)
Definition: accesslog.c:161
void warning(int err, const char *fmt,...)
Definition: log.c:624
void alog_open(char *fname, int use_localtm, int use_markers)
Definition: accesslog.c:129
void gwlist_lock(List *list)
Definition: list.c:347
void alog_reopen(void)
Definition: accesslog.c:85
void * gwlist_consume(List *list)
Definition: list.c:427
void alog(const char *fmt,...)
Definition: accesslog.c:206
static List * writers
Definition: accesslog.c:83
struct tm gw_localtime(time_t t)
Definition: protected.c:121
static FILE * file
Definition: accesslog.c:75
void alog_close(void)
Definition: accesslog.c:111
#define gwlist_create()
Definition: list.h:136
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.