Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

accesslog.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * accesslog.c - implement access logging functions
00059  *
00060  * see accesslog.h.
00061  *
00062  * Kalle Marjola 2000 for Project Kannel
00063  */
00064 
00065 
00066 #include <stdio.h>
00067 #include <stdlib.h>
00068 #include <errno.h>
00069 #include <time.h>
00070 #include <stdarg.h>
00071 #include <string.h>
00072 
00073 #include "gwlib.h"
00074 
00075 static FILE *file = NULL;
00076 static char filename[FILENAME_MAX + 1]; /* to allow re-open */
00077 static int use_localtime;
00078 static int markers = 1;     /* can be turned-off by 'access-log-clean = yes' */
00079 
00080 /*
00081  * Reopen/rotate lock.
00082  */
00083 static List *writers = NULL;
00084 
00085 void alog_reopen(void)
00086 {
00087     if (file == NULL)
00088     return;
00089 
00090     if (markers)
00091         alog("Log ends");
00092 
00093     gwlist_lock(writers);
00094     /* wait for writers to complete */
00095     gwlist_consume(writers);
00096 
00097     fclose(file);
00098     file = fopen(filename, "a");
00099 
00100     gwlist_unlock(writers);
00101 
00102     if (file == NULL) {
00103         error(errno, "Couldn't re-open access logfile `%s'.", filename);
00104     } 
00105     else if (markers) {
00106         alog("Log begins");
00107     }
00108 }
00109 
00110 
00111 void alog_close(void)
00112 {
00113 
00114     if (file != NULL) {
00115         if (markers)
00116             alog("Log ends");
00117         gwlist_lock(writers);
00118         /* wait for writers to complete */
00119         gwlist_consume(writers);
00120         fclose(file);
00121         file = NULL;
00122         gwlist_unlock(writers);
00123         gwlist_destroy(writers, NULL);
00124         writers = NULL;
00125     }
00126 }
00127 
00128 
00129 void alog_open(char *fname, int use_localtm, int use_markers)
00130 {
00131     FILE *f;
00132     
00133     use_localtime = use_localtm;
00134     markers = use_markers;
00135 
00136     if (file != NULL) {
00137         warning(0, "Opening an already opened access log");
00138         alog_close();
00139     }
00140     if (strlen(fname) > FILENAME_MAX) {
00141         error(0, "Access Log filename too long: `%s', cannot open.", fname);
00142         return;
00143     }
00144 
00145     if (writers == NULL)
00146         writers = gwlist_create();
00147 
00148     f = fopen(fname, "a");
00149     if (f == NULL) {
00150         error(errno, "Couldn't open logfile `%s'.", fname);
00151         return;
00152     }
00153     file = f;
00154     strcpy(filename, fname);
00155     info(0, "Started access logfile `%s'.", filename);
00156     if (markers)
00157         alog("Log begins");
00158 }
00159 
00160 
00161 void alog_use_localtime(void)
00162 {
00163     use_localtime = 1;
00164 }
00165 
00166 
00167 void alog_use_gmtime(void)
00168 {
00169     use_localtime = 0;
00170 }
00171 
00172 
00173 #define FORMAT_SIZE (10*1024)
00174 static void format(char *buf, const char *fmt)
00175 {
00176     time_t t;
00177     struct tm tm;
00178     char *p, prefix[1024];
00179     
00180     p = prefix;
00181 
00182     if (markers) {
00183         time(&t);
00184         if (use_localtime)
00185             tm = gw_localtime(t);
00186         else
00187             tm = gw_gmtime(t);
00188 
00189         sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d ",
00190                 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
00191                 tm.tm_hour, tm.tm_min, tm.tm_sec);
00192     } else {
00193         *p = '\0';
00194     }
00195 
00196     if (strlen(prefix) + strlen(fmt) > FORMAT_SIZE / 2) {
00197         sprintf(buf, "%s <OUTPUT message too long>\n", prefix);
00198         return;
00199     }
00200     sprintf(buf, "%s%s\n", prefix, fmt);
00201 }
00202 
00203 
00204 /* XXX should we also log automatically into main log, too? */
00205 
00206 void alog(const char *fmt, ...)
00207 {
00208     char buf[FORMAT_SIZE + 1];
00209     va_list args;
00210 
00211     if (file == NULL)
00212         return;
00213 
00214     format(buf, fmt);
00215     va_start(args, fmt);
00216 
00217     gwlist_lock(writers);
00218     gwlist_add_producer(writers);
00219     gwlist_unlock(writers);
00220 
00221     vfprintf(file, buf, args);
00222     fflush(file);
00223 
00224     gwlist_remove_producer(writers);
00225 
00226     va_end(args);
00227 }
00228 
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.