diff --git a/libexec/Makefile b/libexec/Makefile index 0da423502f17..4ee010a3c17b 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 5.7 (Berkeley) 4/1/91 SUBDIR= bugfiler comsat crond elvispreserve fingerd ftpd getNAME \ - getty mail.local makekey rexecd rlogind rshd talkd telnetd tftpd + getty mail.local makekey rexecd rlogind rshd rpc.rstatd rpc.rusersd \ + rpc.rwalld talkd telnetd tftpd .include diff --git a/libexec/rpc.rstatd/Makefile b/libexec/rpc.rstatd/Makefile new file mode 100644 index 000000000000..fdb97afc1711 --- /dev/null +++ b/libexec/rpc.rstatd/Makefile @@ -0,0 +1,14 @@ +# +# a makefile for /usr/sbin/rpc.rstatd +# +# $Header: /cvsroot/src/libexec/rpc.rstatd/Makefile,v 1.1 1993/06/03 19:26:15 brezak Exp $ +# + +PROG = rpc.rstatd +SRCS = rstatd.c rstat_proc.c +MAN8= rpc.rstatd.0 + +DPADD= ${LIBRPCSVC} ${LIBRPC} ${LIBUTIL} +LDADD= ${LDARGS} -lrpcsvc -lrpc -lutil + +.include diff --git a/libexec/rpc.rstatd/rpc.rstatd.8 b/libexec/rpc.rstatd/rpc.rstatd.8 new file mode 100644 index 000000000000..005d792369d6 --- /dev/null +++ b/libexec/rpc.rstatd/rpc.rstatd.8 @@ -0,0 +1,24 @@ +.\" @(#)rpc.rstatd.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI +.TH RPC.RSTATD 8C "24 November 1987" +.SH NAME +rpc.rstatd \- kernel statistics server +.SH SYNOPSIS +.B /usr/sbin/rpc.rstatd +.SH DESCRIPTION +.LP +.B rpc.rstatd +is a server which returns performance statistics +obtained from the kernel. +These statistics are read using the +.BR rup (1) +command. +The +.B rpc.rstatd +daemon is normally invoked through /usr/sbin/inetd. +.PP +.B rpc.rstatd +uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x. +.SH "SEE ALSO" +.BR rup (1), +.BR inetd (8), + diff --git a/libexec/rpc.rstatd/rstat_proc.c b/libexec/rpc.rstatd/rstat_proc.c new file mode 100644 index 000000000000..708c9f7c9559 --- /dev/null +++ b/libexec/rpc.rstatd/rstat_proc.c @@ -0,0 +1,419 @@ +/* @(#)rstat_proc.c 2.2 88/08/01 4.0 RPCSRC */ +#ifndef lint +static char sccsid[] = "@(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro"; +#endif + +/* + * Copyright (c) 1984 by Sun Microsystems, Inc. + */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * rstat service: built with rstat.x and derived from rpc.rstatd.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BSD +#include +#include +#else +#include +#endif +#include +#include + +struct nlist nl[] = { +#define X_CPTIME 0 + { "_cp_time" }, +#define X_SUM 1 + { "_sum" }, +#define X_IFNET 2 + { "_ifnet" }, +#define X_DKXFER 3 + { "_dk_xfer" }, +#define X_BOOTTIME 4 + { "_boottime" }, +#define X_HZ 5 + { "_hz" }, +#ifdef vax +#define X_AVENRUN 6 + { "_avenrun" }, +#endif + "", +}; +int firstifnet, numintfs; /* chain of ethernet interfaces */ +int stats_service(); + +extern int from_inetd; +int sincelastreq = 0; /* number of alarms since last request */ +extern int closedown; + +union { + struct stats s1; + struct statsswtch s2; + struct statstime s3; +} stats_all; + +void updatestat(); +static stat_is_init = 0; +extern int errno; + +#ifndef FSCALE +#define FSCALE (1 << 8) +#endif + +#ifndef BSD +/* + * BSD has the kvm facility for getting info from the + * kernel. If you aren't on BSD, this surfices. + */ +int kmem; + +kvm_read(off, addr, size) + unsigned long off, size; + char *addr; +{ + int len; + if (lseek(kmem, (long)off, 0) == -1) + return(-1); + return(read(kmem, addr, size)); +} + +kvm_nlist(nl) + struct nlist *nl; +{ + int n = nlist("/vmunix", nl); + if (nl[0].n_value == 0) + return(n); + + if ((kmem = open("/dev/kmem", 0)) < 0) + return(-1); + return(0); +} +#endif + +stat_init() +{ + stat_is_init = 1; + setup(); + updatestat(); + (void) signal(SIGALRM, updatestat); + alarm(1); +} + +statstime * +rstatproc_stats_3() +{ + if (! stat_is_init) + stat_init(); + sincelastreq = 0; + return(&stats_all.s3); +} + +statsswtch * +rstatproc_stats_2() +{ + if (! stat_is_init) + stat_init(); + sincelastreq = 0; + return(&stats_all.s2); +} + +stats * +rstatproc_stats_1() +{ + if (! stat_is_init) + stat_init(); + sincelastreq = 0; + return(&stats_all.s1); +} + +u_int * +rstatproc_havedisk_3() +{ + static u_int have; + + if (! stat_is_init) + stat_init(); + sincelastreq = 0; + have = havedisk(); + return(&have); +} + +u_int * +rstatproc_havedisk_2() +{ + return(rstatproc_havedisk_3()); +} + +u_int * +rstatproc_havedisk_1() +{ + return(rstatproc_havedisk_3()); +} + +void +updatestat() +{ + int off, i, hz; + struct vmmeter sum; + struct ifnet ifnet; + double avrun[3]; + struct timeval tm, btm; + +#ifdef DEBUG + fprintf(stderr, "entering updatestat\n"); +#endif + if (sincelastreq >= closedown) { +#ifdef DEBUG + fprintf(stderr, "about to closedown\n"); +#endif + if (from_inetd) + exit(0); + else { + stat_is_init = 0; + return; + } + } + sincelastreq++; + + if (kvm_read((long)nl[X_HZ].n_value, (char *)&hz, sizeof hz) != sizeof hz) { + syslog(LOG_ERR, "rstat: can't read hz from kmem\n"); + exit(1); + } + if (kvm_read((long)nl[X_CPTIME].n_value, (char *)stats_all.s1.cp_time, sizeof (stats_all.s1.cp_time)) + != sizeof (stats_all.s1.cp_time)) { + syslog(LOG_ERR, "rstat: can't read cp_time from kmem\n"); + exit(1); + } +#ifdef vax + if (kvm_read((long)nl[X_AVENRUN].n_value, (char *)avrun, sizeof (avrun)) != sizeof (avrun)) { + syslog(LOG_ERR, "rstat: can't read avenrun from kmem\n"); + exit(1); + } +#endif +#ifdef BSD + (void)getloadavg(avrun, sizeof(avrun) / sizeof(avrun[0])); +#endif + stats_all.s2.avenrun[0] = avrun[0] * FSCALE; + stats_all.s2.avenrun[1] = avrun[1] * FSCALE; + stats_all.s2.avenrun[2] = avrun[2] * FSCALE; + if (kvm_read((long)nl[X_BOOTTIME].n_value, (char *)&btm, sizeof (stats_all.s2.boottime)) + != sizeof (stats_all.s2.boottime)) { + syslog(LOG_ERR, "rstat: can't read boottime from kmem\n"); + exit(1); + } + stats_all.s2.boottime.tv_sec = btm.tv_sec; + stats_all.s2.boottime.tv_usec = btm.tv_usec; + + +#ifdef DEBUG + fprintf(stderr, "%d %d %d %d\n", stats_all.s1.cp_time[0], + stats_all.s1.cp_time[1], stats_all.s1.cp_time[2], stats_all.s1.cp_time[3]); +#endif + + if (kvm_read((long)nl[X_SUM].n_value, (char *)&sum, sizeof sum) != sizeof sum) { + syslog(LOG_ERR, "rstat: can't read sum from kmem\n"); + exit(1); + } + stats_all.s1.v_pgpgin = sum.v_pgpgin; + stats_all.s1.v_pgpgout = sum.v_pgpgout; + stats_all.s1.v_pswpin = sum.v_pswpin; + stats_all.s1.v_pswpout = sum.v_pswpout; + stats_all.s1.v_intr = sum.v_intr; + gettimeofday(&tm, (struct timezone *) 0); + stats_all.s1.v_intr -= hz*(tm.tv_sec - btm.tv_sec) + + hz*(tm.tv_usec - btm.tv_usec)/1000000; + stats_all.s2.v_swtch = sum.v_swtch; + + if (kvm_read((long)nl[X_DKXFER].n_value, (char *)stats_all.s1.dk_xfer, sizeof (stats_all.s1.dk_xfer)) + != sizeof (stats_all.s1.dk_xfer)) { + syslog(LOG_ERR, "rstat: can't read dk_xfer from kmem\n"); + exit(1); + } + + stats_all.s1.if_ipackets = 0; + stats_all.s1.if_opackets = 0; + stats_all.s1.if_ierrors = 0; + stats_all.s1.if_oerrors = 0; + stats_all.s1.if_collisions = 0; + for (off = firstifnet, i = 0; off && i < numintfs; i++) { + if (kvm_read(off, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) { + syslog(LOG_ERR, "rstat: can't read ifnet from kmem\n"); + exit(1); + } + stats_all.s1.if_ipackets += ifnet.if_ipackets; + stats_all.s1.if_opackets += ifnet.if_opackets; + stats_all.s1.if_ierrors += ifnet.if_ierrors; + stats_all.s1.if_oerrors += ifnet.if_oerrors; + stats_all.s1.if_collisions += ifnet.if_collisions; + off = (int) ifnet.if_next; + } + gettimeofday((struct timeval *)&stats_all.s3.curtime, + (struct timezone *) 0); + alarm(1); +} + +setup() +{ + struct ifnet ifnet; + int off; + + if (kvm_nlist(nl) != 0) { + syslog(LOG_ERR, "rstatd: Can't get namelist."); + exit (1); + } + + if (kvm_read((long)nl[X_IFNET].n_value, &firstifnet, + sizeof(int)) != sizeof(int)) { + syslog(LOG_ERR, "rstat: can't read firstifnet from kmem\n"); + exit(1); + } + + numintfs = 0; + for (off = firstifnet; off;) { + if (kvm_read(off, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) { + syslog(LOG_ERR, "rstat: can't read ifnet from kmem\n"); + exit(1); + } + numintfs++; + off = (int) ifnet.if_next; + } +} + +/* + * returns true if have a disk + */ +havedisk() +{ + int i, cnt; + long xfer[DK_NDRIVE]; + + if (kvm_nlist(nl) != 0) { + syslog(LOG_ERR, "rstatd: Can't get namelist."); + exit (1); + } + + if (kvm_read((long)nl[X_DKXFER].n_value, (char *)xfer, sizeof xfer)!= sizeof xfer) { + syslog(LOG_ERR, "rstat: can't read kmem\n"); + exit(1); + } + cnt = 0; + for (i=0; i < DK_NDRIVE; i++) + cnt += xfer[i]; + return (cnt != 0); +} + +void +rstat_service(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + union { + int fill; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void)svc_sendreply(transp, xdr_void, (char *)NULL); + goto leave; + + case RSTATPROC_STATS: + xdr_argument = xdr_void; + xdr_result = xdr_statstime; + switch (rqstp->rq_vers) { + case RSTATVERS_ORIG: + local = (char *(*)()) rstatproc_stats_1; + break; + case RSTATVERS_SWTCH: + local = (char *(*)()) rstatproc_stats_2; + break; + case RSTATVERS_TIME: + local = (char *(*)()) rstatproc_stats_3; + break; + default: + svcerr_progvers(transp); + goto leave; + /*NOTREACHED*/ + } + break; + + case RSTATPROC_HAVEDISK: + xdr_argument = xdr_void; + xdr_result = xdr_u_int; + switch (rqstp->rq_vers) { + case RSTATVERS_ORIG: + local = (char *(*)()) rstatproc_havedisk_1; + break; + case RSTATVERS_SWTCH: + local = (char *(*)()) rstatproc_havedisk_2; + break; + case RSTATVERS_TIME: + local = (char *(*)()) rstatproc_havedisk_3; + break; + default: + svcerr_progvers(transp); + goto leave; + /*NOTREACHED*/ + } + break; + + default: + svcerr_noproc(transp); + goto leave; + } + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + goto leave; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + (void)fprintf(stderr, "unable to free arguments\n"); + exit(1); + } +leave: + if (from_inetd) + exit(0); +} diff --git a/libexec/rpc.rstatd/rstatd.c b/libexec/rpc.rstatd/rstatd.c new file mode 100644 index 000000000000..6b1fbac604ed --- /dev/null +++ b/libexec/rpc.rstatd/rstatd.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 1993, John Brezak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +extern void rstat_service(); + +int from_inetd = 1; /* started from inetd ? */ +int closedown = 20; /* how long to wait before going dormant */ + +void +cleanup() +{ + (void) pmap_unset(RSTATPROG, RSTATVERS_TIME); + (void) pmap_unset(RSTATPROG, RSTATVERS_SWTCH); + (void) pmap_unset(RSTATPROG, RSTATVERS_ORIG); + exit(0); +} + +main(argc, argv) + int argc; + char *argv[]; +{ + SVCXPRT *transp; + int sock = 0; + int proto = 0; + struct sockaddr_in from; + int fromlen; + + if (argc == 2) + closedown = atoi(argv[1]); + if (closedown <= 0) + closedown = 20; +#if 1 + /* + * See if inetd started us + */ + if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) { + from_inetd = 0; + sock = RPC_ANYSOCK; + proto = IPPROTO_UDP; + } + + if (!from_inetd) { + daemon(0, 0); + + (void)pmap_unset(RSTATPROG, RSTATVERS_TIME); + (void)pmap_unset(RSTATPROG, RSTATVERS_SWTCH); + (void)pmap_unset(RSTATPROG, RSTATVERS_ORIG); + } +#endif + + openlog("rpc.rusersd", LOG_PID, LOG_DAEMON); + + transp = svcudp_create(sock); + if (transp == NULL) { + syslog(LOG_ERR, "cannot create udp service."); + exit(1); + } + if (!svc_register(transp, RSTATPROG, RSTATVERS_TIME, rstat_service, proto)) { + syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_TIME, udp)."); + exit(1); + } + if (!svc_register(transp, RSTATPROG, RSTATVERS_SWTCH, rstat_service, proto)) { + syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_SWTCH, udp)."); + exit(1); + } + if (!svc_register(transp, RSTATPROG, RSTATVERS_ORIG, rstat_service, proto)) { + syslog(LOG_ERR, "unable to register (RSTATPROG, RSTATVERS_ORIG, udp)."); + exit(1); + } + (void) signal(SIGINT, cleanup); + (void) signal(SIGTERM, cleanup); + (void) signal(SIGHUP, cleanup); + + svc_run(); + syslog(LOG_ERR, "svc_run returned"); + exit(1); +} diff --git a/libexec/rpc.rusersd/Makefile b/libexec/rpc.rusersd/Makefile new file mode 100644 index 000000000000..24d531612d19 --- /dev/null +++ b/libexec/rpc.rusersd/Makefile @@ -0,0 +1,14 @@ +# +# a makefile for /usr/sbin/rpc.rusersd +# +# $Header: /cvsroot/src/libexec/rpc.rusersd/Makefile,v 1.1 1993/06/03 19:26:21 brezak Exp $ +# + +PROG = rpc.rusersd +SRCS = rusersd.c rusers_proc.c +NOMAN= noman + +DPADD= ${LIBRPCSVC} ${LIBRPC} ${LIBUTIL} +LDADD= ${LDARGS} -lrpcsvc -lrpc -lutil + +.include diff --git a/libexec/rpc.rusersd/rusers_proc.c b/libexec/rpc.rusersd/rusers_proc.c new file mode 100644 index 000000000000..6acf302a60cb --- /dev/null +++ b/libexec/rpc.rusersd/rusers_proc.c @@ -0,0 +1,373 @@ +/*- + * Copyright (c) 1993, John Brezak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef XIDLE +#include +#include +#endif +#define utmp rutmp +#include +#undef utmp + +#define IGNOREUSER "sleeper" + +#ifdef OSF +#define _PATH_UTMP UTMP_FILE +#endif + +#ifndef _PATH_UTMP +#define _PATH_UTMP "/etc/utmp" +#endif + +#ifndef _PATH_DEV +#define _PATH_DEV "/dev" +#endif + +#ifndef UT_LINESIZE +#define UT_LINESIZE sizeof(((struct utmp *)0)->ut_line) +#endif +#ifndef UT_NAMESIZE +#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name) +#endif +#ifndef UT_HOSTSIZE +#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host) +#endif + +typedef char ut_line_t[UT_LINESIZE]; +typedef char ut_name_t[UT_NAMESIZE]; +typedef char ut_host_t[UT_HOSTSIZE]; + +utmpidle utmp_idle[MAXUSERS]; +rutmp old_utmp[MAXUSERS]; +ut_line_t line[MAXUSERS]; +ut_name_t name[MAXUSERS]; +ut_host_t host[MAXUSERS]; + +extern int from_inetd; + +FILE *ufp; + +#ifdef XIDLE +Display *dpy; + +static jmp_buf openAbort; + +static void +abortOpen () +{ + longjmp (openAbort, 1); +} + +XqueryIdle(char *display) +{ + int first_event, first_error; + Time IdleTime; + + (void) signal (SIGALRM, abortOpen); + (void) alarm ((unsigned) 10); + if (!setjmp (openAbort)) { + if (!(dpy= XOpenDisplay(display))) { + syslog(LOG_ERR, "Cannot open display %s", display); + return(-1); + } + if (XidleQueryExtension(dpy, &first_event, &first_error)) { + if (!XGetIdleTime(dpy, &IdleTime)) { + syslog(LOG_ERR, "%s: Unable to get idle time.", display); + return(-1); + } + } + else { + syslog(LOG_ERR, "%s: Xidle extension not loaded.", display); + return(-1); + } + XCloseDisplay(dpy); + } + else { + syslog(LOG_ERR, "%s: Server grabbed for over 10 seconds.", display); + return(-1); + } + (void) signal (SIGALRM, SIG_DFL); + (void) alarm ((unsigned) 0); + + idleTime /= 1000; + return((idleTime + 30) / 60); +} +#endif + +static u_int +getidle(char *tty, char *display) +{ + struct stat st; + char devname[PATH_MAX]; + time_t now; + u_long idle = 0; + + /* + * If this is an X terminal or console, then try the + * XIdle extension + */ +#ifdef XIDLE + if (display && (idle = XqueryIdle(display)) >= 0) + return(idle); +#endif + if (*tty == 'X') { + u_long kbd_idle, mouse_idle; + kbd_idle = getidle("kbd", NULL); + mouse_idle = getidle("mouse", NULL); + idle = (kbd_idle < mouse_idle)?kbd_idle:mouse_idle; + } + else { + sprintf(devname, "%s/%s", _PATH_DEV, tty); + if (stat(devname, &st) < 0) { + syslog(LOG_ERR, "%s: %m", devname); + return(-1); + } + time(&now); +#ifdef DEBUG + printf("%s: now=%d atime=%d\n", devname, now, + st.st_atime); +#endif + idle = now - st.st_atime; + idle = (idle + 30) / 60; /* secs->mins */ + } + if (idle < 0) idle = 0; + + return(idle); +} + +static utmpidlearr * +do_names_2(int all) +{ + static utmpidlearr ut; + struct utmp usr; + int nusers = 0; + + bzero((char *)&ut, sizeof(ut)); + ut.utmpidlearr_val = &utmp_idle[0]; + + ufp = fopen(_PATH_UTMP, "r"); + if (!ufp) { + syslog(LOG_ERR, "%m"); + return(&ut); + } + + /* only entries with both name and line fields */ + while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1 && + nusers < MAXUSERS) + if (*usr.ut_name && *usr.ut_line && + strncmp(usr.ut_name, IGNOREUSER, + sizeof(usr.ut_name)) +#ifdef OSF + && usr.ut_type == USER_PROCESS +#endif + ) { + utmp_idle[nusers].ui_utmp.ut_time = + usr.ut_time; + utmp_idle[nusers].ui_idle = + getidle(usr.ut_line, usr.ut_host); + utmp_idle[nusers].ui_utmp.ut_line = line[nusers]; + strncpy(line[nusers], usr.ut_line, sizeof(line[nusers])); + utmp_idle[nusers].ui_utmp.ut_name = name[nusers]; + strncpy(name[nusers], usr.ut_name, sizeof(name[nusers])); + utmp_idle[nusers].ui_utmp.ut_host = host[nusers]; + strncpy(host[nusers], usr.ut_host, sizeof(host[nusers])); + nusers++; + } + + ut.utmpidlearr_len = nusers; + fclose(ufp); + return(&ut); +} + +int * +rusers_num() +{ + int num_users = 0; + struct utmp usr; + + ufp = fopen(_PATH_UTMP, "r"); + if (!ufp) { + syslog(LOG_ERR, "%m"); + return(0); + } + + /* only entries with both name and line fields */ + while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1) + if (*usr.ut_name && *usr.ut_line && + strncmp(usr.ut_name, IGNOREUSER, + sizeof(usr.ut_name)) +#ifdef OSF + && usr.ut_type == USER_PROCESS +#endif + ) { + num_users++; + } + + fclose(ufp); + return(&num_users); +} + +static utmparr * +do_names_1(int all) +{ + utmpidlearr *utidle; + utmparr ut; + int i; + + bzero((char *)&ut, sizeof(ut)); + + utidle = do_names_2(all); + if (utidle) { + ut.utmparr_len = utidle->utmpidlearr_len; + ut.utmparr_val = &old_utmp[0]; + for (i = 0; i < ut.utmparr_len; i++) + bcopy(&utmp_idle[i].ui_utmp, &old_utmp[i], + sizeof(old_utmp[0])); + + } + + return(&ut); +} + +utmpidlearr * +rusersproc_names_2() +{ + return(do_names_2(0)); +} + +utmpidlearr * +rusersproc_allnames_2() +{ + return(do_names_2(1)); +} + +utmparr * +rusersproc_names_1() +{ + return(do_names_1(0)); +} + +utmparr * +rusersproc_allnames_1() +{ + return(do_names_1(1)); +} + +void +rusers_service(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + union { + int fill; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void)svc_sendreply(transp, xdr_void, (char *)NULL); + goto leave; + + case RUSERSPROC_NUM: + xdr_argument = xdr_void; + xdr_result = xdr_int; + local = (char *(*)()) rusers_num; + break; + + case RUSERSPROC_NAMES: + xdr_argument = xdr_void; + xdr_result = xdr_utmpidlearr; + switch (rqstp->rq_vers) { + case RUSERSVERS_ORIG: + local = (char *(*)()) rusersproc_names_1; + break; + case RUSERSVERS_IDLE: + local = (char *(*)()) rusersproc_names_2; + break; + default: + svcerr_progvers(transp); + goto leave; + /*NOTREACHED*/ + } + break; + + case RUSERSPROC_ALLNAMES: + xdr_argument = xdr_void; + xdr_result = xdr_utmpidlearr; + switch (rqstp->rq_vers) { + case RUSERSVERS_ORIG: + local = (char *(*)()) rusersproc_allnames_1; + break; + case RUSERSVERS_IDLE: + local = (char *(*)()) rusersproc_allnames_2; + break; + default: + svcerr_progvers(transp); + goto leave; + /*NOTREACHED*/ + } + break; + + default: + svcerr_noproc(transp); + goto leave; + } + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + goto leave; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + (void)fprintf(stderr, "unable to free arguments\n"); + exit(1); + } +leave: + if (from_inetd) + exit(0); +} diff --git a/libexec/rpc.rusersd/rusersd.c b/libexec/rpc.rusersd/rusersd.c new file mode 100644 index 000000000000..f85a7bd9ce70 --- /dev/null +++ b/libexec/rpc.rusersd/rusersd.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 1993, John Brezak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#define utmp rutmp +#include +#undef utmp + +extern void rusers_service(); + +int from_inetd = 1; + +void +cleanup() +{ + (void) pmap_unset(RUSERSPROG, RUSERSVERS_IDLE); + (void) pmap_unset(RUSERSPROG, RUSERSVERS_ORIG); + exit(0); +} + +main(argc, argv) + int argc; + char *argv[]; +{ + SVCXPRT *transp; + int sock = 0; + int proto = 0; + struct sockaddr_in from; + int fromlen; + + /* + * See if inetd started us + */ + if (getsockname(0, (struct sockaddr *)&from, &fromlen) < 0) { + from_inetd = 0; + sock = RPC_ANYSOCK; + proto = IPPROTO_UDP; + } + + if (!from_inetd) { + daemon(0, 0); + + (void) pmap_unset(RUSERSPROG, RUSERSVERS_IDLE); + (void) pmap_unset(RUSERSPROG, RUSERSVERS_ORIG); + } + + openlog("rpc.rusersd", LOG_PID, LOG_DAEMON); + + transp = svcudp_create(sock); + if (transp == NULL) { + syslog(LOG_ERR, "cannot create udp service."); + exit(1); + } + if (!svc_register(transp, RUSERSPROG, RUSERSVERS_IDLE, rusers_service, proto)) { + syslog(LOG_ERR, "unable to register (RUSERSPROG, RUSERSVERS_IDLE, %s).", proto?"udp":"(inetd)"); + exit(1); + } + + if (!svc_register(transp, RUSERSPROG, RUSERSVERS_ORIG, rusers_service, proto)) { + syslog(LOG_ERR, "unable to register (RUSERSPROG, RUSERSVERS_ORIG, %s).", proto?"udp":"(inetd)"); + exit(1); + } + + (void) signal(SIGINT, cleanup); + (void) signal(SIGTERM, cleanup); + (void) signal(SIGHUP, cleanup); + + svc_run(); + syslog(LOG_ERR, "svc_run returned"); + exit(1); +} diff --git a/libexec/rpc.rwalld/Makefile b/libexec/rpc.rwalld/Makefile new file mode 100644 index 000000000000..e4b79f92f3fe --- /dev/null +++ b/libexec/rpc.rwalld/Makefile @@ -0,0 +1,14 @@ +# +# a makefile for /usr/sbin/rpc.rwalld +# +# $Header: /cvsroot/src/libexec/rpc.rwalld/Makefile,v 1.1 1993/06/03 19:26:30 brezak Exp $ +# + +PROG = rpc.rwalld +SRCS = rwalld.c +NOMAN= noman + +DPADD= ${LIBRPCSVC} ${LIBRPC} ${LIBUTIL} +LDADD= ${LDARGS} -lrpcsvc -lrpc -lutil + +.include diff --git a/libexec/rpc.rwalld/rwalld.c b/libexec/rpc.rwalld/rwalld.c new file mode 100644 index 000000000000..f0cfedf61cdf --- /dev/null +++ b/libexec/rpc.rwalld/rwalld.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1993 Christopher G. Demetriou + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char rcsid[] = "/b/source/CVS/src/usr.sbin/rwalld/rwalld.c,v 1.2 1993/04/10 17:59:30 cgd Exp"; +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef OSF +#define WALL_CMD "/usr/sbin/wall" +#else +#define WALL_CMD "/usr/bin/wall -n" +#endif + +void wallprog_1(); +void possess(); +void killkids(); + +int nodaemon = 0; +int from_inetd = 1; + +main(argc, argv) + int argc; + char *argv[]; +{ + SVCXPRT *transp; + int s, salen; + struct sockaddr_in sa; + int sock = 0; + int proto = 0; + + if (argc == 2 && !strcmp(argv[1], "-n")) + nodaemon = 1; + if (argc != 1 && !nodaemon) { + printf("usage: %s [-n]\n", argv[0]); + exit(1); + } + + if (geteuid() == 0) { + struct passwd *pep = getpwnam("nobody"); + if (pep) + setuid(pep->pw_uid); + else + setuid(getuid()); + } + + /* + * See if inetd started us + */ + if (getsockname(0, (struct sockaddr *)&sa, &salen) < 0) { + from_inetd = 0; + sock = RPC_ANYSOCK; + proto = IPPROTO_UDP; + } + + if (!from_inetd) { + if (!nodaemon) + possess(); + + (void)pmap_unset(WALLPROG, WALLVERS); + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("socket"); + exit(1); + } + bzero((char *)&sa, sizeof sa); + if (bind(s, (struct sockaddr *)&sa, sizeof sa) < 0) { + perror("bind"); + exit(1); + } + + salen = sizeof sa; + if (getsockname(s, (struct sockaddr *)&sa, &salen)) { + perror("getsockname"); + exit(1); + } + + pmap_set(WALLPROG, WALLVERS, IPPROTO_UDP, ntohs(sa.sin_port)); + if (dup2(s, 0) < 0) { + perror("dup2"); + exit(1); + } + (void)pmap_unset(WALLPROG, WALLVERS); + } + + (void)signal(SIGCHLD, killkids); + + transp = svcudp_create(sock); + if (transp == NULL) { + (void)fprintf(stderr, "cannot create udp service.\n"); + exit(1); + } + if (!svc_register(transp, WALLPROG, WALLVERS, wallprog_1, proto)) { + (void)fprintf(stderr, "unable to register (WALLPROG, WALLVERS, udp).\n"); + exit(1); + } + svc_run(); + (void)fprintf(stderr, "svc_run returned\n"); + exit(1); + +} + +void possess() +{ + daemon(0, 0); +} + +void killkids() +{ + while(wait4(-1, NULL, WNOHANG, NULL) > 0) + ; +} + +void *wallproc_wall_1(s) + char **s; +{ + /* fork, popen wall with special option, and send the message */ + if (fork() == 0) { + FILE *pfp; + + pfp = popen(WALL_CMD, "w"); + if (pfp != NULL) { + fprintf(pfp, "\007\007%s", *s); + pclose(pfp); + exit(0); + } + } +} + +void +wallprog_1(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + union { + char *wallproc_wall_1_arg; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void)svc_sendreply(transp, xdr_void, (char *)NULL); + goto leave; + + case WALLPROC_WALL: + xdr_argument = xdr_wrapstring; + xdr_result = xdr_void; + local = (char *(*)()) wallproc_wall_1; + break; + + default: + svcerr_noproc(transp); + goto leave; + } + bzero((char *)&argument, sizeof(argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + goto leave; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + (void)fprintf(stderr, "unable to free arguments\n"); + exit(1); + } +leave: + if (from_inetd) + exit(0); +}