GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/rpc/clnt_perror.c Lines: 0 61 0.0 %
Date: 2017-11-07 Branches: 0 62 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: clnt_perror.c,v 1.24 2015/09/13 15:36:56 guenther Exp $ */
2
3
/*
4
 * Copyright (c) 2010, Oracle America, Inc.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are
8
 * met:
9
 *
10
 *     * Redistributions of source code must retain the above copyright
11
 *       notice, this list of conditions and the following disclaimer.
12
 *     * Redistributions in binary form must reproduce the above
13
 *       copyright notice, this list of conditions and the following
14
 *       disclaimer in the documentation and/or other materials
15
 *       provided with the distribution.
16
 *     * Neither the name of the "Oracle America, Inc." nor the names of its
17
 *       contributors may be used to endorse or promote products derived
18
 *       from this software without specific prior written permission.
19
 *
20
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
 *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27
 *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
 *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
 *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
 *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 */
33
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <rpc/rpc.h>
38
#include <rpc/types.h>
39
#include <rpc/auth.h>
40
#include <rpc/clnt.h>
41
42
static char *auth_errmsg(enum auth_stat stat);
43
#define CLNT_PERROR_BUFLEN 256
44
45
static char buf[CLNT_PERROR_BUFLEN];
46
47
/*
48
 * Print reply error info
49
 */
50
char *
51
clnt_sperror(CLIENT *rpch, char *s)
52
{
53
	char *err, *str = buf;
54
	struct rpc_err e;
55
	int ret, len = CLNT_PERROR_BUFLEN;
56
57
	CLNT_GETERR(rpch, &e);
58
59
	ret = snprintf(str, len, "%s: %s", s, clnt_sperrno(e.re_status));
60
	if (ret == -1)
61
		ret = 0;
62
	else if (ret >= len)
63
		goto truncated;
64
	str += ret;
65
	len -= ret;
66
67
	switch (e.re_status) {
68
	case RPC_SUCCESS:
69
	case RPC_CANTENCODEARGS:
70
	case RPC_CANTDECODERES:
71
	case RPC_TIMEDOUT:
72
	case RPC_PROGUNAVAIL:
73
	case RPC_PROCUNAVAIL:
74
	case RPC_CANTDECODEARGS:
75
	case RPC_SYSTEMERROR:
76
	case RPC_UNKNOWNHOST:
77
	case RPC_UNKNOWNPROTO:
78
	case RPC_PMAPFAILURE:
79
	case RPC_PROGNOTREGISTERED:
80
	case RPC_FAILED:
81
		break;
82
83
	case RPC_CANTSEND:
84
	case RPC_CANTRECV:
85
		ret = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
86
		if (ret == -1 || ret >= len)
87
			goto truncated;
88
		break;
89
90
	case RPC_VERSMISMATCH:
91
		ret = snprintf(str, len,
92
		    "; low version = %u, high version = %u",
93
		    e.re_vers.low, e.re_vers.high);
94
		if (ret == -1 || ret >= len)
95
			goto truncated;
96
		break;
97
98
	case RPC_AUTHERROR:
99
		ret = snprintf(str, len, "; why = ");
100
		if (ret == -1)
101
			ret = 0;
102
		else if (ret >= len)
103
			goto truncated;
104
		str += ret;
105
		len -= ret;
106
		err = auth_errmsg(e.re_why);
107
		if (err != NULL) {
108
			ret = snprintf(str, len, "%s", err);
109
			if (ret == -1 || ret >= len)
110
				goto truncated;
111
		} else {
112
			ret = snprintf(str, len,
113
			    "(unknown authentication error - %d)",
114
			    (int) e.re_why);
115
			if (ret == -1 || ret >= len)
116
				goto truncated;
117
		}
118
		break;
119
120
	case RPC_PROGVERSMISMATCH:
121
		ret = snprintf(str, len,
122
		    "; low version = %u, high version = %u",
123
		    e.re_vers.low, e.re_vers.high);
124
		if (ret == -1 || ret >= len)
125
			goto truncated;
126
		break;
127
128
	default:	/* unknown */
129
		ret = snprintf(str, len, "; s1 = %u, s2 = %u",
130
		    e.re_lb.s1, e.re_lb.s2);
131
		if (ret == -1 || ret >= len)
132
			goto truncated;
133
		break;
134
	}
135
	if (strlcat(buf, "\n", CLNT_PERROR_BUFLEN) >= CLNT_PERROR_BUFLEN)
136
		goto truncated;
137
	return (buf);
138
139
truncated:
140
	snprintf(buf + CLNT_PERROR_BUFLEN - 5, 5, "...\n");
141
	return (buf);
142
}
143
DEF_WEAK(clnt_sperror);
144
145
void
146
clnt_perror(CLIENT *rpch, char *s)
147
{
148
	(void) fprintf(stderr, "%s", clnt_sperror(rpch, s));
149
}
150
DEF_WEAK(clnt_perror);
151
152
static const char *const rpc_errlist[] = {
153
	"RPC: Success",				/*  0 - RPC_SUCCESS */
154
	"RPC: Can't encode arguments",		/*  1 - RPC_CANTENCODEARGS */
155
	"RPC: Can't decode result",		/*  2 - RPC_CANTDECODERES */
156
	"RPC: Unable to send",			/*  3 - RPC_CANTSEND */
157
	"RPC: Unable to receive",		/*  4 - RPC_CANTRECV */
158
	"RPC: Timed out",			/*  5 - RPC_TIMEDOUT */
159
	"RPC: Incompatible versions of RPC",	/*  6 - RPC_VERSMISMATCH */
160
	"RPC: Authentication error",		/*  7 - RPC_AUTHERROR */
161
	"RPC: Program unavailable",		/*  8 - RPC_PROGUNAVAIL */
162
	"RPC: Program/version mismatch",	/*  9 - RPC_PROGVERSMISMATCH */
163
	"RPC: Procedure unavailable",		/* 10 - RPC_PROCUNAVAIL */
164
	"RPC: Server can't decode arguments",	/* 11 - RPC_CANTDECODEARGS */
165
	"RPC: Remote system error",		/* 12 - RPC_SYSTEMERROR */
166
	"RPC: Unknown host",			/* 13 - RPC_UNKNOWNHOST */
167
	"RPC: Port mapper failure",		/* 14 - RPC_PMAPFAILURE */
168
	"RPC: Program not registered",		/* 15 - RPC_PROGNOTREGISTERED */
169
	"RPC: Failed (unspecified error)",	/* 16 - RPC_FAILED */
170
	"RPC: Unknown protocol"			/* 17 - RPC_UNKNOWNPROTO */
171
};
172
173
174
/*
175
 * This interface for use by clntrpc
176
 */
