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

📄 debug.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission.  U.M. makes no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: James da Silva, Systems Design and Analysis Group *			   Computer Science Department *			   University of Maryland at College Park *//* * $Id: debug.c,v 1.40 2006/07/26 11:49:32 martinea Exp $ * * Logging support */#include "amanda.h"#include "util.h"#include "arglist.h"#include "clock.h"#include "timestamp.h"#include "conffile.h"/* Minimum file descriptor on which to keep the debug file.  This is intended * to keep the descriptor "out of the way" of other processing.  It's not clear * that this is required any longer, but it doesn't hurt anything. */#define	MIN_DB_FD			10/* information on the current debug file */static int db_fd = 2;			/* file descriptor (default stderr) */static FILE *db_file = NULL;		/* stdio stream */static char *db_name  = NULL;		/* unqualified filename */static char *db_filename = NULL;	/* fully qualified pathname *//* directory containing debug file, including trailing slash */static char *dbgdir = NULL;/* time debug log was opened (timestamp of the file) */static time_t open_time;/* pointer to logfile.c's 'logerror()', if we're linked * with it */static void (*logerror_fn)(char *) = NULL;/* storage for global variables */erroutput_type_t erroutput_type = ERR_INTERACTIVE;int error_exit_status = 1;/* static function prototypes */static char *get_debug_name(time_t t, int n);static void debug_setup_1(char *config, char *subdir);static void debug_setup_2(char *s, int fd, char *annotation);static char *msg_timestamp(void);static void debug_logging_handler(const gchar *log_domain,	GLogLevelFlags log_level,	const gchar *message,	gpointer user_data);static void debug_setup_logging(void);/* * Generate a debug file name.  The name is based on the program name, * followed by a timestamp, an optional sequence number, and ".debug". * * @param t: timestamp * @param n: sequence number between 1 and 1000; if zero, no sequence number * is included. */static char *get_debug_name(    time_t	t,    int		n){    char number[NUM_STR_SIZE];    char *ts;    char *result;    if(n < 0 || n > 1000) {	return NULL;    }    ts = get_timestamp_from_time(t);    if(n == 0) {	number[0] = '\0';    } else {	g_snprintf(number, SIZEOF(number), "%03d", n - 1);    }    result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL);    amfree(ts);    return result;}/* A GLogFunc to handle g_log calls.  This function assumes that user_data * is either NULL or a pointer to one of the debug_* configuration variables * in conffile.c, indicating whether logging for this log domain is enabled. * * @param log_domain: the log domain, or NULL for general logging * @param log_level: level, fatality, and recursion flags * @param message: the message to log * @param user_pointer: unused */static voiddebug_logging_handler(const gchar *log_domain G_GNUC_UNUSED,	    GLogLevelFlags log_level,	    const gchar *message,	    gpointer user_data G_GNUC_UNUSED){    char *maxlevel = NULL;    /* convert the highest level to a string and dbprintf it */    if (log_level & G_LOG_LEVEL_ERROR)	maxlevel = _("error (fatal): ");    else if (log_level & G_LOG_LEVEL_CRITICAL)	maxlevel = _("critical (fatal): ");    else if (log_level & G_LOG_LEVEL_WARNING)	maxlevel = _("warning: ");    else if (log_level & G_LOG_LEVEL_MESSAGE)	maxlevel = _("message: ");    else if (log_level & G_LOG_LEVEL_INFO)	maxlevel = _("info: ");    else	maxlevel = ""; /* no level displayed for debugging */    debug_printf("%s%s\n", maxlevel, message);    /* error and critical levels have special handling */    if (log_level & (G_LOG_LEVEL_ERROR|G_LOG_LEVEL_CRITICAL)) {	if (erroutput_type & ERR_AMANDALOG && logerror_fn != NULL)	    (*logerror_fn)((char *)message); /* discard 'const' */	if (erroutput_type & ERR_SYSLOG) {#ifdef LOG_AUTH	    openlog(get_pname(), LOG_PID, LOG_AUTH);#else	    openlog(get_pname(), LOG_PID, 0);#endif	    syslog(LOG_NOTICE, "%s", message);	    closelog();	}	if (erroutput_type & ERR_INTERACTIVE) {	    g_fprintf(stderr, "%s: %s\n", get_pname(), message);	    fflush(stderr);	}	/* we're done */	if (log_level & G_LOG_LEVEL_CRITICAL)	    exit(error_exit_status);	else	    abort();	g_assert_not_reached();    }}/* Install our handler into the glib log handling system. */static voiddebug_setup_logging(void){    /* g_error and g_critical should be fatal, although the log handler     * takes care of this anyway */    g_log_set_always_fatal(G_LOG_LEVEL_ERROR |  G_LOG_LEVEL_CRITICAL);    /* set up handler (g_log_set_default_handler is new in glib-2.6, and     * hence not useable here) */    g_log_set_handler(NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,		      debug_logging_handler, NULL);}/* Set the global dbgdir according to 'config' and 'subdir', and clean * old debug files out of that directory * * The global open_time is set to the current time, and used to delete * old files. * * @param config: configuration or NULL * @param subdir: subdirectory (server, client, etc.) or NULL */static voiddebug_setup_1(char *config, char *subdir){    char *pname;    size_t pname_len;    char *e = NULL;    char *s = NULL;    DIR *d;    struct dirent *entry;    int do_rename;    char *test_name;    size_t test_name_len;    size_t d_name_len;    struct stat sbuf;    char *dbfilename = NULL;    char *sane_config = NULL;    int i;    memset(&sbuf, 0, SIZEOF(sbuf));    pname = get_pname();    pname_len = strlen(pname);    /*     * Create the debug directory if it does not yet exist.     */    amfree(dbgdir);    if (config)	sane_config = sanitise_filename(config);    if (sane_config && subdir)	dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", sane_config,			   "/", NULL);    else if (sane_config)	dbgdir = vstralloc(AMANDA_DBGDIR, "/", sane_config, "/", NULL);    else if (subdir)	dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", NULL);    else	dbgdir = stralloc2(AMANDA_DBGDIR, "/");    if(mkpdir(dbgdir, 0700, get_client_uid(), get_client_gid()) == -1) {	error(_("create debug directory \"%s\": %s"),	      dbgdir, strerror(errno));	/*NOTREACHED*/    }    amfree(sane_config);    /*     * Clean out old debug files.  We also rename files with old style     * names (XXX.debug or XXX.$PID.debug) into the new name format.     * We assume no system has 17 digit PID-s :-) and that there will     * not be a conflict between an old and new name.     */    if((d = opendir(dbgdir)) == NULL) {	error(_("open debug directory \"%s\": %s"),	      dbgdir, strerror(errno));	/*NOTREACHED*/    }    time(&open_time);    test_name = get_debug_name(open_time - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);    test_name_len = strlen(test_name);    while((entry = readdir(d)) != NULL) {	if(is_dot_or_dotdot(entry->d_name)) {	    continue;	}	d_name_len = strlen(entry->d_name);	if(strncmp(entry->d_name, pname, pname_len) != 0	   || entry->d_name[pname_len] != '.'	   || d_name_len < 6	   || strcmp(entry->d_name + d_name_len - 6, ".debug") != 0) {	    continue;				/* not one of our debug files */	}	e = newvstralloc(e, dbgdir, entry->d_name, NULL);	if(d_name_len < test_name_len) {	    /*	     * Create a "pretend" name based on the last modification	     * time.  This name will be used to decide if the real name	     * should be removed.  If not, it will be used to rename the	     * real name.	     */	    if(stat(e, &sbuf) != 0) {		continue;			/* ignore errors */	    }	    amfree(dbfilename);	    dbfilename = get_debug_name((time_t)sbuf.st_mtime, 0);	    do_rename = 1;	} else {	    dbfilename = newstralloc(dbfilename, entry->d_name);	    do_rename = 0;	}	if(strcmp(dbfilename, test_name) < 0) {	    (void) unlink(e);			/* get rid of old file */	    continue;	}	if(do_rename) {	    i = 0;	    while(dbfilename != NULL		  && (s = newvstralloc(s, dbgdir, dbfilename, NULL)) != NULL		  && rename(e, s) != 0 && errno != ENOENT) {		amfree(dbfilename);		dbfilename = get_debug_name((time_t)sbuf.st_mtime, ++i);	    }	    if(dbfilename == NULL) {		error(_("cannot rename old debug file \"%s\""), entry->d_name);		/*NOTREACHED*/	    }	}    }    amfree(dbfilename);    amfree(e);    amfree(s);    amfree(test_name);    closedir(d);}/* Given an already-opened debug file, set the file's ownership * appropriately, move its file descriptor above MIN_DB_FD, and * add an initial log entry to the file. * * This function records the file's identity in the globals * db_filename, db_fd, and db_file.  It does *not* set db_name. * db_file is not set if fd is -1 * * This function uses the global 'open_time', which is set by * debug_setup_1. * * @param s: the filename of the debug file; string should be malloc'd, * and should *not* be freed by the caller. * @param fd: the descriptor connected to the debug file, or -1 if * no decriptor moving should take place. * @param annotation: an extra string to include in the initial * log entry. */static voiddebug_setup_2(    char *	s,    int		fd,    char *	annotation){    int i;    int fd_close[MIN_DB_FD+1];    amfree(db_filename);    db_filename = s;    s = NULL;    /* If we're root, change the ownership of the debug files.  If we're not root,     * this would either be redundant or an error. */    if (geteuid() == 0) {	if (chown(db_filename, get_client_uid(), get_client_gid()) < 0) {	    dbprintf(_("chown(%s, %d, %d) failed: %s"),		     db_filename, (int)get_client_uid(), (int)get_client_gid(), strerror(errno));	}    }    amfree(dbgdir);

⌨️ 快捷键说明

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