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

📄 log.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* error logging functions * Copyright (C) 1997 Angelos D. Keromytis. * Copyright (C) 1998-2001  D. Hugh Redelmeier. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. * * RCSID $Id: log.c,v 1.90 2004/11/15 14:34:03 mcr Exp $ */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <stdarg.h>#include <syslog.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <signal.h>	/* used only if MSG_NOSIGNAL not defined */#include <sys/queue.h>#include <libgen.h>#include <sys/stat.h>#include <sys/types.h>#include <openswan.h>#include "constants.h"#include "oswlog.h"#include "defs.h"#include "log.h"#include "server.h"#include "state.h"#include "id.h"#include "x509.h"#include "pgp.h"#include "certs.h"#include "smartcard.h"#ifdef XAUTH_USEPAM#include <security/pam_appl.h>#endif#include "connections.h"	/* needs id.h */#include "kernel.h"	/* needs connections.h */#include "whack.h"	/* needs connections.h */#include "timer.h"#include "paths.h"#include "kernel_alg.h"#include "ike_alg.h"#include "plutoalg.h"#ifndef NO_DB_OPS_STATS#define NO_DB_CONTEXT#include "db_ops.h"#endif/* close one per-peer log */static void perpeer_logclose(struct connection *c);	/* forward */bool    log_to_stderr = TRUE,	/* should log go to stderr? */    log_to_syslog = TRUE,	/* should log go to syslog? */    log_to_perpeer= FALSE;	/* should log go to per-IP file? */bool    logged_txt_warning = FALSE;  /* should we complain about finding KEY? *//* should we complain when we find no local id */bool    logged_myid_fqdn_txt_warning = FALSE,    logged_myid_ip_txt_warning   = FALSE,    logged_myid_fqdn_key_warning = FALSE,    logged_myid_ip_key_warning   = FALSE;/* may include trailing / */const char *base_perpeer_logdir = PERPEERLOGDIR;static int perpeer_count = 0;/* what to put in front of debug output */char debug_prefix = '|';/* * used in some messages to distiguish * which pluto is which, when doing unit testing * gets set by "use_interface" in server.c, if it is going to be changed. * Is used by pluto_helpers in their process-title. * could be used by debug routines as well, but is not yet. */const char *pluto_ifn_inst = "";  /* from sys/queue.h */static CIRCLEQ_HEAD(,connection) perpeer_list;/* Context for logging. * * Global variables: must be carefully adjusted at transaction boundaries! * If the context provides a whack file descriptor, messages * should be copied to it -- see whack_log() */int whack_log_fd = NULL_FD;	/* only set during whack_handle() */struct state *cur_state = NULL;	/* current state, for diagnostics */struct connection *cur_connection = NULL;	/* current connection, for diagnostics */const ip_address *cur_from = NULL;	/* source of current current message */u_int16_t cur_from_port;	/* host order */voidpluto_init_log(void){    set_exit_log_func(exit_log);    set_paths(ipsec_dir);    if (log_to_stderr)	setbuf(stderr, NULL);    if (log_to_syslog)	openlog("pluto", LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);    CIRCLEQ_INIT(&perpeer_list);}/* format a string for the log, with suitable prefixes. * A format starting with ~ indicates that this is a reprocessing * of the message, so prefixing and quoting is suppressed. */static voidfmt_log(char *buf, size_t buf_len, const char *fmt, va_list ap){    bool reproc = *fmt == '~';    size_t ps;    struct connection *c = cur_state != NULL ? cur_state->st_connection	: cur_connection;    buf[0] = '\0';    if (reproc)	fmt++;	/* ~ at start of format suppresses this prefix */    else if (c != NULL)    {	/* start with name of connection */	char *const be = buf + buf_len;	char *bp = buf;	snprintf(bp, be - bp, "\"%s\"", c->name);	bp += strlen(bp);	/* if it fits, put in any connection instance information */	if (be - bp > CONN_INST_BUF)	{	    fmt_conn_instance(c, bp);	    bp += strlen(bp);	}	if (cur_state != NULL)	{	    /* state number */	    snprintf(bp, be - bp, " #%lu", cur_state->st_serialno);	    bp += strlen(bp);	}	snprintf(bp, be - bp, ": ");    }    else if (cur_from != NULL)    {	/* peer's IP address */	/* Note: must not use ip_str() because our caller might! */	char ab[ADDRTOT_BUF];	(void) addrtot(cur_from, 0, ab, sizeof(ab));	snprintf(buf, buf_len, "packet from %s:%u: "	    , ab, (unsigned)cur_from_port);    }    ps = strlen(buf);    vsnprintf(buf + ps, buf_len - ps, fmt, ap);    if (!reproc)	(void)sanitize_string(buf, buf_len);}voidclose_peerlog(void){    /* exit if the circular queue has not been initialized */    if (perpeer_list.cqh_first == NULL)        return;    /* end of circular queue is given by pointer to "HEAD" */    while (perpeer_list.cqh_first != (void *)&perpeer_list)	perpeer_logclose(perpeer_list.cqh_first);}voidclose_log(void){    if (log_to_syslog)	closelog();    close_peerlog();}static voidperpeer_logclose(struct connection *c){    /* only free/close things if we had used them! */    if (c->log_file != NULL)    {	passert(perpeer_count > 0);	CIRCLEQ_REMOVE(&perpeer_list, c, log_link);	perpeer_count--;	fclose(c->log_file);	c->log_file=NULL;    }}voidperpeer_logfree(struct connection *c){    perpeer_logclose(c);    if (c->log_file_name != NULL)    {	pfree(c->log_file_name);	c->log_file_name = NULL;	c->log_file_err = FALSE;    }}/* open the per-peer log */static voidopen_peerlog(struct connection *c){    syslog(LOG_INFO, "opening log file for conn %s", c->name);    if (c->log_file_name == NULL)    {	char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];	int  peernamelen, lf_len;	addrtot(&c->spd.that.host_addr, 'Q', peername, sizeof(peername));	peernamelen = strlen(peername);	/* copy IP address, turning : and . into / */	{	    char c, *p, *q;	    p = peername;	    q = dname;	    do {		c = *p++;		if (c == '.' || c == ':')		    c = '/';		*q++ = c;	    } while (c != '\0');	}	lf_len = peernamelen * 2	    + strlen(base_perpeer_logdir)	    + sizeof("//.log")	    + 1;	c->log_file_name = alloc_bytes(lf_len, "per-peer log file name");	fprintf(stderr, "base dir |%s| dname |%s| peername |%s|"		, base_perpeer_logdir, dname, peername);	snprintf(c->log_file_name, lf_len, "%s/%s/%s.log"		 , base_perpeer_logdir, dname, peername);	syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name);    }    /* now open the file, creating directories if necessary */    {  /* create the directory */	char *dname;	int   bpl_len = strlen(base_perpeer_logdir);	char *slashloc;	dname = clone_str(c->log_file_name, "temp copy of file name");	dname = dirname(dname);	if (access(dname, W_OK) != 0)	{	    if (errno != ENOENT)	    {		if (c->log_file_err)		{		    syslog(LOG_CRIT, "can not write to %s: %s"			   , dname, strerror(errno));		    c->log_file_err = TRUE;		    pfree(dname);		    return;		}	    }	    /* directory does not exist, walk path creating dirs */	    /* start at base_perpeer_logdir */	    slashloc = dname + bpl_len;	    slashloc++;    /* since, by construction there is a slash			      right there */	    while (*slashloc != '\0')	    {		char saveslash;		/* look for next slash */		while (*slashloc != '\0' && *slashloc != '/') slashloc++;		saveslash = *slashloc;		*slashloc = '\0';		if (mkdir(dname, 0750) != 0 && errno != EEXIST)		{		    syslog(LOG_CRIT, "can not create dir %s: %s"			   , dname, strerror(errno));		    c->log_file_err = TRUE;		    pfree(dname);		    return;		}		syslog(LOG_DEBUG, "created new directory %s", dname);		*slashloc = saveslash;		slashloc++;	    }	}	pfree(dname);    }    c->log_file = fopen(c->log_file_name, "a");    if (c->log_file == NULL)    {	if (c->log_file_err)	{	    syslog(LOG_CRIT, "logging system can not open %s: %s"		   , c->log_file_name, strerror(errno));	    c->log_file_err = TRUE;	}	return;    }    /* look for a connection to close! */    while (perpeer_count >= MAX_PEERLOG_COUNT)    {	/* can not be NULL because perpeer_count > 0 */	passert(perpeer_list.cqh_last != (void *)&perpeer_list);	perpeer_logclose(perpeer_list.cqh_last);    }    /* insert this into the list */    CIRCLEQ_INSERT_HEAD(&perpeer_list, c, log_link);    passert(c->log_file != NULL);    perpeer_count++;}/* log a line to cur_connection's log */static voidpeerlog(const char *prefix, const char *m){    if (cur_connection == NULL)    {	/* we can not log it in this case. Oh well. */	return;    }    if (cur_connection->log_file == NULL)    {	open_peerlog(cur_connection);    }    /* despite our attempts above, we may not be able to open the file. */    if (cur_connection->log_file != NULL)    {	char datebuf[32];	time_t n;	struct tm *t;	time(&n);	t = localtime(&n);	strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);	fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);	/* now move it to the front of the list */	CIRCLEQ_REMOVE(&perpeer_list, cur_connection, log_link);	CIRCLEQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);    }}voidopenswan_log(const char *message, ...){    va_list args;    char m[LOG_WIDTH];	/* longer messages will be truncated */    va_start(args, message);    fmt_log(m, sizeof(m), message, args);    va_end(args);    if (log_to_stderr)	fprintf(stderr, "%s\n", m);    if (log_to_syslog)	syslog(LOG_WARNING, "%s", m);    if (log_to_perpeer)	peerlog("", m);    whack_log(RC_LOG, "~%s", m);}voidloglog(int mess_no, const char *message, ...){    va_list args;    char m[LOG_WIDTH];	/* longer messages will be truncated */    va_start(args, message);    fmt_log(m, sizeof(m), message, args);    va_end(args);    if (log_to_stderr)	fprintf(stderr, "%s\n", m);    if (log_to_syslog)	syslog(LOG_WARNING, "%s", m);    if (log_to_perpeer)	peerlog("", m);    whack_log(mess_no, "~%s", m);}

⌨️ 快捷键说明

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