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