174462Salfred/*	$NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $	*/
274462Salfred
374462Salfred
41901Swollman/*
51901Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
61901Swollman * unrestricted use provided that this legend is included on all tape
71901Swollman * media and as a part of the software program in whole or part.  Users
81901Swollman * may copy or modify Sun RPC without charge, but are not authorized
91901Swollman * to license or distribute it to anyone else except as part of a product or
101901Swollman * program developed by the user.
118870Srgrimes *
121901Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
131901Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
141901Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
158870Srgrimes *
161901Swollman * Sun RPC is provided with no support and without any obligation on the
171901Swollman * part of Sun Microsystems, Inc. to assist in its use, correction,
181901Swollman * modification or enhancement.
198870Srgrimes *
201901Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
211901Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
221901Swollman * OR ANY PART THEREOF.
238870Srgrimes *
241901Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue
251901Swollman * or profits or other special, indirect and consequential damages, even if
261901Swollman * Sun has been advised of the possibility of such damages.
278870Srgrimes *
281901Swollman * Sun Microsystems, Inc.
291901Swollman * 2550 Garcia Avenue
301901Swollman * Mountain View, California  94043
311901Swollman */
321901Swollman
331901Swollman#if defined(LIBC_SCCS) && !defined(lint)
34136581Sobrienstatic char *sccsid2 = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
3574462Salfredstatic char *sccsid = "@(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";
361901Swollman#endif
3792990Sobrien#include <sys/cdefs.h>
3892990Sobrien__FBSDID("$FreeBSD$");
391901Swollman
401901Swollman/*
411901Swollman * clnt_perror.c
421901Swollman *
431901Swollman * Copyright (C) 1984, Sun Microsystems, Inc.
441901Swollman *
451901Swollman */
4674462Salfred#include "namespace.h"
4774462Salfred#include <assert.h>
481901Swollman#include <stdio.h>
4911666Sphk#include <stdlib.h>
501901Swollman#include <string.h>
5174462Salfred
521901Swollman#include <rpc/rpc.h>
531901Swollman#include <rpc/types.h>
541901Swollman#include <rpc/auth.h>
551901Swollman#include <rpc/clnt.h>
5674462Salfred#include "un-namespace.h"
571901Swollman
5874462Salfredstatic char *buf;
5974462Salfred
6092905Sobrienstatic char *_buf(void);
6192905Sobrienstatic char *auth_errmsg(enum auth_stat);
6221068Speter#define CLNT_PERROR_BUFLEN 256
631901Swollman
641901Swollmanstatic char *
651901Swollman_buf()
661901Swollman{
671901Swollman
681901Swollman	if (buf == 0)
6921068Speter		buf = (char *)malloc(CLNT_PERROR_BUFLEN);
701901Swollman	return (buf);
711901Swollman}
721901Swollman
731901Swollman/*
741901Swollman * Print reply error info
751901Swollman */
761901Swollmanchar *
771901Swollmanclnt_sperror(rpch, s)
781901Swollman	CLIENT *rpch;
7974462Salfred	const char *s;
801901Swollman{
811901Swollman	struct rpc_err e;
821901Swollman	char *err;
8374462Salfred	char *str;
8474462Salfred	char *strstart;
8574462Salfred	size_t len, i;
861901Swollman
8774462Salfred	assert(rpch != NULL);
8874462Salfred	assert(s != NULL);
8974462Salfred
9074462Salfred	str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
911901Swollman	if (str == 0)
921901Swollman		return (0);
9374462Salfred	len = CLNT_PERROR_BUFLEN;
9474462Salfred	strstart = str;
951901Swollman	CLNT_GETERR(rpch, &e);
961901Swollman
9781966Sbrian	if ((i = snprintf(str, len, "%s: ", s)) > 0) {
9881966Sbrian		str += i;
9981966Sbrian		len -= i;
10081966Sbrian	}
1011901Swollman
10274462Salfred	(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
10374462Salfred	i = strlen(str);
10474462Salfred	str += i;
10574462Salfred	len -= i;
10674462Salfred
1071901Swollman	switch (e.re_status) {
1081901Swollman	case RPC_SUCCESS:
1091901Swollman	case RPC_CANTENCODEARGS:
1101901Swollman	case RPC_CANTDECODERES:
1118870Srgrimes	case RPC_TIMEDOUT:
1121901Swollman	case RPC_PROGUNAVAIL:
1131901Swollman	case RPC_PROCUNAVAIL:
1141901Swollman	case RPC_CANTDECODEARGS:
1151901Swollman	case RPC_SYSTEMERROR:
1161901Swollman	case RPC_UNKNOWNHOST:
1171901Swollman	case RPC_UNKNOWNPROTO:
1181901Swollman	case RPC_PMAPFAILURE:
1191901Swollman	case RPC_PROGNOTREGISTERED:
1201901Swollman	case RPC_FAILED:
1211901Swollman		break;
1221901Swollman
1231901Swollman	case RPC_CANTSEND:
1241901Swollman	case RPC_CANTRECV:
12574462Salfred		i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
12681966Sbrian		if (i > 0) {
12781966Sbrian			str += i;
12881966Sbrian			len -= i;
12981966Sbrian		}
1301901Swollman		break;
1311901Swollman
1321901Swollman	case RPC_VERSMISMATCH:
13374462Salfred		i = snprintf(str, len, "; low version = %u, high version = %u",
13474462Salfred			e.re_vers.low, e.re_vers.high);
13581966Sbrian		if (i > 0) {
13681966Sbrian			str += i;
13781966Sbrian			len -= i;
13881966Sbrian		}
1391901Swollman		break;
1401901Swollman
1411901Swollman	case RPC_AUTHERROR:
1421901Swollman		err = auth_errmsg(e.re_why);
14374462Salfred		i = snprintf(str, len, "; why = ");
14481966Sbrian		if (i > 0) {
14581966Sbrian			str += i;
14681966Sbrian			len -= i;
14781966Sbrian		}
1481901Swollman		if (err != NULL) {
14974462Salfred			i = snprintf(str, len, "%s",err);
1501901Swollman		} else {
15174462Salfred			i = snprintf(str, len,
15274462Salfred				"(unknown authentication error - %d)",
1531901Swollman				(int) e.re_why);
1541901Swollman		}
15581966Sbrian		if (i > 0) {
15681966Sbrian			str += i;
15781966Sbrian			len -= i;
15881966Sbrian		}
1591901Swollman		break;
1601901Swollman
1611901Swollman	case RPC_PROGVERSMISMATCH:
16274462Salfred		i = snprintf(str, len, "; low version = %u, high version = %u",
16374462Salfred			e.re_vers.low, e.re_vers.high);
16481966Sbrian		if (i > 0) {
16581966Sbrian			str += i;
16681966Sbrian			len -= i;
16781966Sbrian		}
1681901Swollman		break;
1691901Swollman
1701901Swollman	default:	/* unknown */
17174462Salfred		i = snprintf(str, len, "; s1 = %u, s2 = %u",
17274462Salfred			e.re_lb.s1, e.re_lb.s2);
17381966Sbrian		if (i > 0) {
17481966Sbrian			str += i;
17581966Sbrian			len -= i;
17681966Sbrian		}
1771901Swollman		break;
1781901Swollman	}
17921068Speter	strstart[CLNT_PERROR_BUFLEN-1] = '\0';
1801901Swollman	return(strstart) ;
1811901Swollman}
1821901Swollman
1831901Swollmanvoid
1841901Swollmanclnt_perror(rpch, s)
1851901Swollman	CLIENT *rpch;
18674462Salfred	const char *s;
1871901Swollman{
18874462Salfred
18974462Salfred	assert(rpch != NULL);
19074462Salfred	assert(s != NULL);
19174462Salfred
19274462Salfred	(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
1931901Swollman}
1941901Swollman
19521068Speterstatic const char *const rpc_errlist[] = {
19621068Speter	"RPC: Success",				/*  0 - RPC_SUCCESS */
19721068Speter	"RPC: Can't encode arguments",		/*  1 - RPC_CANTENCODEARGS */
19821068Speter	"RPC: Can't decode result",		/*  2 - RPC_CANTDECODERES */
19921068Speter	"RPC: Unable to send",			/*  3 - RPC_CANTSEND */
20021068Speter	"RPC: Unable to receive",		/*  4 - RPC_CANTRECV */
20121068Speter	"RPC: Timed out",			/*  5 - RPC_TIMEDOUT */
20221068Speter	"RPC: Incompatible versions of RPC",	/*  6 - RPC_VERSMISMATCH */
20321068Speter	"RPC: Authentication error",		/*  7 - RPC_AUTHERROR */
20421068Speter	"RPC: Program unavailable",		/*  8 - RPC_PROGUNAVAIL */
20521068Speter	"RPC: Program/version mismatch",	/*  9 - RPC_PROGVERSMISMATCH */
20621068Speter	"RPC: Procedure unavailable",		/* 10 - RPC_PROCUNAVAIL */
20721068Speter	"RPC: Server can't decode arguments",	/* 11 - RPC_CANTDECODEARGS */
20821068Speter	"RPC: Remote system error",		/* 12 - RPC_SYSTEMERROR */
20921068Speter	"RPC: Unknown host",			/* 13 - RPC_UNKNOWNHOST */
21021068Speter	"RPC: Port mapper failure",		/* 14 - RPC_PMAPFAILURE */
21121068Speter	"RPC: Program not registered",		/* 15 - RPC_PROGNOTREGISTERED */
21221068Speter	"RPC: Failed (unspecified error)",	/* 16 - RPC_FAILED */
21321068Speter	"RPC: Unknown protocol"			/* 17 - RPC_UNKNOWNPROTO */
2141901Swollman};
2151901Swollman
2161901Swollman
2171901Swollman/*
2181901Swollman * This interface for use by clntrpc
2191901Swollman */
2201901Swollmanchar *
2211901Swollmanclnt_sperrno(stat)
2221901Swollman	enum clnt_stat stat;
2231901Swollman{
22421068Speter	unsigned int errnum = stat;
2251901Swollman
22621068Speter	if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
22774462Salfred		/* LINTED interface problem */
22821068Speter		return (char *)rpc_errlist[errnum];
22921068Speter
2301901Swollman	return ("RPC: (unknown error code)");
2311901Swollman}
2321901Swollman
2331901Swollmanvoid
2341901Swollmanclnt_perrno(num)
2351901Swollman	enum clnt_stat num;
2361901Swollman{
23774462Salfred	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
2381901Swollman}
2391901Swollman
2401901Swollman
2411901Swollmanchar *
2421901Swollmanclnt_spcreateerror(s)
24374462Salfred	const char *s;
2441901Swollman{
245241007Spfg	char *str;
24674462Salfred	size_t len, i;
2471901Swollman
24874462Salfred	assert(s != NULL);
24974462Salfred
25074462Salfred	str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
2511901Swollman	if (str == 0)
2521901Swollman		return(0);
25374462Salfred	len = CLNT_PERROR_BUFLEN;
25474462Salfred	i = snprintf(str, len, "%s: ", s);
25581966Sbrian	if (i > 0)
25681966Sbrian		len -= i;
25774462Salfred	(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
2581901Swollman	switch (rpc_createerr.cf_stat) {
2591901Swollman	case RPC_PMAPFAILURE:
26074462Salfred		(void) strncat(str, " - ", len - 1);
261241007Spfg		(void) strncat(str,
262241007Spfg		    clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
2631901Swollman		break;
2641901Swollman
2651901Swollman	case RPC_SYSTEMERROR:
26674462Salfred		(void)strncat(str, " - ", len - 1);
26774462Salfred		(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
26874462Salfred		    len - 4);
2691901Swollman		break;
27074462Salfred
27174462Salfred	case RPC_CANTSEND:
27274462Salfred	case RPC_CANTDECODERES:
27374462Salfred	case RPC_CANTENCODEARGS:
27474462Salfred	case RPC_SUCCESS:
27574462Salfred	case RPC_UNKNOWNPROTO:
27674462Salfred	case RPC_PROGNOTREGISTERED:
27774462Salfred	case RPC_FAILED:
27874462Salfred	case RPC_UNKNOWNHOST:
27974462Salfred	case RPC_CANTDECODEARGS:
28074462Salfred	case RPC_PROCUNAVAIL:
28174462Salfred	case RPC_PROGVERSMISMATCH:
28274462Salfred	case RPC_PROGUNAVAIL:
28374462Salfred	case RPC_AUTHERROR:
28474462Salfred	case RPC_VERSMISMATCH:
28574462Salfred	case RPC_TIMEDOUT:
28674462Salfred	case RPC_CANTRECV:
28716283Sjraynard	default:
28816283Sjraynard		break;
2891901Swollman	}
29021068Speter	str[CLNT_PERROR_BUFLEN-1] = '\0';
2911901Swollman	return (str);
2921901Swollman}
2931901Swollman
2941901Swollmanvoid
2951901Swollmanclnt_pcreateerror(s)
29674462Salfred	const char *s;
2971901Swollman{
29874462Salfred
29974462Salfred	assert(s != NULL);
30074462Salfred
30174462Salfred	(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
3021901Swollman}
3031901Swollman
30421068Speterstatic const char *const auth_errlist[] = {
30521068Speter	"Authentication OK",			/* 0 - AUTH_OK */
30621068Speter	"Invalid client credential",		/* 1 - AUTH_BADCRED */
30721068Speter	"Server rejected credential",		/* 2 - AUTH_REJECTEDCRED */
30874462Salfred	"Invalid client verifier", 		/* 3 - AUTH_BADVERF */
30974462Salfred	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
31021068Speter	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
31121068Speter	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
312181344Sdfr	"Failed (unspecified error)",		/* 7 - AUTH_FAILED */
313181344Sdfr	"Kerberos generic error",		/* 8 - AUTH_KERB_GENERIC*/
314181344Sdfr	"Kerberos credential expired",		/* 9 - AUTH_TIMEEXPIRE */
315181344Sdfr	"Bad kerberos ticket file",		/* 10 - AUTH_TKT_FILE */
316181344Sdfr	"Can't decode kerberos authenticator",	/* 11 - AUTH_DECODE */
317181344Sdfr	"Address wrong in kerberos ticket",	/* 12 - AUTH_NET_ADDR */
318181344Sdfr	"GSS-API crediential problem",		/* 13 - RPCSEC_GSS_CREDPROBLEM */
319181344Sdfr	"GSS-API context problem"		/* 14 - RPCSEC_GSS_CTXPROBLEM */
3201901Swollman};
3211901Swollman
3221901Swollmanstatic char *
3231901Swollmanauth_errmsg(stat)
3241901Swollman	enum auth_stat stat;
3251901Swollman{
32621068Speter	unsigned int errnum = stat;
3271901Swollman
32821068Speter	if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
32974462Salfred		/* LINTED interface problem */
33021068Speter		return (char *)auth_errlist[errnum];
33121068Speter
3321901Swollman	return(NULL);
3331901Swollman}
334