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 <afs/param.h>
11 #include <afsconfig.h>
17 #include "error_table.h"
18 #include "mit-sipb-cr.h"
19 #include <afs/errors.h>
22 static const char copyright[] =
23 "Copyright 1986, 1987, 1988 by the Student Information Processing Board\nand the department of Information Systems\nof the Massachusetts Institute of Technology";
25 static char buffer[64];
27 static struct et_list * _et_list = (struct et_list *) NULL;
29 #ifdef AFS_PTHREAD_ENV
34 * This mutex protects the following variables:
38 static pthread_mutex_t et_list_mutex;
39 static int et_list_done = 0;
40 static pthread_once_t et_list_once = PTHREAD_ONCE_INIT;
43 * Function to initialize the et_list_mutex
46 void et_mutex_once(void) {
47 assert(!pthread_mutex_init(&et_list_mutex, (const pthread_mutexattr_t*)0));
50 #define LOCK_ET_LIST \
51 (et_list_done || pthread_once(&et_list_once, et_mutex_once)); \
52 assert(pthread_mutex_lock(&et_list_mutex)==0);
53 #define UNLOCK_ET_LIST assert(pthread_mutex_unlock(&et_list_mutex)==0);
56 #define UNLOCK_ET_LIST
57 #endif /* AFS_PTHREAD_ENV */
60 static char *vmsgs[] = {
61 "volume needs to be salvaged", /* 101, in Pittsburghese */
62 "no such entry (vnode)", /* 102 */
63 "volume does not exist / did not salvage", /* 103 */
64 "volume already exists", /* 104 */
65 "volume out of service", /* 105 */
66 "volume offline (utility running)", /* 106 */
67 "volume already online", /* 107 */
68 "unknown volume error 108", /* 108 */
69 "unknown volume error 109", /* 109 */
70 "volume temporarily busy", /* 110 */
71 "volume moved", /* 111 */
75 static char *negative_message(code)
78 return "server or network not responding";
80 return "invalid RPC (RX) operation";
82 return "server not responding promptly";
84 return "port address already in use";
85 else if (code <= -450 && code > -500) {
86 sprintf(buffer, "RPC interface mismatch (%d)", code);
90 sprintf(buffer, "unknown RPC error (%d)", code);
95 static char *volume_message(code)
97 if (code >= 101 && code <= 111)
98 return vmsgs[code-101];
100 return "unknown volume error";
103 const char * error_message (code)
113 /* check for rpc errors first */
114 if (code < 0) return negative_message(code);
116 offset = code & ((1<<ERRCODE_RANGE)-1);
117 table_num = code - offset;
119 if ( (err_msg = strerror(offset)) != NULL)
121 else if (offset < 140)
122 return volume_message(code);
127 for (et = _et_list; et; et = et->next) {
128 if (et->table->base == table_num) {
129 /* This is the right table */
130 if (et->table->n_msgs <= offset)
133 return(et->table->msgs[offset]);
138 strcpy (buffer, "Unknown code ");
140 strcat (buffer, error_table_name (table_num));
141 strcat (buffer, " ");
143 for (cp = buffer; *cp; cp++)
146 *cp++ = '0' + offset / 100;
150 if (started || offset >= 10) {
151 *cp++ = '0' + offset / 10;
154 *cp++ = '0' + offset;
155 if (code > -10000) sprintf (cp, " (%d)", code);
160 void add_to_error_table(struct et_list *new_table) {
165 * Protect against adding the same error table twice
168 for (et = _et_list; et; et = et->next) {
169 if (et->table->base == new_table->table->base) {
175 new_table->next = _et_list;
176 _et_list = new_table;