#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include "com_err.h"
#include "error_table.h"
#if defined(_WIN32)
#include <io.h>
#endif
k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER;
static void default_com_err_proc
(const char *whoami, errcode_t code,
const char *fmt, va_list ap);
#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
#define MAX_HOOKS 3
static et_old_error_hook_func com_err_hook[MAX_HOOKS] = { default_com_err_proc,
NULL, NULL };
static int hook_count = 1;
#define gettext(X) X
struct msg_map {
char *msgid;
char *c_msgstr;
};
struct msg_map msgmap[] = {
#define MSG_WHILE 0
{ gettext("%s\n## com_err msg of format: 'while ...'"),
"%s\n" },
#define MSG_ERROR_MSG 1
{ gettext("%s\n## com_err message of format: 'error msg ...'"),
"%s\n" },
#define MSG_ERROR_MSG_WHILE 2
{ gettext("%1$s %2$s\n## com_err message of format: "
"'error msg ... while ...'"),
"%1$s %2$s\n" },
#define MSG_WHOAMI_WHILE 3
{ gettext("%1$s: %2$s\n## com_err msg of format: 'whoami: while ...'"),
"%1$s: %2$s\n" },
#define MSG_WHOAMI_ERROR_MSG 4
{ gettext("%1$s: %2$s\n## com_err message of format: "
"'whoami: error msg ...'"),
"%1$s: %2$s\n" },
#define MSG_WHOAMI_ERROR_MSG_WHILE 5
{ gettext("%1$s: %2$s %3$s\n## com_err message of format: "
"'whoami: error msg ... while ...'"),
"%1$s: %2$s %3$s\n" },
#define MSG_WHOAMI 6
{ gettext("%s:\n ## com_err message of format: "
"'whoami: with no error msg or while ...'"),
"%s:\n " }
};
#undef gettext
static char *
my_gettext(int msg_idx)
{
char *msgid = msgmap[msg_idx].msgid;
char *c_msgstr = msgmap[msg_idx].c_msgstr;
char *msgstr = dgettext(TEXT_DOMAIN, msgid);
if (strcmp(msgstr, msgid) == 0)
return (c_msgstr);
else
return (msgstr);
}
static void default_com_err_proc (const char *whoami, errcode_t code,
const char *fmt, va_list ap)
{
char whilebuf[1024] = "";
*whilebuf = '\0';
if (fmt) {
vsprintf(whilebuf, fmt, ap);
}
if (!whoami) {
if ((!code) && fmt) {
fprintf(stderr, my_gettext(MSG_WHILE),
whilebuf);
} else if (code && !fmt) {
fprintf(stderr, my_gettext(MSG_ERROR_MSG),
error_message(code));
} else if (code && fmt) {
fprintf(stderr, my_gettext(MSG_ERROR_MSG_WHILE),
error_message(code), whilebuf);
} else
return;
} else {
if ((!code) && fmt) {
fprintf(stderr, my_gettext(MSG_WHOAMI_WHILE),
whoami, whilebuf);
} else if (code && !fmt) {
fprintf(stderr, my_gettext(MSG_WHOAMI_ERROR_MSG),
whoami, error_message(code));
} else if (code && fmt) {
fprintf(stderr,
my_gettext(MSG_WHOAMI_ERROR_MSG_WHILE),
whoami, error_message(code), whilebuf);
} else {
fprintf(stderr,
my_gettext(MSG_WHOAMI),
whoami);
}
}
fflush(stderr);
}
void KRB5_CALLCONV com_err_va(const char *whoami,
errcode_t code,
const char *fmt,
va_list ap)
{
int err;
int i;
err = com_err_finish_init();
if (err)
goto best_try;
err = k5_mutex_lock(&com_err_hook_lock);
if (err)
goto best_try;
for (i = 0; i < hook_count; i++) {
(com_err_hook[i])(whoami, code, fmt, ap);
}
k5_mutex_unlock(&com_err_hook_lock);
return;
best_try:
for (i = 0; i < hook_count; i++) {
(com_err_hook[i])(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)
{
int i;
et_old_error_hook_func x;
assert(com_err_finish_init() == 0);
assert(com_err_lock_hook_handle() == 0);
x = com_err_hook[0];
for (i = 0; i < hook_count; i++)
com_err_hook[i] = NULL;
com_err_hook[0] = new_proc;
hook_count = 1;
k5_mutex_unlock(&com_err_hook_lock);
return x;
}
et_old_error_hook_func reset_com_err_hook ()
{
int i;
et_old_error_hook_func x;
assert(com_err_finish_init() == 0);
assert(com_err_lock_hook_handle() == 0);
x = com_err_hook[0];
for (i = 0; i < hook_count; i++)
com_err_hook[i] = NULL;
com_err_hook[0] = default_com_err_proc;
hook_count = 1;
k5_mutex_unlock(&com_err_hook_lock);
return x;
}
void add_com_err_hook(et_old_error_hook_func f) {
int i;
if (hook_count < MAX_HOOKS) {
for (i = 0; i < hook_count; i++) {
if (com_err_hook[i] == NULL)
break;
}
com_err_hook[i] = f;
hook_count++;
}
}
void rem_com_err_hook(et_old_error_hook_func f) {
int i, j;
for (i = 0; i < hook_count; i++) {
if (com_err_hook[i] == f) {
for (j = i; j < hook_count - 1; j++) {
com_err_hook[j] = com_err_hook[j+1];
}
com_err_hook[j] = NULL;
hook_count--;
}
}
}
void rem_default_com_err_hook() {
rem_com_err_hook(default_com_err_proc);
}
void add_default_com_err_hook() {
add_com_err_hook(default_com_err_proc);
}