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>
23 #include <afs/errors.h>
24 #include <afs/afsutil.h>
27 #include "error_table.h"
28 #include "mit-sipb-cr.h"
31 static char buffer
[64];
33 static struct et_list
*_et_list
= NULL
;
35 #ifdef AFS_PTHREAD_ENV
40 * This mutex protects the following variables:
44 static pthread_mutex_t et_list_mutex
;
45 static int et_list_done
= 0;
46 static pthread_once_t et_list_once
= PTHREAD_ONCE_INIT
;
49 * Function to initialize the et_list_mutex
55 opr_Verify(!pthread_mutex_init(&et_list_mutex
, NULL
));
59 #define LOCK_ET_LIST \
62 pthread_once(&et_list_once, et_mutex_once); \
63 opr_Verify(pthread_mutex_lock(&et_list_mutex)==0); \
65 #define UNLOCK_ET_LIST opr_Verify(pthread_mutex_unlock(&et_list_mutex)==0)
68 #define UNLOCK_ET_LIST
69 #endif /* AFS_PTHREAD_ENV */
72 static char *vmsgs
[] = {
73 "volume needs to be salvaged", /* 101, in Pittsburghese */
74 "no such entry (vnode)", /* 102 */
75 "volume does not exist / did not salvage", /* 103 */
76 "volume already exists", /* 104 */
77 "volume out of service", /* 105 */
78 "volume offline (utility running)", /* 106 */
79 "volume already online", /* 107 */
80 "unknown volume error 108", /* 108 */
81 "unknown volume error 109", /* 109 */
82 "volume temporarily busy", /* 110 */
83 "volume moved", /* 111 */
88 negative_message(int code
)
91 return "server or network not responding";
93 return "invalid RPC (RX) operation";
95 return "server not responding promptly";
97 return "port address already in use";
98 else if (code
<= -450 && code
> -500) {
99 sprintf(buffer
, "RPC interface mismatch (%d)", code
);
102 sprintf(buffer
, "unknown RPC error (%d)", code
);
108 volume_message(int code
)
110 if (code
>= 101 && code
<= 111)
111 return vmsgs
[code
- 101];
113 return "unknown volume error";
116 #ifdef AFS_DARWIN_ENV
117 static_inline
const char *
118 _intlize(const char *msg
, int base
, char *str
, size_t len
)
121 CFStringRef cfstring
= CFStringCreateWithCString(kCFAllocatorSystemDefault
,
123 kCFStringEncodingUTF8
);
124 CFStringRef cfdomain
;
125 CFBundleRef OpenAFSBundle
= CFBundleGetBundleWithIdentifier(CFSTR("org.openafs.filesystems.afs"));
132 snprintf(domain
, sizeof(domain
), "heim_com_err%d", base
);
133 cfdomain
= CFStringCreateWithCString(kCFAllocatorSystemDefault
, domain
,
134 kCFStringEncodingUTF8
);
135 if (OpenAFSBundle
!= NULL
) {
138 cflocal
= CFBundleCopyLocalizedString(OpenAFSBundle
, cfstring
,
140 CFStringGetCString(cflocal
, str
, len
, kCFStringEncodingUTF8
);
143 CFStringGetCString(cfstring
, str
, len
, kCFStringEncodingUTF8
);
151 static_inline
const char *
152 _intlize(const char *msg
, int base
, char *str
, size_t len
)
154 #if defined(HAVE_LIBINTL)
159 #if defined(HAVE_LIBINTL)
160 snprintf(domain
, sizeof(domain
), "heim_com_err%d", base
);
161 strlcpy(str
, dgettext(domain
, msg
), len
);
163 strlcpy(str
, msg
, len
);
170 afs_error_message_int(struct et_list
*list
, afs_int32 code
, char *str
, size_t len
)
174 int table_num
, unlock
= 0;
179 /* check for rpc errors first */
181 return _intlize(negative_message(code
), -1, str
, len
);
183 offset
= code
& ((1 << ERRCODE_RANGE
) - 1);
184 table_num
= code
- offset
;
186 if ((err_msg
= strerror(offset
)) != NULL
)
187 return _intlize(err_msg
, 0, str
, len
);
188 else if (offset
< 140)
189 return _intlize(volume_message(code
), 0, str
, len
);
200 for (; et
; et
= et
->next
) {
201 if (et
->table
->base
== table_num
) {
202 /* This is the right table */
203 if (et
->table
->n_msgs
<= offset
)
205 err_msg
= _intlize(et
->table
->msgs
[offset
], et
->table
->base
,
215 /* Unknown code can be included in the negative errors catalog */
216 _intlize("Unknown code ", -1, buffer
, sizeof buffer
);
218 strlcat(buffer
, afs_error_table_name(table_num
), sizeof buffer
);
219 strlcat(buffer
, " ", sizeof buffer
);
221 for (cp
= buffer
; *cp
; cp
++);
223 *cp
++ = '0' + offset
/ 100;
227 if (started
|| offset
>= 10) {
228 *cp
++ = '0' + offset
/ 10;
231 *cp
++ = '0' + offset
;
233 sprintf(cp
, " (%d)", code
);
240 afs_error_message_localize(afs_int32 code
, char *str
, size_t len
)
242 return afs_error_message_int((struct et_list
*)0, code
, str
, len
);
246 afs_com_right_r(struct et_list
*list
, long code
, char *str
, size_t len
)
248 return afs_error_message_int(list
, (afs_int32
)code
, str
, len
);
252 afs_com_right(struct et_list
*list
, long code
)
254 return afs_error_message_int(list
, (afs_int32
)code
, (char *)0, 0);
258 afs_error_message(afs_int32 code
)
260 return afs_error_message_int((struct et_list
*)0, code
, (char *)0, 0);
264 afs_add_to_error_table(struct et_list
*new_table
)
270 * Protect against adding the same error table twice
272 for (et
= _et_list
; et
; et
= et
->next
) {
273 if (et
->table
->base
== new_table
->table
->base
) {
279 new_table
->next
= _et_list
;
280 _et_list
= new_table
;