xref: /netbsd/lib/libc/rpc/clnt_perror.c (revision 6550d01e)
1 /*	$NetBSD: clnt_perror.c,v 1.28 2008/04/25 17:44:44 christos Exp $	*/
2 
3 /*
4  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5  * unrestricted use provided that this legend is included on all tape
6  * media and as a part of the software program in whole or part.  Users
7  * may copy or modify Sun RPC without charge, but are not authorized
8  * to license or distribute it to anyone else except as part of a product or
9  * program developed by the user.
10  *
11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14  *
15  * Sun RPC is provided with no support and without any obligation on the
16  * part of Sun Microsystems, Inc. to assist in its use, correction,
17  * modification or enhancement.
18  *
19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21  * OR ANY PART THEREOF.
22  *
23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24  * or profits or other special, indirect and consequential damages, even if
25  * Sun has been advised of the possibility of such damages.
26  *
27  * Sun Microsystems, Inc.
28  * 2550 Garcia Avenue
29  * Mountain View, California  94043
30  */
31 
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 #if 0
35 static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
36 static char *sccsid = "@(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";
37 #else
38 __RCSID("$NetBSD: clnt_perror.c,v 1.28 2008/04/25 17:44:44 christos Exp $");
39 #endif
40 #endif
41 
42 /*
43  * clnt_perror.c
44  *
45  * Copyright (C) 1984, Sun Microsystems, Inc.
46  *
47  */
48 #include "namespace.h"
49 
50 #include <assert.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 
55 #include <rpc/rpc.h>
56 #include <rpc/types.h>
57 #include <rpc/auth.h>
58 #include <rpc/clnt.h>
59 
60 #ifdef __weak_alias
61 __weak_alias(clnt_pcreateerror,_clnt_pcreateerror)
62 __weak_alias(clnt_perrno,_clnt_perrno)
63 __weak_alias(clnt_perror,_clnt_perror)
64 __weak_alias(clnt_spcreateerror,_clnt_spcreateerror)
65 __weak_alias(clnt_sperrno,_clnt_sperrno)
66 __weak_alias(clnt_sperror,_clnt_sperror)
67 #endif
68 
69 static char *buf;
70 static size_t buflen;
71 
72 static char *_buf __P((void));
73 static char *auth_errmsg __P((enum auth_stat));
74 
75 static char *
76 _buf()
77 {
78 
79 	buflen = 256;
80 	if (buf == 0)
81 		buf = malloc(buflen);
82 	return (buf);
83 }
84 
85 /*
86  * Print reply error info
87  */
88 char *
89 clnt_sperror(rpch, s)
90 	CLIENT *rpch;
91 	const char *s;
92 {
93 	struct rpc_err e;
94 	char *err;
95 	char *str;
96 	char *strstart;
97 	size_t len, i;
98 
99 	_DIAGASSERT(rpch != NULL);
100 	_DIAGASSERT(s != NULL);
101 
102 	str = _buf(); /* side effect: sets "buflen" */
103 	if (str == 0)
104 		return (0);
105 	len = buflen;
106 	strstart = str;
107 	CLNT_GETERR(rpch, &e);
108 
109 	i = snprintf(str, len, "%s: ", s);
110 	str += i;
111 	len -= i;
112 
113 	(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
114 	i = strlen(str);
115 	str += i;
116 	len -= i;
117 
118 	switch (e.re_status) {
119 	case RPC_SUCCESS:
120 	case RPC_CANTENCODEARGS:
121 	case RPC_CANTDECODERES:
122 	case RPC_TIMEDOUT:
123 	case RPC_PROGUNAVAIL:
124 	case RPC_PROCUNAVAIL:
125 	case RPC_CANTDECODEARGS:
126 	case RPC_SYSTEMERROR:
127 	case RPC_UNKNOWNHOST:
128 	case RPC_UNKNOWNPROTO:
129 	case RPC_PMAPFAILURE:
130 	case RPC_PROGNOTREGISTERED:
131 	case RPC_FAILED:
132 		break;
133 
134 	case RPC_CANTSEND:
135 	case RPC_CANTRECV:
136 		i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
137 		str += i;
138 		len -= i;
139 		break;
140 
141 	case RPC_VERSMISMATCH:
142 		i = snprintf(str, len, "; low version = %u, high version = %u",
143 			e.re_vers.low, e.re_vers.high);
144 		str += i;
145 		len -= i;
146 		break;
147 
148 	case RPC_AUTHERROR:
149 		err = auth_errmsg(e.re_why);
150 		i = snprintf(str, len, "; why = ");
151 		str += i;
152 		len -= i;
153 		if (err != NULL) {
154 			i = snprintf(str, len, "%s",err);
155 		} else {
156 			i = snprintf(str, len,
157 				"(unknown authentication error - %d)",
158 				(int) e.re_why);
159 		}
160 		str += i;
161 		len -= i;
162 		break;
163 
164 	case RPC_PROGVERSMISMATCH:
165 		i = snprintf(str, len, "; low version = %u, high version = %u",
166 			e.re_vers.low, e.re_vers.high);
167 		str += i;
168 		len -= i;
169 		break;
170 
171 	default:	/* unknown */
172 		i = snprintf(str, len, "; s1 = %u, s2 = %u",
173 			e.re_lb.s1, e.re_lb.s2);
174 		str += i;
175 		len -= i;
176 		break;
177 	}
178 	return(strstart) ;
179 }
180 
181 void
182 clnt_perror(rpch, s)
183 	CLIENT *rpch;
184 	const char *s;
185 {
186 
187 	_DIAGASSERT(rpch != NULL);
188 	_DIAGASSERT(s != NULL);
189 
190 	(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
191 }
192 
193 static const char *const rpc_errlist[] = {
194 	[RPC_SUCCESS] =			"RPC: Success",
195 	[RPC_CANTENCODEARGS] =		"RPC: Can't encode arguments",
196 	[RPC_CANTDECODERES] =		"RPC: Can't decode result",
197 	[RPC_CANTSEND] =		"RPC: Unable to send",
198 	[RPC_CANTRECV] =		"RPC: Unable to receive",
199 	[RPC_TIMEDOUT] =		"RPC: Timed out",
200 	[RPC_VERSMISMATCH] =		"RPC: Incompatible versions of RPC",
201 	[RPC_AUTHERROR] = 		"RPC: Authentication error",
202 	[RPC_PROGUNAVAIL] =		"RPC: Program unavailable",
203 	[RPC_PROGVERSMISMATCH] =	"RPC: Program/version mismatch",
204 	[RPC_PROCUNAVAIL] =		"RPC: Procedure unavailable",
205 	[RPC_CANTDECODEARGS] =		"RPC: Server can't decode arguments",
206 	[RPC_SYSTEMERROR] =		"RPC: Remote system error",
207 	[RPC_UNKNOWNHOST] =		"RPC: Unknown host",
208 	[RPC_PMAPFAILURE] =		"RPC: Port mapper failure",
209 	[RPC_PROGNOTREGISTERED] =	"RPC: Program not registered",
210 	[RPC_FAILED] =			"RPC: Failed (unspecified error)",
211 	[RPC_UNKNOWNPROTO] =		"RPC: Unknown protocol",
212 	[RPC_UNKNOWNADDR] =		"RPC: Remote address unknown",
213 	[RPC_TLIERROR] =		"RPC: Misc error in the TLI library",
214 	[RPC_NOBROADCAST] =		"RPC: Broadcasting not supported",
215 	[RPC_N2AXLATEFAILURE] =		"RPC: Name -> addr translation failed",
216 	[RPC_INPROGRESS] =		"RPC: In progress",
217 	[RPC_STALERACHANDLE] =		"RPC: Stale handle",
218 };
219 
220 
221 /*
222  * This interface for use by clntrpc
223  */
224 char *
225 clnt_sperrno(stat)
226 	enum clnt_stat stat;
227 {
228 	unsigned int errnum = stat;
229 	const char *msg;
230 
231 	msg = NULL;
232 	if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) {
233 		msg = rpc_errlist[errnum];
234 	}
235 	if (msg == NULL) {
236 		msg = "RPC: (unknown error code)";
237 	}
238 	return __UNCONST(msg);
239 }
240 
241 void
242 clnt_perrno(num)
243 	enum clnt_stat num;
244 {
245 	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
246 }
247 
248 
249 char *
250 clnt_spcreateerror(s)
251 	const char *s;
252 {
253 	char *str;
254 	size_t len, i;
255 
256 	_DIAGASSERT(s != NULL);
257 
258 	str = _buf(); /* side effect: sets "buflen" */
259 	if (str == 0)
260 		return(0);
261 	len = buflen;
262 	i = snprintf(str, len, "%s: ", s);
263 	len -= i;
264 	(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
265 	switch (rpc_createerr.cf_stat) {
266 	case RPC_PMAPFAILURE:
267 		(void) strncat(str, " - ", len - 1);
268 		(void) strncat(str,
269 		    clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
270 		break;
271 
272 	case RPC_SYSTEMERROR:
273 		(void)strncat(str, " - ", len - 1);
274 		(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
275 		    len - 4);
276 		break;
277 
278 	case RPC_CANTSEND:
279 	case RPC_CANTDECODERES:
280 	case RPC_CANTENCODEARGS:
281 	case RPC_SUCCESS:
282 	case RPC_UNKNOWNPROTO:
283 	case RPC_PROGNOTREGISTERED:
284 	case RPC_FAILED:
285 	case RPC_UNKNOWNHOST:
286 	case RPC_CANTDECODEARGS:
287 	case RPC_PROCUNAVAIL:
288 	case RPC_PROGVERSMISMATCH:
289 	case RPC_PROGUNAVAIL:
290 	case RPC_AUTHERROR:
291 	case RPC_VERSMISMATCH:
292 	case RPC_TIMEDOUT:
293 	case RPC_CANTRECV:
294 	default:
295 		break;
296 	}
297 	return (str);
298 }
299 
300 void
301 clnt_pcreateerror(s)
302 	const char *s;
303 {
304 
305 	_DIAGASSERT(s != NULL);
306 
307 	(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
308 }
309 
310 static const char *const auth_errlist[] = {
311 	"Authentication OK",			/* 0 - AUTH_OK */
312 	"Invalid client credential",		/* 1 - AUTH_BADCRED */
313 	"Server rejected credential",		/* 2 - AUTH_REJECTEDCRED */
314 	"Invalid client verifier", 		/* 3 - AUTH_BADVERF */
315 	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
316 	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
317 	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
318 	"Failed (unspecified error)"		/* 7 - AUTH_FAILED */
319 };
320 
321 static char *
322 auth_errmsg(stat)
323 	enum auth_stat stat;
324 {
325 	unsigned int errnum = stat;
326 
327 	if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
328 		return __UNCONST(auth_errlist[errnum]);
329 
330 	return(NULL);
331 }
332