1 /* $NetBSD: clnt_perror.c,v 1.29 2012/03/20 17:14:50 matt 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.29 2012/03/20 17:14:50 matt 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(void); 73 static char *auth_errmsg(enum auth_stat); 74 75 static char * 76 _buf(void) 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(CLIENT *rpch, const char *s) 90 { 91 struct rpc_err e; 92 char *err; 93 char *str; 94 char *strstart; 95 size_t len, i; 96 97 _DIAGASSERT(rpch != NULL); 98 _DIAGASSERT(s != NULL); 99 100 str = _buf(); /* side effect: sets "buflen" */ 101 if (str == 0) 102 return (0); 103 len = buflen; 104 strstart = str; 105 CLNT_GETERR(rpch, &e); 106 107 i = snprintf(str, len, "%s: ", s); 108 str += i; 109 len -= i; 110 111 (void)strncpy(str, clnt_sperrno(e.re_status), len - 1); 112 i = strlen(str); 113 str += i; 114 len -= i; 115 116 switch (e.re_status) { 117 case RPC_SUCCESS: 118 case RPC_CANTENCODEARGS: 119 case RPC_CANTDECODERES: 120 case RPC_TIMEDOUT: 121 case RPC_PROGUNAVAIL: 122 case RPC_PROCUNAVAIL: 123 case RPC_CANTDECODEARGS: 124 case RPC_SYSTEMERROR: 125 case RPC_UNKNOWNHOST: 126 case RPC_UNKNOWNPROTO: 127 case RPC_PMAPFAILURE: 128 case RPC_PROGNOTREGISTERED: 129 case RPC_FAILED: 130 break; 131 132 case RPC_CANTSEND: 133 case RPC_CANTRECV: 134 i = snprintf(str, len, "; errno = %s", strerror(e.re_errno)); 135 str += i; 136 len -= i; 137 break; 138 139 case RPC_VERSMISMATCH: 140 i = snprintf(str, len, "; low version = %u, high version = %u", 141 e.re_vers.low, e.re_vers.high); 142 str += i; 143 len -= i; 144 break; 145 146 case RPC_AUTHERROR: 147 err = auth_errmsg(e.re_why); 148 i = snprintf(str, len, "; why = "); 149 str += i; 150 len -= i; 151 if (err != NULL) { 152 i = snprintf(str, len, "%s",err); 153 } else { 154 i = snprintf(str, len, 155 "(unknown authentication error - %d)", 156 (int) e.re_why); 157 } 158 str += i; 159 len -= i; 160 break; 161 162 case RPC_PROGVERSMISMATCH: 163 i = snprintf(str, len, "; low version = %u, high version = %u", 164 e.re_vers.low, e.re_vers.high); 165 str += i; 166 len -= i; 167 break; 168 169 default: /* unknown */ 170 i = snprintf(str, len, "; s1 = %u, s2 = %u", 171 e.re_lb.s1, e.re_lb.s2); 172 str += i; 173 len -= i; 174 break; 175 } 176 return(strstart) ; 177 } 178 179 void 180 clnt_perror(CLIENT *rpch, const char *s) 181 { 182 183 _DIAGASSERT(rpch != NULL); 184 _DIAGASSERT(s != NULL); 185 186 (void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s)); 187 } 188 189 static const char *const rpc_errlist[] = { 190 [RPC_SUCCESS] = "RPC: Success", 191 [RPC_CANTENCODEARGS] = "RPC: Can't encode arguments", 192 [RPC_CANTDECODERES] = "RPC: Can't decode result", 193 [RPC_CANTSEND] = "RPC: Unable to send", 194 [RPC_CANTRECV] = "RPC: Unable to receive", 195 [RPC_TIMEDOUT] = "RPC: Timed out", 196 [RPC_VERSMISMATCH] = "RPC: Incompatible versions of RPC", 197 [RPC_AUTHERROR] = "RPC: Authentication error", 198 [RPC_PROGUNAVAIL] = "RPC: Program unavailable", 199 [RPC_PROGVERSMISMATCH] = "RPC: Program/version mismatch", 200 [RPC_PROCUNAVAIL] = "RPC: Procedure unavailable", 201 [RPC_CANTDECODEARGS] = "RPC: Server can't decode arguments", 202 [RPC_SYSTEMERROR] = "RPC: Remote system error", 203 [RPC_UNKNOWNHOST] = "RPC: Unknown host", 204 [RPC_PMAPFAILURE] = "RPC: Port mapper failure", 205 [RPC_PROGNOTREGISTERED] = "RPC: Program not registered", 206 [RPC_FAILED] = "RPC: Failed (unspecified error)", 207 [RPC_UNKNOWNPROTO] = "RPC: Unknown protocol", 208 [RPC_UNKNOWNADDR] = "RPC: Remote address unknown", 209 [RPC_TLIERROR] = "RPC: Misc error in the TLI library", 210 [RPC_NOBROADCAST] = "RPC: Broadcasting not supported", 211 [RPC_N2AXLATEFAILURE] = "RPC: Name -> addr translation failed", 212 [RPC_INPROGRESS] = "RPC: In progress", 213 [RPC_STALERACHANDLE] = "RPC: Stale handle", 214 }; 215 216 217 /* 218 * This interface for use by clntrpc 219 */ 220 char * 221 clnt_sperrno(enum clnt_stat stat) 222 { 223 unsigned int errnum = stat; 224 const char *msg; 225 226 msg = NULL; 227 if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0]))) { 228 msg = rpc_errlist[errnum]; 229 } 230 if (msg == NULL) { 231 msg = "RPC: (unknown error code)"; 232 } 233 return __UNCONST(msg); 234 } 235 236 void 237 clnt_perrno(enum clnt_stat num) 238 { 239 (void) fprintf(stderr, "%s\n", clnt_sperrno(num)); 240 } 241 242 243 char * 244 clnt_spcreateerror(const char *s) 245 { 246 char *str; 247 size_t len, i; 248 249 _DIAGASSERT(s != NULL); 250 251 str = _buf(); /* side effect: sets "buflen" */ 252 if (str == 0) 253 return(0); 254 len = buflen; 255 i = snprintf(str, len, "%s: ", s); 256 len -= i; 257 (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1); 258 switch (rpc_createerr.cf_stat) { 259 case RPC_PMAPFAILURE: 260 (void) strncat(str, " - ", len - 1); 261 (void) strncat(str, 262 clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4); 263 break; 264 265 case RPC_SYSTEMERROR: 266 (void)strncat(str, " - ", len - 1); 267 (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno), 268 len - 4); 269 break; 270 271 case RPC_CANTSEND: 272 case RPC_CANTDECODERES: 273 case RPC_CANTENCODEARGS: 274 case RPC_SUCCESS: 275 case RPC_UNKNOWNPROTO: 276 case RPC_PROGNOTREGISTERED: 277 case RPC_FAILED: 278 case RPC_UNKNOWNHOST: 279 case RPC_CANTDECODEARGS: 280 case RPC_PROCUNAVAIL: 281 case RPC_PROGVERSMISMATCH: 282 case RPC_PROGUNAVAIL: 283 case RPC_AUTHERROR: 284 case RPC_VERSMISMATCH: 285 case RPC_TIMEDOUT: 286 case RPC_CANTRECV: 287 default: 288 break; 289 } 290 return (str); 291 } 292 293 void 294 clnt_pcreateerror(const char *s) 295 { 296 297 _DIAGASSERT(s != NULL); 298 299 (void) fprintf(stderr, "%s\n", clnt_spcreateerror(s)); 300 } 301 302 static const char *const auth_errlist[] = { 303 "Authentication OK", /* 0 - AUTH_OK */ 304 "Invalid client credential", /* 1 - AUTH_BADCRED */ 305 "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */ 306 "Invalid client verifier", /* 3 - AUTH_BADVERF */ 307 "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */ 308 "Client credential too weak", /* 5 - AUTH_TOOWEAK */ 309 "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */ 310 "Failed (unspecified error)" /* 7 - AUTH_FAILED */ 311 }; 312 313 static char * 314 auth_errmsg(enum auth_stat stat) 315 { 316 unsigned int errnum = stat; 317 318 if (errnum < __arraycount(auth_errlist)) 319 return __UNCONST(auth_errlist[errnum]); 320 321 return(NULL); 322 } 323