1*47c0e0c3Stron /* $NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $ */
29e15c989Scgd
363d7b677Scgd /*
4*47c0e0c3Stron * Copyright (c) 2010, Oracle America, Inc.
563d7b677Scgd *
6*47c0e0c3Stron * Redistribution and use in source and binary forms, with or without
7*47c0e0c3Stron * modification, are permitted provided that the following conditions are
8*47c0e0c3Stron * met:
963d7b677Scgd *
10*47c0e0c3Stron * * Redistributions of source code must retain the above copyright
11*47c0e0c3Stron * notice, this list of conditions and the following disclaimer.
12*47c0e0c3Stron * * Redistributions in binary form must reproduce the above
13*47c0e0c3Stron * copyright notice, this list of conditions and the following
14*47c0e0c3Stron * disclaimer in the documentation and/or other materials
15*47c0e0c3Stron * provided with the distribution.
16*47c0e0c3Stron * * Neither the name of the "Oracle America, Inc." nor the names of its
17*47c0e0c3Stron * contributors may be used to endorse or promote products derived
18*47c0e0c3Stron * from this software without specific prior written permission.
1963d7b677Scgd *
20*47c0e0c3Stron * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*47c0e0c3Stron * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*47c0e0c3Stron * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*47c0e0c3Stron * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24*47c0e0c3Stron * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25*47c0e0c3Stron * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*47c0e0c3Stron * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27*47c0e0c3Stron * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28*47c0e0c3Stron * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29*47c0e0c3Stron * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30*47c0e0c3Stron * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*47c0e0c3Stron * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3263d7b677Scgd */
3363d7b677Scgd
34b8138fe7Schristos #include <sys/cdefs.h>
3563d7b677Scgd #if defined(LIBC_SCCS) && !defined(lint)
36b8138fe7Schristos #if 0
37b8138fe7Schristos static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
38b8138fe7Schristos static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";
39b8138fe7Schristos #else
40*47c0e0c3Stron __RCSID("$NetBSD: clnt_perror.c,v 1.30 2013/03/11 20:19:29 tron Exp $");
41b8138fe7Schristos #endif
4263d7b677Scgd #endif
4363d7b677Scgd
4463d7b677Scgd /*
4563d7b677Scgd * clnt_perror.c
4663d7b677Scgd *
4763d7b677Scgd * Copyright (C) 1984, Sun Microsystems, Inc.
4863d7b677Scgd *
4963d7b677Scgd */
5043fa6fe3Sjtc #include "namespace.h"
5146e6c5e8Slukem
52b48252f3Slukem #include <assert.h>
5363d7b677Scgd #include <stdio.h>
542e2a3a25Scgd #include <stdlib.h>
5563d7b677Scgd #include <string.h>
5646e6c5e8Slukem
5763d7b677Scgd #include <rpc/rpc.h>
5863d7b677Scgd #include <rpc/types.h>
5963d7b677Scgd #include <rpc/auth.h>
6063d7b677Scgd #include <rpc/clnt.h>
6163d7b677Scgd
6243fa6fe3Sjtc #ifdef __weak_alias
6360549036Smycroft __weak_alias(clnt_pcreateerror,_clnt_pcreateerror)
6460549036Smycroft __weak_alias(clnt_perrno,_clnt_perrno)
6560549036Smycroft __weak_alias(clnt_perror,_clnt_perror)
6660549036Smycroft __weak_alias(clnt_spcreateerror,_clnt_spcreateerror)
6760549036Smycroft __weak_alias(clnt_sperrno,_clnt_sperrno)
6860549036Smycroft __weak_alias(clnt_sperror,_clnt_sperror)
6943fa6fe3Sjtc #endif
7043fa6fe3Sjtc
7163d7b677Scgd static char *buf;
7228fbffc2Schristos static size_t buflen;
7363d7b677Scgd
74adb74221Smatt static char *_buf(void);
75adb74221Smatt static char *auth_errmsg(enum auth_stat);
76b8138fe7Schristos
7763d7b677Scgd static char *
_buf(void)78adb74221Smatt _buf(void)
7963d7b677Scgd {
8063d7b677Scgd
819cd5492cSmrg buflen = 256;
826c13a3b8Slukem if (buf == 0)
83c9cdc302Schristos buf = malloc(buflen);
8463d7b677Scgd return (buf);
8563d7b677Scgd }
8663d7b677Scgd
8763d7b677Scgd /*
8863d7b677Scgd * Print reply error info
8963d7b677Scgd */
9063d7b677Scgd char *
clnt_sperror(CLIENT * rpch,const char * s)91adb74221Smatt clnt_sperror(CLIENT *rpch, const char *s)
9263d7b677Scgd {
9363d7b677Scgd struct rpc_err e;
9463d7b677Scgd char *err;
95b48252f3Slukem char *str;
9693eb76ddSexplorer char *strstart;
9765bf8c30Sdrochner size_t len, i;
9863d7b677Scgd
99b48252f3Slukem _DIAGASSERT(rpch != NULL);
100b48252f3Slukem _DIAGASSERT(s != NULL);
101b48252f3Slukem
10265bf8c30Sdrochner str = _buf(); /* side effect: sets "buflen" */
103ce147c1cSlukem if (str == 0)
104ce147c1cSlukem return (0);
10565bf8c30Sdrochner len = buflen;
10693eb76ddSexplorer strstart = str;
10763d7b677Scgd CLNT_GETERR(rpch, &e);
10863d7b677Scgd
1099cd5492cSmrg i = snprintf(str, len, "%s: ", s);
1109cd5492cSmrg str += i;
1119cd5492cSmrg len -= i;
11263d7b677Scgd
1139cd5492cSmrg (void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
1149cd5492cSmrg i = strlen(str);
1159cd5492cSmrg str += i;
1169cd5492cSmrg len -= i;
11763d7b677Scgd
11863d7b677Scgd switch (e.re_status) {
11963d7b677Scgd case RPC_SUCCESS:
12063d7b677Scgd case RPC_CANTENCODEARGS:
12163d7b677Scgd case RPC_CANTDECODERES:
12263d7b677Scgd case RPC_TIMEDOUT:
12363d7b677Scgd case RPC_PROGUNAVAIL:
12463d7b677Scgd case RPC_PROCUNAVAIL:
12563d7b677Scgd case RPC_CANTDECODEARGS:
12663d7b677Scgd case RPC_SYSTEMERROR:
12763d7b677Scgd case RPC_UNKNOWNHOST:
12863d7b677Scgd case RPC_UNKNOWNPROTO:
12963d7b677Scgd case RPC_PMAPFAILURE:
13063d7b677Scgd case RPC_PROGNOTREGISTERED:
13163d7b677Scgd case RPC_FAILED:
13263d7b677Scgd break;
13363d7b677Scgd
13463d7b677Scgd case RPC_CANTSEND:
13563d7b677Scgd case RPC_CANTRECV:
1366c13a3b8Slukem i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
1379cd5492cSmrg str += i;
1389cd5492cSmrg len -= i;
13963d7b677Scgd break;
14063d7b677Scgd
14163d7b677Scgd case RPC_VERSMISMATCH:
1426c13a3b8Slukem i = snprintf(str, len, "; low version = %u, high version = %u",
14363d7b677Scgd e.re_vers.low, e.re_vers.high);
1449cd5492cSmrg str += i;
1459cd5492cSmrg len -= i;
14663d7b677Scgd break;
14763d7b677Scgd
14863d7b677Scgd case RPC_AUTHERROR:
14963d7b677Scgd err = auth_errmsg(e.re_why);
1509cd5492cSmrg i = snprintf(str, len, "; why = ");
1519cd5492cSmrg str += i;
1529cd5492cSmrg len -= i;
15363d7b677Scgd if (err != NULL) {
1549cd5492cSmrg i = snprintf(str, len, "%s",err);
15563d7b677Scgd } else {
1569cd5492cSmrg i = snprintf(str, len,
15763d7b677Scgd "(unknown authentication error - %d)",
15863d7b677Scgd (int) e.re_why);
15963d7b677Scgd }
1609cd5492cSmrg str += i;
1619cd5492cSmrg len -= i;
16263d7b677Scgd break;
16363d7b677Scgd
16463d7b677Scgd case RPC_PROGVERSMISMATCH:
1656c13a3b8Slukem i = snprintf(str, len, "; low version = %u, high version = %u",
16663d7b677Scgd e.re_vers.low, e.re_vers.high);
1679cd5492cSmrg str += i;
1689cd5492cSmrg len -= i;
16963d7b677Scgd break;
17063d7b677Scgd
17163d7b677Scgd default: /* unknown */
1726c13a3b8Slukem i = snprintf(str, len, "; s1 = %u, s2 = %u",
17363d7b677Scgd e.re_lb.s1, e.re_lb.s2);
1749cd5492cSmrg str += i;
1759cd5492cSmrg len -= i;
17663d7b677Scgd break;
17763d7b677Scgd }
17863d7b677Scgd return(strstart) ;
17963d7b677Scgd }
18063d7b677Scgd
18163d7b677Scgd void
clnt_perror(CLIENT * rpch,const char * s)182adb74221Smatt clnt_perror(CLIENT *rpch, const char *s)
18363d7b677Scgd {
184b48252f3Slukem
185b48252f3Slukem _DIAGASSERT(rpch != NULL);
186b48252f3Slukem _DIAGASSERT(s != NULL);
187b48252f3Slukem
1888453143fSjtc (void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
18963d7b677Scgd }
19063d7b677Scgd
19161207f14Sjtc static const char *const rpc_errlist[] = {
192b848cb99Syamt [RPC_SUCCESS] = "RPC: Success",
193b848cb99Syamt [RPC_CANTENCODEARGS] = "RPC: Can't encode arguments",
194b848cb99Syamt [RPC_CANTDECODERES] = "RPC: Can't decode result",
195b848cb99Syamt [RPC_CANTSEND] = "RPC: Unable to send",
196b848cb99Syamt [RPC_CANTRECV] = "RPC: Unable to receive",
197b848cb99Syamt [RPC_TIMEDOUT] = "RPC: Timed out",
198b848cb99Syamt [RPC_VERSMISMATCH] = "RPC: Incompatible versions of RPC",
199b848cb99Syamt [RPC_AUTHERROR] = "RPC: Authentication error",
200b848cb99Syamt [RPC_PROGUNAVAIL] = "RPC: Program unavailable",
201b848cb99Syamt [RPC_PROGVERSMISMATCH] = "RPC: Program/version mismatch",
202b848cb99Syamt [RPC_PROCUNAVAIL] = "RPC: Procedure unavailable",
203b848cb99Syamt [RPC_CANTDECODEARGS] = "RPC: Server can't decode arguments",
204b848cb99Syamt [RPC_SYSTEMERROR] = "RPC: Remote system error",
205b848cb99Syamt [RPC_UNKNOWNHOST] = "RPC: Unknown host",
206b848cb99Syamt [RPC_PMAPFAILURE] = "RPC: Port mapper failure",
207b848cb99Syamt [RPC_PROGNOTREGISTERED] = "RPC: Program not registered",
208b848cb99Syamt [RPC_FAILED] = "RPC: Failed (unspecified error)",
209b848cb99Syamt [RPC_UNKNOWNPROTO] = "RPC: Unknown protocol",
210b848cb99Syamt [RPC_UNKNOWNADDR] = "RPC: Remote address unknown",
211b848cb99Syamt [RPC_TLIERROR] = "RPC: Misc error in the TLI library",
212b848cb99Syamt [RPC_NOBROADCAST] = "RPC: Broadcasting not supported",
213b848cb99Syamt [RPC_N2AXLATEFAILURE] = "RPC: Name -> addr translation failed",
214b848cb99Syamt [RPC_INPROGRESS] = "RPC: In progress",
215b848cb99Syamt [RPC_STALERACHANDLE] = "RPC: Stale handle",
21663d7b677Scgd };
21763d7b677Scgd
21863d7b677Scgd
21963d7b677Scgd /*
22063d7b677Scgd * This interface for use by clntrpc
22163d7b677Scgd */
22263d7b677Scgd char *
clnt_sperrno(enum clnt_stat stat)223adb74221Smatt clnt_sperrno(enum clnt_stat stat)
22463d7b677Scgd {
22561207f14Sjtc unsigned int errnum = stat;
226b848cb99Syamt const char *msg;
22761207f14Sjtc
228b848cb99Syamt msg = NULL;
229b848cb99Syamt if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) {
230b848cb99Syamt msg = rpc_errlist[errnum];
231b848cb99Syamt }
232b848cb99Syamt if (msg == NULL) {
233b848cb99Syamt msg = "RPC: (unknown error code)";
234b848cb99Syamt }
235b848cb99Syamt return __UNCONST(msg);
23663d7b677Scgd }
23763d7b677Scgd
23863d7b677Scgd void
clnt_perrno(enum clnt_stat num)239adb74221Smatt clnt_perrno(enum clnt_stat num)
24063d7b677Scgd {
2418453143fSjtc (void) fprintf(stderr, "%s\n", clnt_sperrno(num));
24263d7b677Scgd }
24363d7b677Scgd
24463d7b677Scgd
24563d7b677Scgd char *
clnt_spcreateerror(const char * s)246adb74221Smatt clnt_spcreateerror(const char *s)
24763d7b677Scgd {
248b48252f3Slukem char *str;
24965bf8c30Sdrochner size_t len, i;
25063d7b677Scgd
251b48252f3Slukem _DIAGASSERT(s != NULL);
252b48252f3Slukem
25365bf8c30Sdrochner str = _buf(); /* side effect: sets "buflen" */
254ce147c1cSlukem if (str == 0)
255ce147c1cSlukem return(0);
25665bf8c30Sdrochner len = buflen;
2579cd5492cSmrg i = snprintf(str, len, "%s: ", s);
2589cd5492cSmrg len -= i;
2599cd5492cSmrg (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
26063d7b677Scgd switch (rpc_createerr.cf_stat) {
26163d7b677Scgd case RPC_PMAPFAILURE:
2629cd5492cSmrg (void) strncat(str, " - ", len - 1);
2639cd5492cSmrg (void) strncat(str,
2649cd5492cSmrg clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
26563d7b677Scgd break;
26663d7b677Scgd
26763d7b677Scgd case RPC_SYSTEMERROR:
2689cd5492cSmrg (void)strncat(str, " - ", len - 1);
2699cd5492cSmrg (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
2709cd5492cSmrg len - 4);
27163d7b677Scgd break;
272b8138fe7Schristos
273b8138fe7Schristos case RPC_CANTSEND:
274b8138fe7Schristos case RPC_CANTDECODERES:
275b8138fe7Schristos case RPC_CANTENCODEARGS:
276b8138fe7Schristos case RPC_SUCCESS:
277b8138fe7Schristos case RPC_UNKNOWNPROTO:
278b8138fe7Schristos case RPC_PROGNOTREGISTERED:
279b8138fe7Schristos case RPC_FAILED:
280b8138fe7Schristos case RPC_UNKNOWNHOST:
281b8138fe7Schristos case RPC_CANTDECODEARGS:
282b8138fe7Schristos case RPC_PROCUNAVAIL:
283b8138fe7Schristos case RPC_PROGVERSMISMATCH:
284b8138fe7Schristos case RPC_PROGUNAVAIL:
285b8138fe7Schristos case RPC_AUTHERROR:
286b8138fe7Schristos case RPC_VERSMISMATCH:
287b8138fe7Schristos case RPC_TIMEDOUT:
288b8138fe7Schristos case RPC_CANTRECV:
2897df0ccbaSfvdl default:
290b8138fe7Schristos break;
29163d7b677Scgd }
29263d7b677Scgd return (str);
29363d7b677Scgd }
29463d7b677Scgd
29563d7b677Scgd void
clnt_pcreateerror(const char * s)296adb74221Smatt clnt_pcreateerror(const char *s)
29763d7b677Scgd {
298b48252f3Slukem
299b48252f3Slukem _DIAGASSERT(s != NULL);
300b48252f3Slukem
3018453143fSjtc (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
30263d7b677Scgd }
30363d7b677Scgd
30461207f14Sjtc static const char *const auth_errlist[] = {
30561207f14Sjtc "Authentication OK", /* 0 - AUTH_OK */
30661207f14Sjtc "Invalid client credential", /* 1 - AUTH_BADCRED */
30761207f14Sjtc "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
30861207f14Sjtc "Invalid client verifier", /* 3 - AUTH_BADVERF */
30961207f14Sjtc "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
31061207f14Sjtc "Client credential too weak", /* 5 - AUTH_TOOWEAK */
31161207f14Sjtc "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
31261207f14Sjtc "Failed (unspecified error)" /* 7 - AUTH_FAILED */
31363d7b677Scgd };
31463d7b677Scgd
31563d7b677Scgd static char *
auth_errmsg(enum auth_stat stat)316adb74221Smatt auth_errmsg(enum auth_stat stat)
31763d7b677Scgd {
31861207f14Sjtc unsigned int errnum = stat;
31963d7b677Scgd
320adb74221Smatt if (errnum < __arraycount(auth_errlist))
32103256c6eSchristos return __UNCONST(auth_errlist[errnum]);
32261207f14Sjtc
32363d7b677Scgd return(NULL);
32463d7b677Scgd }
325