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