From: Neil Brown Date: Fri, 20 Apr 2007 02:42:49 +0000 (+1000) Subject: Store mapping table in a file. X-Git-Tag: portmap_6.0~6 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=a74b5b47c7d7e733682e927f54184c98dad50f94;p=portmap.git Store mapping table in a file. Thus we can restore it if killed and restarted. --- diff --git a/portmap.8 b/portmap.8 index 96294e4..c021e15 100644 --- a/portmap.8 +++ b/portmap.8 @@ -92,6 +92,12 @@ like any other daemon. then logs errors using .Xr syslog 3 . .Pp +.Nm Portmap +records all current mapping in the file +.Nm /var/run/portmap_mapping +so that if it gets killed and restarted, it can reload the mapping for +currently active services. +.Pp Options available: .Bl -tag -width Ds .It Fl d @@ -172,10 +178,6 @@ manual pages. .Xr tcpd 8 , .Xr hosts_access 5 , .Xr hosts_options 5 -.Sh BUGS -If -.Nm portmap -crashes, all rpc servers must be restarted. .Sh HISTORY The .Nm diff --git a/portmap.c b/portmap.c index 984d46f..76cb6f5 100644 --- a/portmap.c +++ b/portmap.c @@ -88,6 +88,7 @@ static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; #include #include #include +#include #include #include #include @@ -126,6 +127,9 @@ static void reap(int); static void callit(struct svc_req *rqstp, SVCXPRT *xprt); struct pmaplist *pmaplist; int debugging = 0; +int store_fd = -1; +static void dump_table(void); +static void load_table(void); #include "pmap_check.h" @@ -322,6 +326,9 @@ main(int argc, char **argv) (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); + store_fd = open("/var/run/portmap_mapping", O_RDWR|O_CREAT, 0600); + load_table(); + /* additional initializations */ if (chroot_path) { if (chroot(chroot_path) < 0) { @@ -448,6 +455,7 @@ static void reg_service(struct svc_req *rqstp, SVCXPRT *xprt) fnd->pml_next = pml; } ans = 1; + dump_table(); } done: if ((!svc_sendreply(xprt, (xdrproc_t)xdr_int, @@ -504,6 +512,7 @@ static void reg_service(struct svc_req *rqstp, SVCXPRT *xprt) else prevpml->pml_next = pml; free(t); + dump_table(); } if ((!svc_sendreply(xprt, (xdrproc_t)xdr_int, (caddr_t)&ans)) && @@ -742,3 +751,71 @@ static void reap(int ignore) errno = save_errno; } #endif + +/* Dump and restore mapping table so that we can survive kill/restart. + * To cope with chroot, an fd is opened early and we just write to that. + * If we are killed while writing the file, we lose, but that isn't + * very likely... + */ + +static void dump_table(void) +{ + FILE *f; + struct pmaplist *pml; + + if (store_fd < 0) + return; + ftruncate(store_fd, 0); + lseek(store_fd, 0, 0); + f = fdopen(dup(store_fd), "w"); + if (!f) + return; + + for (pml = pmaplist ; pml ; pml = pml->pml_next) { + struct flagged_pml *fpml = (struct flagged_pml*)pml; + + fprintf(f, "%lu %lu %lu %lu %d\n", + pml->pml_map.pm_prog, + pml->pml_map.pm_vers, + pml->pml_map.pm_prot, + pml->pml_map.pm_port, + fpml->priv); + } + fclose(f); +} + +static void load_table(void) +{ + FILE *f; + struct pmaplist **ep; + struct flagged_pml fpml, *fpmlp; + + ep = &pmaplist; + while ((*ep)->pml_next) + ep = & (*ep)->pml_next; + + if (store_fd < 0) + return; + lseek(store_fd, 0, 0); + f = fdopen(dup(store_fd), "r"); + if (f == NULL) + return; + + while (fscanf(f, "%lu %lu %lu %lu %d\n", + &fpml.pml.pml_map.pm_prog, + &fpml.pml.pml_map.pm_vers, + &fpml.pml.pml_map.pm_prot, + &fpml.pml.pml_map.pm_port, + &fpml.priv) == 5) { + if (fpml.pml.pml_map.pm_port == PMAPPORT) + continue; + fpmlp = malloc(sizeof(struct flagged_pml)); + if (!fpmlp) + break; + *fpmlp = fpml; + *ep = &fpmlp->pml; + ep = &fpmlp->pml.pml_next; + *ep = NULL; + } + fclose(f); +}