char * clnt_spcreateerror( char *s) { char *str = _buf(); if (str == 0) return(0); (void) sprintf(str, "%s: ", s); (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) strcat(str, " - "); (void) strcat(str, clnt_sperrno(rpc_createerr.cf_error.re_status)); break; case RPC_SYSTEMERROR: { const char* errmsg = strerror(rpc_createerr.cf_error.re_errno); (void) strcat(str, " - "); if (NULL != errmsg) (void) strcat(str, errmsg); else (void) sprintf(&str[strlen(str)], "Error %d", rpc_createerr.cf_error.re_errno); break; } } (void) strcat(str, "\n"); return (str); }
char * clnt_spcreateerror (const char *msg) { char chrbuf[1024]; char *str = _buf (); char *cp; int len; struct rpc_createerr *ce; if (str == NULL) return NULL; ce = &get_rpc_createerr (); len = sprintf (str, "%s: ", msg); cp = str + len; cp = stpcpy (cp, clnt_sperrno (ce->cf_stat)); switch (ce->cf_stat) { case RPC_PMAPFAILURE: cp = stpcpy (stpcpy (cp, " - "), clnt_sperrno (ce->cf_error.re_status)); break; case RPC_SYSTEMERROR: cp = stpcpy (stpcpy (cp, " - "), __strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf)); break; default: break; } *cp = '\n'; *++cp = '\0'; return str; }
char * clnt_spcreateerror( const char *s) { char *str = _buf(); if (str == 0) return(0); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, clnt_sperrno(rpc_createerr.cf_stat), clnt_sperrno(rpc_createerr.cf_error.re_status)); break; case RPC_SYSTEMERROR: (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, clnt_sperrno(rpc_createerr.cf_stat), strerror(rpc_createerr.cf_error.re_errno)); break; default: (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s, clnt_sperrno(rpc_createerr.cf_stat)); break; } str[CLNT_PERROR_BUFLEN-2] = '\n'; str[CLNT_PERROR_BUFLEN-1] = '\0'; return (str); }
char * clnt_spcreateerror(char *s) { switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, clnt_sperrno(rpc_createerr.cf_stat), clnt_sperrno(rpc_createerr.cf_error.re_status)); break; case RPC_SYSTEMERROR: (void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s, clnt_sperrno(rpc_createerr.cf_stat), strerror(rpc_createerr.cf_error.re_errno)); break; default: (void) snprintf(buf, CLNT_PERROR_BUFLEN, "%s: %s\n", s, clnt_sperrno(rpc_createerr.cf_stat)); break; } buf[CLNT_PERROR_BUFLEN-2] = '\n'; buf[CLNT_PERROR_BUFLEN-1] = '\0'; return (buf); }
void clnt_perrno (enum clnt_stat num) { #ifdef USE_IN_LIBIO if (_IO_fwide (stderr, 0) > 0) (void) fwprintf (stderr, L"%s", clnt_sperrno (num)); else #endif (void) fputs (clnt_sperrno (num), stderr); }
char * clnt_spcreateerror(char *s) { char *str = get_buf(); char *strend; if (str == 0) return(0); strend = str+BUFSIZ; (void) snprintf(str, strend-str, "%s: ", s); str[BUFSIZ - 1] = '\0'; (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); (void) strncat(str, clnt_sperrno(rpc_createerr.cf_error.re_status), BUFSIZ - 1 - strlen(str)); break; case RPC_SYSTEMERROR: (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); { const char *m = strerror(rpc_createerr.cf_error.re_errno); if (m) (void) strncat(str, m, BUFSIZ - 1 - strlen(str)); else (void) snprintf(&str[strlen(str)], BUFSIZ - strlen(str), "Error %d", rpc_createerr.cf_error.re_errno); } break; case RPC_CANTSEND: case RPC_CANTDECODERES: case RPC_CANTENCODEARGS: case RPC_SUCCESS: case RPC_UNKNOWNPROTO: case RPC_PROGNOTREGISTERED: case RPC_FAILED: case RPC_UNKNOWNHOST: case RPC_CANTDECODEARGS: case RPC_PROCUNAVAIL: case RPC_PROGVERSMISMATCH: case RPC_PROGUNAVAIL: case RPC_AUTHERROR: case RPC_VERSMISMATCH: case RPC_TIMEDOUT: case RPC_CANTRECV: default: break; } (void) strncat(str, "\n", BUFSIZ - 1 - strlen(str)); return (str); }
char * clnt_spcreateerror(const char *s) { char *str; size_t len, i; assert(s != NULL); str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */ if (str == NULL) return(0); len = CLNT_PERROR_BUFLEN; i = snprintf(str, len, "%s: ", s); if (i > 0) len -= i; (void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) strncat(str, " - ", len - 1); (void) strncat(str, clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4); break; case RPC_SYSTEMERROR: (void)strncat(str, " - ", len - 1); (void)strncat(str, strerror(rpc_createerr.cf_error.re_errno), len - 4); break; case RPC_CANTSEND: case RPC_CANTDECODERES: case RPC_CANTENCODEARGS: case RPC_SUCCESS: case RPC_UNKNOWNPROTO: case RPC_PROGNOTREGISTERED: case RPC_FAILED: case RPC_UNKNOWNHOST: case RPC_CANTDECODEARGS: case RPC_PROCUNAVAIL: case RPC_PROGVERSMISMATCH: case RPC_PROGUNAVAIL: case RPC_AUTHERROR: case RPC_VERSMISMATCH: case RPC_TIMEDOUT: case RPC_CANTRECV: default: break; } str[CLNT_PERROR_BUFLEN-1] = '\0'; return (str); }
static int test_read_cb(nct_req_t *req) { test_read_priv_t *priv = req->req_priv; nct_mnt_t *mnt = req->req_mnt; nct_vn_t *vn = mnt->mnt_vn; off_t offset; XDR_DESTROY(&req->req_msg->msg_xdr); if (req->req_msg->msg_stat != RPC_SUCCESS) { eprint("read failed: %d %s\n", req->req_msg->msg_stat, clnt_sperrno(req->req_msg->msg_stat)); nct_req_free(req); return req->req_msg->msg_stat; } if (req->req_tsc_stop >= req->req_tsc_finish) { nct_req_free(req); return ETIMEDOUT; } offset = __sync_fetch_and_add(&priv->pr_offset, priv->pr_length); if (offset + priv->pr_length > vn->xvn_fattr.size) { offset = __sync_fetch_and_sub(&priv->pr_offset, priv->pr_offset); } nct_nfs_read3_encode(req, offset, priv->pr_length); nct_req_send(req); return 0; }
char * clnt_sperror(struct client *clnt, const char *msg) { /* FIXME should use snprintf instead sprintf */ static char buff[ERROR_STR_MAX_SZ]; struct rpc_err err; char *curr, *auth_msg; assert((clnt != NULL) && (msg != NULL)); clnt_geterr(clnt, &err); curr = buff; curr += sprintf(curr, "%s: %s", msg, clnt_sperrno(err.status)); switch (err.status) { default: curr += sprintf(curr, "; s1 = %u, s2 = %u", err.extra.mminfo.low, err.extra.mminfo.high); break; case RPC_SUCCESS: case RPC_CANTENCODEARGS: case RPC_CANTDECODERES: case RPC_TIMEDOUT: case RPC_PROGUNAVAIL: case RPC_PROCUNAVAIL: case RPC_CANTDECODEARGS: case RPC_SYSTEMERROR: case RPC_UNKNOWNHOST: case RPC_PMAPFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: case RPC_UNKNOWNPROTO: break; case RPC_CANTSEND: case RPC_CANTRECV: curr += sprintf(curr, "; errno = %s", strerror(err.extra.error)); break; case RPC_VERSMISMATCH: curr += sprintf(curr, "; low version = %u, high version = %u", err.extra.mminfo.low, err.extra.mminfo.high); break; case RPC_AUTHERROR: auth_msg = get_auth_msg(err.extra.reason); if (auth_msg != NULL) { curr += sprintf(curr, "; why = %s", auth_msg); } else { curr += sprintf(curr, "; why = (unknown authentication error - %d)", err.extra.reason); } break; case RPC_PROGVERSMISMATCH: curr += sprintf(curr, "; low version = %u, high version = %u", err.extra.mminfo.low, err.extra.mminfo.high); break; } assert(curr < buff + sizeof buff); // TODO remove this return buff; }
/* * init_nsm -- * Reset the NSM state-of-the-world and acquire its state. */ void init_nsm(void) { enum clnt_stat ret; my_id id; sm_stat stat; char name[] = "NFS NLM"; /* * !!! * The my_id structure isn't used by the SM_UNMON_ALL call, as far * as I know. Leave it empty for now. */ memset(&id, 0, sizeof(id)); id.my_name = name; /* * !!! * The statd program must already be registered when lockd runs. */ do { ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat); if (ret == RPC_PROGUNAVAIL) { syslog(LOG_WARNING, "%lu %s", SM_PROG, clnt_sperrno(ret)); sleep(2); continue; } break; } while (0); if (ret != 0) { syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); exit(1); } nsm_state = stat.state; /* setup constant data for SM_MON calls */ mon_host.mon_id.my_id.my_name = localhost; mon_host.mon_id.my_id.my_prog = NLM_PROG; mon_host.mon_id.my_id.my_vers = NLM_SM; mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY; /* bsdi addition */ }
/* * Send a product from file-descriptor to clnt using LDM-5 protocol. */ static void send_product_5(CLIENT *clnt, int fd, prod_info *infop) { static ldm_replyt reply; enum clnt_stat rpc_stat; datapkt pkt; ssize_t unsent; ssize_t nread; char buf[DBUFMAX]; rpc_stat = my_comingsoon_5(clnt, infop, DBUFMAX, &reply); if(rpc_stat != RPC_SUCCESS) { uerror("send_product_5: %s %s", infop->ident, clnt_sperrno(rpc_stat)); return; } /* else */ if(reply.code != OK) { if(reply.code == DONT_SEND) uinfo("send_product_5: %s: %s", infop->ident, s_ldm_errt(reply.code)); else uerror("send_product_5: %s: %s", infop->ident, s_ldm_errt(reply.code)); return; } pkt.signaturep = &infop->signature; pkt.pktnum = 0; for(unsent = (ssize_t)infop->sz; unsent > 0; unsent -= nread ) { nread = read(fd, buf, DBUFMAX); if(nread <= 0) { serror("read: %s (seqno %d)", infop->ident, infop->seqno); break; } /* else */ pkt.data.dbuf_len = (u_int)nread; pkt.data.dbuf_val = buf; rpc_stat = my_blkdata_5(clnt, &pkt, &reply); if(rpc_stat != RPC_SUCCESS) break; if(reply.code != OK) break; pkt.pktnum++; } }
/* * Create a unix style authenticator. * Returns an auth handle with the given stuff in it. */ AUTH * authunix_ncreate(char *machname, uid_t uid, gid_t gid, int len, gid_t *aup_gids) { struct audata *au = mem_alloc(sizeof(*au)); AUTH *auth = &au->au_auth; struct authunix_parms aup; struct timespec now; XDR xdrs; /* * Allocate and set up auth handle */ auth->ah_ops = authunix_ops(); auth->ah_private = NULL; auth->ah_error.re_status = RPC_SUCCESS; auth->ah_verf = au->au_shcred = _null_auth; auth->ah_refcnt = 1; au->au_shfaults = 0; /* * fill in param struct from the given params */ (void)clock_gettime(CLOCK_MONOTONIC_FAST, &now); aup.aup_time = now.tv_sec; aup.aup_machname = machname; aup.aup_uid = uid; aup.aup_gid = gid; aup.aup_len = (u_int) len; aup.aup_gids = aup_gids; /* * Serialize the parameters into origcred */ xdrmem_create(&xdrs, au->au_origcred.oa_body, MAX_AUTH_BYTES, XDR_ENCODE); if (!xdr_authunix_parms(&xdrs, &aup)) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "%s: %s", __func__, clnt_sperrno(RPC_CANTENCODEARGS)); auth->ah_error.re_status = RPC_CANTENCODEARGS; return (auth); } au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); au->au_origcred.oa_flavor = AUTH_UNIX; /* * set auth handle to reflect new cred. */ auth->ah_cred = au->au_origcred; /* auth_get not needed: ah_refcnt == 1, as desired */ marshal_new_auth(auth); /* */ return (auth); }
static void allhosts(void) { statstime host_stat; enum clnt_stat clnt_stat; clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_statstime, &host_stat, (resultproc_t)rstat_reply); if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) errx(1, "%s", clnt_sperrno(clnt_stat)); }
static int bind_tohost(struct sockaddr_in *sin, char *dom, char *server) { struct ypbind_setdom ypsd; struct in_addr iaddr; struct hostent *hp; struct timeval tv; CLIENT *client; int sock, port, r; port = getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP); if (port == 0) errx(1, "%s not running ypserv", server); port = htons(port); memset(&ypsd, 0, sizeof ypsd); if (inet_aton(server, &iaddr) == 0) { hp = gethostbyname(server); if (hp == NULL) errx(1, "can't find address for %s", server); memmove(&iaddr.s_addr, hp->h_addr, sizeof(iaddr.s_addr)); } ypsd.ypsetdom_domain = dom; bcopy(&iaddr.s_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr, sizeof(ypsd.ypsetdom_binding.ypbind_binding_addr)); bcopy(&port, &ypsd.ypsetdom_binding.ypbind_binding_port, sizeof(ypsd.ypsetdom_binding.ypbind_binding_port)); ypsd.ypsetdom_vers = YPVERS; tv.tv_sec = 15; tv.tv_usec = 0; sock = RPC_ANYSOCK; client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock); if (client == NULL) { warnx("can't yp_bind: reason: %s", yperr_string(YPERR_YPBIND)); return YPERR_YPBIND; } client->cl_auth = authunix_create_default(); r = clnt_call(client, YPBINDPROC_SETDOM, xdr_ypbind_setdom, &ypsd, xdr_void, NULL, tv); if (r) { warnx("Cannot ypset for domain %s on host %s: %s", dom, server, clnt_sperrno(r)); clnt_destroy(client); return YPERR_YPBIND; } clnt_destroy(client); return 0; }
static void allhosts(void) { utmpidlearr up; enum clnt_stat clnt_stat; bzero((char *)&up, sizeof(up)); clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE, RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_utmpidlearr, (char *)&up, (resultproc_t)rusers_reply); if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) errx(1, "%s", clnt_sperrno(clnt_stat)); }
int main(int argn, char *argc[]) { //Program parameters : argc[1] : HostName or Host IP // argc[2] : Server Program Number // other arguments depend on test case //run_mode can switch into stand alone program or program launch by shell script //1 : stand alone, debug mode, more screen information //0 : launch by shell script as test case, only one printf -> result status int run_mode = 0; int test_status = 1; //Default test result set to FAILED int progNum = atoi(argc[2]); char nettype[16] = "udp"; CLIENT *clnt = NULL; enum clnt_stat rslt; int recVar = -1; struct timeval total_timeout; char *chrRslt = NULL; if (run_mode == 1) { printf("Server : %s\n", argc[1]); printf("Server # %d\n", progNum); printf("Net : %s\n", nettype); } //Initialisation total_timeout.tv_sec = 1; total_timeout.tv_usec = 1;/**/ //First of all, create client using top level API clnt = clnt_create(argc[1], progNum, VERSNUM, nettype); //Then call remote procedure rslt = clnt_call((CLIENT *)clnt, PROCNUM, (xdrproc_t)xdr_int, (char *)&recVar, // xdr_in (xdrproc_t)xdr_int, (char *)&recVar, // xdr_out total_timeout); /**/ chrRslt = clnt_sperrno(rslt); //If we are here, test has passed test_status = (chrRslt == NULL); //This last printf gives the result status to the tests suite //normally should be 0: test has passed or 1: test has failed printf("%d\n", test_status); return test_status; }
char * clnt_spcreateerror(const char *msg) { /* FIXME should use snprintf instead sprintf */ static char buff[ERROR_STR_MAX_SZ]; char *curr; assert(msg != NULL); curr = buff; curr += sprintf(curr, "%s: %s", msg, clnt_sperrno(rpc_create_error.stat)); switch (rpc_create_error.stat) { default: break; case RPC_PMAPFAILURE: curr += sprintf(curr, " - %s", clnt_sperrno(rpc_create_error.err.status)); break; case RPC_SYSTEMERROR: curr += sprintf(curr, " - %s", strerror(rpc_create_error.err.extra.error)); break; } assert(curr < buff + sizeof buff); // TODO remove this return buff; }
static int lpm_call (int type, char *ip, char *op) { struct timeval tv; Parm *pm; if (type < LPMINIT || type > LPMMAXPROC) return 0; pm = &LpmParm[type]; if (!lpm_cl) if (!lpm_clnt_create ()) return 0; tv.tv_sec = 25; tv.tv_usec = 0; LpmRpcError = clnt_call (lpm_cl, type, (xdrproc_t)pm->ixdr, ip, (xdrproc_t)pm->oxdr, op, tv); if (LpmRpcError != RPC_SUCCESS) { strcpy (lpm_errmsg, clnt_sperrno (LpmRpcError)); switch (LpmRpcError) { default: return 0; case RPC_CANTSEND: /* failure in sending call */ case RPC_CANTRECV: /* failure in receiving result */ case RPC_TIMEDOUT: /* call timed out */ break; } lpm_clnt_create (); if (!lpm_cl) return 0; if (clnt_call (lpm_cl, type, (xdrproc_t)pm->ixdr, ip, (xdrproc_t)pm->oxdr, op, tv) != RPC_SUCCESS) return 0; } return 1; }
/* * Purpose: Transmit result for nlm4_xxx_msg pseudo-RPCs * Returns: Nothing - we have no idea if the datagram got there * Notes: clnt_call() will always fail (with timeout) as we are * calling it with timeout 0 as a hack to just issue a datagram * without expecting a result */ void transmit4_result(int opcode, nlm4_res *result, struct sockaddr_in *addr) { static char dummy; CLIENT *cli; struct timeval timeo; int success; if ((cli = get_client(addr, NLM_VERS4)) != NULL) { /* No timeout - not expecting response */ timerclear(&timeo); success = clnt_call(cli, opcode, xdr_nlm4_res, result, xdr_void, &dummy, timeo); if (debug_level > 2) syslog(LOG_DEBUG, "clnt_call returns %d(%s)", success, clnt_sperrno(success)); } }
static int my_hiya_5(CLIENT *clnt, prod_class_t **clsspp) { static ldm_replyt reply; enum clnt_stat rpc_stat; memset(&reply, 0, sizeof(ldm_replyt)); rpc_stat = clnt_call(clnt, HIYA, xdr_prod_class, (caddr_t)*clsspp, xdr_ldm_replyt, (caddr_t)&reply, timeo); if(rpc_stat != RPC_SUCCESS) { uerror("hiya %s: %s", remote, clnt_sperrno(rpc_stat)); return ECONNABORTED; /* Perhaps could be more descriptive */ } switch (reply.code) { case OK: break; case SHUTTING_DOWN: uerror("%s is shutting down", remote); return ECONNABORTED; case DONT_SEND: case RESTART: case REDIRECT: /* TODO */ default: uerror("%s: unexpected reply type %s", remote, s_ldm_errt(reply.code)); return ECONNABORTED; case RECLASS: *clsspp = reply.ldm_replyt_u.newclssp; clss_regcomp(*clsspp); /* N.B. we use the downstream patterns */ unotice("%s: reclass: %s", remote, s_prod_class(NULL, 0, *clsspp)); break; } return 0; }
/* * Check if the portmapper is running and reachable: 0==down, 1==up */ int check_pmap_up(char *host, struct sockaddr_in* sin) { CLIENT *client; enum clnt_stat clnt_stat = RPC_TIMEDOUT; /* assume failure */ int socket = RPC_ANYSOCK; struct timeval timeout; timeout.tv_sec = 2; timeout.tv_usec = 0; sin->sin_port = htons(PMAPPORT); client = clntudp_create(sin, PMAPPROG, PMAPVERS, timeout, &socket); if (client == (CLIENT *) NULL) { plog(XLOG_ERROR, "check_pmap_up: cannot create connection to contact portmapper on host \"%s\"%s", host, clnt_spcreateerror("")); return 0; } timeout.tv_sec = 6; /* Ping the portmapper on a remote system by calling the nullproc */ clnt_stat = clnt_call(client, PMAPPROC_NULL, (XDRPROC_T_TYPE) xdr_void, NULL, (XDRPROC_T_TYPE) xdr_void, NULL, timeout); clnt_destroy(client); close(socket); sin->sin_port = 0; if (clnt_stat == RPC_TIMEDOUT) { plog(XLOG_ERROR, "check_pmap_up: failed to contact portmapper on host \"%s\": %s", host, clnt_sperrno(clnt_stat)); return 0; } return 1; }
/* Convert RPC errors into strings */ static int rpc_strerror(int spos) { int cf_stat = rpc_createerr.cf_stat; int pos = 0, cf_errno = rpc_createerr.cf_error.re_errno; char *ptr, *estr = clnt_sperrno(cf_stat); char *tmp; if (estr) { if ((ptr = index(estr, ':'))) estr = ++ptr; tmp = &errbuf[spos]; if (cf_stat == RPC_SYSTEMERROR) pos = snprintf(tmp, (erreob - tmp), _("System Error: %s"), strerror(cf_errno)); else pos = snprintf(tmp, (erreob - tmp), _("RPC Error:%s"), estr); } return pos; }
/* * Print reply error info */ char * clnt_sperror (CLIENT * rpch, const char *msg) { char chrbuf[1024]; struct rpc_err e; char *err; char *str = _buf (); char *strstart = str; int len; if (str == NULL) return NULL; CLNT_GETERR (rpch, &e); len = sprintf (str, "%s: ", msg); str += len; (void) strcpy(str, clnt_sperrno(e.re_status)); str += strlen(str); switch (e.re_status) { case RPC_SUCCESS: case RPC_CANTENCODEARGS: case RPC_CANTDECODERES: case RPC_TIMEDOUT: case RPC_PROGUNAVAIL: case RPC_PROCUNAVAIL: case RPC_CANTDECODEARGS: case RPC_SYSTEMERROR: case RPC_UNKNOWNHOST: case RPC_UNKNOWNPROTO: case RPC_PMAPFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: break; case RPC_CANTSEND: case RPC_CANTRECV: strerror_r (e.re_errno, chrbuf, sizeof chrbuf); len = sprintf (str, "; errno = %s", chrbuf); str += len; break; case RPC_VERSMISMATCH: len= sprintf (str, _("; low version = %lu, high version = %lu"), e.re_vers.low, e.re_vers.high); str += len; break; case RPC_AUTHERROR: err = auth_errmsg (e.re_why); (void) strcpy(str, _("; why = ")); str += strlen(str); if (err != NULL) { (void) strcpy(str, err); str += strlen(str); } else { len = sprintf (str, _("(unknown authentication error - %d)"), (int) e.re_why); str += len; } break; case RPC_PROGVERSMISMATCH: len = sprintf (str, _("; low version = %lu, high version = %lu"), e.re_vers.low, e.re_vers.high); str += len; break; default: /* unknown */ len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2); str += len; break; } *str = '\n'; *++str = '\0'; return (strstart); }
static int do_rquota_user(struct fs_quota_root *root, uint64_t *bytes_value_r, uint64_t *bytes_limit_r, uint64_t *count_value_r, uint64_t *count_limit_r) { struct getquota_rslt result; struct getquota_args args; struct timeval timeout; enum clnt_stat call_status; CLIENT *cl; struct fs_quota_mountpoint *mount = root->mount; const char *host; char *path; path = strchr(mount->device_path, ':'); i_assert(path != NULL); host = t_strdup_until(mount->device_path, path); path++; /* For NFSv4, we send the filesystem path without initial /. Server prepends proper NFS pseudoroot automatically and uses this for detection of NFSv4 mounts. */ if (strcmp(root->mount->type, "nfs4") == 0) { while (*path == '/') path++; } if (root->root.quota->set->debug) { i_debug("quota-fs: host=%s, path=%s, uid=%s", host, path, dec2str(root->uid)); } /* clnt_create() polls for a while to establish a connection */ cl = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp"); if (cl == NULL) { i_error("quota-fs: could not contact RPC service on %s", host); return -1; } /* Establish some RPC credentials */ auth_destroy(cl->cl_auth); cl->cl_auth = authunix_create_default(); /* make the rquota call on the remote host */ args.gqa_pathp = path; args.gqa_uid = root->uid; timeout.tv_sec = RQUOTA_GETQUOTA_TIMEOUT_SECS; timeout.tv_usec = 0; call_status = clnt_call(cl, RQUOTAPROC_GETQUOTA, (xdrproc_t)xdr_getquota_args, (char *)&args, (xdrproc_t)xdr_getquota_rslt, (char *)&result, timeout); /* the result has been deserialized, let the client go */ auth_destroy(cl->cl_auth); clnt_destroy(cl); if (call_status != RPC_SUCCESS) { const char *rpc_error_msg = clnt_sperrno(call_status); i_error("quota-fs: remote rquota call failed: %s", rpc_error_msg); return -1; } switch (result.status) { case Q_OK: { rquota_get_result(&result.getquota_rslt_u.gqr_rquota, bytes_value_r, bytes_limit_r, count_value_r, count_limit_r); if (root->root.quota->set->debug) { i_debug("quota-fs: uid=%s, bytes=%llu/%llu files=%llu/%llu", dec2str(root->uid), (unsigned long long)*bytes_value_r, (unsigned long long)*bytes_limit_r, (unsigned long long)*count_value_r, (unsigned long long)*count_limit_r); } return 1; } case Q_NOQUOTA: if (root->root.quota->set->debug) { i_debug("quota-fs: uid=%s, limit=unlimited", dec2str(root->uid)); } fs_quota_root_disable(root, FALSE); return 0; case Q_EPERM: i_error("quota-fs: permission denied to rquota service"); return -1; default: i_error("quota-fs: unrecognized status code (%d) " "from rquota service", result.status); return -1; } }
int main(int argc, char *argv[]) { char *svraddr = NULL; CLIENT *clntp = NULL; char *fpath = NULL; char *name = NULL; struct mkdir3args args; struct diropres3 res; /*struct fattr *fattrp = NULL;*/ struct timeval to = {120, 0}; enum clnt_stat st; int err = 0; int argv_len = 0; struct hsfs_inode *parent = NULL ; struct hsfs_inode *new; cliname = basename (argv[0]); if (argc < 3) { err = EINVAL; fprintf(stderr, "%s $svraddr $fpath.\n", cliname); goto out; } parent = (struct hsfs_inode *) malloc(sizeof(struct hsfs_inode)); svraddr = argv[1]; fpath = argv[2]; name = argv[3]; clntp = clnt_create(svraddr, 100003, NFS_V3, "tcp"); if (NULL == clntp) { fprintf(stderr, "%s: Create handle to RPC server (%s, %u, %u) failed: (%s).\n", cliname,svraddr, NFSPROC3_MKDIR, NFS_V3, clnt_spcreateerror(cliname)); err = ENXIO; goto out; } memset (&args, 0, sizeof(args)); memset (&res, 0, sizeof(res)); args.where.name = fpath; //args.path.fpath_len = strlen(fpath); int st_tmp; size_t fh_len = 0; unsigned char *fh; st_tmp = map_path_to_nfs3fh(svraddr, fpath, &fh_len, &fh); args.where.dir.data.data_len = fh_len; args.where.dir.data.data_val = fh; parent->sb = (struct hsfs_super *) malloc(sizeof(struct hsfs_super)); if (NULL == parent->sb) { printf("No memory:parent->sb.\n"); } parent->sb->clntp = clntp; parent->fh.data.data_len = args.where.dir.data.data_len; parent->fh.data.data_val = args.where.dir.data.data_val; st = hsi_nfs3_rmdir(parent, name); if (st) { err = EIO; fprintf (stderr, "%s: Call RPC Server (%s, %u, %u) failure: (%s).\n", cliname, svraddr, NFSPROC3_MKDIR, NFS_V3,clnt_sperrno(st)); goto out; } if (0 == st){ printf("Rm ok!\n"); } out: free(parent->sb); free(parent); if (NULL != clntp) clnt_destroy(clntp); exit(st); }
/* * Print reply error info */ char * clnt_sperror( CLIENT *rpch, const char *s) { struct rpc_err e; char *err; char *str = _buf(); char *strstart = str; if (str == 0) return (0); CLNT_GETERR(rpch, &e); (void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status)); str += strlen(str); switch (e.re_status) { case RPC_SUCCESS: case RPC_CANTENCODEARGS: case RPC_CANTDECODERES: case RPC_TIMEDOUT: case RPC_PROGUNAVAIL: case RPC_PROCUNAVAIL: case RPC_CANTDECODEARGS: case RPC_SYSTEMERROR: case RPC_UNKNOWNHOST: case RPC_UNKNOWNPROTO: case RPC_PMAPFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: break; case RPC_CANTSEND: case RPC_CANTRECV: (void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart), "; errno = %s\n", strerror(e.re_errno)); break; case RPC_VERSMISMATCH: (void) sprintf(str, "; low version = %lu, high version = %lu\n", (u_long)e.re_vers.low, (u_long)e.re_vers.high); break; case RPC_AUTHERROR: err = auth_errmsg(e.re_why); (void) sprintf(str,"; why = "); str += strlen(str); if (err != NULL) { (void) sprintf(str, "%s\n",err); } else { (void) sprintf(str, "(unknown authentication error - %d)\n", (int) e.re_why); } break; case RPC_PROGVERSMISMATCH: (void) sprintf(str, "; low version = %lu, high version = %lu\n", (u_long)e.re_vers.low, (u_long)e.re_vers.high); break; default: /* unknown */ (void) sprintf(str, "; s1 = %lu, s2 = %lu\n", (long)e.re_lb.s1, (long)e.re_lb.s2); break; } strstart[CLNT_PERROR_BUFLEN-2] = '\n'; strstart[CLNT_PERROR_BUFLEN-1] = '\0'; return(strstart) ; }
void clnt_perrno( enum clnt_stat num) { (void) fprintf(stderr,"%s\n",clnt_sperrno(num)); }
/* * Tell mountd we're done. * This is not quite right, because we may still * have other filesystems mounted, but the existing * mountd protocol is badly broken anyway. */ static void amfs_host_umounted(mntfs *mf) { char *host; CLIENT *client; enum clnt_stat clnt_stat; struct sockaddr_in sin; int sock = RPC_ANYSOCK; struct timeval tv; u_long mnt_version; if (mf->mf_error || mf->mf_refc > 1 || !mf->mf_server) return; /* * WebNFS servers shouldn't ever get here. */ if (mf->mf_flags & MFF_WEBNFS) { plog(XLOG_ERROR, "amfs_host_umounted: cannot support WebNFS"); return; } /* * Take a copy of the server hostname, address, and NFS version * to mount version conversion. */ host = mf->mf_server->fs_host; sin = *mf->mf_server->fs_ip; plog(XLOG_INFO, "amfs_host_umounted: NFS version %d", (int) mf->mf_server->fs_version); #ifdef HAVE_FS_NFS3 if (mf->mf_server->fs_version == NFS_VERSION3) mnt_version = AM_MOUNTVERS3; else #endif /* HAVE_FS_NFS3 */ mnt_version = MOUNTVERS; /* * Create a client attached to mountd */ tv.tv_sec = 10; tv.tv_usec = 0; client = get_mount_client(host, &sin, &tv, &sock, mnt_version); if (client == NULL) { #ifdef HAVE_CLNT_SPCREATEERROR plog(XLOG_ERROR, "get_mount_client failed for %s: %s", host, clnt_spcreateerror("")); #else /* not HAVE_CLNT_SPCREATEERROR */ plog(XLOG_ERROR, "get_mount_client failed for %s", host); #endif /* not HAVE_CLNT_SPCREATEERROR */ goto out; } if (!nfs_auth) { if (make_nfs_auth()) goto out; } client->cl_auth = nfs_auth; dlog("Unmounting all from %s", host); clnt_stat = clnt_call(client, MOUNTPROC_UMNTALL, (XDRPROC_T_TYPE) xdr_void, 0, (XDRPROC_T_TYPE) xdr_void, 0, tv); if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_SYSTEMERROR) { /* RPC_SYSTEMERROR seems to be returned for no good reason ... */ const char *msg = clnt_sperrno(clnt_stat); plog(XLOG_ERROR, "unmount all from %s rpc failed: %s", host, msg); goto out; } out: if (sock != RPC_ANYSOCK) (void) amu_close(sock); if (client) clnt_destroy(client); }
static int amfs_host_mount(am_node *am, mntfs *mf) { struct timeval tv2; CLIENT *client; enum clnt_stat clnt_stat; int n_export; int j, k; exports exlist = 0, ex; exports *ep = NULL; am_nfs_handle_t *fp = NULL; char *host; int error = 0; struct sockaddr_in sin; int sock = RPC_ANYSOCK; int ok = FALSE; mntlist *mlist; char fs_name[MAXPATHLEN], *rfs_dir; char mntpt[MAXPATHLEN]; struct timeval tv; u_long mnt_version; /* * WebNFS servers don't necessarily run mountd. */ if (mf->mf_flags & MFF_WEBNFS) { plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS"); return EIO; } /* * Read the mount list */ mlist = read_mtab(mf->mf_mount, mnttab_file_name); #ifdef MOUNT_TABLE_ON_FILE /* * Unlock the mount list */ unlock_mntlist(); #endif /* MOUNT_TABLE_ON_FILE */ /* * Take a copy of the server hostname, address, and nfs version * to mount version conversion. */ host = mf->mf_server->fs_host; sin = *mf->mf_server->fs_ip; plog(XLOG_INFO, "amfs_host_mount: NFS version %d", (int) mf->mf_server->fs_version); #ifdef HAVE_FS_NFS3 if (mf->mf_server->fs_version == NFS_VERSION3) mnt_version = AM_MOUNTVERS3; else #endif /* HAVE_FS_NFS3 */ mnt_version = MOUNTVERS; /* * The original 10 second per try timeout is WAY too large, especially * if we're only waiting 10 or 20 seconds max for the response. * That would mean we'd try only once in 10 seconds, and we could * lose the transmit or receive packet, and never try again. * A 2-second per try timeout here is much more reasonable. * 09/28/92 Mike Mitchell, [email protected] */ tv.tv_sec = 2; tv.tv_usec = 0; /* * Create a client attached to mountd */ client = get_mount_client(host, &sin, &tv, &sock, mnt_version); if (client == NULL) { #ifdef HAVE_CLNT_SPCREATEERROR plog(XLOG_ERROR, "get_mount_client failed for %s: %s", host, clnt_spcreateerror("")); #else /* not HAVE_CLNT_SPCREATEERROR */ plog(XLOG_ERROR, "get_mount_client failed for %s", host); #endif /* not HAVE_CLNT_SPCREATEERROR */ error = EIO; goto out; } if (!nfs_auth) { error = make_nfs_auth(); if (error) goto out; } client->cl_auth = nfs_auth; dlog("Fetching export list from %s", host); /* * Fetch the export list */ tv2.tv_sec = 10; tv2.tv_usec = 0; clnt_stat = clnt_call(client, MOUNTPROC_EXPORT, (XDRPROC_T_TYPE) xdr_void, 0, (XDRPROC_T_TYPE) xdr_exports, (SVC_IN_ARG_TYPE) & exlist, tv2); if (clnt_stat != RPC_SUCCESS) { const char *msg = clnt_sperrno(clnt_stat); plog(XLOG_ERROR, "host_mount rpc failed: %s", msg); /* clnt_perror(client, "rpc"); */ error = EIO; goto out; } /* * Figure out how many exports were returned */ for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) { n_export++; } /* * Allocate an array of pointers into the list * so that they can be sorted. If the filesystem * is already mounted then ignore it. */ ep = (exports *) xmalloc(n_export * sizeof(exports)); for (j = 0, ex = exlist; ex; ex = ex->ex_next) { make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount); if (already_mounted(mlist, mntpt)) /* we have at least one mounted f/s, so don't fail the mount */ ok = TRUE; else ep[j++] = ex; } n_export = j; /* * Sort into order. * This way the mounts are done in order down the tree, * instead of any random order returned by the mount * daemon (the protocol doesn't specify...). */ qsort(ep, n_export, sizeof(exports), sortfun); /* * Allocate an array of filehandles */ fp = (am_nfs_handle_t *) xmalloc(n_export * sizeof(am_nfs_handle_t)); /* * Try to obtain filehandles for each directory. * If a fetch fails then just zero out the array * reference but discard the error. */ for (j = k = 0; j < n_export; j++) { /* Check and avoid a duplicated export entry */ if (j > k && ep[k] && STREQ(ep[j]->ex_dir, ep[k]->ex_dir)) { dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir); ep[j] = NULL; } else { k = j; error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j], mf->mf_server->fs_version); if (error) ep[j] = NULL; } } /* * Mount each filesystem for which we have a filehandle. * If any of the mounts succeed then mark "ok" and return * error code 0 at the end. If they all fail then return * the last error code. */ xstrlcpy(fs_name, mf->mf_info, sizeof(fs_name)); if ((rfs_dir = strchr(fs_name, ':')) == (char *) NULL) { plog(XLOG_FATAL, "amfs_host_mount: mf_info has no colon"); error = EINVAL; goto out; } ++rfs_dir; for (j = 0; j < n_export; j++) { ex = ep[j]; if (ex) { /* * Note: the sizeof space left in rfs_dir is what's left in fs_name * after strchr() above returned a pointer _inside_ fs_name. The * calculation below also takes into account that rfs_dir was * incremented by the ++ above. */ xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name)); make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount); if (do_mount(&fp[j], mntpt, fs_name, mf) == 0) ok = TRUE; } } /* * Clean up and exit */ out: discard_mntlist(mlist); XFREE(ep); XFREE(fp); if (sock != RPC_ANYSOCK) (void) amu_close(sock); if (client) clnt_destroy(client); if (exlist) xdr_pri_free((XDRPROC_T_TYPE) xdr_exports, (caddr_t) &exlist); if (ok) return 0; return error; }
/* * Get filehandle */ static int fetch_fhandle(CLIENT *client, char *dir, am_nfs_handle_t *fhp, u_long nfs_version) { struct timeval tv; enum clnt_stat clnt_stat; struct fhstatus res; #ifdef HAVE_FS_NFS3 struct am_mountres3 res3; #endif /* HAVE_FS_NFS3 */ /* * Pick a number, any number... */ tv.tv_sec = 20; tv.tv_usec = 0; dlog("Fetching fhandle for %s", dir); /* * Call the mount daemon on the remote host to * get the filehandle. Use NFS version specific call. */ plog(XLOG_INFO, "fetch_fhandle: NFS version %d", (int) nfs_version); #ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3 #ifdef HAVE_FS_NFS4 #ifndef NO_FALLBACK || nfs_version == NFS_VERSION4 #endif /* NO_FALLBACK */ #endif /* HAVE_FS_NFS4 */ ) { memset((char *) &res3, 0, sizeof(res3)); clnt_stat = clnt_call(client, MOUNTPROC_MNT, (XDRPROC_T_TYPE) xdr_dirpath, (SVC_IN_ARG_TYPE) &dir, (XDRPROC_T_TYPE) xdr_am_mountres3, (SVC_IN_ARG_TYPE) &res3, tv); if (clnt_stat != RPC_SUCCESS) { plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat)); return EIO; } /* Check the status of the filehandle */ if ((errno = res3.fhs_status)) { dlog("fhandle fetch for mount version 3 failed: %m"); return errno; } memset((voidp) &fhp->v3, 0, sizeof(am_nfs_fh3)); fhp->v3.am_fh3_length = res3.mountres3_u.mountinfo.fhandle.fhandle3_len; memmove(fhp->v3.am_fh3_data, res3.mountres3_u.mountinfo.fhandle.fhandle3_val, fhp->v3.am_fh3_length); } else { /* not NFS_VERSION3 mount */ #endif /* HAVE_FS_NFS3 */ clnt_stat = clnt_call(client, MOUNTPROC_MNT, (XDRPROC_T_TYPE) xdr_dirpath, (SVC_IN_ARG_TYPE) &dir, (XDRPROC_T_TYPE) xdr_fhstatus, (SVC_IN_ARG_TYPE) &res, tv); if (clnt_stat != RPC_SUCCESS) { plog(XLOG_ERROR, "mountd rpc failed: %s", clnt_sperrno(clnt_stat)); return EIO; } /* Check status of filehandle */ if (res.fhs_status) { errno = res.fhs_status; dlog("fhandle fetch for mount version 1 failed: %m"); return errno; } memmove(&fhp->v2, &res.fhs_fh, NFS_FHSIZE); #ifdef HAVE_FS_NFS3 } /* end of "if (nfs_version == NFS_VERSION3)" statement */ #endif /* HAVE_FS_NFS3 */ /* all is well */ return 0; }