summaryrefslogtreecommitdiffstats
path: root/src/util/support
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/support')
-rw-r--r--src/util/support/ChangeLog8
-rw-r--r--src/util/support/Makefile.in3
-rw-r--r--src/util/support/errors.c134
-rw-r--r--src/util/support/libkrb5support.exports6
-rw-r--r--src/util/support/threads.c4
5 files changed, 155 insertions, 0 deletions
diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog
index 295f42f12..d1fae1dbe 100644
--- a/src/util/support/ChangeLog
+++ b/src/util/support/ChangeLog
@@ -1,3 +1,11 @@
+2006-03-26 Ken Raeburn <raeburn@mit.edu>
+
+ * errors.c: New file.
+ * Makefile.in (SRCS, LIBOBJS, STLIBOBJS): Add it.
+ * threads.c (krb5int_thread_support_init): Call krb5int_err_init
+ to initialize the new file.
+ * libkrb5support.exports: Add the new symbols.
+
2006-03-13 Ken Raeburn <raeburn@mit.edu>
* plugins.c (krb5int_get_plugin_dir_data): If dirhandle is null or
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index e6c75f525..2e96a88db 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -28,12 +28,14 @@ STLIBOBJS= \
threads.o \
init-addrinfo.o \
plugins.o \
+ errors.o \
fake-addrinfo.o
LIBOBJS= \
$(OUTPRE)threads.$(OBJEXT) \
$(OUTPRE)init-addrinfo.$(OBJEXT) \
$(OUTPRE)plugins.$(OBJEXT) \
+ $(OUTPRE)errors.$(OBJEXT) \
$(OUTPRE)fake-addrinfo.$(OBJEXT)
STOBJLISTS=OBJS.ST
@@ -45,6 +47,7 @@ LOCALINCLUDES=-I. -I$(srcdir)
SRCS=\
$(srcdir)/threads.c \
$(srcdir)/init-addrinfo.c \
+ $(srcdir)/errors.c \
$(srcdir)/fake-addrinfo.c
SHLIB_EXPDEPS =
# Add -lm if dumping thread stats, for sqrt.
diff --git a/src/util/support/errors.c b/src/util/support/errors.c
new file mode 100644
index 000000000..185cb425a
--- /dev/null
+++ b/src/util/support/errors.c
@@ -0,0 +1,134 @@
+/* Can't include krb5.h here, or k5-int.h which includes it, because
+ krb5.h needs to be generated with error tables, after util/et,
+ which builds after this directory. */
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "k5-err.h"
+
+#include "k5-thread.h"
+#include "k5-platform.h"
+
+/* It would be nice to just use error_message() always. Pity that
+ it's defined in a library that depends on this one, and we're not
+ allowed to make circular dependencies. */
+/* We really want a rwlock here, since we should hold it while calling
+ the function and copying out its results. But I haven't
+ implemented shims for rwlock yet. */
+static k5_mutex_t krb5int_error_info_support_mutex =
+ K5_MUTEX_PARTIAL_INITIALIZER;
+static const char *(KRB5_CALLCONV *fptr)(long); /* = &error_message */
+
+int
+krb5int_err_init (void)
+{
+ return k5_mutex_finish_init (&krb5int_error_info_support_mutex);
+}
+#define initialize() krb5int_call_thread_support_init()
+#define lock() k5_mutex_lock(&krb5int_error_info_support_mutex)
+#define unlock() k5_mutex_unlock(&krb5int_error_info_support_mutex)
+
+void
+krb5int_set_error (struct errinfo *ep, long code, const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ krb5int_vset_error (ep, code, fmt, args);
+ va_end (args);
+}
+
+void
+krb5int_vset_error (struct errinfo *ep, long code,
+ const char *fmt, va_list args)
+{
+ if (ep->msg && ep->msg != ep->scratch_buf) {
+ free (ep->msg);
+ ep->msg = NULL;
+ }
+ ep->code = code;
+#ifdef HAVE_VASPRINTF
+ {
+ char *str = NULL;
+ if (vasprintf(&str, fmt, args) >= 0 && str != NULL) {
+ ep->msg = str;
+ return;
+ }
+ }
+#endif
+ vsnprintf(ep->scratch_buf, sizeof(ep->scratch_buf), fmt, args);
+ ep->msg = ep->scratch_buf;
+}
+
+char *
+krb5int_get_error (struct errinfo *ep, long code)
+{
+ char *r, *r2;
+ if (code != ep->code)
+ krb5int_clear_error (ep);
+ if (ep->msg) {
+ r = ep->msg;
+ ep->msg = NULL;
+ return r;
+ }
+ if (initialize() != 0) {
+ strncpy(ep->scratch_buf, _("Kerberos library initialization failure"),
+ sizeof(ep->scratch_buf));
+ ep->scratch_buf[sizeof(ep->scratch_buf)-1] = 0;
+ ep->msg = NULL;
+ return ep->scratch_buf;
+ }
+ lock();
+ if (fptr == NULL) {
+ unlock();
+ r = strerror (code);
+ if (r) {
+ if (strlen (r) < sizeof (ep->scratch_buf)
+ || (r2 = strdup (r)) == NULL) {
+ strncpy (ep->scratch_buf, r, sizeof(ep->scratch_buf));
+ return ep->scratch_buf;
+ } else
+ return r2;
+ }
+ format_number:
+ sprintf (ep->scratch_buf, _("error %ld"), code);
+ return ep->scratch_buf;
+ }
+ r = fptr(code);
+ if (r == NULL) {
+ unlock();
+ goto format_number;
+ }
+ r2 = strdup (r);
+ if (r2 == NULL) {
+ strncpy(ep->scratch_buf, r, sizeof(ep->scratch_buf));
+ unlock();
+ return ep->scratch_buf;
+ } else {
+ unlock();
+ return r2;
+ }
+}
+
+void
+krb5int_free_error (struct errinfo *ep, char *msg)
+{
+ if (msg != ep->scratch_buf)
+ free (msg);
+}
+
+void
+krb5int_clear_error (struct errinfo *ep)
+{
+ krb5int_free_error (ep, ep->msg);
+ ep->msg = NULL;
+}
+
+void
+krb5int_set_error_info_callout_fn (const char *(KRB5_CALLCONV *f)(long))
+{
+ initialize();
+ lock();
+ fptr = f;
+ unlock();
+}
diff --git a/src/util/support/libkrb5support.exports b/src/util/support/libkrb5support.exports
index 1d7bc717f..00ce5c3e3 100644
--- a/src/util/support/libkrb5support.exports
+++ b/src/util/support/libkrb5support.exports
@@ -25,3 +25,9 @@ krb5int_mutex_alloc
krb5int_mutex_free
krb5int_mutex_lock
krb5int_mutex_unlock
+krb5int_set_error
+krb5int_vset_error
+krb5int_get_error
+krb5int_free_error
+krb5int_clear_error
+krb5int_set_error_info_callout_fn
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
index d0697bd93..7dc2e4828 100644
--- a/src/util/support/threads.c
+++ b/src/util/support/threads.c
@@ -453,6 +453,10 @@ int krb5int_thread_support_init (void)
if (err)
return err;
+ err = krb5int_err_init();
+ if (err)
+ return err;
+
return 0;
}