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