* Copyright (c) 1993, John Brezak
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
static char rcsid
[] = "$Id: rusers_proc.c,v 1.1 1993/09/16 00:34:46 jtc Exp $";
#include <X11/extensions/xidle.h>
#include <rpcsvc/rnusers.h>
#define IGNOREUSER "sleeper"
#define _PATH_UTMP UTMP_FILE
#define _PATH_UTMP "/etc/utmp"
#define UT_LINESIZE sizeof(((struct utmp *)0)->ut_line)
#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
typedef char ut_line_t
[UT_LINESIZE
+1];
typedef char ut_name_t
[UT_NAMESIZE
+1];
typedef char ut_host_t
[UT_HOSTSIZE
+1];
utmpidle utmp_idle
[MAXUSERS
];
rutmp old_utmp
[MAXUSERS
];
ut_line_t line
[MAXUSERS
];
ut_name_t name
[MAXUSERS
];
ut_host_t host
[MAXUSERS
];
static jmp_buf openAbort
;
XqueryIdle(char *display
)
int first_event
, first_error
;
(void) signal (SIGALRM
, abortOpen
);
(void) alarm ((unsigned) 10);
if (!setjmp (openAbort
)) {
if (!(dpy
= XOpenDisplay(display
))) {
syslog(LOG_ERR
, "Cannot open display %s", display
);
if (XidleQueryExtension(dpy
, &first_event
, &first_error
)) {
if (!XGetIdleTime(dpy
, &IdleTime
)) {
syslog(LOG_ERR
, "%s: Unable to get idle time.", display
);
syslog(LOG_ERR
, "%s: Xidle extension not loaded.", display
);
syslog(LOG_ERR
, "%s: Server grabbed for over 10 seconds.", display
);
(void) signal (SIGALRM
, SIG_DFL
);
(void) alarm ((unsigned) 0);
return((IdleTime
+ 30) / 60);
getidle(char *tty
, char *display
)
* If this is an X terminal or console, then try the
if (display
&& *display
&& (idle
= XqueryIdle(display
)) >= 0)
u_long kbd_idle
, mouse_idle
;
kbd_idle
= getidle("kbd", NULL
);
kbd_idle
= getidle("vga", NULL
);
mouse_idle
= getidle("mouse", NULL
);
idle
= (kbd_idle
< mouse_idle
)?kbd_idle
:mouse_idle
;
sprintf(devname
, "%s/%s", _PATH_DEV
, tty
);
if (stat(devname
, &st
) < 0) {
printf("%s: %s\n", devname
, strerror(errno
));
printf("%s: now=%d atime=%d\n", devname
, now
,
idle
= now
- st
.st_atime
;
idle
= (idle
+ 30) / 60; /* secs->mins */
bzero((char *)&ut
, sizeof(ut
));
ut
.utmpidlearr_val
= &utmp_idle
[0];
ufp
= fopen(_PATH_UTMP
, "r");
/* 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
,
&& usr
.ut_type
== USER_PROCESS
utmp_idle
[nusers
].ui_utmp
.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
, UT_LINESIZE
);
utmp_idle
[nusers
].ui_utmp
.ut_name
= name
[nusers
];
strncpy(name
[nusers
], usr
.ut_name
, UT_NAMESIZE
);
utmp_idle
[nusers
].ui_utmp
.ut_host
= host
[nusers
];
strncpy(host
[nusers
], usr
.ut_host
, UT_HOSTSIZE
);
/* Make sure entries are NUL terminated */
line
[nusers
][UT_LINESIZE
] =
name
[nusers
][UT_NAMESIZE
] =
host
[nusers
][UT_HOSTSIZE
] = '\0';
ut
.utmpidlearr_len
= nusers
;
ufp
= fopen(_PATH_UTMP
, "r");
/* 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
,
&& usr
.ut_type
== USER_PROCESS
bzero((char *)&ut
, sizeof(ut
));
utidle
= do_names_2(all
);
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
],
rusers_service(rqstp
, transp
)
bool_t (*xdr_argument
)(), (*xdr_result
)();
switch (rqstp
->rq_proc
) {
(void)svc_sendreply(transp
, xdr_void
, (char *)NULL
);
local
= (char *(*)()) rusers_num
;
xdr_result
= xdr_utmpidlearr
;
switch (rqstp
->rq_vers
) {
local
= (char *(*)()) rusersproc_names_1
;
local
= (char *(*)()) rusersproc_names_2
;
svcerr_progvers(transp
, RUSERSVERS_ORIG
, RUSERSVERS_IDLE
);
case RUSERSPROC_ALLNAMES
:
xdr_result
= xdr_utmpidlearr
;
switch (rqstp
->rq_vers
) {
local
= (char *(*)()) rusersproc_allnames_1
;
local
= (char *(*)()) rusersproc_allnames_2
;
svcerr_progvers(transp
, RUSERSVERS_ORIG
, RUSERSVERS_IDLE
);
bzero((char *)&argument
, sizeof(argument
));
if (!svc_getargs(transp
, xdr_argument
, &argument
)) {
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");