/* * find the IP address that can be used to connect autofs service to. */ static int get_autofs_address(struct netconfig *ncp, struct t_bind *tbp) { int ret; struct nd_addrlist *addrs = (struct nd_addrlist *) NULL; struct nd_hostserv service; service.h_host = HOST_SELF_CONNECT; service.h_serv = "autofs"; ret = netdir_getbyname(ncp, &service, &addrs); if (ret) { plog(XLOG_FATAL, "get_autofs_address: cannot get local host address: %s", netdir_sperror()); goto out; } /* * XXX: there may be more more than one address for this local * host. Maybe something can be done with those. */ tbp->addr.len = addrs->n_addrs->len; tbp->addr.maxlen = addrs->n_addrs->len; memcpy(tbp->addr.buf, addrs->n_addrs->buf, addrs->n_addrs->len); tbp->qlen = 8; /* arbitrary? who cares really */ /* all OK */ netdir_free((voidp) addrs, ND_ADDRLIST); out: return ret; }
/* * Return string reply error info. For use after clnt_call(). * It allocates the buffer of size MAXPATHLEN and assumes * caller's responsibility to free the memory after use. */ char * clnt_sperror(const CLIENT *cl, const char *s) { struct rpc_err e; #ifdef notyet char *err; #endif char *str; char *strstart; str = kmem_alloc(MAXPATHLEN, KM_SLEEP); strstart = str; CLNT_GETERR((CLIENT *) cl, &e); (void) sprintf(str, "%s: ", s); str += strlen(str); (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_UNKNOWNADDR: case RPC_NOBROADCAST: case RPC_RPCBFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: case RPC_INPROGRESS: break; #ifdef notyet case RPC_N2AXLATEFAILURE: (void) sprintf(str, "; %s", netdir_sperror()); break; #endif case RPC_TLIERROR: #ifdef notyet (void) sprintf(str, "; %s", t_errlist[e.re_terrno]); #else (void) sprintf(str, "; %d", e.re_terrno); #endif str += strlen(str); if (e.re_errno) { #ifdef notyet (void) sprintf(str, "; %s", strerror(e.re_errno)); #else (void) sprintf(str, "; %d", e.re_errno); #endif } break; case RPC_CANTSEND: case RPC_CANTRECV: if (e.re_errno) { #ifdef notyet (void) sprintf(str, "; errno = %s", strerror(e.re_errno)); #else (void) sprintf(str, "; errno = %d", e.re_errno); #endif str += strlen(str); } if (e.re_terrno) { #ifdef notyet (void) sprintf(str, "; %s", t_errlist[e.re_terrno]); #else (void) sprintf(str, "; %d", e.re_terrno); #endif } break; case RPC_VERSMISMATCH: (void) sprintf(str, "; low version = %" PRIu32 ", high version = %" PRIu32, e.re_vers.low, e.re_vers.high); break; #ifdef notyet case RPC_AUTHERROR: err = auth_errmsg(e.re_why); (void) sprintf(str, "; why = "); str += strlen(str); if (err != NULL) { (void) sprintf(str, "%s", err); } else { (void) sprintf(str, "(unknown authentication error - %d)", (int)e.re_why); } break; #endif case RPC_PROGVERSMISMATCH: (void) sprintf(str, "; low version = %" PRIu32 ", high version = %" PRIu32, e.re_vers.low, e.re_vers.high); break; default: /* unknown */ (void) sprintf(str, "; s1 = %" PRIu32 ", s2 = %" PRIu32, e.re_lb.s1, e.re_lb.s2); break; } return (strstart); }
static char * charmap_search(struct netbuf *nbuf, char *opts) { char *copts; char *next; char *name; char *result = NULL; char *netid; struct netconfig *nconf; struct nd_hostservlist *hl = NULL; struct sockaddr *sa; /* eventually charopts should be dynamically setup */ if (charopts == NULL) { free(copts); return (NULL); } sa = (struct sockaddr *)nbuf->buf; switch (sa->sa_family) { case AF_INET: nconf = getnetconfigent("tcp"); break; case AF_INET6: nconf = getnetconfigent("tcp6"); break; default: return (NULL); } if (nconf == NULL) { return (NULL); } /* * Use the this API instead of the netdir_getbyaddr() * to avoid service lookup. */ if (__netdir_getbyaddr_nosrv(nconf, &hl, nbuf)) { syslog(LOG_ERR, "netdir: %s\n", netdir_sperror()); freenetconfigent(nconf); return (NULL); } copts = strdup(opts); if (copts == NULL) { freenetconfigent(nconf); return (NULL); } next = copts; while (*next != '\0') { char *val; name = next; if (getsubopt(&next, charopts, &val) >= 0) { char *cp; /* * name will have the whole opt and val the value. Set * the '=' to '\0' and we have the charmap in name and * the access list in val. */ cp = strchr(name, '='); if (cp != NULL) *cp = '\0'; if (in_access_list(nbuf, hl, val)) { result = name; break; } } } if (result != NULL) result = strdup(result); free(copts); freenetconfigent(nconf); return (result); }