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
1576300Skris#ifndef lint
1676300Skrisstatic const char rcsid[] =
1776300Skris  "$FreeBSD$";
1876300Skris#endif /* not lint */
1976300Skris
206081Sphk#include <stdio.h>
216081Sphk#include <string.h>
226081Sphk#include <stdarg.h>
236081Sphk#include <time.h>
246695Sphk#include <errno.h>
256081Sphk#include "error.h"
266081Sphk
276081Sphkstatic FILE *error_fp = NULL;
286081Sphkstatic char *prog = NULL;
296081Sphk
306081Sphk
316081Sphk/*
326081Sphk * Log errors to the given file.
336081Sphk */
346081Sphkvoid
356081Sphkerr_set_log(char *log_file)
366081Sphk    {
376081Sphk    FILE *fp;
386081Sphk
396081Sphk    if ((fp = fopen(log_file, "a")) == NULL)
406081Sphk	err("cannot log to '%s'", log_file);
416081Sphk    else
426081Sphk	error_fp = fp;
436081Sphk    }
446081Sphk
456081Sphk
466081Sphk/*
476081Sphk * Set the error prefix if not logging to a file.
486081Sphk */
496081Sphkvoid
506081Sphkerr_prog_name(char *name)
516081Sphk    {
526081Sphk    if ((prog = strrchr(name, '/')) == NULL)
536081Sphk	prog = name;
546081Sphk    else
556081Sphk	prog++;
566081Sphk    }
576081Sphk
586081Sphk
596081Sphk/*
606081Sphk * Log an error.
616695Sphk *
626695Sphk * A leading '*' in the message format means we want the system errno
636695Sphk * decoded and appended.
646081Sphk */
656081Sphkvoid
6676300Skriserr(const char *fmt, ...)
676081Sphk    {
686081Sphk    va_list ap;
696081Sphk    time_t now;
706081Sphk    struct tm *tm;
716081Sphk    FILE *fp;
726695Sphk    int x = errno;
736695Sphk    int want_errno;
746081Sphk
756081Sphk    if ((fp = error_fp) == NULL)
766081Sphk	{
776081Sphk	fp = stderr;
786081Sphk	if (prog != NULL)
796081Sphk	    fprintf(fp, "%s: ", prog);
806081Sphk	}
816081Sphk    else
826081Sphk	{
836081Sphk	time(&now);
846081Sphk	tm = localtime(&now);
856081Sphk	fprintf(fp, "%04d-%02d-%02d %02d:%02d ", tm->tm_year+1900,
866081Sphk	    tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
876081Sphk	}
886081Sphk
896695Sphk    want_errno = 0;
906695Sphk    if (*fmt == '*')
916695Sphk	want_errno++, fmt++;
926695Sphk
936081Sphk    va_start(ap, fmt);
946081Sphk    vfprintf(fp, fmt, ap);
956081Sphk    va_end(ap);
966081Sphk
976695Sphk    if (want_errno)
986695Sphk	fprintf(fp, ": %s", strerror(x));
996695Sphk
1006081Sphk    fprintf(fp, "\n");
1016081Sphk    fflush(fp);
1026081Sphk    }
103