-: 0:Source:error_message.c -: 0:Graph:/var/tsitkova/Sources/v10/trunk/src/util/et/error_message.so.gcno -: 0:Data:/var/tsitkova/Sources/v10/trunk/src/util/et/error_message.so.gcda -: 0:Runs:1634 -: 0:Programs:1 -: 1:/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -: 2:/* -: 3: * Copyright 1997,2000,2001,2004,2008 by Massachusetts Institute of Technology -: 4: * -: 5: * Copyright 1987, 1988 by MIT Student Information Processing Board -: 6: * -: 7: * Permission to use, copy, modify, and distribute this software -: 8: * and its documentation for any purpose and without fee is -: 9: * hereby granted, provided that the above copyright notice -: 10: * appear in all copies and that both that copyright notice and -: 11: * this permission notice appear in supporting documentation, -: 12: * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be -: 13: * used in advertising or publicity pertaining to distribution -: 14: * of the software without specific, written prior permission. -: 15: * Furthermore if you modify this software you must label -: 16: * your software as modified software and not distribute it in such a -: 17: * fashion that it might be confused with the original M.I.T. software. -: 18: * M.I.T. and the M.I.T. S.I.P.B. make no representations about -: 19: * the suitability of this software for any purpose. It is -: 20: * provided "as is" without express or implied warranty. -: 21: */ -: 22: -: 23:#include "autoconf.h" -: 24:#include -: 25:#ifdef HAVE_STDLIB_H -: 26:#include -: 27:#endif -: 28:#include -: 29:#include "com_err.h" -: 30:#include "error_table.h" -: 31:#include "k5-platform.h" -: 32: -: 33:#if !defined(HAVE_STRERROR) && !defined(SYS_ERRLIST_DECLARED) -: 34:extern char const * const sys_errlist[]; -: 35:extern const int sys_nerr; -: 36:#endif -: 37: -: 38:static struct et_list *et_list; -: 39:static k5_mutex_t et_list_lock = K5_MUTEX_PARTIAL_INITIALIZER; -: 40:static int terminated = 0; /* for debugging shlib fini sequence errors */ -: 41: 1490: 42:MAKE_INIT_FUNCTION(com_err_initialize); -: 43:MAKE_FINI_FUNCTION(com_err_terminate); -: 44: 1490: 45:int com_err_initialize(void) -: 46:{ -: 47: int err; -: 48:#ifdef SHOW_INITFINI_FUNCS -: 49: printf("com_err_initialize\n"); -: 50:#endif 1490: 51: terminated = 0; 1490: 52: err = k5_mutex_finish_init(&et_list_lock); 1490: 53: if (err) #####: 54: return err; 1490: 55: err = k5_mutex_finish_init(&com_err_hook_lock); 1490: 56: if (err) #####: 57: return err; 1490: 58: err = k5_key_register(K5_KEY_COM_ERR, free); 1490: 59: if (err) #####: 60: return err; 1490: 61: return 0; -: 62:} -: 63: #####: 64:void com_err_terminate(void) -: 65:{ -: 66: struct et_list *e, *enext; #####: 67: if (! INITIALIZER_RAN(com_err_initialize) || PROGRAM_EXITING()) { -: 68:#ifdef SHOW_INITFINI_FUNCS -: 69: printf("com_err_terminate: skipping\n"); -: 70:#endif #####: 71: return; -: 72: } -: 73:#ifdef SHOW_INITFINI_FUNCS -: 74: printf("com_err_terminate\n"); -: 75:#endif #####: 76: k5_key_delete(K5_KEY_COM_ERR); #####: 77: k5_mutex_destroy(&com_err_hook_lock); #####: 78: if (k5_mutex_lock(&et_list_lock) != 0) #####: 79: return; #####: 80: for (e = et_list; e; e = enext) { #####: 81: enext = e->next; #####: 82: free(e); -: 83: } #####: 84: k5_mutex_unlock(&et_list_lock); #####: 85: k5_mutex_destroy(&et_list_lock); #####: 86: terminated = 1; -: 87:} -: 88: -: 89:#ifndef DEBUG_TABLE_LIST -: 90:#define dprintf(X) -: 91:#else -: 92:#define dprintf(X) printf X -: 93:#endif -: 94: -: 95:static char * 513: 96:get_thread_buffer () -: 97:{ -: 98: char *cp; 513: 99: cp = k5_getspecific(K5_KEY_COM_ERR); 513: 100: if (cp == NULL) { 88: 101: cp = malloc(ET_EBUFSIZ); 88: 102: if (cp == NULL) { #####: 103: return NULL; -: 104: } 88: 105: if (k5_setspecific(K5_KEY_COM_ERR, cp) != 0) { #####: 106: free(cp); #####: 107: return NULL; -: 108: } -: 109: } 513: 110: return cp; -: 111:} -: 112: -: 113:const char * KRB5_CALLCONV 1610: 114:error_message(long code) -: 115:{ -: 116: unsigned long offset; -: 117: unsigned long l_offset; -: 118: struct et_list *e; -: 119: unsigned long table_num; 1610: 120: int started = 0; 1610: 121: unsigned int divisor = 100; -: 122: char *cp, *cp1; -: 123: const struct error_table *table; -: 124: int merr; -: 125: 1610: 126: l_offset = (unsigned long)code & ((1< 0 && code <= 1600) -: 136:#endif -: 137: ) { 113: 138: if (code == 0) 38: 139: goto oops; -: 140: -: 141: /* This could trip if int is 16 bits. */ -: 142: if ((unsigned long)(int)code != (unsigned long)code) -: 143: abort (); -: 144:#ifdef HAVE_STRERROR_R 75: 145: cp = get_thread_buffer(); 75: 146: if (cp && strerror_r((int) code, cp, ET_EBUFSIZ) == 0) 70: 147: return cp; -: 148:#endif -: 149:#ifdef HAVE_STRERROR 5: 150: cp = strerror((int) code); 5: 151: if (cp) 5: 152: return cp; -: 153:#elif defined HAVE_SYS_ERRLIST -: 154: if (offset < sys_nerr) -: 155: return(sys_errlist[offset]); -: 156:#endif #####: 157: goto oops; -: 158: } -: 159: 1497: 160: if (CALL_INIT_FUNCTION(com_err_initialize)) #####: 161: return 0; 1497: 162: merr = k5_mutex_lock(&et_list_lock); 1497: 163: if (merr) #####: 164: goto oops; -: 165: dprintf(("scanning list for %x\n", table_num)); 4344: 166: for (e = et_list; e != NULL; e = e->next) { -: 167: dprintf(("\t%x = %s\n", e->table->base & ERRCODE_MAX, -: 168: e->table->msgs[0])); 3944: 169: if ((e->table->base & ERRCODE_MAX) == table_num) { 1097: 170: table = e->table; 1097: 171: goto found; -: 172: } -: 173: } 400: 174: goto no_table_found; -: 175: -: 176:found: 1097: 177: k5_mutex_unlock(&et_list_lock); -: 178: dprintf (("found it!\n")); -: 179: /* This is the right table */ -: 180: -: 181: /* This could trip if int is 16 bits. */ -: 182: if ((unsigned long)(unsigned int)offset != offset) -: 183: goto no_table_found; -: 184: 1097: 185: if (table->n_msgs <= (unsigned int) offset) #####: 186: goto no_table_found; -: 187: -: 188: /* If there's a string at the end of the table, it's a text domain. */ 1097: 189: if (table->msgs[table->n_msgs] != NULL) 1097: 190: return dgettext(table->msgs[table->n_msgs], table->msgs[offset]); -: 191: else #####: 192: return table->msgs[offset]; -: 193: -: 194:no_table_found: 400: 195: k5_mutex_unlock(&et_list_lock); -: 196:#if defined(_WIN32) -: 197: /* -: 198: * WinSock errors exist in the 10000 and 11000 ranges -: 199: * but might not appear if WinSock is not initialized -: 200: */ -: 201: if (code >= WSABASEERR && code < WSABASEERR + 1100) { -: 202: table_num = 0; -: 203: offset = code; -: 204: divisor = WSABASEERR; -: 205: } -: 206:#endif -: 207:#ifdef _WIN32 -: 208: { -: 209: LPVOID msgbuf; -: 210: -: 211: if (! FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, -: 212: NULL /* lpSource */, -: 213: (DWORD) code, -: 214: MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), -: 215: (LPTSTR) &msgbuf, -: 216: (DWORD) 0 /*sizeof(buffer)*/, -: 217: NULL /* va_list */ )) { -: 218: /* -: 219: * WinSock errors exist in the 10000 and 11000 ranges -: 220: * but might not appear if WinSock is not initialized -: 221: */ -: 222: if (code >= WSABASEERR && code < WSABASEERR + 1100) { -: 223: table_num = 0; -: 224: offset = code; -: 225: divisor = 10000; -: 226: } -: 227: -: 228: goto oops; -: 229: } else { -: 230: char *buffer; -: 231: cp = get_thread_buffer(); -: 232: if (cp == NULL) -: 233: return "Unknown error code"; -: 234: buffer = cp; -: 235: strncpy(buffer, msgbuf, ET_EBUFSIZ); -: 236: buffer[ET_EBUFSIZ-1] = '\0'; -: 237: cp = buffer + strlen(buffer) - 1; -: 238: if (*cp == '\n') *cp-- = '\0'; -: 239: if (*cp == '\r') *cp-- = '\0'; -: 240: if (*cp == '.') *cp-- = '\0'; -: 241: -: 242: LocalFree(msgbuf); -: 243: return buffer; -: 244: } -: 245: } -: 246:#endif -: 247: -: 248:oops: -: 249: 438: 250: cp = get_thread_buffer(); 438: 251: if (cp == NULL) #####: 252: return "Unknown error code"; 438: 253: cp1 = cp; 438: 254: strlcpy(cp, "Unknown code ", ET_EBUFSIZ); 438: 255: cp += sizeof("Unknown code ") - 1; 438: 256: if (table_num != 0L) { 400: 257: (void) error_table_name_r(table_num, cp); 1990: 258: while (*cp != '\0') 1190: 259: cp++; 400: 260: *cp++ = ' '; -: 261: } 1752: 262: while (divisor > 1) { 876: 263: if (started != 0 || offset >= divisor) { 15: 264: *cp++ = '0' + offset / divisor; 15: 265: offset %= divisor; 15: 266: started++; -: 267: } 876: 268: divisor /= 10; -: 269: } 438: 270: *cp++ = '0' + offset; 438: 271: *cp = '\0'; 438: 272: return(cp1); -: 273:} -: 274: -: 275:errcode_t KRB5_CALLCONV 14690: 276:add_error_table(const struct error_table *et) -: 277:{ -: 278: struct et_list *e; -: 279: int merr; -: 280: 14690: 281: if (CALL_INIT_FUNCTION(com_err_initialize)) #####: 282: return 0; -: 283: 14690: 284: e = malloc(sizeof(struct et_list)); 14690: 285: if (e == NULL) #####: 286: return ENOMEM; -: 287: 14690: 288: e->table = et; -: 289: 14690: 290: merr = k5_mutex_lock(&et_list_lock); 14690: 291: if (merr) { #####: 292: free(e); #####: 293: return merr; -: 294: } 14690: 295: e->next = et_list; 14690: 296: et_list = e; -: 297: -: 298: /* If there are two strings at the end of the table, they are a text domain -: 299: * and locale dir, and we are supposed to call bindtextdomain. */ 14690: 300: if (et->msgs[et->n_msgs] != NULL && et->msgs[et->n_msgs + 1] != NULL) #####: 301: bindtextdomain(et->msgs[et->n_msgs], et->msgs[et->n_msgs + 1]); -: 302: 14690: 303: return k5_mutex_unlock(&et_list_lock); -: 304:} -: 305: -: 306:errcode_t KRB5_CALLCONV 11970: 307:remove_error_table(const struct error_table *et) -: 308:{ -: 309: struct et_list **ep, *e; -: 310: int merr; -: 311: 11970: 312: if (CALL_INIT_FUNCTION(com_err_initialize)) #####: 313: return 0; 11970: 314: merr = k5_mutex_lock(&et_list_lock); 11970: 315: if (merr) #####: 316: return merr; -: 317: -: 318: /* Remove the entry that matches the error table instance. */ 77808: 319: for (ep = &et_list; *ep; ep = &(*ep)->next) { 77798: 320: if ((*ep)->table == et) { 11960: 321: e = *ep; 11960: 322: *ep = e->next; 11960: 323: free(e); 11960: 324: return k5_mutex_unlock(&et_list_lock); -: 325: } -: 326: } 10: 327: k5_mutex_unlock(&et_list_lock); 10: 328: return ENOENT; -: 329:} -: 330: 2384: 331:int com_err_finish_init() -: 332:{ 2384: 333: return CALL_INIT_FUNCTION(com_err_initialize); -: 334:}