#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "com_err.h"
#include "error_table.h"
#if defined(_WIN32)
#include <io.h>
#endif
static et_old_error_hook_func com_err_hook = 0;
k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER;
#if defined(_WIN32)
BOOL isGuiApp() {
DWORD mypid;
HANDLE myprocess;
mypid = GetCurrentProcessId();
myprocess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, mypid);
return GetGuiResources(myprocess, 1) > 0;
}
#endif
static void default_com_err_proc (const char *whoami, errcode_t code,
const char *fmt, va_list ap)
{
#if defined(_WIN32)
char errbuf[1024] = "";
if (whoami) {
errbuf[sizeof(errbuf) - 1] = '\0';
strncat (errbuf, whoami, sizeof(errbuf) - 1 - strlen(errbuf));
strncat (errbuf, ": ", sizeof(errbuf) - 1 - strlen(errbuf));
}
if (code) {
errbuf[sizeof(errbuf) - 1] = '\0';
strncat (errbuf, error_message(code), sizeof(errbuf) - 1 - strlen(errbuf));
strncat (errbuf, " ", sizeof(errbuf) - 1 - strlen(errbuf));
}
if (fmt)
vsprintf (errbuf + strlen (errbuf), fmt, ap);
errbuf[sizeof(errbuf) - 1] = '\0';
if (_isatty(_fileno(stderr)) || !isGuiApp()) {
fputs(errbuf, stderr);
fputc('\r', stderr);
fputc('\n', stderr);
fflush(stderr);
} else
MessageBox ((HWND)NULL, errbuf, "Kerberos", MB_ICONEXCLAMATION);
#else
if (whoami) {
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code) {
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt) {
vfprintf(stderr, fmt, ap);
}
putc('\r', stderr);
putc('\n', stderr);
fflush(stderr);
#endif
}
void KRB5_CALLCONV com_err_va(const char *whoami,
errcode_t code,
const char *fmt,
va_list ap)
{
int err;
et_old_error_hook_func p;
err = com_err_finish_init();
if (err)
goto best_try;
err = k5_mutex_lock(&com_err_hook_lock);
if (err)
goto best_try;
p = com_err_hook ? com_err_hook : default_com_err_proc;
(*p)(whoami, code, fmt, ap);
k5_mutex_unlock(&com_err_hook_lock);
return;
best_try:
if (!com_err_hook)
default_com_err_proc(whoami, code, fmt, ap);
else
(com_err_hook)(whoami, code, fmt, ap);
assert(err == 0);
abort();
}
void KRB5_CALLCONV_C com_err(const char *whoami,
errcode_t code,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
com_err_va(whoami, code, fmt, ap);
va_end(ap);
}
static int com_err_lock_hook_handle(void)
{
return k5_mutex_lock(&com_err_hook_lock);
}
et_old_error_hook_func set_com_err_hook (et_old_error_hook_func new_proc)
{
et_old_error_hook_func x;
assert(com_err_finish_init() == 0);
assert(com_err_lock_hook_handle() == 0);
x = com_err_hook;
com_err_hook = new_proc;
k5_mutex_unlock(&com_err_hook_lock);
return x;
}
et_old_error_hook_func reset_com_err_hook ()
{
et_old_error_hook_func x;
assert(com_err_finish_init() == 0);
assert(com_err_lock_hook_handle() == 0);
x = com_err_hook;
com_err_hook = NULL;
k5_mutex_unlock(&com_err_hook_lock);
return x;
}