Postfix3.3.1
bounce_cleanup.c
[詳解]
1 /*++
2 /* NAME
3 /* bounce_cleanup 3
4 /* SUMMARY
5 /* cleanup logfile upon error
6 /* SYNOPSIS
7 /* #include "bounce_service.h"
8 /*
9 /* int bounce_cleanup_registered()
10 /*
11 /* void bounce_cleanup_register(queue_id)
12 /* char *queue_id;
13 /*
14 /* void bounce_cleanup_log(void)
15 /*
16 /* void bounce_cleanup_unregister(void)
17 /* DESCRIPTION
18 /* This module implements support for deleting the current
19 /* bounce logfile in case of errors, and upon the arrival
20 /* of a SIGTERM signal (shutdown).
21 /*
22 /* bounce_cleanup_register() registers a callback routine with the
23 /* run-time error handler, for automatic logfile removal in case
24 /* of a fatal run-time error.
25 /*
26 /* bounce_cleanup_unregister() cleans up storage used by
27 /* bounce_cleanup_register().
28 /*
29 /* In-between bounce_cleanup_register() and bounce_cleanup_unregister()
30 /* calls, a call of bounce_cleanup_log() will delete the registered
31 /* bounce logfile.
32 /*
33 /* bounce_cleanup_registered() returns non-zero when a cleanup
34 /* trap has been set.
35 /* DIAGNOSTICS
36 /* Fatal error: all file access errors. Panic: nested calls of
37 /* bounce_cleanup_register(); any calls of bounce_cleanup_unregister()
38 /* or bounce_cleanup_log() without preceding bounce_cleanup_register()
39 /* call.
40 /* BUGS
41 /* SEE ALSO
42 /* master(8) process manager
43 /* LICENSE
44 /* .ad
45 /* .fi
46 /* The Secure Mailer license must be distributed with this software.
47 /* AUTHOR(S)
48 /* Wietse Venema
49 /* IBM T.J. Watson Research
50 /* P.O. Box 704
51 /* Yorktown Heights, NY 10598, USA
52 /*--*/
53 
54 /* System library. */
55 
56 #include <sys_defs.h>
57 #include <unistd.h>
58 #include <signal.h>
59 #include <stdlib.h>
60 
61 /* Utility library. */
62 
63 #include <msg.h>
64 #include <mymalloc.h>
65 #include <vstring.h>
66 
67 /* Global library. */
68 
69 #include <mail_queue.h>
70 
71 /* Application-specific. */
72 
73 #include "bounce_service.h"
74 
75  /*
76  * Support for removing a logfile when an update fails. In order to do this,
77  * we save a copy of the currently-open logfile name, and register a
78  * callback function pointer with the run-time error handler. The saved
79  * pathname is made global so that the application can see whether or not a
80  * trap was set up.
81  */
82 static MSG_CLEANUP_FN bounce_cleanup_func; /* saved callback */
83 VSTRING *bounce_cleanup_path; /* saved path name */
84 
85 /* bounce_cleanup_callback - run-time callback to cleanup logfile */
86 
87 static void bounce_cleanup_callback(void)
88 {
89 
90  /*
91  * Remove the logfile.
92  */
93  if (bounce_cleanup_path)
95 
96  /*
97  * Execute the saved cleanup action.
98  */
99  if (bounce_cleanup_func)
100  bounce_cleanup_func();
101 }
102 
103 /* bounce_cleanup_log - clean up the logfile */
104 
106 {
107  const char *myname = "bounce_cleanup_log";
108 
109  /*
110  * Sanity checks.
111  */
112  if (bounce_cleanup_path == 0)
113  msg_panic("%s: no cleanup context", myname);
114 
115  /*
116  * This function may be called before a logfile is created or after it
117  * has been deleted, so do not complain.
118  */
119  (void) unlink(vstring_str(bounce_cleanup_path));
120 }
121 
122 /* bounce_cleanup_sig - signal handler */
123 
124 static void bounce_cleanup_sig(int sig)
125 {
126 
127  /*
128  * Running as a signal handler - don't do complicated stuff.
129  */
130  if (bounce_cleanup_path)
131  (void) unlink(vstring_str(bounce_cleanup_path));
132  _exit(sig);
133 }
134 
135 /* bounce_cleanup_register - register logfile to clean up */
136 
137 void bounce_cleanup_register(char *service, char *queue_id)
138 {
139  const char *myname = "bounce_cleanup_register";
140 
141  /*
142  * Sanity checks.
143  */
144  if (bounce_cleanup_path)
145  msg_panic("%s: nested call", myname);
146 
147  /*
148  * Save a copy of the logfile path, and of the last callback function
149  * pointer registered with the run-time error handler.
150  */
151  bounce_cleanup_path = vstring_alloc(10);
152  (void) mail_queue_path(bounce_cleanup_path, service, queue_id);
153  bounce_cleanup_func = msg_cleanup(bounce_cleanup_callback);
154  signal(SIGTERM, bounce_cleanup_sig);
155 }
156 
157 /* bounce_cleanup_unregister - unregister logfile to clean up */
158 
160 {
161  const char *myname = "bounce_cleanup_unregister";
162 
163  /*
164  * Sanity checks.
165  */
166  if (bounce_cleanup_path == 0)
167  msg_panic("%s: no cleanup context", myname);
168 
169  /*
170  * Restore the saved callback function pointer, and release storage for
171  * the saved logfile pathname.
172  */
173  signal(SIGTERM, SIG_DFL);
174  (void) msg_cleanup(bounce_cleanup_func);
175  vstring_free(bounce_cleanup_path);
176  bounce_cleanup_path = 0;
177 }
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
void(* MSG_CLEANUP_FN)(void)
Definition: msg.h:23
#define vstring_str(vp)
Definition: vstring.h:71
void bounce_cleanup_register(char *service, char *queue_id)
const char * mail_queue_path(VSTRING *buf, const char *queue_name, const char *queue_id)
Definition: mail_queue.c:204
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
void bounce_cleanup_log(void)
void bounce_cleanup_unregister(void)
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
VSTRING * bounce_cleanup_path
MSG_CLEANUP_FN msg_cleanup(MSG_CLEANUP_FN cleanup_fn)
Definition: msg.c:317