xref: /netbsd-src/libexec/rpc.rstatd/rstat_proc.c (revision 8a0d3fa9d7f680af3b51f305231fc6da9398e710)
1*8a0d3fa9Sbad /*	$NetBSD: rstat_proc.c,v 1.22 1998/02/11 17:27:37 bad Exp $	*/
2176865a0Sthorpej 
3e7153151Sbrezak /*
4e7153151Sbrezak  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5e7153151Sbrezak  * unrestricted use provided that this legend is included on all tape
6e7153151Sbrezak  * media and as a part of the software program in whole or part.  Users
7e7153151Sbrezak  * may copy or modify Sun RPC without charge, but are not authorized
8e7153151Sbrezak  * to license or distribute it to anyone else except as part of a product or
9e7153151Sbrezak  * program developed by the user.
10e7153151Sbrezak  *
11e7153151Sbrezak  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12e7153151Sbrezak  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13e7153151Sbrezak  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14e7153151Sbrezak  *
15e7153151Sbrezak  * Sun RPC is provided with no support and without any obligation on the
16e7153151Sbrezak  * part of Sun Microsystems, Inc. to assist in its use, correction,
17e7153151Sbrezak  * modification or enhancement.
18e7153151Sbrezak  *
19e7153151Sbrezak  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20e7153151Sbrezak  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21e7153151Sbrezak  * OR ANY PART THEREOF.
22e7153151Sbrezak  *
23e7153151Sbrezak  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24e7153151Sbrezak  * or profits or other special, indirect and consequential damages, even if
25e7153151Sbrezak  * Sun has been advised of the possibility of such damages.
26e7153151Sbrezak  *
27e7153151Sbrezak  * Sun Microsystems, Inc.
28e7153151Sbrezak  * 2550 Garcia Avenue
29e7153151Sbrezak  * Mountain View, California  94043
30e7153151Sbrezak  */
31a5a68ff5Smrg 
32a5a68ff5Smrg #include <sys/cdefs.h>
33e9d867efSmycroft #ifndef lint
34a5a68ff5Smrg #if 0
35a5a68ff5Smrg static char sccsid[] = "from: @(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro";
36a5a68ff5Smrg static char sccsid[] = "from: @(#)rstat_proc.c	2.2 88/08/01 4.0 RPCSRC";
37a5a68ff5Smrg #else
38*8a0d3fa9Sbad __RCSID("$NetBSD: rstat_proc.c,v 1.22 1998/02/11 17:27:37 bad Exp $");
39a5a68ff5Smrg #endif
40e9d867efSmycroft #endif
41e7153151Sbrezak 
42e7153151Sbrezak /*
43e7153151Sbrezak  * rstat service:  built with rstat.x and derived from rpc.rstatd.c
44e9d867efSmycroft  *
45e9d867efSmycroft  * Copyright (c) 1984 by Sun Microsystems, Inc.
46e7153151Sbrezak  */
47e7153151Sbrezak 
48f1d37094Smrg #include <sys/param.h>
49f1d37094Smrg #include <sys/errno.h>
50f1d37094Smrg #include <sys/socket.h>
51f1d37094Smrg 
52e7153151Sbrezak #include <stdio.h>
5359e456d7Sjtc #include <stdlib.h>
5459e456d7Sjtc #include <string.h>
5559e456d7Sjtc #include <signal.h>
567cb090d9Spk #include <fcntl.h>
577cb090d9Spk #include <kvm.h>
587cb090d9Spk #include <limits.h>
59e7153151Sbrezak #include <nlist.h>
60e7153151Sbrezak #include <syslog.h>
61e7153151Sbrezak #ifdef BSD
62f1d37094Smrg #if defined(UVM)
63f1d37094Smrg #include <sys/sysctl.h>
64f1d37094Smrg #include <vm/vm.h>
65f1d37094Smrg #include <uvm/uvm_extern.h>
66f1d37094Smrg #else
67e7153151Sbrezak #include <sys/vmmeter.h>
68f1d37094Smrg #endif
69e7153151Sbrezak #include <sys/dkstat.h>
70b817db1eSthorpej #include "dkstats.h"
71e7153151Sbrezak #else
72e7153151Sbrezak #include <sys/dk.h>
73e7153151Sbrezak #endif
74f1d37094Smrg 
75e7153151Sbrezak #include <net/if.h>
7659e456d7Sjtc 
77f1d37094Smrg /*
78f1d37094Smrg  * XXX
79f1d37094Smrg  *
80f1d37094Smrg  * this is a huge hack to stop `struct pmap' being
81f1d37094Smrg  * defined twice!
82f1d37094Smrg  */
83*8a0d3fa9Sbad #define _RPC_PMAP_PROT_H_
84f1d37094Smrg #include <rpc/rpc.h>
85f1d37094Smrg 
8659e456d7Sjtc #undef FSHIFT			 /* Use protocol's shift and scale values */
8759e456d7Sjtc #undef FSCALE
88570159beSmycroft #undef DK_NDRIVE
8900b7161eScgd #undef CPUSTATES
9000b7161eScgd #undef if_ipackets
9100b7161eScgd #undef if_ierrors
9200b7161eScgd #undef if_opackets
9300b7161eScgd #undef if_oerrors
9400b7161eScgd #undef if_collisions
95e7153151Sbrezak #include <rpcsvc/rstat.h>
96e7153151Sbrezak 
977cb090d9Spk #ifdef BSD
987cb090d9Spk #define BSD_CPUSTATES	5	/* Use protocol's idea of CPU states */
997cb090d9Spk int	cp_xlat[CPUSTATES] = { CP_USER, CP_NICE, CP_SYS, CP_IDLE };
1007cb090d9Spk #endif
1017cb090d9Spk 
102e7153151Sbrezak struct nlist nl[] = {
103f1d37094Smrg #define	X_IFNET		0
104e7153151Sbrezak 	{ "_ifnet" },
105f1d37094Smrg #define	X_BOOTTIME	1
106e7153151Sbrezak 	{ "_boottime" },
107f1d37094Smrg #if !defined(UVM)
108f1d37094Smrg #define	X_CNT		2
109f1d37094Smrg 	{ "_cnt" },
110f1d37094Smrg #endif
111d09d0bdcScgd 	{ NULL },
112e7153151Sbrezak };
113b817db1eSthorpej 
114b817db1eSthorpej extern int dk_ndrive;		/* From dkstats.c */
115b817db1eSthorpej extern struct _disk cur, last;
116b817db1eSthorpej int hz;
117b817db1eSthorpej char *memf = NULL, *nlistf = NULL;
118b817db1eSthorpej 
119fe84ea21Scgd struct ifnet_head ifnetq;	/* chain of ethernet interfaces */
120b54e7589Scgd int numintfs;
121e7153151Sbrezak 
122e7153151Sbrezak extern int from_inetd;
123e7153151Sbrezak int sincelastreq = 0;		/* number of alarms since last request */
124e7153151Sbrezak extern int closedown;
1257cb090d9Spk kvm_t *kfd;
126e7153151Sbrezak 
127e7153151Sbrezak union {
128e7153151Sbrezak 	struct stats s1;
129e7153151Sbrezak 	struct statsswtch s2;
130e7153151Sbrezak 	struct statstime s3;
131e7153151Sbrezak } stats_all;
132e7153151Sbrezak 
133a5a68ff5Smrg extern void dkreadstats __P((void));
134a5a68ff5Smrg extern int dkinit __P((int));
135a5a68ff5Smrg 
136a5a68ff5Smrg void updatestat __P((int));
137a5a68ff5Smrg void setup __P((void));
138a5a68ff5Smrg void stat_init __P((void));
139a5a68ff5Smrg int havedisk __P((void));
140a5a68ff5Smrg void rstat_service __P((struct svc_req *, SVCXPRT *));
141a5a68ff5Smrg 
142e7153151Sbrezak static stat_is_init = 0;
143e7153151Sbrezak extern int errno;
144e7153151Sbrezak 
145e7153151Sbrezak #ifndef FSCALE
146e7153151Sbrezak #define FSCALE (1 << 8)
147e7153151Sbrezak #endif
148e7153151Sbrezak 
149a5a68ff5Smrg void
150e7153151Sbrezak stat_init()
151e7153151Sbrezak {
152e7153151Sbrezak 	stat_is_init = 1;
153e7153151Sbrezak 	setup();
154a5a68ff5Smrg 	updatestat(0);
155e7153151Sbrezak 	(void) signal(SIGALRM, updatestat);
156e7153151Sbrezak 	alarm(1);
157e7153151Sbrezak }
158e7153151Sbrezak 
159e7153151Sbrezak statstime *
160fed935ebSpk rstatproc_stats_3_svc(arg, rqstp)
161fed935ebSpk 	void *arg;
162fed935ebSpk 	struct svc_req *rqstp;
163e7153151Sbrezak {
164e7153151Sbrezak 	if (!stat_is_init)
165e7153151Sbrezak 	        stat_init();
166e7153151Sbrezak 	sincelastreq = 0;
167e7153151Sbrezak 	return (&stats_all.s3);
168e7153151Sbrezak }
169e7153151Sbrezak 
170e7153151Sbrezak statsswtch *
171fed935ebSpk rstatproc_stats_2_svc(arg, rqstp)
172fed935ebSpk 	void *arg;
173fed935ebSpk 	struct svc_req *rqstp;
174e7153151Sbrezak {
175e7153151Sbrezak 	if (!stat_is_init)
176e7153151Sbrezak 	        stat_init();
177e7153151Sbrezak 	sincelastreq = 0;
1786ca80cfbSfvdl 	stats_all.s2.if_opackets = stats_all.s3.if_opackets;
179e7153151Sbrezak 	return (&stats_all.s2);
180e7153151Sbrezak }
181e7153151Sbrezak 
182e7153151Sbrezak stats *
183fed935ebSpk rstatproc_stats_1_svc(arg, rqstp)
184fed935ebSpk 	void *arg;
185fed935ebSpk 	struct svc_req *rqstp;
186e7153151Sbrezak {
187e7153151Sbrezak 	if (!stat_is_init)
188e7153151Sbrezak 	        stat_init();
189e7153151Sbrezak 	sincelastreq = 0;
1906ca80cfbSfvdl 	stats_all.s1.if_opackets = stats_all.s3.if_opackets;
191e7153151Sbrezak 	return (&stats_all.s1);
192e7153151Sbrezak }
193e7153151Sbrezak 
194e7153151Sbrezak u_int *
195fed935ebSpk rstatproc_havedisk_3_svc(arg, rqstp)
196fed935ebSpk 	void *arg;
197fed935ebSpk 	struct svc_req *rqstp;
198e7153151Sbrezak {
199e7153151Sbrezak 	static u_int have;
200e7153151Sbrezak 
201e7153151Sbrezak 	if (!stat_is_init)
202e7153151Sbrezak 	        stat_init();
203e7153151Sbrezak 	sincelastreq = 0;
204e7153151Sbrezak 	have = havedisk();
205e7153151Sbrezak 	return (&have);
206e7153151Sbrezak }
207e7153151Sbrezak 
208e7153151Sbrezak u_int *
209fed935ebSpk rstatproc_havedisk_2_svc(arg, rqstp)
210fed935ebSpk 	void *arg;
211fed935ebSpk 	struct svc_req *rqstp;
212e7153151Sbrezak {
213fed935ebSpk 	return (rstatproc_havedisk_3_svc(arg, rqstp));
214e7153151Sbrezak }
215e7153151Sbrezak 
216e7153151Sbrezak u_int *
217fed935ebSpk rstatproc_havedisk_1_svc(arg, rqstp)
218fed935ebSpk 	void *arg;
219fed935ebSpk 	struct svc_req *rqstp;
220e7153151Sbrezak {
221fed935ebSpk 	return (rstatproc_havedisk_3_svc(arg, rqstp));
222e7153151Sbrezak }
223e7153151Sbrezak 
224e7153151Sbrezak void
225a5a68ff5Smrg updatestat(dummy)
226a5a68ff5Smrg 	int dummy;
227e7153151Sbrezak {
228b54e7589Scgd 	long off;
229b817db1eSthorpej 	int i;
230f1d37094Smrg #if defined(UVM)
231f1d37094Smrg 	struct uvmexp uvmexp;
232f1d37094Smrg 	size_t len;
233f1d37094Smrg 	int mib[2];
234f1d37094Smrg #else
2356fb7527eScgd 	struct vmmeter cnt;
236f1d37094Smrg #endif
237e7153151Sbrezak 	struct ifnet ifnet;
238e7153151Sbrezak 	double avrun[3];
239e7153151Sbrezak 	struct timeval tm, btm;
240e7153151Sbrezak 
241e7153151Sbrezak #ifdef DEBUG
24248bf1a7fSmycroft 	syslog(LOG_DEBUG, "entering updatestat");
243e7153151Sbrezak #endif
244e7153151Sbrezak 	if (sincelastreq >= closedown) {
245e7153151Sbrezak #ifdef DEBUG
24648bf1a7fSmycroft                 syslog(LOG_DEBUG, "about to closedown");
247e7153151Sbrezak #endif
248e7153151Sbrezak                 if (from_inetd)
249e7153151Sbrezak                         exit(0);
250e7153151Sbrezak                 else {
251e7153151Sbrezak                         stat_is_init = 0;
252e7153151Sbrezak                         return;
253e7153151Sbrezak                 }
254e7153151Sbrezak 	}
255e7153151Sbrezak 	sincelastreq++;
256e7153151Sbrezak 
257b817db1eSthorpej 	/*
258b817db1eSthorpej 	 * dkreadstats reads in the "disk_count" as well as the "disklist"
259b817db1eSthorpej 	 * statistics.  It also retrieves "hz" and the "cp_time" array.
260b817db1eSthorpej 	 */
261b817db1eSthorpej 	dkreadstats();
2626ca80cfbSfvdl 	memset(stats_all.s3.dk_xfer, 0, sizeof(stats_all.s3.dk_xfer));
263b817db1eSthorpej 	for (i = 0; i < dk_ndrive && i < DK_NDRIVE; i++)
2646ca80cfbSfvdl 		stats_all.s3.dk_xfer[i] = cur.dk_xfer[i];
265b817db1eSthorpej 
2667cb090d9Spk #ifdef BSD
2677cb090d9Spk 	for (i = 0; i < CPUSTATES; i++)
2686ca80cfbSfvdl 		stats_all.s3.cp_time[i] = cur.cp_time[cp_xlat[i]];
2697cb090d9Spk #else
2707cb090d9Spk  	if (kvm_read(kfd, (long)nl[X_CPTIME].n_value,
2716ca80cfbSfvdl 		     (char *)stats_all.s3.cp_time,
2726ca80cfbSfvdl 		     sizeof (stats_all.s3.cp_time))
2736ca80cfbSfvdl 	    != sizeof (stats_all.s3.cp_time)) {
27448bf1a7fSmycroft 		syslog(LOG_ERR, "can't read cp_time from kmem");
275e7153151Sbrezak 		exit(1);
276e7153151Sbrezak 	}
2777cb090d9Spk #endif
278e7153151Sbrezak #ifdef BSD
279e7153151Sbrezak         (void)getloadavg(avrun, sizeof(avrun) / sizeof(avrun[0]));
280e7153151Sbrezak #endif
2816ca80cfbSfvdl 	stats_all.s3.avenrun[0] = avrun[0] * FSCALE;
2826ca80cfbSfvdl 	stats_all.s3.avenrun[1] = avrun[1] * FSCALE;
2836ca80cfbSfvdl 	stats_all.s3.avenrun[2] = avrun[2] * FSCALE;
2847cb090d9Spk  	if (kvm_read(kfd, (long)nl[X_BOOTTIME].n_value,
2856ca80cfbSfvdl 		     (char *)&btm, sizeof (stats_all.s3.boottime))
2866ca80cfbSfvdl 	    != sizeof (stats_all.s3.boottime)) {
28748bf1a7fSmycroft 		syslog(LOG_ERR, "can't read boottime from kmem");
288e7153151Sbrezak 		exit(1);
289e7153151Sbrezak 	}
2906ca80cfbSfvdl 	stats_all.s3.boottime.tv_sec = btm.tv_sec;
2916ca80cfbSfvdl 	stats_all.s3.boottime.tv_usec = btm.tv_usec;
292e7153151Sbrezak 
293e7153151Sbrezak 
294e7153151Sbrezak #ifdef DEBUG
2956ca80cfbSfvdl 	syslog(LOG_DEBUG, "%d %d %d %d\n", stats_all.s3.cp_time[0],
2966ca80cfbSfvdl 	    stats_all.s3.cp_time[1], stats_all.s3.cp_time[2], stats_all.s3.cp_time[3]);
297e7153151Sbrezak #endif
298e7153151Sbrezak 
299f1d37094Smrg #if defined(UVM)
300f1d37094Smrg 	mib[0] = CTL_VM;
301f1d37094Smrg 	mib[1] = VM_UVMEXP;
302f1d37094Smrg 	len = sizeof(uvmexp);
303f1d37094Smrg 	if (sysctl(mib, 2, &uvmexp, &len, NULL, 0) < 0) {
304f1d37094Smrg 		syslog(LOG_ERR, "can't sysctl vm.uvmexp");
305f1d37094Smrg 		exit(1);
306f1d37094Smrg 	}
307f1d37094Smrg 	stats_all.s3.v_pgpgin = uvmexp.fltanget;
308f1d37094Smrg 	stats_all.s3.v_pgpgout = uvmexp.pdpageouts;
309f1d37094Smrg 	stats_all.s3.v_pswpin = uvmexp.swapins;
310f1d37094Smrg 	stats_all.s3.v_pswpout = uvmexp.swapouts;
311f1d37094Smrg 	stats_all.s3.v_intr = uvmexp.intrs;
312f1d37094Smrg 	stats_all.s3.v_swtch = uvmexp.swtch;
313f1d37094Smrg #else
3147cb090d9Spk  	if (kvm_read(kfd, (long)nl[X_CNT].n_value, (char *)&cnt, sizeof cnt) !=
3157cb090d9Spk 	    sizeof cnt) {
31648bf1a7fSmycroft 		syslog(LOG_ERR, "can't read cnt from kmem");
317e7153151Sbrezak 		exit(1);
318e7153151Sbrezak 	}
3196ca80cfbSfvdl 	stats_all.s3.v_pgpgin = cnt.v_pgpgin;
3206ca80cfbSfvdl 	stats_all.s3.v_pgpgout = cnt.v_pgpgout;
3216ca80cfbSfvdl 	stats_all.s3.v_pswpin = cnt.v_pswpin;
3226ca80cfbSfvdl 	stats_all.s3.v_pswpout = cnt.v_pswpout;
3236ca80cfbSfvdl 	stats_all.s3.v_intr = cnt.v_intr;
324f1d37094Smrg 	stats_all.s3.v_swtch = cnt.v_swtch;
325f1d37094Smrg #endif
326e7153151Sbrezak 	gettimeofday(&tm, (struct timezone *) 0);
3276ca80cfbSfvdl 	stats_all.s3.v_intr -= hz*(tm.tv_sec - btm.tv_sec) +
328e7153151Sbrezak 	    hz*(tm.tv_usec - btm.tv_usec)/1000000;
329e7153151Sbrezak 
3306ca80cfbSfvdl 	stats_all.s3.if_ipackets = 0;
3316ca80cfbSfvdl 	stats_all.s3.if_opackets = 0;
3326ca80cfbSfvdl 	stats_all.s3.if_ierrors = 0;
3336ca80cfbSfvdl 	stats_all.s3.if_oerrors = 0;
3346ca80cfbSfvdl 	stats_all.s3.if_collisions = 0;
335fe84ea21Scgd 	for (off = (long)ifnetq.tqh_first, i = 0; off && i < numintfs; i++) {
3367cb090d9Spk 		if (kvm_read(kfd, off, (char *)&ifnet, sizeof ifnet) !=
3377cb090d9Spk 		    sizeof ifnet) {
33848bf1a7fSmycroft 			syslog(LOG_ERR, "can't read ifnet from kmem");
339e7153151Sbrezak 			exit(1);
340e7153151Sbrezak 		}
3416ca80cfbSfvdl 		stats_all.s3.if_ipackets += ifnet.if_data.ifi_ipackets;
3426ca80cfbSfvdl 		stats_all.s3.if_opackets += ifnet.if_data.ifi_opackets;
3436ca80cfbSfvdl 		stats_all.s3.if_ierrors += ifnet.if_data.ifi_ierrors;
3446ca80cfbSfvdl 		stats_all.s3.if_oerrors += ifnet.if_data.ifi_oerrors;
3456ca80cfbSfvdl 		stats_all.s3.if_collisions += ifnet.if_data.ifi_collisions;
346fe84ea21Scgd 		off = (long)ifnet.if_list.tqe_next;
347e7153151Sbrezak 	}
348e7153151Sbrezak 	gettimeofday((struct timeval *)&stats_all.s3.curtime,
349e7153151Sbrezak 		(struct timezone *) 0);
350e7153151Sbrezak 	alarm(1);
351e7153151Sbrezak }
352e7153151Sbrezak 
353a5a68ff5Smrg void
354e7153151Sbrezak setup()
355e7153151Sbrezak {
356e7153151Sbrezak 	struct ifnet ifnet;
357b54e7589Scgd 	long off;
3587cb090d9Spk 	char errbuf[_POSIX2_LINE_MAX];
359e7153151Sbrezak 
3607cb090d9Spk 	kfd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
3617cb090d9Spk 	if (kfd == NULL) {
36248bf1a7fSmycroft 		syslog(LOG_ERR, "%s", errbuf);
3637cb090d9Spk 		exit (1);
3647cb090d9Spk 	}
3657cb090d9Spk 
3667cb090d9Spk 	if (kvm_nlist(kfd, nl) != 0) {
36748bf1a7fSmycroft 		syslog(LOG_ERR, "can't get namelist");
368e7153151Sbrezak 		exit (1);
369e7153151Sbrezak         }
370e7153151Sbrezak 
371fe84ea21Scgd 	if (kvm_read(kfd, (long)nl[X_IFNET].n_value, &ifnetq,
372fe84ea21Scgd                      sizeof ifnetq) != sizeof ifnetq)  {
373fe84ea21Scgd 		syslog(LOG_ERR, "can't read ifnet queue head from kmem");
374e7153151Sbrezak 		exit(1);
375e7153151Sbrezak         }
376e7153151Sbrezak 
377e7153151Sbrezak 	numintfs = 0;
378fe84ea21Scgd 	for (off = (long)ifnetq.tqh_first; off;) {
3797cb090d9Spk 		if (kvm_read(kfd, off, (char *)&ifnet, sizeof ifnet) !=
3807cb090d9Spk 		    sizeof ifnet) {
38148bf1a7fSmycroft 			syslog(LOG_ERR, "can't read ifnet from kmem");
382e7153151Sbrezak 			exit(1);
383e7153151Sbrezak 		}
384e7153151Sbrezak 		numintfs++;
385fe84ea21Scgd 		off = (long)ifnet.if_list.tqe_next;
386e7153151Sbrezak 	}
387b817db1eSthorpej 	dkinit(0);
388e7153151Sbrezak }
389e7153151Sbrezak 
390e7153151Sbrezak /*
391e7153151Sbrezak  * returns true if have a disk
392e7153151Sbrezak  */
3937cb090d9Spk int
394e7153151Sbrezak havedisk()
395e7153151Sbrezak {
396b817db1eSthorpej 	return dk_ndrive != 0;
397e7153151Sbrezak }
398e7153151Sbrezak 
399e7153151Sbrezak void
400e7153151Sbrezak rstat_service(rqstp, transp)
401e7153151Sbrezak 	struct svc_req *rqstp;
402e7153151Sbrezak 	SVCXPRT *transp;
403e7153151Sbrezak {
404e7153151Sbrezak 	union {
405e7153151Sbrezak 		int fill;
406e7153151Sbrezak 	} argument;
407e7153151Sbrezak 	char *result;
4084a5c9a20Spk 	xdrproc_t xdr_argument, xdr_result;
409fed935ebSpk 	char *(*local) __P((void *, struct svc_req *));
410e7153151Sbrezak 
411e7153151Sbrezak 	switch (rqstp->rq_proc) {
412e7153151Sbrezak 	case NULLPROC:
413e7153151Sbrezak 		(void)svc_sendreply(transp, xdr_void, (char *)NULL);
414e7153151Sbrezak 		goto leave;
415e7153151Sbrezak 
416e7153151Sbrezak 	case RSTATPROC_STATS:
4174a5c9a20Spk 		xdr_argument = (xdrproc_t)xdr_void;
4184a5c9a20Spk 		xdr_result = (xdrproc_t)xdr_statstime;
419e7153151Sbrezak                 switch (rqstp->rq_vers) {
420e7153151Sbrezak                 case RSTATVERS_ORIG:
421fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
422fed935ebSpk 				rstatproc_stats_1_svc;
423e7153151Sbrezak                         break;
424e7153151Sbrezak                 case RSTATVERS_SWTCH:
425fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
426fed935ebSpk 				rstatproc_stats_2_svc;
427e7153151Sbrezak                         break;
428e7153151Sbrezak                 case RSTATVERS_TIME:
429fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
430fed935ebSpk 				rstatproc_stats_3_svc;
431e7153151Sbrezak                         break;
432e7153151Sbrezak                 default:
43348b71954Sbrezak                         svcerr_progvers(transp, RSTATVERS_ORIG, RSTATVERS_TIME);
434e7153151Sbrezak                         goto leave;
435e7153151Sbrezak                 }
436e7153151Sbrezak 		break;
437e7153151Sbrezak 
438e7153151Sbrezak 	case RSTATPROC_HAVEDISK:
4394a5c9a20Spk 		xdr_argument = (xdrproc_t)xdr_void;
4404a5c9a20Spk 		xdr_result = (xdrproc_t)xdr_u_int;
441e7153151Sbrezak                 switch (rqstp->rq_vers) {
442e7153151Sbrezak                 case RSTATVERS_ORIG:
443fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
444fed935ebSpk 				rstatproc_havedisk_1_svc;
445e7153151Sbrezak                         break;
446e7153151Sbrezak                 case RSTATVERS_SWTCH:
447fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
448fed935ebSpk 				rstatproc_havedisk_2_svc;
449e7153151Sbrezak                         break;
450e7153151Sbrezak                 case RSTATVERS_TIME:
451fed935ebSpk                         local = (char *(*) __P((void *, struct svc_req *)))
452fed935ebSpk 				rstatproc_havedisk_3_svc;
453e7153151Sbrezak                         break;
454e7153151Sbrezak                 default:
45548b71954Sbrezak                         svcerr_progvers(transp, RSTATVERS_ORIG, RSTATVERS_TIME);
456e7153151Sbrezak                         goto leave;
457e7153151Sbrezak                 }
458e7153151Sbrezak 		break;
459e7153151Sbrezak 
460e7153151Sbrezak 	default:
461e7153151Sbrezak 		svcerr_noproc(transp);
462e7153151Sbrezak 		goto leave;
463e7153151Sbrezak 	}
464e7153151Sbrezak 	bzero((char *)&argument, sizeof(argument));
465b54e7589Scgd 	if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) {
466e7153151Sbrezak 		svcerr_decode(transp);
467e7153151Sbrezak 		goto leave;
468e7153151Sbrezak 	}
469e7153151Sbrezak 	result = (*local)(&argument, rqstp);
470e7153151Sbrezak 	if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
471e7153151Sbrezak 		svcerr_systemerr(transp);
472e7153151Sbrezak 	}
473b54e7589Scgd 	if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) {
474e7153151Sbrezak 		(void)fprintf(stderr, "unable to free arguments\n");
475e7153151Sbrezak 		exit(1);
476e7153151Sbrezak 	}
477e7153151Sbrezak leave:
478e7153151Sbrezak         if (from_inetd)
479e7153151Sbrezak                 exit(0);
480e7153151Sbrezak }
481