failures.c revision 89a126810703c666309310d0f3189e9834d70b5b
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "lib.h"
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "ioloop.h"
8c294c1cd4d721818a59684cf7f2b36123f79163Stephen Gallagher#include "str.h"
c252d148fa8ab50aaaa8bbae7beb4d208025171dNikolai Kondrashov#include "backtrace-string.h"
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher#include "printf-format-fix.h"
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher#include "write-full.h"
9542512d7be40f2000298c86d3d2b728f4f0f65aStephen Gallagher#include "fd-close-on-exec.h"
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov#include <stdio.h>
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov#include <stdlib.h>
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov#include <syslog.h>
c6e39e15178675d0779e0ae855245774a09b4eb5Nikolai Kondrashov#include <time.h>
fd5a4eacd56700ffb08a73121aeacdc806cb0132Sumit Bose
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void failure_exit(int status) ATTR_NORETURN;
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void default_panic_handler(const char *format, va_list args)
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagher ATTR_NORETURN ATTR_FORMAT(1, 0);
8b1f525acd20f36c836e827de3c251088961c5d9Stephen Gallagherstatic void default_fatal_handler(int status, const char *format, va_list args)
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher ATTR_NORETURN ATTR_FORMAT(2, 0);
428db8a58c0c149d5efccc6d788f70916c1d34d7Jakub Hrozek
428db8a58c0c149d5efccc6d788f70916c1d34d7Jakub Hrozekstatic void default_error_handler(const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ATTR_FORMAT(1, 0);
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagherstatic void default_warning_handler(const char *format, va_list args)
df4cc3a83c5d6700b6a09ff96cb4a6b1949b1aa9Stephen Gallagher ATTR_FORMAT(1, 0);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void default_info_handler(const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ATTR_FORMAT(1, 0);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher/* Initialize working defaults */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic failure_callback_t *panic_handler ATTR_NORETURN =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher default_panic_handler;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic fatal_failure_callback_t *fatal_handler ATTR_NORETURN =
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher default_fatal_handler;
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;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bosestatic FILE *log_fd = NULL, *log_info_fd = NULL;
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bosestatic char *log_prefix = NULL, *log_stamp_format = NULL;
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose/* kludgy .. we want to trust log_stamp_format with -Wformat-nonliteral */
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bosestatic const char *get_log_stamp_format(const char *unused)
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose ATTR_FORMAT_ARG(1);
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzkestatic const char *get_log_stamp_format(const char *unused ATTR_UNUSED)
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke{
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose return log_stamp_format;
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose}
f3c85d900c4663854cc7bbae7d9f77867ed1f69bSumit Bose
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void failure_exit(int status)
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher{
2a552e43581c74f51205c7141ec9f6e9542509f8Stephen Gallagher if (failure_exit_callback != NULL)
8214510f125879c3b1d247f2ce981ee20b5375d1Jakub Hrozek failure_exit_callback(&status);
1a59af8245f183f22d87d067a90197d8e2ea958dJakub Hrozek exit(status);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
d921c1eba437662437847279f251a0a5d8f70127Maximstatic void write_prefix(FILE *f)
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozek{
b9c8ce2bdd4045782c243605a1b999098bedcffcNoam Meltzer struct tm *tm;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher char str[256];
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher time_t now;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (log_prefix != NULL)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fputs(log_prefix, f);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (log_stamp_format != NULL) {
2a5790216f57e9bdfb2930d52860bb5300366536Jakub Hrozek now = time(NULL);
5377441d7a846461c2d9a7a870cea711360a529aNikolai Kondrashov tm = localtime(&now);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (strftime(str, sizeof(str),
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley get_log_stamp_format("unused"), tm) > 0)
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher fputs(str, f);
4b6a0d0b3d42e5fdb457f47d9adfa5e66b160256Stephen Gallagher }
e124844907ed6973915e4d56f5442ecd07535a12Jakub Hrozek}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagherstatic int ATTR_FORMAT(3, 0)
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagherdefault_handler(const char *prefix, FILE *f, const char *format, va_list args)
87d3b47abba6a40fcf809c85a2b138bc1013d9c5Jakub Hrozek{
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek static int recursed = 0;
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek va_list args2;
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek int old_errno = errno;
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek if (recursed == 2) {
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek /* we're being called from some signal handler, or
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek printf_format_fix_unsafe() killed us again */
bc13c352ba9c2877f1e9bc62e55ad60fc000a55dJakub Hrozek return -1;
87d3b47abba6a40fcf809c85a2b138bc1013d9c5Jakub Hrozek }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher recursed++;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (f == NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher f = stderr;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
054b5d4bb98973698f74d66b14ccd14394b53f10Lukas Slebodnik if (log_fd == NULL)
054b5d4bb98973698f74d66b14ccd14394b53f10Lukas Slebodnik log_fd = stderr;
a3d176d116ceccd6a7547c128fab5df5cdd2c2b6Michal Zidek }
a3d176d116ceccd6a7547c128fab5df5cdd2c2b6Michal Zidek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher VA_COPY(args2, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
4f6931e854c698dcb1c09f99eb330ce2fb97e7c6Lukas Slebodnik if (recursed == 2) {
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher /* printf_format_fix_unsafe() probably killed us last time,
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher just write the format now. */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
558998ce664055a75595371118f818084d8f2b23Jan Cholasta fputs("recursed: ", f);
558998ce664055a75595371118f818084d8f2b23Jan Cholasta fputs(format, f);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta } else {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta write_prefix(f);
558998ce664055a75595371118f818084d8f2b23Jan Cholasta fputs(prefix, f);
558998ce664055a75595371118f818084d8f2b23Jan Cholasta
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 errno = old_errno;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* make sure there's no %n in there and fix %m */
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher vfprintf(f, printf_format_fix_unsafe(format), args2);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
c737e1444fb186e349e59bfa9dac4995b720b4b1Jan Zeleny fputc('\n', f);
f1828234a850dd28465425248a83a993f262918fPavel Březina
6ea6ec5cb7d9985e2730fb9d4657624d10aed4d8Nick Guay errno = old_errno;
6ea6ec5cb7d9985e2730fb9d4657624d10aed4d8Nick Guay recursed--;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_FORMAT(1, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherdefault_panic_handler(const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek const char *backtrace;
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek
1746e8b8399da2a7a8da4aace186f66055ccfec1Jakub Hrozek (void)default_handler("Panic: ", log_fd, format, args);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (backtrace_get(&backtrace) == 0)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina i_error("Raw backtrace: %s", backtrace);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina abort();
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek}
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void log_fd_flush_stop(struct ioloop *ioloop)
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta{
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta io_loop_stop(ioloop);
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta}
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozekstatic int log_fd_flush(FILE *fd)
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek{
19d3aba12c70528708be9440aca66038a291f29eYassir Elley struct ioloop *ioloop;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley struct io *io;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley
cb4d5b588e704114b7090678752d33512baa718eJakub Hrozek while (fflush(fd) < 0) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (errno == EINTR)
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose continue;
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose if (errno != EAGAIN)
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose return -1;
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher /* wait until we can write more. this can happen at least
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher when writing to terminal, even if fd is blocking. */
36ccdecd053a9ad88dce86b8c84770dc2aa11d21Simo Sorce ioloop = io_loop_create();
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher io = io_add(IO_WRITE, fileno(log_fd),
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_fd_flush_stop, ioloop);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher io_loop_run(ioloop);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher io_remove(&io);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher io_loop_destroy(&ioloop);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_FORMAT(2, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherdefault_fatal_handler(int status, const char *format, va_list args)
effcbdb12c7ef892f1fd92a745cb33a08ca4ba30Stephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (default_handler("Fatal: ", log_fd, format, args) < 0 &&
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek status == FATAL_DEFAULT)
4dd615c01357b8715711aad6820ba9595d3ad377Stephen Gallagher status = FATAL_LOGERROR;
fe60346714a73ac3987f786731389320633dd245Pavel Březina
a6098862048d4bb469130b9ff21be3020d6f2c54Sumit Bose if (log_fd_flush(log_fd) < 0 && status == FATAL_DEFAULT)
2d257ccf620ce1b611f89cec8f0a94c88c2f2881Sumit Bose status = FATAL_LOGWRITE;
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek failure_exit(status);
e5e8252ec48bfdd4e7529debc705c8e090264b9aSumit Bose}
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březina
8359bf07a2e6c0181251ce8d5d9160dc57546c55Stephen Gallagherstatic void ATTR_FORMAT(1, 0)
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březinadefault_error_handler(const char *format, va_list args)
71e7918be3ca5d38794a16a17f6b4f19a24d51fcPavel Březina{
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina if (default_handler("Error: ", log_fd, format, args) < 0)
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina failure_exit(FATAL_LOGERROR);
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina if (log_fd_flush(log_fd) < 0)
bbaba8b3ef9bc101863b8687f234f4ee956caacdPavel Březina failure_exit(FATAL_LOGWRITE);
80314a6f3ea8d81abe73d501d5b953a256cb2167Pavel Březina}
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozekstatic void ATTR_FORMAT(1, 0)
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozekdefault_warning_handler(const char *format, va_list args)
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek{
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek (void)default_handler("Warning: ", log_fd, format, args);
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek
4bd20c075f0f187db0181dc53d00ab6cd47fdb4dJakub Hrozek if (log_fd_flush(log_fd) < 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher failure_exit(FATAL_LOGWRITE);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek}
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek
a65a64aee968bd2ac18156ced15a1e2509a8acbaAbhishek Singhstatic void ATTR_FORMAT(1, 0)
ae6c1596225c65bec2a2dabff9eee4e3e0691181Abhishek Singhdefault_info_handler(const char *format, va_list args)
2a9af1f71887f02935e2fb6ad5023afba5b6d43eSumit Bose{
d00ffd2cb4e2f17c75b466178bb645b5c9317909Pallavi Jha (void)default_handler("Info: ", log_info_fd, format, args);
461da2984c747708e8badd27fa55ef879f40e712Pallavi Jha
9cb46bc62f22e0104f1b41a423b014c281ef5fc2Jakub Hrozek if (log_fd_flush(log_info_fd) < 0)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek failure_exit(FATAL_LOGWRITE);
d064fef06dcbcb5f6c1be03e286b1a3433d6dfd7Sumit Bose}
e046ae03d0f55b1c8b0ec2fa6139bf86a3449adfPavel Březina
939246537b0b9a4af6862c513d3919501ad57d92Sumit Bosevoid i_panic(const char *format, ...)
f69f3581658351003a6d9245045e41d0efb85022Sumit Bose{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek va_list args;
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek
90afedb00608547ae1f32aa7aafd552c4b306909Jakub Hrozek va_start(args, format);
7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926Jakub Hrozek panic_handler(format, args);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek va_end(args);
f43c6a9ae2aea13b7a83fd932139f9352efbfcadPavel Březina}
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozekvoid i_fatal(const char *format, ...)
a524965fbe0551f1b3a68f1e5c7a5689a652998fSumit Bose{
e592d5f157be869151983bd1b46d6f4f7a29daafJakub Hrozek va_list args;
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek va_start(args, format);
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek fatal_handler(FATAL_DEFAULT, format, args);
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek va_end(args);
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek}
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik
99f8be128274eba264ea1434a7eb2800bced5902Lukas Slebodnikvoid i_fatal_status(int status, const char *format, ...)
99f8be128274eba264ea1434a7eb2800bced5902Lukas Slebodnik{
99f8be128274eba264ea1434a7eb2800bced5902Lukas Slebodnik va_list args;
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik va_start(args, format);
f92ace4a52602e8c38a34f2392bec3deeac2ddddJakub Hrozek fatal_handler(status, format, args);
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek va_end(args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
f232789430a080384188d5da89b19d874cf17513Jakub Hrozekvoid i_error(const char *format, ...)
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher int old_errno = errno;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher va_list args;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher va_start(args, format);
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher error_handler(format, args);
fa551077410019fb34460dc730950e93b62b2963Jakub Hrozek va_end(args);
fa551077410019fb34460dc730950e93b62b2963Jakub Hrozek
fa551077410019fb34460dc730950e93b62b2963Jakub Hrozek errno = old_errno;
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher}
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher
03a071399ab5fb58d4bb4fa38928413a21ae4d61Nikolai Kondrashovvoid i_warning(const char *format, ...)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
bf5a808fa92007c325c3996e79694badfab201d4Stephen Gallagher int old_errno = errno;
150b76e13b7c4f3ccf1d709bf517ca2af6b2c9a2Jakub Hrozek va_list args;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher va_start(args, format);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher warning_handler(format, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher va_end(args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher errno = old_errno;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnikvoid i_info(const char *format, ...)
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik{
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik int old_errno = errno;
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik va_list args;
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik
a2e417f38c57ed87c956ddcecf4dafca93842b65Lukas Slebodnik va_start(args, format);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher info_handler(format, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher va_end(args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher errno = old_errno;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_panic_handler(failure_callback_t *callback ATTR_NORETURN)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose if (callback == NULL)
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose callback = default_panic_handler;
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose panic_handler = callback;
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose}
8a5e793a0576250da80371e53aa3e7eba15cdb63Sumit Bose
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bosevoid i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN)
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose{
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose if (callback == NULL)
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose callback = default_fatal_handler;
90fd1bbd6035cdab46faa3a695a2fb2be6508b17Sumit Bose fatal_handler = callback;
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke}
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzkevoid i_set_error_handler(failure_callback_t *callback)
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke{
af4ffe1001adcc0a96897e426d26444f07af9aa1Benjamin Franzke if (callback == NULL)
96453f402831275a39d5fb89c33c9776e148d03fStephen Gallagher callback = default_error_handler;
96453f402831275a39d5fb89c33c9776e148d03fStephen Gallagher error_handler = callback;
96453f402831275a39d5fb89c33c9776e148d03fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_warning_handler(failure_callback_t *callback)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta if (callback == NULL)
b35f20cd8ecdc8308a3201e55752fb0443ec6ae4Jan Cholasta callback = default_warning_handler;
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta warning_handler = callback;
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek}
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_info_handler(failure_callback_t *callback)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (callback == NULL)
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta callback = default_info_handler;
b35f20cd8ecdc8308a3201e55752fb0443ec6ae4Jan Cholasta info_handler = callback;
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta}
69aaef8719c5cf33ed1c4090fa313ba281bf8a02Jakub Hrozek
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int ATTR_FORMAT(2, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghersyslog_handler(int level, const char *format, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher static int recursed = 0;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (recursed != 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return -1;
3b1df539835367cb81cd5ff0f9959947d5642e55Stephen Gallagher
3b1df539835367cb81cd5ff0f9959947d5642e55Stephen Gallagher recursed++;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
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);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher recursed--;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher return 0;
667db40da4db362d7ca0a1f7f1c4ba40fb71795aJakub Hrozek}
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
c080a11e9e88f35e40aff4e476cabbd971833019Sumit Bosevoid i_syslog_panic_handler(const char *fmt, va_list args)
c080a11e9e88f35e40aff4e476cabbd971833019Sumit Bose{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher const char *backtrace;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)syslog_handler(LOG_CRIT, fmt, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (backtrace_get(&backtrace) == 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_error("Raw backtrace: %s", backtrace);
1467daed400d6c186bd0c99c057c42e764309ff3Stephen Gallagher abort();
1467daed400d6c186bd0c99c057c42e764309ff3Stephen Gallagher}
15b266d9f14dad26da8678a79019749d0f69532eStephen Gallagher
1467daed400d6c186bd0c99c057c42e764309ff3Stephen Gallaghervoid i_syslog_fatal_handler(int status, const char *fmt, va_list args)
b97595ae059c69b1960a6e7e56d74660388a683bJan Zeleny{
6a6a821866091e0f722808566c25b951aa346d7cStephen Gallagher if (syslog_handler(LOG_CRIT, fmt, args) < 0 && status == FATAL_DEFAULT)
48d7840cae22c5ff4d786149b0d8ecee7efb8306Lukas Slebodnik status = FATAL_LOGERROR;
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov failure_exit(status);
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov}
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovvoid i_syslog_error_handler(const char *fmt, va_list args)
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov{
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose if (syslog_handler(LOG_ERR, fmt, args) < 0)
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose failure_exit(FATAL_LOGERROR);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
84ae5edab16ad6be5e3be956cb6fa031c1428eb5Stephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_syslog_warning_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)syslog_handler(LOG_WARNING, fmt, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
17f08cbd0f909181536b93d6c12c7cd69995f09eSumit Bosevoid i_syslog_info_handler(const char *fmt, va_list args)
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov{
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov (void)syslog_handler(LOG_INFO, fmt, args);
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov}
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovvoid i_set_failure_syslog(const char *ident, int options, int facility)
6398f22526303343193a18e514602f1af6fb29cbNikolai Kondrashov{
6398f22526303343193a18e514602f1af6fb29cbNikolai Kondrashov openlog(ident, options, facility);
6398f22526303343193a18e514602f1af6fb29cbNikolai Kondrashov
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 Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void open_log_file(FILE **file, const char *path)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (*file != NULL && *file != stderr)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)fclose(*file);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (path == NULL || strcmp(path, "/dev/stderr") == 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *file = stderr;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher else {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher *file = fopen(path, "a");
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (*file == NULL) {
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fprintf(stderr, "Can't open log file %s: %s\n",
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher path, strerror(errno));
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher failure_exit(FATAL_LOGOPEN);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher fd_close_on_exec(fileno(*file), TRUE);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
bfbf5cb0f00c60c0f000f56c282377b13b9a89abSumit Bosevoid i_set_failure_file(const char *path, const char *prefix)
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher{
77c0d1f6074059dafd2293f9c42ea0f9d60f8aadJakub Hrozek i_set_failure_prefix(prefix);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (log_info_fd != NULL && log_info_fd != log_fd &&
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_info_fd != stderr)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)fclose(log_info_fd);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce open_log_file(&log_fd, path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_info_fd = log_fd;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
b9e5bd09a5ff7009537a18914dbebcf10498f592Sumit Bose i_set_panic_handler(NULL);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_fatal_handler(NULL);
0ef783e186ef1c9f60e61a4e8e54c44cb366fdfePavel Březina i_set_error_handler(NULL);
2cbdd12983eb85eddb90f64cfafb24eae5b448f4Jakub Hrozek i_set_warning_handler(NULL);
e7311aec8d691e5427317442387af1bc8fff3742Jan Cholasta}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_failure_prefix(const char *prefix)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_free(log_prefix);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_prefix = i_strdup(prefix);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic int ATTR_FORMAT(2, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherinternal_handler(char log_type, const char *format, va_list args)
c0f9698cd951b7223f251ff2511c4b22a6e4ba60Jan Zeleny{
769347ad4d35d43488eb98f980143495b0db415dStef Walter string_t *str;
115de6d50f0d0bdd5745a5d8eb0d067be9128528Sumit Bose int ret;
769347ad4d35d43488eb98f980143495b0db415dStef Walter
769347ad4d35d43488eb98f980143495b0db415dStef Walter t_push();
769347ad4d35d43488eb98f980143495b0db415dStef Walter str = t_str_new(512);
769347ad4d35d43488eb98f980143495b0db415dStef Walter str_append_c(str, 1);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append_c(str, log_type);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_vprintfa(str, format, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher str_append_c(str, '\n');
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher ret = write_full(2, str_data(str), str_len(str));
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher t_pop();
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
db78f4c750943fcd4b60bca5f3fdfd6cc5d3d4f8Ondrej Kos return ret;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozekstatic void ATTR_NORETURN ATTR_FORMAT(1, 0)
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozeki_internal_panic_handler(const char *fmt, va_list args)
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek{
543676afec3c08fdc0a5a794976adc8dfdca974bJakub Hrozek const char *backtrace;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina (void)internal_handler('F', fmt, args);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (backtrace_get(&backtrace) == 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_error("Raw backtrace: %s", backtrace);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher abort();
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_NORETURN ATTR_FORMAT(2, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_fatal_handler(int status, const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (internal_handler('F', fmt, args) < 0 && status == FATAL_DEFAULT)
77d165f0629966db65753a3aee84a8b4971673afPavel Březina status = FATAL_LOGERROR;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher failure_exit(status);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_FORMAT(1, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_error_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (internal_handler('E', fmt, args) < 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher failure_exit(FATAL_LOGERROR);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_FORMAT(1, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_warning_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
126c9338cf12a3e4404c36bbe4ec14b18f23537cMaxim (void)internal_handler('W', fmt, args);
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagherstatic void ATTR_FORMAT(1, 0)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagheri_internal_info_handler(const char *fmt, va_list args)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher (void)internal_handler('I', fmt, args);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_failure_internal(void)
2e6087c6cc903d5164b9a1d5e3d791fd046001d9Jakub Hrozek{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_set_panic_handler(i_internal_panic_handler);
126c9338cf12a3e4404c36bbe4ec14b18f23537cMaxim i_set_fatal_handler(i_internal_fatal_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);
eaa723b4d06b4c1e588df67bef44a84bbfaebf1aLukas Slebodnik}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_info_file(const char *path)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher if (log_info_fd == log_fd)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_info_fd = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher open_log_file(&log_info_fd, path);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher info_handler = default_info_handler;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
bfbf5cb0f00c60c0f000f56c282377b13b9a89abSumit Bose
fe2091327ff44f80d6681c261494e4432404e9baStephen Gallaghervoid i_set_failure_timestamp_format(const char *fmt)
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_free(log_stamp_format);
2e6087c6cc903d5164b9a1d5e3d791fd046001d9Jakub Hrozek log_stamp_format = i_strdup(fmt);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid i_set_failure_exit_callback(void (*callback)(int *status))
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher{
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher failure_exit_callback = callback;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallaghervoid failures_deinit(void)
3a4186ae40d0c3b7be46a4c973166f6048fcfe38Lukas Slebodnik{
8bcabb97d988d1602882a1f036aac2eaf5e09234Simo Sorce if (log_info_fd == log_fd)
b9d8c6172e48a2633ebe196b2e88bebdf9523c20Stef Walter log_info_fd = NULL;
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
1658c567191c35beaddffafdb079abe33248037bLukas Slebodnik if (log_fd != NULL && log_fd != stderr) {
29be7d76c949b82350c7603cfd362a1fcb47eb1bJan Zeleny (void)fclose(log_fd);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher log_fd = stderr;
72e60fd4eabcfbcdbfe01e8c38b94052bc6c2067Jakub Hrozek }
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher
823a5b3f4375f12b6edae4dd5169ee01771baebeJan Zeleny if (log_info_fd != NULL && log_info_fd != stderr) {
b32159300fea63222d8dd9200ed634087704ea74Stephen Gallagher (void)fclose(log_info_fd);
748ba184db97b7534254f97018fa04e8aa458faeJan Cholasta log_info_fd = stderr;
7de6e3534fd61c7619ed34a6b1afe7230b5e6504Ondrej Kos }
701f13b5c8e27bcbfc79e77ce7c76d9f768a448cLukas Slebodnik
3fc158e59eebbc2f538fe0076a03928d0d4eab9fPavel Březina i_free_and_null(log_prefix);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher i_free_and_null(log_stamp_format);
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher}
551aa6c36797ed720487f5974dcadabf19e6ff9fStephen Gallagher