/* * Copyright 1997 by Massachusetts Institute of Technology * * Copyright 1987, 1988 by MIT Student Information Processing Board * * Permission to use, copy, modify, and distribute this software * and its documentation for any purpose and without fee is * hereby granted, provided that the above copyright notice * appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be * used in advertising or publicity pertaining to distribution * of the software without specific, written prior permission. * M.I.T. and the M.I.T. S.I.P.B. make no representations about * the suitability of this software for any purpose. It is * provided "as is" without express or implied warranty. */ #include #ifdef HAVE_STDLIB_H #include #endif #include #include "com_err.h" #include "error_table.h" #if defined(_MSDOS) || defined(_WIN32) #define HAVE_STRERROR #endif #ifdef _MACINTOSH #define sys_nerr 100 #endif #if !defined(HAVE_STRERROR) && !defined(SYS_ERRLIST_DECLARED) extern char const * const sys_errlist[]; extern const int sys_nerr; #endif static char buffer[ET_EBUFSIZ]; #ifndef unix static struct et_list * _et_list = (struct et_list *) NULL; #else /* Old interface compatibility */ struct et_list * _et_list = (struct et_list *) NULL; #endif KRB5_DLLIMP const char FAR * KRB5_CALLCONV error_message(code) long code; { unsigned long offset; unsigned long l_offset; struct et_list *et; long table_num; int started = 0; unsigned int divisor = 100; char *cp; l_offset = (unsigned long)code & ((1<table->base - table_num)) == 0) { /* This is the right table */ if (et->table->n_msgs <= offset) break; return(et->table->msgs[offset]); } et = et->next; } #if defined(_MSDOS) || defined(_WIN32) { LPVOID msgbuf; if (! FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL /* lpSource */, (DWORD) code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msgbuf, (DWORD) 0 /*sizeof(buffer)*/, NULL /* va_list */ )) { /* * WinSock errors exist in the 10000 and 11000 ranges * but might not appear if WinSock is not initialized */ if (code < 12000) { table_num = 0; offset = code; divisor = 10000; } goto oops; } else { strncpy(buffer, msgbuf, sizeof(buffer)); buffer[sizeof(buffer)-1] = '\0'; cp = buffer + strlen(buffer) - 1; if (*cp == '\n') *cp-- = '\0'; if (*cp == '\r') *cp-- = '\0'; if (*cp == '.') *cp-- = '\0'; LocalFree(msgbuf); return buffer; } } #endif oops: cp = buffer; strcpy(cp, "Unknown code "); cp += sizeof("Unknown code ") - 1; if (table_num) { error_table_name_r(table_num, cp); while (*cp) cp++; *cp++ = ' '; } while (divisor > 1) { fprintf(stderr, "divisor %d, offset %d\n", divisor, offset); if (started || offset >= divisor) { *cp++ = '0' + offset / divisor; offset %= divisor; started++; } divisor /= 10; } fprintf(stderr, "divisor %d, offset %d\n", divisor, offset); *cp++ = '0' + offset; *cp = '\0'; return(buffer); } KRB5_DLLIMP errcode_t KRB5_CALLCONV add_error_table(et) const struct error_table FAR * et; { struct et_list *el = _et_list; while (el) { if (el->table->base == et->base) return EEXIST; el = el->next; } if (! (el = (struct et_list *)malloc(sizeof(struct et_list)))) return ENOMEM; el->table = et; el->next = _et_list; _et_list = el; return 0; } KRB5_DLLIMP errcode_t KRB5_CALLCONV remove_error_table(et) const struct error_table FAR * et; { struct et_list *el = _et_list; struct et_list *el2 = 0; while (el) { if (el->table->base == et->base) { if (el2) /* Not the beginning of the list */ el2->next = el->next; else _et_list = el->next; (void) free(el); return 0; } el2 = el; el = el->next; } return ENOENT; }