1/* $NetBSD$ */ 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 */ 84static MSG_CLEANUP_FN bounce_cleanup_func; /* saved callback */ 85VSTRING *bounce_cleanup_path; /* saved path name */ 86 87/* bounce_cleanup_callback - run-time callback to cleanup logfile */ 88 89static 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 107void 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 126static 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 139void 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 161void 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