1 /*
2
3 # # #### #### ####
4 ## ## # # # # #
5 # ## # #### # #
6 # # # # ### ### #
7 # # # # # # ### # #
8 # # #### #### ### ####
9
10 Fatal messages.
11 */
12
13 /*
14 * $Id$
15 *
16 * Copyright (c) 1990-2006, Raphael Manfredi
17 *
18 * You may redistribute only under the terms of the Artistic License,
19 * as specified in the README file that comes with the distribution.
20 * You may reuse parts of this distribution only within the terms of
21 * that same Artistic License; a copy of which may be found at the root
22 * of the source tree for mailagent 3.0.
23 *
24 * $Log: msg.c,v $
25 * Revision 3.0.1.5 1999/01/13 18:08:06 ram
26 * patch64: added tag-checking heuristic to say()
27 *
28 * Revision 3.0.1.4 1996/12/24 13:59:31 ram
29 * patch45: call my_exit() instead of exit()
30 *
31 * Revision 3.0.1.3 1995/08/31 16:22:00 ram
32 * patch42: new routine say() to print messages onto stderr
33 * patch42: all messages on stderr now also include the filter pid
34 * patch42: fatal() now prefixes its supplied reason with FATAL
35 *
36 * Revision 3.0.1.2 1995/08/07 16:10:55 ram
37 * patch37: commented and re-organized fatal code for emergency saving
38 *
39 * Revision 3.0.1.1 1994/09/22 13:46:01 ram
40 * patch12: made fatal() arguments long rather than int for 64-bit machines
41 *
42 * Revision 3.0 1993/11/29 13:48:17 ram
43 * Baseline for mailagent 3.0 netwide release.
44 *
45 */
46
47 #include "config.h"
48 #include "portable.h"
49 #include <stdio.h>
50 #include <sys/types.h>
51 #include <ctype.h>
52 #include "sysexits.h"
53 #include "logfile.h"
54 #include "lock.h"
55 #include "io.h"
56 #include "confmagic.h"
57
58 #define MAX_STRING 1024 /* Maximum length for error string */
59
60 extern void my_exit();
61
62 /* VARARGS2 */
say(msg,arg1,arg2,arg3,arg4,arg5)63 public void say(msg, arg1, arg2, arg3, arg4, arg5)
64 char *msg;
65 long arg1, arg2, arg3, arg4, arg5; /* Use longs, hope (char *) fits in it! */
66 {
67 /* Write important message to stderr */
68
69 fprintf(stderr, "%s[%d]: ", progname, progpid);
70 fprintf(stderr, msg, arg1, arg2, arg3, arg4, arg5);
71 fputc('\n', stderr);
72
73 /*
74 * A little heuristic here...
75 *
76 * If the message begins with an upper-cased don't prepend
77 * the ERROR tag, assuming a tag was already specified.
78 */
79
80 if (isupper(msg[0]))
81 add_log(2, msg, arg1, arg2, arg3, arg4, arg5);
82 else {
83 char buffer[MAX_STRING];
84 sprintf(buffer, "ERROR %s", msg);
85 add_log(2, buffer, arg1, arg2, arg3, arg4, arg5);
86 }
87 }
88
89 /* VARARGS2 */
fatal(reason,arg1,arg2,arg3,arg4,arg5)90 public void fatal(reason, arg1, arg2, arg3, arg4, arg5)
91 char *reason;
92 long arg1, arg2, arg3, arg4, arg5; /* Use longs, hope (char *) fits in it! */
93 {
94 /* Fatal error -- die with a meaningful error status for sendmail. If the
95 * logfile has been opened, the reason will also be logged there.
96 */
97 char buffer[MAX_STRING];
98 int status; /* Status from emergency_save() */
99
100 /*
101 * Attempt a save as early as possible, since we might not recover
102 * from a fprintf() if we came here on a SIGSEGV or a SIGBUS.
103 */
104
105 status = emergency_save(); /* Attempt emergency saving */
106
107 fprintf(stderr, "%s[%d]: FATAL ", progname, progpid);
108 fprintf(stderr, reason, arg1, arg2, arg3, arg4, arg5);
109 fputc('\n', stderr);
110
111 sprintf(buffer, "FATAL %s", reason);
112 add_log(1, buffer, arg1, arg2, arg3, arg4, arg5);
113
114 release_lock(); /* We're about to exit, free grabbed resources */
115
116 /*
117 * If the emergency saving failed, then the message is not queued
118 * anywhere. We're about to leave the message in the MTA queue in
119 * that case, but we must warn them since we have no guarantee the
120 * MTA will do as we think it will.
121 */
122
123 if (status == -1)
124 add_log(5, "WARNING no saving was ever done");
125
126 if (!was_queued()) {
127 /*
128 * Exit with a meaningful exit code for the MTA (sendmail usually) so
129 * that it leaves the message in its own queue for later delivery when
130 * conditions * are better (hopefully), or it will bounce to the sender
131 * after some delay.
132 */
133
134 add_log(6, "NOTICE leaving mail in MTA's queue");
135 my_exit(EX_TEMPFAIL);
136 }
137
138 /*
139 * Message was saved somewhere where mailagent will find it (either in
140 * its queue, or listed in the agent.wait file). There's no need for
141 * the MTA to worry, hence the following...
142 */
143
144 my_exit(EX_OK);
145 }
146
147