failures.c revision 89a126810703c666309310d0f3189e9834d70b5b
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void failure_exit(int status) ATTR_NORETURN;
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void default_panic_handler(const char *format, va_list args)
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void default_fatal_handler(int status, const char *format, va_list args)
428db8a58c0c149d5efccc6d788f70916c1d34d7Jakub Hrozekstatic void default_error_handler(const char *format, va_list args)
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagherstatic void default_warning_handler(const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void default_info_handler(const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher/* Initialize working defaults */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic failure_callback_t *panic_handler ATTR_NORETURN =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic fatal_failure_callback_t *fatal_handler ATTR_NORETURN =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic failure_callback_t *error_handler = default_error_handler;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic failure_callback_t *warning_handler = default_warning_handler;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic failure_callback_t *info_handler = default_info_handler;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void (*failure_exit_callback)(int *) = NULL;
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bosestatic char *log_prefix = NULL, *log_stamp_format = NULL;
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose/* kludgy .. we want to trust log_stamp_format with -Wformat-nonliteral */
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bosestatic const char *get_log_stamp_format(const char *unused)
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzkestatic const char *get_log_stamp_format(const char *unused ATTR_UNUSED)
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagherdefault_handler(const char *prefix, FILE *f, const char *format, va_list args)
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek static int recursed = 0;
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek /* we're being called from some signal handler, or
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek printf_format_fix_unsafe() killed us again */
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher /* printf_format_fix_unsafe() probably killed us last time,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher just write the format now. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* write may have failed, restore errno so %m works. although
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher it probably can't write the error then anyway. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* make sure there's no %n in there and fix %m */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher vfprintf(f, printf_format_fix_unsafe(format), args2);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherdefault_panic_handler(const char *format, va_list args)
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek (void)default_handler("Panic: ", log_fd, format, args);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void log_fd_flush_stop(struct ioloop *ioloop)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* wait until we can write more. this can happen at least
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher when writing to terminal, even if fd is blocking. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherdefault_fatal_handler(int status, const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (default_handler("Fatal: ", log_fd, format, args) < 0 &&
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (log_fd_flush(log_fd) < 0 && status == FATAL_DEFAULT)
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březinadefault_error_handler(const char *format, va_list args)
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina if (default_handler("Error: ", log_fd, format, args) < 0)
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozekdefault_warning_handler(const char *format, va_list args)
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek (void)default_handler("Warning: ", log_fd, format, args);
ae6c1596225c65bec2a2dabff9eee4e3e0691181Abhishek Singhdefault_info_handler(const char *format, va_list args)
d00ffd2cb4e2f17c75b466178bb645b5c9317909Pallavi Jha (void)default_handler("Info: ", log_info_fd, format, args);
99f8be128274eba264ea1434a7eb2800bced5902Lukas Slebodnikvoid i_fatal_status(int status, const char *format, ...)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_panic_handler(failure_callback_t *callback ATTR_NORETURN)
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bosevoid i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN)
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzkevoid i_set_error_handler(failure_callback_t *callback)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_warning_handler(failure_callback_t *callback)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_info_handler(failure_callback_t *callback)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghersyslog_handler(int level, const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher static int recursed = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* make sure there's no %n in there. vsyslog() supports %m, but since
96453f402831275a39d5fb89c33c9776e148d03fStephen Gallagher we'll convert it ourself anyway, we might as well it */
96453f402831275a39d5fb89c33c9776e148d03fStephen Gallagher vsyslog(level, printf_format_fix_unsafe(format), args);
c080a11e9e88f35e40aff4e476cabbd971833019Sumit Bosevoid i_syslog_panic_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)syslog_handler(LOG_CRIT, fmt, args);
1467daed400d6c186bd0c99c057c42e764309ff3Stephen Gallaghervoid i_syslog_fatal_handler(int status, const char *fmt, va_list args)
6a6a821866091e0f722808566c25b951aa346d7cStephen Gallagher if (syslog_handler(LOG_CRIT, fmt, args) < 0 && status == FATAL_DEFAULT)
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovvoid i_syslog_error_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_syslog_warning_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)syslog_handler(LOG_WARNING, fmt, args);
17f08cbd0f909181536b93d6c12c7cd69995f09eSumit Bosevoid i_syslog_info_handler(const char *fmt, va_list args)
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov (void)syslog_handler(LOG_INFO, fmt, args);
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovvoid i_set_failure_syslog(const char *ident, int options, int facility)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_panic_handler(i_syslog_panic_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_fatal_handler(i_syslog_fatal_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_error_handler(i_syslog_error_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_warning_handler(i_syslog_warning_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_info_handler(i_syslog_info_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void open_log_file(FILE **file, const char *path)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (path == NULL || strcmp(path, "/dev/stderr") == 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fprintf(stderr, "Can't open log file %s: %s\n",
bfbf5cb0f00c60c0f000f56c282377b13b9a89abSumit Bosevoid i_set_failure_file(const char *path, const char *prefix)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (log_info_fd != NULL && log_info_fd != log_fd &&
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_failure_prefix(const char *prefix)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherinternal_handler(char log_type, const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ret = write_full(2, str_data(str), str_len(str));
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozeki_internal_panic_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_NORETURN ATTR_FORMAT(2, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_fatal_handler(int status, const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (internal_handler('F', fmt, args) < 0 && status == FATAL_DEFAULT)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_error_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_warning_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_info_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_panic_handler(i_internal_panic_handler);
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallagher i_set_error_handler(i_internal_error_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_warning_handler(i_internal_warning_handler);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_info_handler(i_internal_info_handler);
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallaghervoid i_set_failure_timestamp_format(const char *fmt)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_failure_exit_callback(void (*callback)(int *status))