⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * log.c - implement logging functions */#include "gwlib.h"#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <time.h>#include <stdarg.h>#include <string.h>#ifdef HAVE_EXECINFO_H#include <execinfo.h>#endif#if HAVE_SYSLOG_H#include <syslog.h>#else/* * If we don't have syslog.h, then we'll use the following dummy definitions * to avoid writing #if HAVE_SYSLOG_H everywhere. */enum {    LOG_PID, LOG_DAEMON, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_ALERT};static void openlog(const char *ident, int option, int facility){}static void syslog(int translog, const char *buf){}static void closelog(void){}#endif/* * List of currently open log files. */#define MAX_LOGFILES 128static struct {    FILE *file;    int minimum_output_level;    char filename[FILENAME_MAX + 1]; /* to allow re-open */    enum excl_state exclusive;} logfiles[MAX_LOGFILES];static int num_logfiles = 0;/* * Mapping array between thread id and logfiles[] index. * This is used for smsc specific logging. */#define THREADTABLE_SIZE 1024static unsigned int thread_to[(long)THREADTABLE_SIZE];/* * Ensure we use the real threadtable slot number to map the thread id * instead of the thread id reported by gwthread_self() */#define thread_slot() \    (gwthread_self() % THREADTABLE_SIZE)/* * List of places that should be logged at debug-level. */#define MAX_LOGGABLE_PLACES (10*1000)static char *loggable_places[MAX_LOGGABLE_PLACES];static int num_places = 0;/* * Reopen/rotate locking things. */static List *writers = NULL;/* * Syslog support. */static int sysloglevel;static int dosyslog = 0;/* * Make sure stderr is included in the list. */static void add_stderr(void){    int i;    for (i = 0; i < num_logfiles; ++i)	if (logfiles[i].file == stderr)	    return;    logfiles[num_logfiles].file = stderr;    logfiles[num_logfiles].minimum_output_level = GW_DEBUG;    logfiles[num_logfiles].exclusive = GW_NON_EXCL;    ++num_logfiles;}void log_init(void){    unsigned long i;    /* default all possible thread to logging index 0, stderr */    for (i = 0; i <= THREADTABLE_SIZE; i++) {        thread_to[i] = 0;    }    add_stderr();    /* initialize rw lock */    if (writers == NULL);        writers = list_create();}void log_shutdown(void){    log_close_all();    if (writers != NULL)        list_destroy(writers, NULL);    writers = NULL;}void log_set_output_level(enum output_level level){    int i;    for (i = 0; i < num_logfiles; ++i) {	if (logfiles[i].file == stderr) {	    logfiles[i].minimum_output_level = level;	    break;	}    }}void log_set_log_level(enum output_level level){    int i;    /* change everything but stderr */    for (i = 0; i < num_logfiles; ++i) {        if (logfiles[i].file != stderr) {            logfiles[i].minimum_output_level = level;            info(0, "Changed logfile `%s' to level `%d'.", logfiles[i].filename, level);        }    }}void log_set_syslog(const char *ident, int syslog_level){    if (ident == NULL)	dosyslog = 0;    else {	dosyslog = 1;	sysloglevel = syslog_level;	openlog(ident, LOG_PID, LOG_DAEMON);	debug("gwlib.log", 0, "Syslog logging enabled.");    }}void log_reopen(void){    int i, j, found;    /*     * Writer lock.     */    if (writers != NULL) {        list_lock(writers);        /* wait for writers complete */        list_consume(writers);    }    for (i = 0; i < num_logfiles; ++i) {        if (logfiles[i].file != stderr) {            found = 0;            /*             * Reverse seek for allready reopened logfile.             * If we find a previous file descriptor for the same file             * name, then don't reopen that duplicate, but assign the             * file pointer to it.             */            for (j = i-1; j >= 0 && found == 0; j--) {                if (strcmp(logfiles[i].filename, logfiles[j].filename) == 0) {                    logfiles[i].file = logfiles[j].file;                    found = 1;                }            }            if (found)                continue;            if (logfiles[i].file != NULL)                fclose(logfiles[i].file);            logfiles[i].file = fopen(logfiles[i].filename, "a");            if (logfiles[i].file == NULL) {                error(errno, "Couldn't re-open logfile `%s'.",                      logfiles[i].filename);            }        }    }    /*     * Unlock writer.     */    if (writers != NULL)        list_unlock(writers);}void log_close_all(void){    /*     * Writer lock.     */    if (writers != NULL) {        list_lock(writers);        /* wait for writers */        list_consume(writers);    }    while (num_logfiles > 0) {        --num_logfiles;        if (logfiles[num_logfiles].file != stderr &&            logfiles[num_logfiles].file != NULL)            fclose(logfiles[num_logfiles].file);        logfiles[num_logfiles].file = NULL;    }    /*     * Unlock writer.     */    if (writers != NULL)        list_unlock(writers);    /* close syslog if used */    if (dosyslog) {        closelog();        dosyslog = 0;    }}int log_open(char *filename, int level, enum excl_state excl){    FILE *f = NULL;    int i;        if (writers == NULL)        writers = list_create();    if (num_logfiles == MAX_LOGFILES) {        error(0, "Too many log files already open, not adding `%s'",              filename);        return -1;    }    if (strlen(filename) > FILENAME_MAX) {        error(0, "Log filename too long: `%s'.", filename);        return -1;    }    /*     * Check if the file is already opened for logging.     * If there is an open file, then assign the file descriptor     * that is already existing for this log file.     */    for (i = 0; i < num_logfiles && f == NULL; ++i) {        if (strcmp(logfiles[i].filename, filename) == 0)            f = logfiles[i].file;    }    /* if not previously opened, then open it now */    if (f == NULL) {        f = fopen(filename, "a");        if (f == NULL) {            error(errno, "Couldn't open logfile `%s'.", filename);            return -1;        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -