4 * Copyright 1987 by the Student Information Processing Board
5 * of the Massachusetts Institute of Technology
7 * For copyright info, see "mit-sipb-cr.h".
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <CoreFoundation/CoreFoundation.h>
22 #include <afs/errors.h>
23 #include <afs/afsutil.h>
26 #include "error_table.h"
27 #include "mit-sipb-cr.h"
30 static const char copyright[] =
31 "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology";
33 static char buffer[64];
35 static struct et_list *_et_list = (struct et_list *)NULL;
37 #ifdef AFS_PTHREAD_ENV
42 * This mutex protects the following variables:
46 static pthread_mutex_t et_list_mutex;
47 static int et_list_done = 0;
48 static pthread_once_t et_list_once = PTHREAD_ONCE_INIT;
51 * Function to initialize the et_list_mutex
57 assert(!pthread_mutex_init
58 (&et_list_mutex, (const pthread_mutexattr_t *)0));
62 #define LOCK_ET_LIST \
65 pthread_once(&et_list_once, et_mutex_once); \
66 assert(pthread_mutex_lock(&et_list_mutex)==0); \
68 #define UNLOCK_ET_LIST assert(pthread_mutex_unlock(&et_list_mutex)==0)
71 #define UNLOCK_ET_LIST
72 #endif /* AFS_PTHREAD_ENV */
75 static char *vmsgs[] = {
76 "volume needs to be salvaged", /* 101, in Pittsburghese */
77 "no such entry (vnode)", /* 102 */
78 "volume does not exist / did not salvage", /* 103 */
79 "volume already exists", /* 104 */
80 "volume out of service", /* 105 */
81 "volume offline (utility running)", /* 106 */
82 "volume already online", /* 107 */
83 "unknown volume error 108", /* 108 */
84 "unknown volume error 109", /* 109 */
85 "volume temporarily busy", /* 110 */
86 "volume moved", /* 111 */
91 negative_message(int code)
94 return "server or network not responding";
96 return "invalid RPC (RX) operation";
98 return "server not responding promptly";
100 return "port address already in use";
101 else if (code <= -450 && code > -500) {
102 sprintf(buffer, "RPC interface mismatch (%d)", code);
105 sprintf(buffer, "unknown RPC error (%d)", code);
111 volume_message(int code)
113 if (code >= 101 && code <= 111)
114 return vmsgs[code - 101];
116 return "unknown volume error";
119 #ifdef AFS_DARWIN_ENV
120 static_inline const char *
121 _intlize(const char *msg, int base, char *str, size_t len)
124 CFStringRef cfstring = CFStringCreateWithCString(kCFAllocatorSystemDefault,
126 kCFStringEncodingUTF8);
127 CFStringRef cfdomain;
128 CFBundleRef OpenAFSBundle = CFBundleGetBundleWithIdentifier(CFSTR("org.openafs.filesystems.afs"));
135 snprintf(domain, sizeof(domain), "heim_com_err%d", base);
136 cfdomain = CFStringCreateWithCString(kCFAllocatorSystemDefault, domain,
137 kCFStringEncodingUTF8);
138 if (OpenAFSBundle != NULL) {
141 cflocal = CFBundleCopyLocalizedString(OpenAFSBundle, cfstring,
143 CFStringGetCString(cflocal, str, len, kCFStringEncodingUTF8);
146 CFStringGetCString(cfstring, str, len, kCFStringEncodingUTF8);
154 static_inline const char *
155 _intlize(const char *msg, int base, char *str, size_t len)
160 snprintf(domain, sizeof(domain), "heim_com_err%d", base);
161 #if defined(HAVE_LIBINTL)
162 strlcpy(str, dgettext(domain, msg), len);
169 afs_error_message_int(struct et_list *list, afs_int32 code, char *str, size_t len)
173 int table_num, unlock = 0;
178 /* check for rpc errors first */
180 return _intlize(negative_message(code), -1, str, len);
182 offset = code & ((1 << ERRCODE_RANGE) - 1);
183 table_num = code - offset;
185 if ((err_msg = strerror(offset)) != NULL)
186 return _intlize(err_msg, 0, str, len);
187 else if (offset < 140)
188 return _intlize(volume_message(code), 0, str, len);
199 for (; et; et = et->next) {
200 if (et->table->base == table_num) {
201 /* This is the right table */
202 if (et->table->n_msgs <= offset)
204 err_msg = _intlize(et->table->msgs[offset], et->table->base,
214 /* Unknown code can be included in the negative errors catalog */
215 _intlize("Unknown code ", -1, buffer, sizeof buffer);
217 strlcat(buffer, afs_error_table_name(table_num), sizeof buffer);
218 strlcat(buffer, " ", sizeof buffer);
220 for (cp = buffer; *cp; cp++);
222 *cp++ = '0' + offset / 100;
226 if (started || offset >= 10) {
227 *cp++ = '0' + offset / 10;
230 *cp++ = '0' + offset;
232 sprintf(cp, " (%d)", code);
239 afs_error_message_localize(afs_int32 code, char *str, size_t len)
241 return afs_error_message_int((struct et_list *)0, code, str, len);
245 afs_com_right_r(struct et_list *list, long code, char *str, size_t len)
247 return afs_error_message_int(list, (afs_int32)code, str, len);
251 afs_com_right(struct et_list *list, long code)
253 return afs_error_message_int(list, (afs_int32)code, (char *)0, 0);
257 afs_error_message(afs_int32 code)
259 return afs_error_message_int((struct et_list *)0, code, (char *)0, 0);
263 afs_add_to_error_table(struct et_list *new_table)
269 * Protect against adding the same error table twice
271 for (et = _et_list; et; et = et->next) {
272 if (et->table->base == new_table->table->base) {
278 new_table->next = _et_list;
279 _et_list = new_table;