Initial import from FreeBSD RELENG_4:
[dragonfly.git] / libexec / rpc.sprayd / sprayd.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1994 Christos Zoulas
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Christos Zoulas.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef lint
32static const char rcsid[] =
33 "$FreeBSD: src/libexec/rpc.sprayd/sprayd.c,v 1.5 1999/08/28 00:09:59 peter Exp $";
34#endif /* not lint */
35
36#include <rpc/rpc.h>
37#include <rpc/pmap_clnt.h>
38#include <rpcsvc/spray.h>
39#include <signal.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <sys/time.h>
43#include <sys/socket.h>
44#include <syslog.h>
45#include <unistd.h>
46
47static void spray_service __P((struct svc_req *, SVCXPRT *));
48
49static int from_inetd = 1;
50
51#define timersub(tvp, uvp, vvp) \
52 do { \
53 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
54 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
55 if ((vvp)->tv_usec < 0) { \
56 (vvp)->tv_sec--; \
57 (vvp)->tv_usec += 1000000; \
58 } \
59 } while (0)
60
61#define TIMEOUT 120
62
63void
64cleanup()
65{
66 (void) pmap_unset(SPRAYPROG, SPRAYVERS);
67 exit(0);
68}
69
70void
71die()
72{
73 exit(0);
74}
75
76int
77main(argc, argv)
78 int argc;
79 char *argv[];
80{
81 SVCXPRT *transp;
82 int sock = 0;
83 int proto = 0;
84 struct sockaddr_in from;
85 int fromlen;
86
87 /*
88 * See if inetd started us
89 */
90 fromlen = sizeof(from);
91 if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) {
92 from_inetd = 0;
93 sock = RPC_ANYSOCK;
94 proto = IPPROTO_UDP;
95 }
96
97 if (!from_inetd) {
98 daemon(0, 0);
99
100 (void) pmap_unset(SPRAYPROG, SPRAYVERS);
101
102 (void) signal(SIGINT, cleanup);
103 (void) signal(SIGTERM, cleanup);
104 (void) signal(SIGHUP, cleanup);
105 } else {
106 (void) signal(SIGALRM, die);
107 alarm(TIMEOUT);
108 }
109
110 openlog("rpc.sprayd", LOG_CONS|LOG_PID, LOG_DAEMON);
111
112 transp = svcudp_create(sock);
113 if (transp == NULL) {
114 syslog(LOG_ERR, "cannot create udp service");
115 return 1;
116 }
117 if (!svc_register(transp, SPRAYPROG, SPRAYVERS, spray_service, proto)) {
118 syslog(LOG_ERR,
119 "unable to register (SPRAYPROG, SPRAYVERS, %s)",
120 proto ? "udp" : "(inetd)");
121 return 1;
122 }
123
124 svc_run();
125 syslog(LOG_ERR, "svc_run returned");
126 return 1;
127}
128
129
130static void
131spray_service(rqstp, transp)
132 struct svc_req *rqstp;
133 SVCXPRT *transp;
134{
135 static spraycumul scum;
136 static struct timeval clear, get;
137
138 switch (rqstp->rq_proc) {
139 case SPRAYPROC_CLEAR:
140 scum.counter = 0;
141 (void) gettimeofday(&clear, 0);
142 /*FALLTHROUGH*/
143
144 case NULLPROC:
145 (void)svc_sendreply(transp, xdr_void, (char *)NULL);
146 return;
147
148 case SPRAYPROC_SPRAY:
149 scum.counter++;
150 return;
151
152 case SPRAYPROC_GET:
153 (void) gettimeofday(&get, 0);
154 timersub(&get, &clear, &get);
155 scum.clock.sec = get.tv_sec;
156 scum.clock.usec = get.tv_usec;
157 break;
158
159 default:
160 svcerr_noproc(transp);
161 return;
162 }
163
164 if (!svc_sendreply(transp, xdr_spraycumul, (caddr_t)&scum)) {
165 svcerr_systemerr(transp);
166 syslog(LOG_ERR, "bad svc_sendreply");
167 }
168}