📄 xutil.c
字号:
/* * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * * 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. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS 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 REGENTS OR 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. * * @(#)xutil.c 8.1 (Berkeley) 6/6/93 * * $Id: xutil.c,v 5.2.2.3 1992/03/07 10:36:09 jsp Exp $ * */#include "config.h"#ifdef HAS_SYSLOG#include <syslog.h>#endif /* HAS_SYSLOG */#ifdef HAS_STRERROR#include <string.h>#endifFILE *logfp = stderr; /* Log errors to stderr initially */#ifdef HAS_SYSLOGint syslogging;#endif /* HAS_SYSLOG */int xlog_level = XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS;int xlog_level_init = ~0;/* * List of log options */struct opt_tab xlog_opt[] = { { "all", XLOG_ALL }, /* All messages */#ifdef DEBUG { "debug", XLOG_DEBUG }, /* Debug messages */#endif /* DEBUG */ { "error", XLOG_ERROR }, /* Non-fatal system errors */ { "fatal", XLOG_FATAL }, /* Fatal errors */ { "info", XLOG_INFO }, /* Information */ { "map", XLOG_MAP }, /* Map errors */ { "stats", XLOG_STATS }, /* Additional statistical information */ { "user", XLOG_USER }, /* Non-fatal user errors */ { "warn", XLOG_WARNING }, /* Warnings */ { "warning", XLOG_WARNING }, /* Warnings */ { 0, 0 }};voidp xmalloc(len)int len;{ voidp p; int retries = 600; /* * Avoid malloc's which return NULL for malloc(0) */ if (len == 0) len = 1; do { p = (voidp) malloc((unsigned) len); if (p) {#if defined(DEBUG) && defined(DEBUG_MEM) Debug(D_MEM) plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p);#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ return p; } if (retries > 0) { plog(XLOG_ERROR, "Retrying memory allocation"); sleep(1); } } while (--retries); plog(XLOG_FATAL, "Out of memory"); going_down(1); abort(); return 0;}voidp xrealloc(ptr, len)voidp ptr;int len;{#if defined(DEBUG) && defined(DEBUG_MEM) Debug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr);#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ if (len == 0) len = 1; if (ptr) ptr = (voidp) realloc(ptr, (unsigned) len); else ptr = (voidp) xmalloc((unsigned) len); if (!ptr) { plog(XLOG_FATAL, "Out of memory in realloc"); going_down(1); abort(); } return ptr;}#if defined(DEBUG) && defined(DEBUG_MEM)xfree(f, l, p)char *f;int l;voidp p;{ Debug(D_MEM) plog(XLOG_DEBUG, "Free in %s:%d: block %#x", f, l, p);#undef free free(p);}#endif /* defined(DEBUG) && defined(DEBUG_MEM) */#ifdef DEBUG_MEMstatic int mem_bytes;static int orig_mem_bytes;static void checkup_mem(P_void){extern struct mallinfo __mallinfo; if (mem_bytes != __mallinfo.uordbytes) { if (orig_mem_bytes == 0) mem_bytes = orig_mem_bytes = __mallinfo.uordbytes; else { fprintf(logfp, "%s[%d]: ", progname, mypid); if (mem_bytes < __mallinfo.uordbytes) { fprintf(logfp, "ALLOC: %d bytes", __mallinfo.uordbytes - mem_bytes); } else { fprintf(logfp, "FREE: %d bytes", mem_bytes - __mallinfo.uordbytes); } mem_bytes = __mallinfo.uordbytes; fprintf(logfp, ", making %d missing\n", mem_bytes - orig_mem_bytes); } } malloc_verify();}#endif /* DEBUG_MEM *//* * Take a log format string and expand occurences of %m * with the current error code take from errno. */INLINEstatic void expand_error(f, e)char *f;char *e;{#ifndef HAS_STRERROR extern int sys_nerr; extern char *sys_errlist[];#endif char *p; int error = errno; for (p = f; *e = *p; e++, p++) { if (p[0] == '%' && p[1] == 'm') { char *errstr;#ifdef HAS_STRERROR errstr = strerror(error);#else if (error < 0 || error >= sys_nerr) errstr = 0; else errstr = sys_errlist[error];#endif if (errstr) strcpy(e, errstr); else sprintf(e, "Error %d", error); e += strlen(e) - 1; p++; } }}/* * Output the time of day and hostname to the logfile */static void show_time_host_and_name(lvl)int lvl;{static time_t last_t = 0;static char *last_ctime = 0; time_t t = clocktime(); char *sev; extern char *ctime();#if defined(DEBUG) && defined(PARANOID)extern char **gargv;#endif /* defined(DEBUG) && defined(PARANOID) */ if (t != last_t) { last_ctime = ctime(&t); last_t = t; } switch (lvl) { case XLOG_FATAL: sev = "fatal:"; break; case XLOG_ERROR: sev = "error:"; break; case XLOG_USER: sev = "user: "; break; case XLOG_WARNING: sev = "warn: "; break; case XLOG_INFO: sev = "info: "; break; case XLOG_DEBUG: sev = "debug:"; break; case XLOG_MAP: sev = "map: "; break; case XLOG_STATS: sev = "stats:"; break; default: sev = "hmm: "; break; } fprintf(logfp, "%15.15s %s %s[%d]/%s ", last_ctime+4, hostname,#if defined(DEBUG) && defined(PARANOID) gargv[0],#else progname,#endif /* defined(DEBUG) && defined(PARANOID) */ mypid, sev);}#ifdef DEBUG/*VARARGS1*/void dplog(fmt, j,s,_,p,e,n,d,r,y)char *fmt;char *j, *s, *_, *p, *e, *n, *d, *r, *y;{ plog(XLOG_DEBUG, fmt, j,s,_,p,e,n,d,r,y);}#endif /* DEBUG *//*VARARGS1*/void plog(lvl, fmt, j,s,_,p,e,n,d,r,y)int lvl;char *fmt;char *j, *s, *_, *p, *e, *n, *d, *r, *y;{ char msg[1024]; char efmt[1024]; char *ptr = msg; if (!(xlog_level & lvl)) return;#ifdef DEBUG_MEM checkup_mem();#endif /* DEBUG_MEM */ expand_error(fmt, efmt); sprintf(ptr, efmt, j,s,_,p,e,n,d,r,y); ptr += strlen(ptr); if (ptr[-1] == '\n') *--ptr = '\0';#ifdef HAS_SYSLOG if (syslogging) { switch(lvl) { /* from mike <mcooper@usc.edu> */ case XLOG_FATAL: lvl = LOG_CRIT; break; case XLOG_ERROR: lvl = LOG_ERR; break; case XLOG_USER: lvl = LOG_WARNING; break; case XLOG_WARNING: lvl = LOG_WARNING; break; case XLOG_INFO: lvl = LOG_INFO; break; case XLOG_DEBUG: lvl = LOG_DEBUG; break; case XLOG_MAP: lvl = LOG_DEBUG; break; case XLOG_STATS: lvl = LOG_INFO; break; default: lvl = LOG_ERR; break; } syslog(lvl, "%s", msg); return; }#endif /* HAS_SYSLOG */ *ptr++ = '\n'; *ptr = '\0'; /* * Mimic syslog header */ show_time_host_and_name(lvl); fwrite(msg, ptr - msg, 1, logfp); fflush(logfp);}void show_opts P((int ch, struct opt_tab *opts));void show_opts(ch, opts)int ch;struct opt_tab *opts;{ /* * Display current debug options */ int i; int s = '{'; fprintf(stderr, "\t[-%c {no}", ch); for (i = 0; opts[i].opt; i++) { fprintf(stderr, "%c%s", s, opts[i].opt); s = ','; } fputs("}]\n", stderr);}int cmdoption P((char *s, struct opt_tab *optb, int *flags));int cmdoption(s, optb, flags)char *s;struct opt_tab *optb;int *flags;{ char *p = s; int errs = 0; while (p && *p) { int neg; char *opt; struct opt_tab *dp, *dpn = 0; s = p; p = strchr(p, ','); if (p) *p = '\0'; if (s[0] == 'n' && s[1] == 'o') { opt = s + 2; neg = 1; } else { opt = s; neg = 0; } /* * Scan the array of debug options to find the * corresponding flag value. If it is found * then set (or clear) the flag (depending on * whether the option was prefixed with "no"). */ for (dp = optb; dp->opt; dp++) { if (strcmp(opt, dp->opt) == 0) break; if (opt != s && !dpn && strcmp(s, dp->opt) == 0) dpn = dp; } if (dp->opt || dpn) { if (!dp->opt) { dp = dpn; neg = !neg; } if (neg) *flags &= ~dp->flag; else *flags |= dp->flag; } else { /* * This will log to stderr when parsing the command line * since any -l option will not yet have taken effect. */ plog(XLOG_USER, "option \"%s\" not recognised", s); errs++; } /* * Put the comma back */ if (p) *p++ = ','; } return errs;}/* * Switch on/off logging options */int switch_option(opt)char *opt;{ int xl = xlog_level; int rc = cmdoption(opt, xlog_opt, &xl); if (rc) { rc = EINVAL; } else { /* * Keep track of initial log level, and * don't allow options to be turned off. */ if (xlog_level_init == ~0) xlog_level_init = xl; else xl |= xlog_level_init; xlog_level = xl; } return rc;}/* * Change current logfile */int switch_to_logfile P((char *logfile));int switch_to_logfile(logfile)char *logfile;{ FILE *new_logfp = stderr; if (logfile) {#ifdef HAS_SYSLOG syslogging = 0;#endif /* HAS_SYSLOG */ if (strcmp(logfile, "/dev/stderr") == 0) new_logfp = stderr; else if (strcmp(logfile, "syslog") == 0) {#ifdef HAS_SYSLOG syslogging = 1; new_logfp = stderr;#if defined(LOG_CONS) && defined(LOG_NOWAIT) openlog(progname, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_DAEMON);#else /* 4.2 compat mode - XXX */ openlog(progname, LOG_PID);#endif /* LOG_CONS && LOG_NOWAIT */#else plog(XLOG_WARNING, "syslog option not supported, logging unchanged");#endif /* HAS_SYSLOG */ } else { (void) umask(orig_umask); new_logfp = fopen(logfile, "a"); umask(0); } } /* * If we couldn't open a new file, then continue using the old. */ if (!new_logfp && logfile) { plog(XLOG_USER, "%s: Can't open logfile: %m", logfile); return 1; } /* * Close the previous file */ if (logfp && logfp != stderr) (void) fclose(logfp); logfp = new_logfp; return 0;}time_t clock_valid = 0;time_t xclock_valid = 0;#ifndef clocktimetime_t clocktime(P_void){ time_t now = time(&clock_valid); if (xclock_valid > now) { /* * Someone set the clock back! */ plog(XLOG_WARNING, "system clock reset"); reschedule_timeouts(now, xclock_valid); } return xclock_valid = now;}#endif /* clocktime */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -