/* * Called to set up service over a particular transport. */ void do_one(char *provider, NETSELDECL(proto), struct protob *protobp0, int (*svc)(int, struct netbuf, struct netconfig *)) { register int sock; struct protob *protobp; struct netbuf *retaddr; struct netconfig *retnconf; struct netbuf addrmask; int vers; int err; int l; if (provider) sock = bind_to_provider(provider, protobp0->serv, &retaddr, &retnconf); else sock = bind_to_proto(proto, protobp0->serv, &retaddr, &retnconf); if (sock == -1) { (void) syslog(LOG_ERR, "Cannot establish %s service over %s: transport setup problem.", protobp0->serv, provider ? provider : proto); return; } if (set_addrmask(sock, retnconf, &addrmask) < 0) { (void) syslog(LOG_ERR, "Cannot set address mask for %s", retnconf->nc_netid); return; } /* * Register all versions of the programs in the protocol block list. */ l = strlen(NC_UDP); for (protobp = protobp0; protobp; protobp = protobp->next) { for (vers = protobp->versmin; vers <= protobp->versmax; vers++) { if ((protobp->program == NFS_PROGRAM || protobp->program == NFS_ACL_PROGRAM) && vers == NFS_V4 && strncasecmp(retnconf->nc_proto, NC_UDP, l) == 0) continue; (void) rpcb_unset(protobp->program, vers, retnconf); (void) rpcb_set(protobp->program, vers, retnconf, retaddr); } } /* * Register services with CLTS semantics right now. * Note: services with COTS/COTS_ORD semantics will be * registered later from cots_listen_event function. */ if (retnconf->nc_semantics == NC_TPI_CLTS) { /* Don't drop core if supporting module(s) aren't loaded. */ (void) signal(SIGSYS, SIG_IGN); /* * svc() doesn't block, it returns success or failure. */ if (svc == NULL && Mysvc4 != NULL) err = (*Mysvc4)(sock, &addrmask, retnconf, NFS4_SETPORT|NFS4_KRPC_START, retaddr); else err = (*svc)(sock, addrmask, retnconf); if (err < 0) { (void) syslog(LOG_ERR, "Cannot establish %s service over <file desc." " %d, protocol %s> : %m. Exiting", protobp0->serv, sock, retnconf->nc_proto); exit(1); } } free(addrmask.buf); /* * We successfully set up the server over this transport. * Add this descriptor to the one being polled on. */ add_to_poll_list(sock, retnconf); }
/* * Called to set up service over a particular transport. */ void do_one(char *provider, NETSELDECL(proto), struct protob *protobp0, int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap) { register int sock; struct protob *protobp; struct netbuf *retaddr; struct netconfig *retnconf; struct netbuf addrmask; int vers; int err; int l; if (provider) sock = bind_to_provider(provider, protobp0->serv, &retaddr, &retnconf); else sock = bind_to_proto(proto, protobp0->serv, &retaddr, &retnconf); if (sock == -1) { (void) syslog(LOG_ERR, "Cannot establish %s service over %s: transport setup problem.", protobp0->serv, provider ? provider : proto); return; } if (set_addrmask(sock, retnconf, &addrmask) < 0) { (void) syslog(LOG_ERR, "Cannot set address mask for %s", retnconf->nc_netid); return; } /* * Register all versions of the programs in the protocol block list. */ l = strlen(NC_UDP); for (protobp = protobp0; protobp; protobp = protobp->next) { for (vers = protobp->versmin; vers <= protobp->versmax; vers++) { if ((protobp->program == NFS_PROGRAM || protobp->program == NFS_ACL_PROGRAM) && vers == NFS_V4 && strncasecmp(retnconf->nc_proto, NC_UDP, l) == 0) continue; if (protobp->flags & PROTOB_NO_REGISTER) continue; if (use_pmap) { /* * Note that if we're using a portmapper * instead of rpcbind then we can't do an * unregister operation here. * * The reason is that the portmapper unset * operation removes all the entries for a * given program/version regardelss of * transport protocol. * * The caller of this routine needs to ensure * that __pmap_unset() has been called for all * program/version service pairs they plan * to support before they start registering * each program/version/protocol triplet. */ (void) __pmap_set(protobp->program, vers, retnconf, retaddr); } else { (void) rpcb_unset(protobp->program, vers, retnconf); (void) rpcb_set(protobp->program, vers, retnconf, retaddr); } } } if (retnconf->nc_semantics == NC_TPI_CLTS) { /* Don't drop core if supporting module(s) aren't loaded. */ (void) signal(SIGSYS, SIG_IGN); /* * svc() doesn't block, it returns success or failure. */ if (svc == NULL && Mysvc4 != NULL) err = (*Mysvc4)(sock, &addrmask, retnconf, NFS4_SETPORT|NFS4_KRPC_START, retaddr); else err = (*svc)(sock, addrmask, retnconf); if (err < 0) { (void) syslog(LOG_ERR, "Cannot establish %s service over <file desc." " %d, protocol %s> : %m. Exiting", protobp0->serv, sock, retnconf->nc_proto); exit(1); } } /* * We successfully set up the server over this transport. * Add this descriptor to the one being polled on. */ add_to_poll_list(sock, retnconf); }