* 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
* 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
* @(#)xutil.c 8.1 (Berkeley) 6/6/93
* $Id: xutil.c,v 5.2.2.3 1992/03/07 10:36:09 jsp Exp $
FILE *logfp
= stderr
; /* Log errors to stderr initially */
int xlog_level
= XLOG_ALL
& ~XLOG_MAP
& ~XLOG_STATS
;
int xlog_level_init
= ~0;
struct opt_tab xlog_opt
[] = {
{ "all", XLOG_ALL
}, /* All messages */
{ "debug", XLOG_DEBUG
}, /* Debug messages */
{ "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 */
* Avoid malloc's which return NULL for malloc(0)
p
= (voidp
) malloc((unsigned) len
);
#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) */
plog(XLOG_ERROR
, "Retrying memory allocation");
plog(XLOG_FATAL
, "Out of memory");
#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) */
ptr
= (voidp
) realloc(ptr
, (unsigned) len
);
ptr
= (voidp
) xmalloc((unsigned) len
);
plog(XLOG_FATAL
, "Out of memory in realloc");
#if defined(DEBUG) && defined(DEBUG_MEM)
Debug(D_MEM
) plog(XLOG_DEBUG
, "Free in %s:%d: block %#x", f
, l
, p
);
#endif /* defined(DEBUG) && defined(DEBUG_MEM) */
static int orig_mem_bytes
;
static void checkup_mem(P_void
)
extern struct mallinfo __mallinfo
;
if (mem_bytes
!= __mallinfo
.uordbytes
) {
mem_bytes
= orig_mem_bytes
= __mallinfo
.uordbytes
;
fprintf(logfp
, "%s[%d]: ", progname
, mypid
);
if (mem_bytes
< __mallinfo
.uordbytes
) {
fprintf(logfp
, "ALLOC: %d bytes",
__mallinfo
.uordbytes
- mem_bytes
);
fprintf(logfp
, "FREE: %d bytes",
mem_bytes
- __mallinfo
.uordbytes
);
mem_bytes
= __mallinfo
.uordbytes
;
fprintf(logfp
, ", making %d missing\n",
mem_bytes
- orig_mem_bytes
);
* Take a log format string and expand occurences of %m
* with the current error code take from errno.
static void expand_error(f
, e
)
extern char *sys_errlist
[];
for (p
= f
; *e
= *p
; e
++, p
++) {
if (p
[0] == '%' && p
[1] == 'm') {
errstr
= strerror(error
);
if (error
< 0 || error
>= sys_nerr
)
errstr
= sys_errlist
[error
];
sprintf(e
, "Error %d", error
);
* Output the time of day and hostname to the logfile
static void show_time_host_and_name(lvl
)
static time_t last_t
= 0;
static char *last_ctime
= 0;
#if defined(DEBUG) && defined(PARANOID)
#endif /* defined(DEBUG) && defined(PARANOID) */
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 ",
#if defined(DEBUG) && defined(PARANOID)
#endif /* defined(DEBUG) && defined(PARANOID) */
void dplog(fmt
, j
,s
,_
,p
,e
,n
,d
,r
,y
)
char *j
, *s
, *_
, *p
, *e
, *n
, *d
, *r
, *y
;
plog(XLOG_DEBUG
, fmt
, j
,s
,_
,p
,e
,n
,d
,r
,y
);
void plog(lvl
, fmt
, j
,s
,_
,p
,e
,n
,d
,r
,y
)
char *j
, *s
, *_
, *p
, *e
, *n
, *d
, *r
, *y
;
sprintf(ptr
, efmt
, j
,s
,_
,p
,e
,n
,d
,r
,y
);
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;
show_time_host_and_name(lvl
);
fwrite(msg
, ptr
- msg
, 1, logfp
);
void show_opts
P((int ch
, struct opt_tab
*opts
));
* Display current debug options
fprintf(stderr
, "\t[-%c {no}", ch
);
for (i
= 0; opts
[i
].opt
; i
++) {
fprintf(stderr
, "%c%s", s
, opts
[i
].opt
);
int cmdoption
P((char *s
, struct opt_tab
*optb
, int *flags
));
int cmdoption(s
, optb
, flags
)
struct opt_tab
*dp
, *dpn
= 0;
if (s
[0] == 'n' && s
[1] == 'o') {
* 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)
if (opt
!= s
&& !dpn
&& strcmp(s
, dp
->opt
) == 0)
* 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
);
* Switch on/off logging options
int rc
= cmdoption(opt
, xlog_opt
, &xl
);
* Keep track of initial log level, and
* don't allow options to be turned off.
if (xlog_level_init
== ~0)
int switch_to_logfile
P((char *logfile
));
int switch_to_logfile(logfile
)
FILE *new_logfp
= stderr
;
if (strcmp(logfile
, "/dev/stderr") == 0)
else if (strcmp(logfile
, "syslog") == 0) {
#if defined(LOG_CONS) && defined(LOG_NOWAIT)
openlog(progname
, LOG_PID
|LOG_CONS
|LOG_NOWAIT
,
/* 4.2 compat mode - XXX */
openlog(progname
, LOG_PID
);
#endif /* LOG_CONS && LOG_NOWAIT */
plog(XLOG_WARNING
, "syslog option not supported, logging unchanged");
(void) umask(orig_umask
);
new_logfp
= fopen(logfile
, "a");
* 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
);
* Close the previous file
if (logfp
&& logfp
!= stderr
)
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
;