1 /*
2  * relaynews error handling (also used by some other bits)
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <errno.h>
9 #include "fixerrno.h"
10 #include <sys/types.h>
11 #include <sys/timeb.h>		/* solely for getindate call */
12 
13 #include "libc.h"
14 #include "news.h"
15 #include "active.h"
16 #include "headers.h"
17 #include "relay.h"
18 #include "msgs.h"
19 #include "rerror.h"
20 
21 /* common log reporting */
22 static
23 void
cnews_log(stream,art,code,fmt,arg,sverrno)24 cnews_log(stream, art, code, fmt, arg, sverrno)
25 register FILE *stream;
26 register struct article *art;
27 int code;
28 const char *fmt, *arg;
29 register int sverrno;
30 {
31 	time_t now;
32 
33 	if (code != '\0') {
34 		timestamp(stream, &now);
35 		(void) putc(' ', stream);
36 		if (art != NULL)
37 			(void) fputs(sendersite(nullify(art->h.h_path)),
38 				stream);
39 		(void) putc(' ', stream);
40 		(void) putc(code, stream);
41 		(void) putc(' ', stream);
42 		if (art != NULL && art->h.h_msgid != NULL)
43 			(void) fputs(art->h.h_msgid, stream);
44 		else
45 			(void) putc('-', stream);
46 		(void) putc(' ', stream);
47 		(void) fprintf(stream, fmt, arg);
48 		if (sverrno != 0)
49 			(void) fprintf(stream, " (%s)", strerror(sverrno));
50 		(void) putc('\n', stream);
51 		if (ferror(stream))
52 			fulldisk(art, "a log file");
53 	}
54 }
55 
56 /*
57  * log an audit report and continue
58  * article status unaffected
59  */
60 void
logaudit(art,code,fmt,arg)61 logaudit(art, code, fmt, arg)
62 struct article *art;
63 int code;
64 const char *fmt, *arg;
65 {
66 	cnews_log(stdout, art, code, fmt, arg, 0);
67 }
68 
69 /*
70  * log a complaint about bad input and continue
71  * set ST_REFUSED in article status
72  */
73 void
transient(art,code,fmt,arg)74 transient(art, code, fmt, arg)
75 register struct article *art;
76 int code;
77 const char *fmt;
78 const char *arg;
79 {
80 	cnews_log(stdout, art, code, fmt, arg, 0);
81 	if (art != NULL)
82 		art->a_status |= ST_REFUSED;
83 }
84 
85 /*
86  * the news system needs attention; complain and shut down gracefully
87  * sets ST_NEEDATTN and ST_DROPPED in article status
88  */
89 void
persistent(art,code,fmt,arg)90 persistent(art, code, fmt, arg)
91 register struct article *art;
92 int code;
93 const char *fmt, *arg;
94 {
95 	cnews_log(stderr, art, code, fmt, arg, errno);
96 	if (art != NULL)
97 		art->a_status |= ST_NEEDATTN|ST_DROPPED;
98 }
99 
100 /*
101  * something impossible has happened; complain and shut down ASAP
102  * either quits or sets ST_NEEDATTN and ST_DROPPED in article status
103  */
104 /* ARGSUSED art code */
105 void
canthappen(art,code,fmt,arg)106 canthappen(art, code, fmt, arg)
107 struct article *art;
108 int code;
109 const char *fmt, *arg;
110 {
111 	errunlock(fmt, arg);
112 	/* NOTREACHED */
113 }
114 
115 void
fulldisk(art,file)116 fulldisk(art, file)			/* complain once & set status bits */
117 register struct article *art;
118 const char *file;
119 {
120 	if (!(art->a_status&ST_DISKFULL))
121 		art->a_status |= prfulldisk(file);
122 }
123