OSDN Git Service

Rework RPC code once again. By default, only enable the
[uclinux-h8/uClibc.git] / libc / inet / rpc / clnt_perror.c
1 /* @(#)clnt_perror.c    2.1 88/07/29 4.0 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30 #if 0
31 static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
32 #endif
33
34 /*
35  * clnt_perror.c
36  *
37  * Copyright (C) 1984, Sun Microsystems, Inc.
38  *
39  */
40 #define __FORCE_GLIBC
41 #include <features.h>
42
43 #include <stdio.h>
44 #include <string.h>
45 #include "rpc_private.h"
46
47 #ifdef USE_IN_LIBIO
48 # include <wchar.h>
49 # include <libio/iolibio.h>
50 # define fputs(s, f) _IO_fputs (s, f)
51 #endif
52
53 static char *auth_errmsg (enum auth_stat stat) internal_function;
54
55 #ifdef __UCLIBC_HAS_THREADS__
56 /*
57  * Making buf a preprocessor macro requires renaming the local
58  * buf variable in a few functions.  Overriding a global variable
59  * with a local variable of the same name is a bad idea, anyway.
60  */
61 #define buf ((char *)RPC_THREAD_VARIABLE(clnt_perr_buf_s))
62 #else
63 static char *buf;
64 #endif
65
66 static char *
67 _buf (void)
68 {
69   if (buf == NULL)
70     buf = (char *) malloc (256);
71   return buf;
72 }
73
74 /*
75  * Print reply error info
76  */
77 char *
78 clnt_sperror (CLIENT * rpch, const char *msg)
79 {
80   char chrbuf[1024];
81   struct rpc_err e;
82   char *err;
83   char *str = _buf ();
84   char *strstart = str;
85   int len;
86
87   if (str == NULL)
88     return NULL;
89   CLNT_GETERR (rpch, &e);
90
91   len = sprintf (str, "%s: ", msg);
92   str += len;
93
94   (void) strcpy(str, clnt_sperrno(e.re_status));
95   str += strlen(str);
96
97   switch (e.re_status)
98     {
99     case RPC_SUCCESS:
100     case RPC_CANTENCODEARGS:
101     case RPC_CANTDECODERES:
102     case RPC_TIMEDOUT:
103     case RPC_PROGUNAVAIL:
104     case RPC_PROCUNAVAIL:
105     case RPC_CANTDECODEARGS:
106     case RPC_SYSTEMERROR:
107     case RPC_UNKNOWNHOST:
108     case RPC_UNKNOWNPROTO:
109     case RPC_PMAPFAILURE:
110     case RPC_PROGNOTREGISTERED:
111     case RPC_FAILED:
112       break;
113
114     case RPC_CANTSEND:
115     case RPC_CANTRECV:
116       strerror_r (e.re_errno, chrbuf, sizeof chrbuf);
117       len = sprintf (str, "; errno = %s", chrbuf); 
118       str += len;
119       break;
120
121     case RPC_VERSMISMATCH:
122       len= sprintf (str, _("; low version = %lu, high version = %lu"),
123                     e.re_vers.low, e.re_vers.high);
124       str += len;
125       break;
126
127     case RPC_AUTHERROR:
128       err = auth_errmsg (e.re_why);
129       (void) strcpy(str, _("; why = "));
130       str += strlen(str);
131
132       if (err != NULL)
133         {
134           (void) strcpy(str, err);
135           str += strlen(str);
136         }
137       else
138         {
139           len = sprintf (str, _("(unknown authentication error - %d)"),
140                          (int) e.re_why);
141           str += len;
142         }
143       break;
144
145     case RPC_PROGVERSMISMATCH:
146       len = sprintf (str, _("; low version = %lu, high version = %lu"),
147                      e.re_vers.low, e.re_vers.high);
148       str += len;
149       break;
150
151     default:                    /* unknown */
152       len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
153       str += len;
154       break;
155     }
156   *str = '\n';
157   *++str = '\0';
158   return (strstart);
159 }
160
161 void
162 clnt_perror (CLIENT * rpch, const char *msg)
163 {
164 #ifdef USE_IN_LIBIO
165   if (_IO_fwide (stderr, 0) > 0)
166     (void) __fwprintf (stderr, L"%s", clnt_sperror (rpch, msg));
167   else
168 #endif
169     (void) fputs (clnt_sperror (rpch, msg), stderr);
170 }
171
172
173 struct rpc_errtab
174 {
175   enum clnt_stat status;
176   unsigned int message_off;
177 };
178
179 static const char rpc_errstr[] =
180 {
181 #define RPC_SUCCESS_IDX         0
182   _("RPC: Success")
183   "\0"
184 #define RPC_CANTENCODEARGS_IDX  (RPC_SUCCESS_IDX + sizeof "RPC: Success")
185   _("RPC: Can't encode arguments")
186   "\0"
187 #define RPC_CANTDECODERES_IDX   (RPC_CANTENCODEARGS_IDX \
188                                  + sizeof "RPC: Can't encode arguments")
189   _("RPC: Can't decode result")
190   "\0"
191 #define RPC_CANTSEND_IDX        (RPC_CANTDECODERES_IDX \
192                                  + sizeof "RPC: Can't decode result")
193   _("RPC: Unable to send")
194   "\0"
195 #define RPC_CANTRECV_IDX        (RPC_CANTSEND_IDX \
196                                  + sizeof "RPC: Unable to send")
197   _("RPC: Unable to receive")
198   "\0"
199 #define RPC_TIMEDOUT_IDX        (RPC_CANTRECV_IDX \
200                                  + sizeof "RPC: Unable to receive")
201   _("RPC: Timed out")
202   "\0"
203 #define RPC_VERSMISMATCH_IDX    (RPC_TIMEDOUT_IDX \
204                                  + sizeof "RPC: Timed out")
205   _("RPC: Incompatible versions of RPC")
206   "\0"
207 #define RPC_AUTHERROR_IDX       (RPC_VERSMISMATCH_IDX \
208                                  + sizeof "RPC: Incompatible versions of RPC")
209   _("RPC: Authentication error")
210   "\0"
211 #define RPC_PROGUNAVAIL_IDX             (RPC_AUTHERROR_IDX \
212                                  + sizeof "RPC: Authentication error")
213   _("RPC: Program unavailable")
214   "\0"
215 #define RPC_PROGVERSMISMATCH_IDX (RPC_PROGUNAVAIL_IDX \
216                                   + sizeof "RPC: Program unavailable")
217   _("RPC: Program/version mismatch")
218   "\0"
219 #define RPC_PROCUNAVAIL_IDX     (RPC_PROGVERSMISMATCH_IDX \
220                                  + sizeof "RPC: Program/version mismatch")
221   _("RPC: Procedure unavailable")
222   "\0"
223 #define RPC_CANTDECODEARGS_IDX  (RPC_PROCUNAVAIL_IDX \
224                                  + sizeof "RPC: Procedure unavailable")
225   _("RPC: Server can't decode arguments")
226   "\0"
227 #define RPC_SYSTEMERROR_IDX     (RPC_CANTDECODEARGS_IDX \
228                                  + sizeof "RPC: Server can't decode arguments")
229   _("RPC: Remote system error")
230   "\0"
231 #define RPC_UNKNOWNHOST_IDX     (RPC_SYSTEMERROR_IDX \
232                                  + sizeof "RPC: Remote system error")
233   _("RPC: Unknown host")
234   "\0"
235 #define RPC_UNKNOWNPROTO_IDX    (RPC_UNKNOWNHOST_IDX \
236                                  + sizeof "RPC: Unknown host")
237   _("RPC: Unknown protocol")
238   "\0"
239 #define RPC_PMAPFAILURE_IDX     (RPC_UNKNOWNPROTO_IDX \
240                                  + sizeof "RPC: Unknown protocol")
241   _("RPC: Port mapper failure")
242   "\0"
243 #define RPC_PROGNOTREGISTERED_IDX (RPC_PMAPFAILURE_IDX \
244                                    + sizeof "RPC: Port mapper failure")
245   _("RPC: Program not registered")
246   "\0"
247 #define RPC_FAILED_IDX          (RPC_PROGNOTREGISTERED_IDX \
248                                  + sizeof "RPC: Program not registered")
249   _("RPC: Failed (unspecified error)")
250 };
251
252 static const struct rpc_errtab rpc_errlist[] =
253 {
254   { RPC_SUCCESS, RPC_SUCCESS_IDX },
255   { RPC_CANTENCODEARGS, RPC_CANTENCODEARGS_IDX },
256   { RPC_CANTDECODERES, RPC_CANTDECODERES_IDX },
257   { RPC_CANTSEND, RPC_CANTSEND_IDX },
258   { RPC_CANTRECV, RPC_CANTRECV_IDX },
259   { RPC_TIMEDOUT, RPC_TIMEDOUT_IDX },
260   { RPC_VERSMISMATCH, RPC_VERSMISMATCH_IDX },
261   { RPC_AUTHERROR, RPC_AUTHERROR_IDX },
262   { RPC_PROGUNAVAIL, RPC_PROGUNAVAIL_IDX },
263   { RPC_PROGVERSMISMATCH, RPC_PROGVERSMISMATCH_IDX },
264   { RPC_PROCUNAVAIL, RPC_PROCUNAVAIL_IDX },
265   { RPC_CANTDECODEARGS, RPC_CANTDECODEARGS_IDX },
266   { RPC_SYSTEMERROR, RPC_SYSTEMERROR_IDX },
267   { RPC_UNKNOWNHOST, RPC_UNKNOWNHOST_IDX },
268   { RPC_UNKNOWNPROTO, RPC_UNKNOWNPROTO_IDX },
269   { RPC_PMAPFAILURE, RPC_PMAPFAILURE_IDX },
270   { RPC_PROGNOTREGISTERED, RPC_PROGNOTREGISTERED_IDX },
271   { RPC_FAILED, RPC_FAILED_IDX }
272 };
273
274
275 /*
276  * This interface for use by clntrpc
277  */
278 char *
279 clnt_sperrno (enum clnt_stat stat)
280 {
281   size_t i;
282
283   for (i = 0; i < sizeof (rpc_errlist) / sizeof (struct rpc_errtab); i++)
284     {
285       if (rpc_errlist[i].status == stat)
286         {
287           return (char*)_(rpc_errstr + rpc_errlist[i].message_off);
288         }
289     }
290   return _("RPC: (unknown error code)");
291 }
292
293 void
294 clnt_perrno (enum clnt_stat num)
295 {
296 #ifdef USE_IN_LIBIO
297   if (_IO_fwide (stderr, 0) > 0)
298     (void) __fwprintf (stderr, L"%s", clnt_sperrno (num));
299   else
300 #endif
301     (void) fputs (clnt_sperrno (num), stderr);
302 }
303
304
305 char *
306 clnt_spcreateerror (const char *msg)
307 {
308   char chrbuf[1024];
309   char *str = _buf ();
310   char *cp;
311   int len;
312   struct rpc_createerr *ce;
313
314   if (str == NULL)
315     return NULL;
316   ce = &get_rpc_createerr ();
317   len = sprintf (str, "%s: ", msg);
318   cp = str + len;
319   (void) strcpy(cp, clnt_sperrno (ce->cf_stat));
320   cp += strlen(cp);
321
322   switch (ce->cf_stat)
323     {
324     case RPC_PMAPFAILURE:
325       (void) strcpy(cp, " - ");
326       cp += strlen(cp);
327
328       (void) strcpy(cp, clnt_sperrno (ce->cf_error.re_status));
329       cp += strlen(cp);
330
331       break;
332
333     case RPC_SYSTEMERROR:
334       (void) strcpy(cp, " - ");
335       cp += strlen(cp);
336
337       strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf);
338       (void) strcpy(cp, chrbuf);
339       cp += strlen(cp);
340       break;
341     default:
342       break;
343     }
344   *cp = '\n';
345   *++cp = '\0';
346   return str;
347 }
348
349 void
350 clnt_pcreateerror (const char *msg)
351 {
352 #ifdef USE_IN_LIBIO
353   if (_IO_fwide (stderr, 0) > 0)
354     (void) __fwprintf (stderr, L"%s", clnt_spcreateerror (msg));
355   else
356 #endif
357     (void) fputs (clnt_spcreateerror (msg), stderr);
358 }
359
360 struct auth_errtab
361 {
362   enum auth_stat status;
363   unsigned int message_off;
364 };
365
366 static const char auth_errstr[] =
367 {
368 #define AUTH_OK_IDX             0
369    _("Authentication OK")
370    "\0"
371 #define AUTH_BADCRED_IDX        (AUTH_OK_IDX + sizeof "Authentication OK")
372    _("Invalid client credential")
373    "\0"
374 #define AUTH_REJECTEDCRED_IDX   (AUTH_BADCRED_IDX \
375                                  + sizeof "Invalid client credential")
376    _("Server rejected credential")
377    "\0"
378 #define AUTH_BADVERF_IDX        (AUTH_REJECTEDCRED_IDX \
379                                  + sizeof "Server rejected credential")
380    _("Invalid client verifier")
381    "\0"
382 #define AUTH_REJECTEDVERF_IDX   (AUTH_BADVERF_IDX \
383                                  + sizeof "Invalid client verifier")
384    _("Server rejected verifier")
385    "\0"
386 #define AUTH_TOOWEAK_IDX        (AUTH_REJECTEDVERF_IDX \
387                                  + sizeof "Server rejected verifier")
388    _("Client credential too weak")
389    "\0"
390 #define AUTH_INVALIDRESP_IDX    (AUTH_TOOWEAK_IDX \
391                                  + sizeof "Client credential too weak")
392    _("Invalid server verifier")
393    "\0"
394 #define AUTH_FAILED_IDX         (AUTH_INVALIDRESP_IDX \
395                                  + sizeof "Invalid server verifier")
396    _("Failed (unspecified error)")
397 };
398
399 static const struct auth_errtab auth_errlist[] =
400 {
401   { AUTH_OK, AUTH_OK_IDX },
402   { AUTH_BADCRED, AUTH_BADCRED_IDX },
403   { AUTH_REJECTEDCRED, AUTH_REJECTEDCRED_IDX },
404   { AUTH_BADVERF, AUTH_BADVERF_IDX },
405   { AUTH_REJECTEDVERF, AUTH_REJECTEDVERF_IDX },
406   { AUTH_TOOWEAK, AUTH_TOOWEAK_IDX },
407   { AUTH_INVALIDRESP, AUTH_INVALIDRESP_IDX },
408   { AUTH_FAILED, AUTH_FAILED_IDX }
409 };
410
411 static char *
412 internal_function
413 auth_errmsg (enum auth_stat stat)
414 {
415   size_t i;
416
417   for (i = 0; i < sizeof (auth_errlist) / sizeof (struct auth_errtab); i++)
418     {
419       if (auth_errlist[i].status == stat)
420         {
421           return (char*)_(auth_errstr + auth_errlist[i].message_off);
422         }
423     }
424   return NULL;
425 }
426
427
428 static void __attribute__ ((unused))
429 free_mem (void)
430 {
431   free (buf);
432 }