1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * Copyright 1997 by Massachusetts Institute of Technology 10 * 11 * Copyright 1987, 1988 by MIT Student Information Processing Board 12 * 13 * Permission to use, copy, modify, and distribute this software 14 * and its documentation for any purpose and without fee is 15 * hereby granted, provided that the above copyright notice 16 * appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, 18 * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be 19 * used in advertising or publicity pertaining to distribution 20 * of the software without specific, written prior permission. 21 * Furthermore if you modify this software you must label 22 * your software as modified software and not distribute it in such a 23 * fashion that it might be confused with the original M.I.T. software. 24 * M.I.T. and the M.I.T. S.I.P.B. make no representations about 25 * the suitability of this software for any purpose. It is 26 * provided "as is" without express or implied warranty. 27 */ 28 29 30 #include <stdio.h> 31 #include <string.h> 32 #include <locale.h> 33 34 #include "com_err.h" 35 #include "error_table.h" 36 37 #if defined(_MSDOS) || defined(_WIN32) 38 #include <io.h> 39 #endif 40 #ifdef macintosh 41 #include "icons.h" 42 static void MacMessageBox(char *errbuf); 43 #endif 44 45 static et_old_error_hook_func com_err_hook = 0; 46 47 static void default_com_err_proc 48 (const char *whoami, errcode_t code, 49 const char *fmt, va_list ap); 50 51 /* Solaris Kerberos specific fix start --------------------------- */ 52 53 #define gettext(X) X 54 55 struct msg_map { 56 char *msgid; 57 char *c_msgstr; 58 }; 59 60 struct msg_map msgmap[] = { 61 62 #define MSG_WHILE 0 63 { gettext("%s\n## com_err msg of format: 'while ...'"), 64 "%s\n" }, 65 66 #define MSG_ERROR_MSG 1 67 { gettext("%s\n## com_err message of format: 'error msg ...'"), 68 "%s\n" }, 69 70 #define MSG_ERROR_MSG_WHILE 2 71 { gettext("%1$s %2$s\n## com_err message of format: " 72 "'error msg ... while ...'"), 73 "%1$s %2$s\n" }, 74 75 #define MSG_WHOAMI_WHILE 3 76 { gettext("%1$s: %2$s\n## com_err msg of format: 'whoami: while ...'"), 77 "%1$s: %2$s\n" }, 78 79 #define MSG_WHOAMI_ERROR_MSG 4 80 { gettext("%1$s: %2$s\n## com_err message of format: " 81 "'whoami: error msg ...'"), 82 "%1$s: %2$s\n" }, 83 84 #define MSG_WHOAMI_ERROR_MSG_WHILE 5 85 { gettext("%1$s: %2$s %3$s\n## com_err message of format: " 86 "'whoami: error msg ... while ...'"), 87 "%1$s: %2$s %3$s\n" }, 88 89 #define MSG_WHOAMI 6 90 { gettext("%s:\n ## com_err message of format: " 91 "'whoami: with no error msg or while ...'"), 92 "%s:\n " } 93 }; 94 95 #undef gettext 96 97 /* 98 * The idea is that we provide a unique message id that contains extra junk 99 * that we never want to display in the C locale. If dgettext() returns 100 * a string that is equal to the message id, then we return the c_msgstr, 101 * for display in the locale. 102 */ 103 static char * 104 my_gettext(int msg_idx) 105 { 106 char *msgid = msgmap[msg_idx].msgid; 107 char *c_msgstr = msgmap[msg_idx].c_msgstr; 108 char *msgstr = dgettext(TEXT_DOMAIN, msgid); 109 110 if (strcmp(msgstr, msgid) == 0) 111 return (c_msgstr); 112 else 113 return (msgstr); 114 } 115 116 /* Solaris Kerberos specific fix end --------------------------- */ 117 118 /* Solaris Kerberos: this code is significantly altered from 119 * the MIT 1.2.1 version to work with internationalization */ 120 static void default_com_err_proc(whoami, code, fmt, ap) 121 const char *whoami; 122 errcode_t code; 123 const char *fmt; 124 va_list ap; 125 { 126 char whilebuf[1024] = ""; 127 128 *whilebuf = '\0'; 129 130 /* 131 * Because 'while ...' message could contain a format string 132 * we have to intepret it now, in a buffer. We need to put it 133 * into a buffer so that the message can be juxtaposed in a locale 134 * meaningful manner. In some natural languages, the 'while ...' phrase 135 * must be first. 136 */ 137 if (fmt) { 138 vsprintf(whilebuf, fmt, ap); 139 } 140 141 /* 142 * There are 8 possible combinations here depending on whether 143 * a whoami string was provided, error code is non-zero, and if a 144 * a 'while ...' messge was provided. 145 */ 146 if (!whoami) { 147 148 if ((!code) && fmt) { 149 150 fprintf(stderr, my_gettext(MSG_WHILE), 151 whilebuf); 152 153 } else if (code && !fmt) { 154 155 fprintf(stderr, my_gettext(MSG_ERROR_MSG), 156 error_message(code)); 157 158 } else if (code && fmt) { 159 160 fprintf(stderr, my_gettext(MSG_ERROR_MSG_WHILE), 161 error_message(code), whilebuf); 162 } else 163 return; 164 165 } else { 166 167 if ((!code) && fmt) { 168 169 fprintf(stderr, my_gettext(MSG_WHOAMI_WHILE), 170 whoami, whilebuf); 171 172 } else if (code && !fmt) { 173 174 fprintf(stderr, my_gettext(MSG_WHOAMI_ERROR_MSG), 175 whoami, error_message(code)); 176 177 } else if (code && fmt) { 178 179 fprintf(stderr, 180 my_gettext(MSG_WHOAMI_ERROR_MSG_WHILE), 181 whoami, error_message(code), whilebuf); 182 } else { 183 184 fprintf(stderr, 185 my_gettext(MSG_WHOAMI), 186 whoami); 187 } 188 } 189 190 fflush(stderr); 191 } 192 193 void KRB5_CALLCONV com_err_va(whoami, code, fmt, ap) 194 const char *whoami; 195 errcode_t code; 196 const char *fmt; 197 va_list ap; 198 { 199 if (!com_err_hook) 200 default_com_err_proc(whoami, code, fmt, ap); 201 else 202 (com_err_hook)(whoami, code, fmt, ap); 203 } 204 205 206 #ifndef ET_VARARGS 207 void KRB5_CALLCONV_C com_err(const char *whoami, 208 errcode_t code, 209 const char *fmt, ...) 210 #else 211 void KRB5_CALLCONV_C com_err(whoami, code, fmt, va_alist) 212 const char *whoami; 213 errcode_t code; 214 const char *fmt; 215 va_dcl 216 #endif 217 { 218 va_list ap; 219 220 #ifdef ET_VARARGS 221 va_start(ap); 222 #else 223 va_start(ap, fmt); 224 #endif 225 com_err_va(whoami, code, fmt, ap); 226 va_end(ap); 227 } 228 229 #if !(defined(_MSDOS)||defined(_WIN32)) 230 et_old_error_hook_func set_com_err_hook (new_proc) 231 et_old_error_hook_func new_proc; 232 { 233 et_old_error_hook_func x = com_err_hook; 234 235 com_err_hook = new_proc; 236 return x; 237 } 238 239 et_old_error_hook_func reset_com_err_hook () 240 { 241 et_old_error_hook_func x = com_err_hook; 242 243 com_err_hook = 0; 244 return x; 245 } 246 #endif 247