177
char *
178
clnt_sperrno(enum clnt_stat stat)
179
{
180
	unsigned int errnum = stat;
181
182
	if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
183
		return (char *)rpc_errlist[errnum];
184
185
	return ("RPC: (unknown error code)");
186
}
187
DEF_WEAK(clnt_sperrno);
188
189
void
190
clnt_perrno(enum clnt_stat num)
191
{
192
	(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
193
}
194
195
196
char *
197
clnt_spcreateerror(char *s)
198
{
199
	switch (rpc_createerr.cf_stat) {
200
	case RPC_PMAPFAILURE:
201
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
202
		    clnt_sperrno(rpc_createerr.cf_stat),
203
		    clnt_sperrno(rpc_createerr.cf_error.re_status));
204
		break;
205
206
	case RPC_SYSTEMERROR:
207
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
208
		    clnt_sperrno(rpc_createerr.cf_stat),
209
		    strerror(rpc_createerr.cf_error.re_errno));
210
		break;
211
212
	default:
213
		(void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
214
		    clnt_sperrno(rpc_createerr.cf_stat));
215
		break;
216
	}
217
	buf[CLNT_PERROR_BUFLEN-2] = '\n';
218
	buf[CLNT_PERROR_BUFLEN-1] = '\0';
219
	return (buf);
220
}
221
DEF_WEAK(clnt_spcreateerror);
222
223
void
224
clnt_pcreateerror(char *s)
225
{
226
	fprintf(stderr, "%s", clnt_spcreateerror(s));
227
}
228
DEF_WEAK(clnt_pcreateerror);
229
230
static const char *const auth_errlist[] = {
231
	"Authentication OK",			/* 0 - AUTH_OK */
232
	"Invalid client credential",		/* 1 - AUTH_BADCRED */
233
	"Server rejected credential",		/* 2 - AUTH_REJECTEDCRED */
234
	"Invalid client verifier", 		/* 3 - AUTH_BADVERF */
235
	"Server rejected verifier", 		/* 4 - AUTH_REJECTEDVERF */
236
	"Client credential too weak",		/* 5 - AUTH_TOOWEAK */
237
	"Invalid server verifier",		/* 6 - AUTH_INVALIDRESP */
238
	"Failed (unspecified error)"		/* 7 - AUTH_FAILED */
239
};
240
241
static char *
242
auth_errmsg(enum auth_stat stat)
243
{
244
	unsigned int errnum = stat;
245
246
	if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
247
		return (char *)auth_errlist[errnum];
248
249
	return (NULL);
250
}