Npsrv* np_pipesrv_create(int nwthreads) { Npsrv *srv; Pipesrv *ps; ps = malloc(sizeof(*ps)); if (pipe(ps->pipin) < 0) { fprintf(stderr, "cannot create a pipe: %d\n", errno); free(ps); return NULL; } if (pipe(ps->pipout) < 0) { fprintf(stderr, "cannot create a pipe: %d\n", errno); close(ps->pipin[0]); close(ps->pipin[1]); free(ps); return NULL; } ps->fdin = ps->pipin[0]; ps->fdout = ps->pipout[1]; srv = np_srv_create(nwthreads); srv->srvaux = ps; srv->start = np_pipesrv_start; srv->shutdown = np_pipesrv_shutdown; srv->destroy = np_pipesrv_destroy; return srv; }
int main (int argc, char *argv[]) { Npsrv *srv; Npconn *conn; Nptrans *trans; int flags = SRV_FLAGS_DEBUG_9PTRACE | SRV_FLAGS_DEBUG_USER; diod_log_init (argv[0]); diod_conf_init (); if (!(srv = np_srv_create (16, flags))) errn_exit (np_rerror (), "out of memory"); srv->logmsg = diod_log_msg; srv->attach = myattach; srv->clunk = myclunk; /* create one connection */ if (!(trans = ttrans_create ())) err_exit ("ttrans_create"); if (!(conn = np_conn_create (srv, trans, "loopback"))) msg_exit ("np_conn_create failure"); _send_tversion (trans); _send_tauth (trans); _send_tattach (trans, 0, 0); _send_tattach (trans, 0, 1); _send_tattach (trans, 1, 2); _send_tattach (trans, 1, 3); _send_tattach (trans, 0, 4); _send_tclunk (trans, 4); _send_tclunk (trans, 3); _send_tclunk (trans, 2); _send_tclunk (trans, 1); _send_tclunk (trans, 0); ttrans_rpc (trans, NULL, NULL); /* signifies EOF to reader */ /* wait for exactly one connect/disconnect */ np_srv_wait_conncount (srv, 1); sleep(1); /* racy here - conn reader needs time to process EOF */ np_srv_destroy (srv); diod_conf_fini (); diod_log_fini (); exit (0); }
Npsrv* np_socksrv_create_tcp(int nwthreads, int *port) { socklen_t n; Npsrv *srv; Socksrv *ss; struct sockaddr_in* saddr; ss = np_socksrv_create_common(PF_INET, SOCK_STREAM, 0); saddr = malloc(sizeof(*saddr)); ss->saddr = (struct sockaddr *) saddr; ss->saddrlen = sizeof(*saddr); saddr->sin_family = AF_INET; saddr->sin_port = htons(*port); saddr->sin_addr.s_addr = htonl(INADDR_ANY); if (np_socksrv_connect(ss) < 0) { free(saddr); free(ss); return NULL; } saddr->sin_port = 4242; n = sizeof(*saddr); if (getsockname(ss->sock, ss->saddr, &n) < 0) { np_uerror(errno); free(saddr); free(ss); return NULL; } *port = ntohs(saddr->sin_port); srv = np_srv_create(nwthreads); srv->srvaux = ss; srv->start = np_socksrv_start; srv->shutdown = np_socksrv_shutdown; srv->destroy = np_socksrv_destroy; return srv; }
static void _service_run (srvmode_t mode, int rfdno, int wfdno) { List l = diod_conf_get_listen (); int nwthreads = diod_conf_get_nwthreads (); int flags = diod_conf_get_debuglevel (); uid_t euid = geteuid (); int n; ss.mode = mode; ss.rfdno = rfdno; ss.wfdno = wfdno; ss.shutdown = 0; ss.reload = 0; _service_sigsetup (); ss.fds = NULL; ss.nfds = 0; switch (mode) { case SRV_FILEDES: break; case SRV_NORMAL: case SRV_SOCKTEST: if (!diod_sock_listen (l, &ss.fds, &ss.nfds)) msg_exit ("failed to set up listener"); #if WITH_RDMATRANS ss.rdma = diod_rdma_create (); diod_rdma_listen (ss.rdma); #endif break; } /* manipulate squash/runas users if not root */ if (euid != 0) { if (diod_conf_get_allsquash ()) { struct passwd *pw = getpwuid (euid); char *su = diod_conf_get_squashuser (); if (!pw) msg_exit ("getpwuid on effective uid failed"); if (strcmp (pw->pw_name, su) != 0) { if (strcmp (su, DFLT_SQUASHUSER) != 0) msg ("changing squashuser '%s' to '%s' " "since you are not root", su, pw->pw_name); diod_conf_set_squashuser (pw->pw_name); /* fixes issue 41 */ } } else { /* N.B. runasuser cannot be set in the config file */ uid_t ruid = diod_conf_get_runasuid (); if (diod_conf_opt_runasuid () && ruid != euid) msg ("changing runasuid %d to %d " "since you are not root", ruid, euid); diod_conf_set_runasuid (euid); } } if (!diod_conf_get_foreground () && mode != SRV_FILEDES) _daemonize (); /* implicit fork - no pthreads before this */ if (!diod_conf_get_foreground () && mode != SRV_FILEDES) diod_log_set_dest (diod_conf_get_logdest ()); /* drop root */ if (euid == 0) { if (diod_conf_get_allsquash ()) _become_user (diod_conf_get_squashuser (), -1, 1); else if (diod_conf_opt_runasuid ()) _become_user (NULL, diod_conf_get_runasuid (), 1); } /* clear umask */ umask (0); flags |= SRV_FLAGS_LOOSEFID; /* work around buggy clients */ flags |= SRV_FLAGS_AUTHCONN; //flags |= SRV_FLAGS_FLUSHSIG; /* XXX temporarily off */ if (geteuid () == 0) { flags |= SRV_FLAGS_SETFSID; flags |= SRV_FLAGS_DAC_BYPASS; if (_test_setgroups ()) flags |= SRV_FLAGS_SETGROUPS; else msg ("test_setgroups: groups are per-process (disabling)"); } /* Process dumpable flag may have been cleared by uid manipulation above. * Set it here, then maintain it in user.c::np_setfsid () as uids are * further manipulated. */ if (prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) err_exit ("prctl PR_SET_DUMPABLE failed"); if (!diod_conf_get_userdb ()) flags |= SRV_FLAGS_NOUSERDB; if (!(ss.srv = np_srv_create (nwthreads, flags))) /* starts threads */ errn_exit (np_rerror (), "np_srv_create"); if (diod_init (ss.srv) < 0) errn_exit (np_rerror (), "diod_init"); if ((n = pthread_create (&ss.t, NULL, _service_loop, NULL))) errn_exit (n, "pthread_create _service_loop"); #if WITH_RDMATRANS if ((n = pthread_create (&ss.rdma_t, NULL, _service_loop_rdma, NULL))) errn_exit (n, "pthread_create _service_loop_rdma"); #endif switch (mode) { case SRV_FILEDES: case SRV_SOCKTEST: np_srv_wait_conncount (ss.srv, 1); pthread_kill (ss.t, SIGUSR1); break; case SRV_NORMAL: break; } if ((n = pthread_join (ss.t, NULL))) errn_exit (n, "pthread_join _service_loop"); #if WITH_RDMATRANS if ((n = pthread_join (ss.rdma_t, NULL))) errn_exit (n, "pthread_join _service_loop_rdma"); #endif diod_fini (ss.srv); np_srv_destroy (ss.srv); }