Add/update copyright notice in all source code files.
[mmh] / sbr / error.c
1
2 /*
3  * error.c -- main error handling routines
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13
14 #ifdef HAVE_WRITEV
15 # include <sys/types.h>
16 # include <sys/uio.h>
17 #endif
18
19 #include <errno.h>
20
21
22 /*
23  * print out error message
24  */
25 void
26 advise (char *what, char *fmt, ...)
27 {
28     va_list ap;
29
30     va_start(ap, fmt);
31     advertise (what, NULL, fmt, ap);
32     va_end(ap);
33 }
34
35
36 /*
37  * print out error message and exit
38  */
39 void
40 adios (char *what, char *fmt, ...)
41 {
42     va_list ap;
43
44     va_start(ap, fmt);
45     advertise (what, NULL, fmt, ap);
46     va_end(ap);
47     done (1);
48 }
49
50
51 /*
52  * admonish the user
53  */
54 void
55 admonish (char *what, char *fmt, ...)
56 {
57     va_list ap;
58
59     va_start(ap, fmt);
60     advertise (what, "continuing...", fmt, ap);
61     va_end(ap);
62 }
63
64
65 /*
66  * main routine for printing error messages.
67  *
68  * Use writev() if available, for slightly better performance.
69  * Why?  Well, there are a couple of reasons.  Primarily, it
70  * gives a smoother output...  More importantly though, it's a
71  * sexy syscall()...
72  */
73 void
74 advertise (char *what, char *tail, char *fmt, va_list ap)
75 {
76     int eindex = errno;
77
78 #ifdef HAVE_WRITEV
79     char buffer[BUFSIZ], err[BUFSIZ];
80     struct iovec iob[20], *iov;
81 #endif
82
83     fflush (stdout);
84
85 #ifdef HAVE_WRITEV
86     fflush (stderr);
87     iov = iob;
88
89     if (invo_name && *invo_name) {
90         iov->iov_len = strlen (iov->iov_base = invo_name);
91         iov++;
92         iov->iov_len = strlen (iov->iov_base = ": ");
93         iov++;
94     }
95     
96     vsnprintf (buffer, sizeof(buffer), fmt, ap);
97     iov->iov_len = strlen (iov->iov_base = buffer);
98     iov++;
99     if (what) {
100         if (*what) {
101             iov->iov_len = strlen (iov->iov_base = " ");
102             iov++;
103             iov->iov_len = strlen (iov->iov_base = what);
104             iov++;
105             iov->iov_len = strlen (iov->iov_base = ": ");
106             iov++;
107         }
108         if (!(iov->iov_base = strerror (eindex))) {
109             /* this shouldn't happen, but we'll test for it just in case */
110             snprintf (err, sizeof(err), "Error %d", eindex);
111             iov->iov_base = err;
112         }
113         iov->iov_len = strlen (iov->iov_base);
114         iov++;
115     }
116     if (tail && *tail) {
117         iov->iov_len = strlen (iov->iov_base = ", ");
118         iov++;
119         iov->iov_len = strlen (iov->iov_base = tail);
120         iov++;
121     }
122     iov->iov_len = strlen (iov->iov_base = "\n");
123     iov++;
124     writev (fileno (stderr), iob, iov - iob);
125 #else
126     if (invo_name && *invo_name)
127         fprintf (stderr, "%s: ", invo_name);
128     vfprintf (stderr, fmt, ap);
129
130     if (what) {
131         char *s;
132
133         if (*what)
134             fprintf (stderr, " %s: ", what);
135         if ((s = strerror(eindex)))
136             fprintf (stderr, "%s", s);
137         else
138             fprintf (stderr, "Error %d", eindex);
139     }
140     if (tail)
141         fprintf (stderr, ", %s", tail);
142     fputc ('\n', stderr);
143 #endif
144 }