xref: /minix3/lib/libc/rpc/clnt_perror.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $	*/
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /*
4*84d9c625SLionel Sambuc  * Copyright (c) 2010, Oracle America, Inc.
52fe8fb19SBen Gras  *
6*84d9c625SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
7*84d9c625SLionel Sambuc  * modification, are permitted provided that the following conditions are
8*84d9c625SLionel Sambuc  * met:
92fe8fb19SBen Gras  *
10*84d9c625SLionel Sambuc  *     * Redistributions of source code must retain the above copyright
11*84d9c625SLionel Sambuc  *       notice, this list of conditions and the following disclaimer.
12*84d9c625SLionel Sambuc  *     * Redistributions in binary form must reproduce the above
13*84d9c625SLionel Sambuc  *       copyright notice, this list of conditions and the following
14*84d9c625SLionel Sambuc  *       disclaimer in the documentation and/or other materials
15*84d9c625SLionel Sambuc  *       provided with the distribution.
16*84d9c625SLionel Sambuc  *     * Neither the name of the "Oracle America, Inc." nor the names of its
17*84d9c625SLionel Sambuc  *       contributors may be used to endorse or promote products derived
18*84d9c625SLionel Sambuc  *       from this software without specific prior written permission.
192fe8fb19SBen Gras  *
20*84d9c625SLionel Sambuc  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*84d9c625SLionel Sambuc  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*84d9c625SLionel Sambuc  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*84d9c625SLionel Sambuc  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*84d9c625SLionel Sambuc  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*84d9c625SLionel Sambuc  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*84d9c625SLionel Sambuc  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27*84d9c625SLionel Sambuc  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*84d9c625SLionel Sambuc  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29*84d9c625SLionel Sambuc  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30*84d9c625SLionel Sambuc  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*84d9c625SLionel Sambuc  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
322fe8fb19SBen Gras  */
332fe8fb19SBen Gras 
342fe8fb19SBen Gras #include <sys/cdefs.h>
352fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
362fe8fb19SBen Gras #if 0
372fe8fb19SBen Gras static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
382fe8fb19SBen Gras static char *sccsid = "@(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";
392fe8fb19SBen Gras #else
40*84d9c625SLionel Sambuc __RCSID("$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $");
412fe8fb19SBen Gras #endif
422fe8fb19SBen Gras #endif
432fe8fb19SBen Gras 
442fe8fb19SBen Gras /*
452fe8fb19SBen Gras  * clnt_perror.c
462fe8fb19SBen Gras  *
472fe8fb19SBen Gras  * Copyright (C) 1984, Sun Microsystems, Inc.
482fe8fb19SBen Gras  *
492fe8fb19SBen Gras  */
502fe8fb19SBen Gras #include "namespace.h"
512fe8fb19SBen Gras 
522fe8fb19SBen Gras #include <assert.h>
532fe8fb19SBen Gras #include <stdio.h>
542fe8fb19SBen Gras #include <stdlib.h>
552fe8fb19SBen Gras #include <string.h>
562fe8fb19SBen Gras 
572fe8fb19SBen Gras #include <rpc/rpc.h>
582fe8fb19SBen Gras #include <rpc/types.h>
592fe8fb19SBen Gras #include <rpc/auth.h>
602fe8fb19SBen Gras #include <rpc/clnt.h>
612fe8fb19SBen Gras 
622fe8fb19SBen Gras #ifdef __weak_alias
632fe8fb19SBen Gras __weak_alias(clnt_pcreateerror,_clnt_pcreateerror)
642fe8fb19SBen Gras __weak_alias(clnt_perrno,_clnt_perrno)
652fe8fb19SBen Gras __weak_alias(clnt_perror,_clnt_perror)
662fe8fb19SBen Gras __weak_alias(clnt_spcreateerror,_clnt_spcreateerror)
672fe8fb19SBen Gras __weak_alias(clnt_sperrno,_clnt_sperrno)
682fe8fb19SBen Gras __weak_alias(clnt_sperror,_clnt_sperror)
692fe8fb19SBen Gras #endif
702fe8fb19SBen Gras 
712fe8fb19SBen Gras static char *buf;
722fe8fb19SBen Gras static size_t buflen;
732fe8fb19SBen Gras 
74f14fb602SLionel Sambuc static char *_buf(void);
75f14fb602SLionel Sambuc static char *auth_errmsg(enum auth_stat);
762fe8fb19SBen Gras 
772fe8fb19SBen Gras static char *
_buf(void)78f14fb602SLionel Sambuc _buf(void)
792fe8fb19SBen Gras {
802fe8fb19SBen Gras 
812fe8fb19SBen Gras 	buflen = 256;
822fe8fb19SBen Gras 	if (buf == 0)
832fe8fb19SBen Gras 		buf = malloc(buflen);
842fe8fb19SBen Gras 	return (buf);
852fe8fb19SBen Gras }
862fe8fb19SBen Gras 
872fe8fb19SBen Gras /*
882fe8fb19SBen Gras  * Print reply error info
892fe8fb19SBen Gras  */
902fe8fb19SBen Gras char *
clnt_sperror(CLIENT * rpch,const char * s)91f14fb602SLionel Sambuc clnt_sperror(CLIENT *rpch, const char *s)
922fe8fb19SBen Gras {
932fe8fb19SBen Gras 	struct rpc_err e;
942fe8fb19SBen Gras 	char *err;
952fe8fb19SBen Gras 	char *str;
962fe8fb19SBen Gras 	char *strstart;
972fe8fb19SBen Gras 	size_t len, i;
982fe8fb19SBen Gras 
992fe8fb19SBen Gras 	_DIAGASSERT(rpch != NULL);
1002fe8fb19SBen Gras 	_DIAGASSERT(s != NULL);
1012fe8fb19SBen Gras 
1022fe8fb19SBen Gras 	str = _buf(); /* side effect: sets "buflen" */
1032fe8fb19SBen Gras 	if (str == 0)
1042fe8fb19SBen Gras 		return (0);
1052fe8fb19SBen Gras 	len = buflen;
1062fe8fb19SBen Gras 	strstart = str;
1072fe8fb19SBen Gras 	CLNT_GETERR(rpch, &e);
1082fe8fb19SBen Gras 
1092fe8fb19SBen Gras 	i = snprintf(str, len, "%s: ", s);
1102fe8fb19SBen Gras 	str += i;
1112fe8fb19SBen Gras 	len -= i;
1122fe8fb19SBen Gras 
1132fe8fb19SBen Gras 	(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
1142fe8fb19SBen Gras 	i = strlen(str);
1152fe8fb19SBen Gras 	str += i;
1162fe8fb19SBen Gras 	len -= i;
1172fe8fb19SBen Gras 
1182fe8fb19SBen Gras 	switch (e.re_status) {
1192fe8fb19SBen Gras 	case RPC_SUCCESS:
1202fe8fb19SBen Gras 	case RPC_CANTENCODEARGS:
1212fe8fb19SBen Gras 	case RPC_CANTDECODERES:
1222fe8fb19SBen Gras 	case RPC_TIMEDOUT:
1232fe8fb19SBen Gras 	case RPC_PROGUNAVAIL:
1242fe8fb19SBen Gras 	case RPC_PROCUNAVAIL:
1252fe8fb19SBen Gras 	case RPC_CANTDECODEARGS:
1262fe8fb19SBen Gras 	case RPC_SYSTEMERROR:
1272fe8fb19SBen Gras 	case RPC_UNKNOWNHOST:
1282fe8fb19SBen Gras 	case RPC_UNKNOWNPROTO:
1292fe8fb19SBen Gras 	case RPC_PMAPFAILURE:
1302fe8fb19SBen Gras 	case RPC_PROGNOTREGISTERED:
1312fe8fb19SBen Gras 	case RPC_FAILED:
1322fe8fb19SBen Gras 		break;
1332fe8fb19SBen Gras 
1342fe8fb19SBen Gras 	case RPC_CANTSEND:
1352fe8fb19SBen Gras 	case RPC_CANTRECV:
1362fe8fb19SBen Gras 		i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
1372fe8fb19SBen Gras 		str += i;
1382fe8fb19SBen Gras 		len -= i;
1392fe8fb19SBen Gras 		break;
1402fe8fb19SBen Gras 
1412fe8fb19SBen Gras 	case RPC_VERSMISMATCH:
1422fe8fb19SBen Gras 		i = snprintf(str, len, "; low version = %u, high version = %u",
1432fe8fb19SBen Gras 			e.re_vers.low, e.re_vers.high);
1442fe8fb19SBen Gras 		str += i;
1452fe8fb19SBen Gras 		len -= i;
1462fe8fb19SBen Gras 		break;
1472fe8fb19SBen Gras 
1482fe8fb19SBen Gras 	case RPC_AUTHERROR:
1492fe8fb19SBen Gras 		err = auth_errmsg(e.re_why);
1502fe8fb19SBen Gras 		i = snprintf(str, len, "; why = ");
1512fe8fb19SBen Gras 		str += i;
1522fe8fb19SBen Gras 		len -= i;
1532fe8fb19SBen Gras 		if (err != NULL) {
1542fe8fb19SBen Gras 			i = snprintf(str, len, "%s",err);
1552fe8fb19SBen Gras 		} else {
1562fe8fb19SBen Gras 			i = snprintf(str, len,
1572fe8fb19SBen Gras 				"(unknown authentication error - %d)",
1582fe8fb19SBen Gras 				(int) e.re_why);
1592fe8fb19SBen Gras 		}
1602fe8fb19SBen Gras 		str += i;
1612fe8fb19SBen Gras 		len -= i;
1622fe8fb19SBen Gras 		break;
1632fe8fb19SBen Gras 
1642fe8fb19SBen Gras 	case RPC_PROGVERSMISMATCH:
1652fe8fb19SBen Gras 		i = snprintf(str, len, "; low version = %u, high version = %u",
1662fe8fb19SBen Gras 			e.re_vers.low, e.re_vers.high);
1672fe8fb19SBen Gras 		str += i;
1682fe8fb19SBen Gras 		len -= i;
1692fe8fb19SBen Gras 		break;
1702fe8fb19SBen Gras 
1712fe8fb19SBen Gras 	default:	/* unknown */
1722fe8fb19SBen Gras 		i = snprintf(str, len, "; s1 = %u, s2 = %u",
1732fe8fb19SBen Gras 			e.re_lb.s1, e.re_lb.s2);
1742fe8fb19SBen Gras 		str += i;
1752fe8fb19SBen Gras 		len -= i;
1762fe8fb19SBen Gras 		break;
1772fe8fb19SBen Gras 	}
1782fe8fb19SBen Gras 	return(strstart) ;
1792fe8fb19SBen Gras }
1802fe8fb19SBen Gras 
1812fe8fb19SBen Gras void
clnt_perror(CLIENT * rpch,const char * s)182f14fb602SLionel Sambuc clnt_perror(CLIENT *rpch, const char *s)
1832fe8fb19SBen Gras {
1842fe8fb19SBen Gras 
1852fe8fb19SBen Gras 	_DIAGASSERT(rpch != NULL);
1862fe8fb19SBen Gras 	_DIAGASSERT(s != NULL);
1872fe8fb19SBen Gras 
1882fe8fb19SBen Gras 	(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
1892fe8fb19SBen Gras }
1902fe8fb19SBen Gras 
1912fe8fb19SBen Gras static const char *const rpc_errlist[] = {
1922fe8fb19SBen Gras 	[RPC_SUCCESS] =			"RPC: Success",
1932fe8fb19SBen Gras 	[RPC_CANTENCODEARGS] =		"RPC: Can't encode arguments",
1942fe8fb19SBen Gras 	[RPC_CANTDECODERES] =		"RPC: Can't decode result",
1952fe8fb19SBen Gras 	[RPC_CANTSEND] =		"RPC: Unable to send",
1962fe8fb19SBen Gras 	[RPC_CANTRECV] =		"RPC: Unable to receive",
1972fe8fb19SBen Gras 	[RPC_TIMEDOUT] =		"RPC: Timed out",
1982fe8fb19SBen Gras 	[RPC_VERSMISMATCH] =		"RPC: Incompatible versions of RPC",
1992fe8fb19SBen Gras 	[RPC_AUTHERROR] = 		"RPC: Authentication error",
2002fe8fb19SBen Gras 	[RPC_PROGUNAVAIL] =		"RPC: Program unavailable",
2012fe8fb19SBen Gras 	[RPC_PROGVERSMISMATCH] =	"RPC: Program/version mismatch",
2022fe8fb19SBen Gras 	[RPC_PROCUNAVAIL] =		"RPC: Procedure unavailable",
2032fe8fb19SBen Gras 	[RPC_CANTDECODEARGS] =		"RPC: Server can't decode arguments",
2042fe8fb19SBen Gras 	[RPC_SYSTEMERROR] =		"RPC: Remote system error",
2052fe8fb19SBen Gras 	[RPC_UNKNOWNHOST] =		"RPC: Unknown host",
2062fe8fb19SBen Gras 	[RPC_PMAPFAILURE] =		"RPC: Port mapper failure",
2072fe8fb19SBen Gras 	[RPC_PROGNOTREGISTERED] =	"RPC: Program not registered",
2082fe8fb19SBen Gras 	[RPC_FAILED] =			"RPC: Failed (unspecified error)",
2092fe8fb19SBen Gras 	[RPC_UNKNOWNPROTO] =		"RPC: Unknown protocol",
2102fe8fb19SBen Gras 	[RPC_UNKNOWNADDR] =		"RPC: Remote address unknown",
2112fe8fb19SBen Gras 	[RPC_TLIERROR] =		"RPC: Misc error in the TLI library",
2122fe8fb19SBen Gras 	[RPC_NOBROADCAST] =		"RPC: Broadcasting not supported",
2132fe8fb19SBen Gras 	[RPC_N2AXLATEFAILURE] =		"RPC: Name -> addr translation failed",
2142fe8fb19SBen Gras 	[RPC_INPROGRESS] =		"RPC: In progress",
2152fe8fb19SBen Gras 	[RPC_STALERACHANDLE] =		"RPC: Stale handle",
2162fe8fb19SBen Gras };
2172fe8fb19SBen Gras 
2182fe8fb19SBen Gras 
2192fe8fb19SBen Gras /*
2202fe8fb19SBen Gras  * This interface for use by clntrpc
2212fe8fb19SBen Gras  */
2222fe8fb19SBen Gras char *
clnt_sperrno(enum clnt_stat stat)223f14fb602SLionel Sambuc clnt_sperrno(enum clnt_stat stat)
2242fe8fb19SBen Gras {
2252fe8fb19SBen Gras 	unsigned int errnum = stat;
2262fe8fb19SBen Gras 	const char *msg;
2272fe8fb19SBen Gras 
2282fe8fb19SBen Gras 	msg = NULL;
2292fe8fb19SBen Gras 	if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) {
2302fe8fb19SBen Gras 		msg = rpc_errlist[errnum];
2312fe8fb19SBen Gras 	}
2322fe8fb19SBen Gras 	if (msg == NULL) {
2332fe8fb19SBen Gras 		msg = "RPC: (unknown error code)";
2342fe8fb19SBen Gras 	}
2352fe8fb19SBen Gras 	return __UNCONST(msg);
2362fe8fb19SBen Gras }
2372fe8fb19SBen Gras 
2382fe8fb19SBen Gras void
clnt_perrno(enum clnt_stat num)239f14fb602SLionel Sambuc clnt_perrno(enum clnt_stat num)
2402fe8fb19SBen Gras {
2412fe8fb19SBen Gras 	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
2422fe8fb19SBen Gras }
2432fe8fb19SBen Gras 
2442fe8fb19SBen Gras 
2452fe8fb19SBen Gras char *
clnt_spcreateerror(const char * s)246f14fb602SLionel Sambuc clnt_spcreateerror(const char *s)
2472fe8fb19SBen Gras {
2482fe8fb19SBen Gras 	char *str;
2492fe8fb19SBen Gras 	size_t len, i;
2502fe8fb19SBen Gras 
2512fe8fb19SBen Gras 	_DIAGASSERT(s != NULL);
2522fe8fb19SBen Gras 
2532fe8fb19SBen Gras 	str = _buf(); /* side effect: sets "buflen" */
2542fe8fb19SBen Gras 	if (str == 0)
2552fe8fb19SBen Gras 		return(0);
2562fe8fb19SBen Gras 	len = buflen;
2572fe8fb19SBen Gras 	i = snprintf(str, len, "%s: ", s);
2582fe8fb19SBen Gras 	len -= i;
2592fe8fb19SBen Gras 	(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
2602fe8fb19SBen Gras 	switch (rpc_createerr.cf_stat) {
2612fe8fb19SBen Gras 	case RPC_PMAPFAILURE:
2622fe8fb19SBen Gras 		(void) strncat(str, " - ", len - 1);
2632fe8fb19SBen Gras 		(void) strncat(str,
2642fe8fb19SBen Gras 		    clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
2652fe8fb19SBen Gras 		break;
2662fe8fb19SBen Gras 
2672fe8fb19SBen Gras 	case RPC_SYSTEMERROR:
2682fe8fb19SBen Gras 		(void)strncat(str, " - ", len - 1);
2692fe8fb19SBen Gras 		(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
2702fe8fb19SBen Gras 		    len - 4);
2712fe8fb19SBen Gras 		break;
2722fe8fb19SBen Gras 
2732fe8fb19SBen Gras 	case RPC_CANTSEND:
2742fe8fb19SBen Gras 	case RPC_CANTDECODERES:
2752fe8fb19SBen Gras 	case RPC_CANTENCODEARGS:
2762fe8fb19SBen Gras 	case RPC_SUCCESS:
2772fe8fb19SBen Gras 	case RPC_UNKNOWNPROTO:
2782fe8fb19SBen Gras 	case RPC_PROGNOTREGISTERED:
2792fe8fb19SBen Gras 	case RPC_FAILED:
2802fe8fb19SBen Gras 	case RPC_UNKNOWNHOST:
2812fe8fb19SBen Gras 	case RPC_CANTDECODEARGS:
2822fe8fb19SBen Gras 	case RPC_PROCUNAVAIL:
2832fe8fb19SBen Gras 	case RPC_PROGVERSMISMATCH:
2842fe8fb19SBen Gras 	case RPC_PROGUNAVAIL:
2852fe8fb19SBen Gras 	case RPC_AUTHERROR:
2862fe8fb19SBen Gras 	case RPC_VERSMISMATCH:
2872fe8fb19SBen Gras 	case RPC_TIMEDOUT:
2882fe8fb19SBen Gras 	case RPC_CANTRECV:
2892fe8fb19SBen Gras 	default:
2902fe8fb19SBen Gras 		break;
2912fe8fb19SBen Gras 	}
2922fe8fb19SBen Gras 	return (str);
2932fe8fb19SBen Gras }
2942fe8fb19SBen Gras 
2952fe8fb19SBen Gras void
clnt_pcreateerror(const char * s)296f14fb602SLionel Sambuc clnt_pcreateerror(const char *s)
2972fe8fb19SBen Gras {
2982fe8fb19SBen Gras 
2992fe8fb19SBen Gras 	_DIAGASSERT(s != NULL);
3002fe8fb19SBen Gras 
3012fe8fb19SBen Gras 	(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
3022fe8fb19SBen Gras }
3032fe8fb19SBen Gras 
3042fe8fb19SBen Gras static const char *const auth_errlist[] = {
3052fe8fb19SBen Gras 	"Authentication OK",			/* 0 - AUTH_OK */
3062fe8fb19SBen Gras 	"Invalid client credential",		/* 1 - AUTH_BADCRED */
3072fe8fb19SBen Gras 	"Server rejected credential",		/* 2 - AUTH_REJECTEDCRED */
3082fe8fb19SBen Gras 	"Invalid client verifier", 		/* 3 - AUTH_BADVERF */
3092fe8fb19SBen Gras 	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
3102fe8fb19SBen Gras 	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
3112fe8fb19SBen Gras 	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
3122fe8fb19SBen Gras 	"Failed (unspecified error)"		/* 7 - AUTH_FAILED */
3132fe8fb19SBen Gras };
3142fe8fb19SBen Gras 
3152fe8fb19SBen Gras static char *
auth_errmsg(enum auth_stat stat)316f14fb602SLionel Sambuc auth_errmsg(enum auth_stat stat)
3172fe8fb19SBen Gras {
3182fe8fb19SBen Gras 	unsigned int errnum = stat;
3192fe8fb19SBen Gras 
320f14fb602SLionel Sambuc 	if (errnum < __arraycount(auth_errlist))
3212fe8fb19SBen Gras 		return __UNCONST(auth_errlist[errnum]);
3222fe8fb19SBen Gras 
3232fe8fb19SBen Gras 	return(NULL);
3242fe8fb19SBen Gras }
325