summaryrefslogtreecommitdiffstats
path: root/src/lib/kadm5/clnt/err_handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/kadm5/clnt/err_handle.c')
-rw-r--r--src/lib/kadm5/clnt/err_handle.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/lib/kadm5/clnt/err_handle.c b/src/lib/kadm5/clnt/err_handle.c
new file mode 100644
index 0000000000..997544d5e6
--- /dev/null
+++ b/src/lib/kadm5/clnt/err_handle.c
@@ -0,0 +1,185 @@
+/**********************************************************************
+*
+* C %name: err_handle.c %
+* Instance: idc_sec_1
+* Description:
+* %created_by: spradeep %
+* %date_created: Thu Apr 7 15:36:27 2005 %
+*
+**********************************************************************/
+#ifndef lint
+static char *_csrc = "@(#) %filespec: err_handle.c~1 % (%full_filespec: err_handle.c~1:csrc:idc_sec#2 %)";
+#endif
+
+/* this file should be ideally be in util/et. But, for now thread safety requirement stops me from putting there.
+ if I do, then all the applications have to link to pthread */
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include "err_handle.h"
+#include <assert.h>
+
+#ifdef NOVELL
+krb5_errcode_2_string_func old_error_2_string = NULL;
+#endif
+
+typedef struct {
+ char krb5_err_str[KRB5_MAX_ERR_STR + 1];
+ long err_code;
+ krb5_err_subsystem subsystem;
+ krb5_context kcontext;
+} krb5_err_struct_t;
+
+#ifdef HAVE_PTHREAD_H
+static void tsd_key_destructor(void *data)
+{
+ free(data);
+}
+
+static pthread_key_t krb5_err_key;
+
+static void init_err_handling( void )
+{
+ assert(!pthread_key_create(&krb5_err_key, tsd_key_destructor));
+#ifdef NOVELL
+ old_error_2_string = error_message;
+ error_message = krb5_get_err_string;
+#endif
+}
+
+static pthread_once_t krb5_key_create = PTHREAD_ONCE_INIT;
+
+krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str )
+{
+ int ret;
+ krb5_err_struct_t *err_struct;
+ pthread_once(&krb5_key_create, init_err_handling);
+
+ err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key);
+ if( err_struct == NULL )
+ {
+ err_struct = calloc(sizeof(krb5_err_struct_t), 1);
+ if( err_struct == NULL )
+ return ENOMEM;
+
+ if((ret = pthread_setspecific(krb5_err_key, err_struct)))
+ {
+ free( err_struct );
+ return ret;
+ }
+ }
+
+ err_struct->subsystem = subsystem;
+ err_struct->err_code = err_code;
+ err_struct->kcontext = kcontext;
+ if( err_struct->subsystem == krb5_err_have_str )
+ {
+ strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) );
+ err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0';
+ }
+
+ return 0;
+}
+
+const char * KRB5_CALLCONV krb5_get_err_string(long err_code)
+{
+ krb5_err_struct_t *err_struct;
+ pthread_once(&krb5_key_create, init_err_handling);
+
+ err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key);
+ if( err_struct && (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) )
+ {
+ /* checking error code is for safety.
+ In case, the caller ignores a database error and calls other calls before doing com_err.
+ Though not perfect, caller should call krb5_clr_error before this*/
+ err_struct->subsystem = krb5_err_unknown;
+ return err_struct->krb5_err_str;
+ }
+
+ /* Error strings are not generated here. the remaining two cases are handled by the default error string convertor */
+#ifdef NOVELL
+ return old_error_2_string(err_code);
+#else
+ return error_message(err_code);
+#endif
+}
+
+void krb5_clr_error()
+{
+ krb5_err_struct_t *err_struct;
+ pthread_once(&krb5_key_create, init_err_handling);
+
+ err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key);
+ if( err_struct )
+ err_struct->subsystem = krb5_err_unknown;
+}
+
+#else
+krb5_err_struct_t krb5_err = {{0}, 0, 0, 0};
+krb5_boolean krb5_init_once = TRUE;
+
+static void init_err_handling( void )
+{
+ if( krb5_init_once )
+ {
+#ifdef NOVELL
+ old_error_2_string = error_message;
+ error_message = krb5_get_err_string;
+#endif
+ krb5_init_once = FALSE;
+ }
+}
+
+krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str )
+{
+ krb5_err_struct_t *err_struct = &krb5_err;
+
+ init_err_handling(); /* takes care for multiple inits */
+
+ err_struct->subsystem = subsystem;
+ err_struct->err_code = err_code;
+ err_struct->kcontext = kcontext;
+ if( err_struct->subsystem == krb5_err_have_str )
+ {
+ strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) );
+ err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0';
+ }
+
+ return 0;
+}
+
+const char * KRB5_CALLCONV krb5_get_err_string(long err_code)
+{
+ krb5_err_struct_t *err_struct = &krb5_err;
+
+ init_err_handling(); /* takes care for multiple inits */
+
+ if( (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) )
+ {
+ /* checking error code is for safety.
+ In case, the caller ignores a database error and calls other calls before doing com_err.
+ Though not perfect, caller should call krb5_clr_error before this*/
+ err_struct->subsystem = krb5_err_unknown;
+ return err_struct->krb5_err_str;
+ }
+
+ /* it is not generated here. the remaining two cases are handled by the default error string convertor */
+#ifdef NOVELL
+ return old_error_2_string(err_code);
+#else
+ return error_message(err_code);
+#endif
+}
+
+void krb5_clr_error()
+{
+ krb5_err_struct_t *err_struct = &krb5_err;
+
+ init_err_handling(); /* takes care for multiple inits */
+
+ err_struct->subsystem = krb5_err_unknown;
+}
+
+
+#endif