2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 1993, John Brezak
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * $FreeBSD: head/libexec/rpc.rusersd/rusers_proc.c 326025 2017-11-20 19:49:47Z pfg $
40 #include <sys/param.h>
47 #include <X11/extensions/xidle.h>
49 #include <rpcsvc/rnusers.h>
54 #define _PATH_DEV "/dev"
57 static utmpidle utmp_idle
[MAXUSERS
];
58 static utmp old_utmp
[MAXUSERS
];
59 static struct utmpx utmp_list
[MAXUSERS
];
64 static jmp_buf openAbort
;
69 longjmp (openAbort
, 1);
72 XqueryIdle(char *display
)
74 int first_event
, first_error
;
77 (void) signal (SIGALRM
, abortOpen
);
78 (void) alarm ((unsigned) 10);
79 if (!setjmp (openAbort
)) {
80 if (!(dpy
= XOpenDisplay(display
))) {
81 syslog(LOG_ERR
, "Cannot open display %s", display
);
84 if (XidleQueryExtension(dpy
, &first_event
, &first_error
)) {
85 if (!XGetIdleTime(dpy
, &IdleTime
)) {
86 syslog(LOG_ERR
, "%s: unable to get idle time", display
);
90 syslog(LOG_ERR
, "%s: Xidle extension not loaded", display
);
95 syslog(LOG_ERR
, "%s: server grabbed for over 10 seconds", display
);
98 (void) signal (SIGALRM
, SIG_DFL
);
99 (void) alarm ((unsigned) 0);
102 return((IdleTime
+ 30) / 60);
107 getidle(const char *tty
, const char *display __unused
)
110 char ttyname
[PATH_MAX
];
115 * If this is an X terminal or console, then try the
119 if (display
&& *display
&& (idle
= XqueryIdle(display
)) >= 0)
124 u_long kbd_idle
, mouse_idle
;
125 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
126 kbd_idle
= getidle("kbd", NULL
);
128 kbd_idle
= getidle("vga", NULL
);
130 mouse_idle
= getidle("mouse", NULL
);
131 idle
= (kbd_idle
< mouse_idle
)?kbd_idle
:mouse_idle
;
133 sprintf(ttyname
, "%s/%s", _PATH_DEV
, tty
);
134 if (stat(ttyname
, &st
) < 0) {
136 printf("%s: %s\n", ttyname
, strerror(errno
));
142 printf("%s: now=%d atime=%d\n", ttyname
, now
,
145 idle
= now
- st
.st_atime
;
146 idle
= (idle
+ 30) / 60; /* secs->mins */
155 static utmpidlearr ut
;
159 memset(&ut
, 0, sizeof(ut
));
160 ut
.utmpidlearr_val
= &utmp_idle
[0];
163 while ((usr
= getutxent()) != NULL
&& nusers
< MAXUSERS
) {
164 if (usr
->ut_type
!= USER_PROCESS
)
167 memcpy(&utmp_list
[nusers
], usr
, sizeof(*usr
));
168 utmp_idle
[nusers
].ui_utmp
.ut_time
= usr
->ut_tv
.tv_sec
;
169 utmp_idle
[nusers
].ui_idle
=
170 getidle(usr
->ut_line
, usr
->ut_host
);
171 utmp_idle
[nusers
].ui_utmp
.ut_line
=
172 utmp_list
[nusers
].ut_line
;
173 utmp_idle
[nusers
].ui_utmp
.ut_name
=
174 utmp_list
[nusers
].ut_user
;
175 utmp_idle
[nusers
].ui_utmp
.ut_host
=
176 utmp_list
[nusers
].ut_host
;
182 ut
.utmpidlearr_len
= nusers
;
187 rusers_num(void *argp __unused
, struct svc_req
*rqstp __unused
)
189 static int num_users
= 0;
193 while ((usr
= getutxent()) != NULL
) {
194 if (usr
->ut_type
!= USER_PROCESS
)
210 bzero((char *)&ut
, sizeof(ut
));
212 utidle
= do_names_2();
214 ut
.utmparr_len
= utidle
->utmpidlearr_len
;
215 ut
.utmparr_val
= &old_utmp
[0];
216 for (i
= 0; i
< ut
.utmparr_len
; i
++)
217 bcopy(&utmp_idle
[i
].ui_utmp
, &old_utmp
[i
],
218 sizeof(old_utmp
[0]));
226 rusersproc_names_2_svc(void *argp __unused
, struct svc_req
*rqstp __unused
)
228 return (do_names_2());
232 rusersproc_allnames_2_svc(void *argp __unused
, struct svc_req
*rqstp __unused
)
234 return (do_names_2());
238 rusersproc_names_1_svc(void *argp __unused
, struct svc_req
*rqstp __unused
)
240 return (do_names_1());
244 rusersproc_allnames_1_svc(void *argp __unused
, struct svc_req
*rqstp __unused
)
246 return (do_names_1());
249 typedef void *(*rusersproc_t
)(void *, struct svc_req
*);
252 rusers_service(struct svc_req
*rqstp
, SVCXPRT
*transp
)
258 xdrproc_t xdr_argument
, xdr_result
;
261 switch (rqstp
->rq_proc
) {
263 (void)svc_sendreply(transp
, (xdrproc_t
)xdr_void
, NULL
);
267 xdr_argument
= (xdrproc_t
)xdr_void
;
268 xdr_result
= (xdrproc_t
)xdr_int
;
269 local
= (rusersproc_t
)rusers_num
;
272 case RUSERSPROC_NAMES
:
273 xdr_argument
= (xdrproc_t
)xdr_void
;
274 xdr_result
= (xdrproc_t
)xdr_utmpidlearr
;
275 switch (rqstp
->rq_vers
) {
276 case RUSERSVERS_ORIG
:
277 local
= (rusersproc_t
)rusersproc_names_1_svc
;
279 case RUSERSVERS_IDLE
:
280 local
= (rusersproc_t
)rusersproc_names_2_svc
;
283 svcerr_progvers(transp
, RUSERSVERS_ORIG
, RUSERSVERS_IDLE
);
289 case RUSERSPROC_ALLNAMES
:
290 xdr_argument
= (xdrproc_t
)xdr_void
;
291 xdr_result
= (xdrproc_t
)xdr_utmpidlearr
;
292 switch (rqstp
->rq_vers
) {
293 case RUSERSVERS_ORIG
:
294 local
= (rusersproc_t
)rusersproc_allnames_1_svc
;
296 case RUSERSVERS_IDLE
:
297 local
= (rusersproc_t
)rusersproc_allnames_2_svc
;
300 svcerr_progvers(transp
, RUSERSVERS_ORIG
, RUSERSVERS_IDLE
);
307 svcerr_noproc(transp
);
310 bzero(&argument
, sizeof(argument
));
311 if (!svc_getargs(transp
, (xdrproc_t
)xdr_argument
, &argument
)) {
312 svcerr_decode(transp
);
315 result
= (*local
)(&argument
, rqstp
);
316 if (result
!= NULL
&&
317 !svc_sendreply(transp
, (xdrproc_t
)xdr_result
, result
)) {
318 svcerr_systemerr(transp
);
320 if (!svc_freeargs(transp
, (xdrproc_t
)xdr_argument
, &argument
)) {
321 syslog(LOG_ERR
, "unable to free arguments");