1 /*
2 * Routines for logging error messages or other informative messages.
3 *
4 * Log messages can easily contain the program name, a time stamp, system
5 * error messages, and arbitrary printf-style strings, and can be directed
6 * to stderr or a log file.
7 *
8 * Author: Stephen McKay
9 *
10 * NOTICE: This is free software. I hope you get some use from this program.
11 * In return you should think about all the nice people who give away software.
12 * Maybe you should write some free software too.
13 */
14
15 #ifndef lint
16 static const char rcsid[] =
17 "$FreeBSD$";
18 #endif /* not lint */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <time.h>
24 #include <errno.h>
25 #include "error.h"
26
27 static FILE *error_fp = NULL;
28 static char *prog = NULL;
29
30
31 /*
32 * Log errors to the given file.
33 */
34 void
err_set_log(char * log_file)35 err_set_log(char *log_file)
36 {
37 FILE *fp;
38
39 if ((fp = fopen(log_file, "a")) == NULL)
40 err("cannot log to '%s'", log_file);
41 else
42 error_fp = fp;
43 }
44
45
46 /*
47 * Set the error prefix if not logging to a file.
48 */
49 void
err_prog_name(char * name)50 err_prog_name(char *name)
51 {
52 if ((prog = strrchr(name, '/')) == NULL)
53 prog = name;
54 else
55 prog++;
56 }
57
58
59 /*
60 * Log an error.
61 *
62 * A leading '*' in the message format means we want the system errno
63 * decoded and appended.
64 */
65 void
err(const char * fmt,...)66 err(const char *fmt, ...)
67 {
68 va_list ap;
69 time_t now;
70 struct tm *tm;
71 FILE *fp;
72 int x = errno;
73 int want_errno;
74
75 if ((fp = error_fp) == NULL)
76 {
77 fp = stderr;
78 if (prog != NULL)
79 fprintf(fp, "%s: ", prog);
80 }
81 else
82 {
83 time(&now);
84 tm = localtime(&now);
85 fprintf(fp, "%04d-%02d-%02d %02d:%02d ", tm->tm_year+1900,
86 tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
87 }
88
89 want_errno = 0;
90 if (*fmt == '*')
91 want_errno++, fmt++;
92
93 va_start(ap, fmt);
94 vfprintf(fp, fmt, ap);
95 va_end(ap);
96
97 if (want_errno)
98 fprintf(fp, ": %s", strerror(x));
99
100 fprintf(fp, "\n");
101 fflush(fp);
102 }
103