error.c revision 6695
16695Sphk/*
26695Sphk * Routines for logging error messages or other informative messages.
36695Sphk *
46695Sphk * Log messages can easily contain the program name, a time stamp, system
56695Sphk * error messages, and arbitrary printf-style strings, and can be directed
66695Sphk * to stderr or a log file.
76695Sphk *
86695Sphk * Author: Stephen McKay
96695Sphk *
106695Sphk * NOTICE: This is free software.  I hope you get some use from this program.
116695Sphk * In return you should think about all the nice people who give away software.
126695Sphk * Maybe you should write some free software too.
136695Sphk */
146695Sphk
156081Sphk#include <stdio.h>
166081Sphk#include <string.h>
176081Sphk#include <stdarg.h>
186081Sphk#include <time.h>
196695Sphk#include <errno.h>
206081Sphk#include "error.h"
216081Sphk
226081Sphkstatic FILE *error_fp = NULL;
236081Sphkstatic char *prog = NULL;
246081Sphk
256081Sphk
266081Sphk/*
276081Sphk * Log errors to the given file.
286081Sphk */
296081Sphkvoid
306081Sphkerr_set_log(char *log_file)
316081Sphk    {
326081Sphk    FILE *fp;
336081Sphk
346081Sphk    if ((fp = fopen(log_file, "a")) == NULL)
356081Sphk	err("cannot log to '%s'", log_file);
366081Sphk    else
376081Sphk	error_fp = fp;
386081Sphk    }
396081Sphk
406081Sphk
416081Sphk/*
426081Sphk * Set the error prefix if not logging to a file.
436081Sphk */
446081Sphkvoid
456081Sphkerr_prog_name(char *name)
466081Sphk    {
476081Sphk    if ((prog = strrchr(name, '/')) == NULL)
486081Sphk	prog = name;
496081Sphk    else
506081Sphk	prog++;
516081Sphk    }
526081Sphk
536081Sphk
546081Sphk/*
556081Sphk * Log an error.
566695Sphk *
576695Sphk * A leading '*' in the message format means we want the system errno
586695Sphk * decoded and appended.
596081Sphk */
606081Sphkvoid
616081Sphkerr(char *fmt, ...)
626081Sphk    {
636081Sphk    va_list ap;
646081Sphk    time_t now;
656081Sphk    struct tm *tm;
666081Sphk    FILE *fp;
676695Sphk    int x = errno;
686695Sphk    int want_errno;
696081Sphk
706081Sphk    if ((fp = error_fp) == NULL)
716081Sphk	{
726081Sphk	fp = stderr;
736081Sphk	if (prog != NULL)
746081Sphk	    fprintf(fp, "%s: ", prog);
756081Sphk	}
766081Sphk    else
776081Sphk	{
786081Sphk	time(&now);
796081Sphk	tm = localtime(&now);
806081Sphk	fprintf(fp, "%04d-%02d-%02d %02d:%02d ", tm->tm_year+1900,
816081Sphk	    tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
826081Sphk	}
836081Sphk
846695Sphk    want_errno = 0;
856695Sphk    if (*fmt == '*')
866695Sphk	want_errno++, fmt++;
876695Sphk
886081Sphk    va_start(ap, fmt);
896081Sphk    vfprintf(fp, fmt, ap);
906081Sphk    va_end(ap);
916081Sphk
926695Sphk    if (want_errno)
936695Sphk	fprintf(fp, ": %s", strerror(x));
946695Sphk
956081Sphk    fprintf(fp, "\n");
966081Sphk    fflush(fp);
976081Sphk    }
98