diff options
author | wpaul <wpaul@FreeBSD.org> | 1996-12-03 02:37:39 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1996-12-03 02:37:39 +0000 |
commit | 47ee9196beeaa7a40be71cf2e8642202eef9a54c (patch) | |
tree | 6de7b34289a2dd1a6de71f645eda8ba5441a4ade /usr.sbin/ypserv/yp_server.c | |
parent | 65c6417408e3df83cd787c930d520484f3ac5fa7 (diff) | |
download | FreeBSD-src-47ee9196beeaa7a40be71cf2e8642202eef9a54c.zip FreeBSD-src-47ee9196beeaa7a40be71cf2e8642202eef9a54c.tar.gz |
Back out the non-forking YPPROC_ALL stuff. Whatever drugs I was doing
when I came up with this idea weren't strong enough to help me see it
through. If this was a self-contained application and I had complete
control over what data got sent through what socket and when, I might
be able to get everything to work right without blocking, but instead
I have RPC/XDR in between me and the socket layer, and they have their
own ideas about what to do.
Maybe one day I'll go totally mad and figure out the right way to do
this; in the meantime this mess goes on the back burner.
Diffstat (limited to 'usr.sbin/ypserv/yp_server.c')
-rw-r--r-- | usr.sbin/ypserv/yp_server.c | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/usr.sbin/ypserv/yp_server.c b/usr.sbin/ypserv/yp_server.c index 837c1cc..77cc6f7 100644 --- a/usr.sbin/ypserv/yp_server.c +++ b/usr.sbin/ypserv/yp_server.c @@ -43,21 +43,18 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <rpc/rpc.h> -#include <setjmp.h> #ifndef lint -static const char rcsid[] = "$Id: yp_server.c,v 1.10 1996/05/31 16:01:51 wpaul Exp $"; +static const char rcsid[] = "$Id: yp_server.c,v 1.12 1996/10/24 18:58:26 wpaul Exp $"; #endif /* not lint */ int forked = 0; int children = 0; static DB *spec_dbp = NULL; /* Special global DB handle for ypproc_all. */ -static SVCXPRT *xprt; /* Special SVCXPRT handle for ypproc_all. */ static char *master_string = "YP_MASTER_NAME"; static char *order_string = "YP_LAST_MODIFIED"; static int master_sz = sizeof("YP_MASTER_NAME") - 1; static int order_sz = sizeof("YP_LAST_MODIFIED") - 1; -static jmp_buf env; /* * NIS v2 support. This is where most of the action happens. @@ -476,19 +473,34 @@ ypproc_clear_2_svc(void *argp, struct svc_req *rqstp) */ /* - * Custom XDR routine for serialzing results of ypproc_all: grab control - * of the transport and xdr handle from the RPC library and this request - * to the async queue. It will multiplex the record transmission in such - * a way that we can service other requests between transmissions and - * avoid blocking. (It will also close the DB handle for us when the - * request is done.) + * Custom XDR routine for serialzing results of ypproc_all: keep + * reading from the database and spew until we run out of records + * or encounter an error. */ static bool_t xdr_my_ypresp_all(register XDR *xdrs, ypresp_all *objp) { - if (yp_add_async(xdrs, xprt, spec_dbp) == FALSE) - return(FALSE); - longjmp(env, 1); /* XXX EVIL!! */ + DBT key = { NULL, 0 } , data = { NULL, 0 }; + + while (1) { + /* Get a record. */ + if ((objp->ypresp_all_u.val.stat = + yp_next_record(spec_dbp,&key,&data,1,0)) == YP_TRUE) { + objp->ypresp_all_u.val.val.valdat_len = data.size; + objp->ypresp_all_u.val.val.valdat_val = data.data; + objp->ypresp_all_u.val.key.keydat_len = key.size; + objp->ypresp_all_u.val.key.keydat_val = key.data; + objp->more = TRUE; + } else { + objp->more = FALSE; + } + + /* Serialize. */ + if (!xdr_ypresp_all(xdrs, objp)) + return(FALSE); + if (objp->more == FALSE) + return(TRUE); + } } ypresp_all * @@ -519,16 +531,38 @@ ypproc_all_2_svc(ypreq_nokey *argp, struct svc_req *rqstp) return (&result); } + /* + * The ypproc_all procedure can take a while to complete. + * Best to handle it in a subprocess so the parent doesn't + * block. (Is there a better way to do this? Maybe with + * async socket I/O?) + */ + if (!debug && children < MAX_CHILDREN && fork()) { + children++; + forked = 0; + return (NULL); + } else { + forked++; + } + +#ifndef DB_CACHE if ((spec_dbp = yp_open_db(argp->domain, argp->map)) == NULL) { result.ypresp_all_u.val.stat = yp_errno; return(&result); } +#else + if ((spec_dbp = yp_open_db_cache(argp->domain, argp->map, NULL, 0)) == NULL) { + result.ypresp_all_u.val.stat = yp_errno; + return(&result); + } +#endif /* Kick off the actual data transfer. */ - xprt = rqstp->rq_xprt; - if (!setjmp(env)) /* XXX EVIL!!! */ - svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, - (char *)&result); + svc_sendreply(rqstp->rq_xprt, xdr_my_ypresp_all, (char *)&result); + +#ifndef DB_CACHE + (void)(spec_dbp->close)(spec_dbp); +#endif /* * Returning NULL prevents the dispatcher from calling * svc_sendreply() since we already did it. |