From owner-freebsd-hackers Sat Dec 16 12:31:17 1995 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id MAA29294 for hackers-outgoing; Sat, 16 Dec 1995 12:31:17 -0800 (PST) Received: from jau.csc.fi (root@jau.csc.fi [193.166.1.196]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id MAA29286 for ; Sat, 16 Dec 1995 12:31:06 -0800 (PST) Received: (from jau@localhost) by jau.csc.fi (8.6.12/8.6.12+CSC-2.1) id WAA07616 for hackers@freebsd.org; Sat, 16 Dec 1995 22:31:19 +0200 From: Jukka Ukkonen Message-Id: <199512162031.WAA07616@jau.csc.fi> Subject: rusers(3) & rnusers(3) To: hackers@freebsd.org Date: Sat, 16 Dec 1995 22:31:17 +0200 (EET) Latin-Date: Simbata XVI Decembrie a.d. MCMXCV Organization: Private person Phone: +358-0-6215280 (home) Content-Conversion: prohibited X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: owner-hackers@freebsd.org Precedence: bulk Hello everybody! After getting a bit frustrated of not having the library routines rusers(3) and rnusers(3) available on FreeBSD I wrote them as well as the underlying xdr_utmpidlearr etc. I have tested them to work between FreeBSD and SunOS-4.1.4, and between FreeBSD and ConvexOS versions 11.0 and 10.1, and also between FreeBSD and Irix versions 6.1, 6.0.1, and 5.2. So, I am not making any claims about any other combinations. In the hope that some of you might be willing to test my rusers stuff against other combinations of OS's I attach it at the end of this message. And as the normal practise is ... "You can use it or abuse it, as long as you don't sell it, and you retain my name on it. If it breaks you get to keep all the pieces." BTW My rnusers() seems to return 0 for practically any computer you care to ask the number of users. On the other hand Sun's own version of rnusers() does the very same thing. This gives me a reason to believe it is Sun's own server code which has spread around to other platforms that is the culprit, not my rnusers(). Cheers, // jau ------ / Jukka A. Ukkonen, FUNET / Centre for Scientific Computing /__ M.Sc. (sw-eng & cs) Tel: (Home) +358-0-6215280 / Internet: ukkonen@csc.fi (Work) +358-0-4573208 / Internet: jau@funet.fi (Mobile) +358-400-606671 v X.400: c=fi, admd=fumail, no prmd, org=csc, pn=jukka.ukkonen # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # rusers.c # rusers.h # rusers_xdr.c # rnusers.c # echo x - rusers.c sed 's/^X//' >rusers.c << 'END-of-rusers.c' X X#include X#include X#include X#include X#include X Xint Xrusers (host, user_arr) X char *host; X struct utmpidlearr *user_arr; X{ X register int failstat; X X if (!host || !*host || !user_arr) { X errno = EINVAL; X return (-1); X } X X memset (user_arr, '\0', sizeof (*user_arr)); X X if (failstat = callrpc (host, RUSERSPROG, X RUSERSVERS_IDLE, RUSERSPROC_NAMES, X xdr_void, NULL, xdr_utmpidlearr, user_arr)) { X clnt_perrno (failstat); X X return (-1); X } X X return (0); X} X END-of-rusers.c echo x - rusers.h sed 's/^X//' >rusers.h << 'END-of-rusers.h' X#define MAXUSERS 100 X#define MAXUTLEN 256 X Xstruct rutmp { X char *ut_line; X char *ut_name; X char *ut_host; X long ut_time; X}; Xtypedef struct rutmp rutmp; Xbool_t xdr_rutmp(); X X Xtypedef rutmp *utmpptr; Xbool_t xdr_utmpptr(); X X Xstruct utmparr { X utmpptr *uta_arr; X u_int uta_cnt; X}; Xtypedef struct utmparr utmparr; Xbool_t xdr_utmparr(); X X Xstruct utmpidle { X struct rutmp ui_utmp; X u_long ui_idle; X}; Xtypedef struct utmpidle utmpidle; Xbool_t xdr_utmpidle(); X X Xtypedef utmpidle *utmpidleptr; Xbool_t xdr_utmpidleptr(); X X Xstruct utmpidlearr { X utmpidleptr *uia_arr; X u_int uia_cnt; X}; Xtypedef struct utmpidlearr utmpidlearr; Xbool_t xdr_utmpidlearr(); X X X#define RUSERSPROG ((u_long)100002) X#define RUSERSVERS_ORIG ((u_long)1) X#define RUSERSPROC_NUM ((u_long)1) Xextern int *rusersproc_num_1(); X#define RUSERSPROC_NAMES ((u_long)2) Xextern utmparr *rusersproc_names_1(); X#define RUSERSPROC_ALLNAMES ((u_long)3) Xextern utmparr *rusersproc_allnames_1(); X#define RUSERSVERS_IDLE ((u_long)2) Xextern int *rusersproc_num_2(); Xextern utmpidlearr *rusersproc_names_2(); Xextern utmpidlearr *rusersproc_allnames_2(); X END-of-rusers.h echo x - rusers_xdr.c sed 's/^X//' >rusers_xdr.c << 'END-of-rusers_xdr.c' X#include X#include "rusers.h" X X Xbool_t Xxdr_rutmp(xdrs, objp) X XDR *xdrs; X rutmp *objp; X{ X unsigned int slen; X X if (! xdr_string (xdrs, &objp->ut_line, MAXUTLEN)) { X return (FALSE); X } X X if (! xdr_string (xdrs, &objp->ut_name, MAXUTLEN)) { X return (FALSE); X } X X if (! xdr_string (xdrs, &objp->ut_host, MAXUTLEN)) { X return (FALSE); X } X X if (! xdr_u_long (xdrs, &objp->ut_time)) { X return (FALSE); X } X X return (TRUE); X} X Xbool_t Xxdr_utmpptr(xdrs, objp) X XDR *xdrs; X utmpptr *objp; X{ X if (! xdr_reference (xdrs, (char **)objp, sizeof(rutmp), xdr_rutmp)) { X return (FALSE); X } X X return (TRUE); X} X Xbool_t Xxdr_utmparr(xdrs, objp) X XDR *xdrs; X utmparr *objp; X{ X if (! xdr_array (xdrs, (char **)&objp->uta_arr, &objp->uta_cnt, X MAXUSERS, sizeof(*objp->uta_arr), xdr_utmpptr)) { X return (FALSE); X } X X return (TRUE); X} X Xbool_t Xxdr_utmpidle(xdrs, objp) X XDR *xdrs; X utmpidle *objp; X{ X if (! xdr_rutmp(xdrs, &objp->ui_utmp)) { X return (FALSE); X } X X if (!xdr_u_long(xdrs, &objp->ui_idle)) { X return (FALSE); X } X X return (TRUE); X} X Xbool_t Xxdr_utmpidleptr(xdrs, objp) X XDR *xdrs; X utmpidleptr *objp; X{ X if (! xdr_reference (xdrs, (char **)objp, X sizeof(struct utmpidle), xdr_utmpidle)) { X return (FALSE); X } X X return (TRUE); X} X Xbool_t Xxdr_utmpidlearr(xdrs, objp) X XDR *xdrs; X utmpidlearr *objp; X{ X register int i; X register utmpidle **ptr; X X if (! xdr_array (xdrs, (char **)&objp->uia_arr, X &objp->uia_cnt, MAXUSERS, X sizeof(objp->uia_arr), xdr_utmpidleptr)) { X return (FALSE); X } X X#ifdef DEBUG_UTMPIDLEARR X X printf ("objp->uia_cnt: %u\n", objp->uia_cnt); X X for (ptr = objp->uia_arr, i = 0; i < objp->uia_cnt; i++, ptr++) { X X printf ("TTY: %s\n", (*ptr)->ui_utmp.ut_line); X X printf ("User: %s\n", (*ptr)->ui_utmp.ut_name); X X printf ("From: %s\n", (*ptr)->ui_utmp.ut_host); X X printf ("On since: %s", ctime (&(*ptr)->ui_utmp.ut_time)); X X printf ("(*ptr)->ui_idle: %u:%u\n", X (*ptr)->ui_idle/60, (*ptr)->ui_idle%60); X } X X#endif X X return (TRUE); X} X X END-of-rusers_xdr.c echo x - rnusers.c sed 's/^X//' >rnusers.c << 'END-of-rnusers.c' X X#include X#include X#include X#include X#include X Xint Xrnusers (host) X char *host; X{ X static int nusers; X register int failstat; X X if (!host || !*host) { X errno = EINVAL; X return (-1); X } X X if (failstat = callrpc (host, RUSERSPROG, X RUSERSVERS_IDLE, RUSERSPROC_NUM, X xdr_void, NULL, xdr_int, &nusers)) { X clnt_perrno (failstat); X X return (-1); X } X X return (nusers); X} X X#ifdef DEBUG_RNUSERS X X#include X Xint Xmain (ac, av) X int ac; X char **av; X{ X struct hostent *target, *canonify(); X register char *host; X X int n; X X if (ac < 2) { X fprintf (stderr, "usage: %s host\n", av[0]); X exit (-1); X } X X target = canonify (av[1]); X X if (! target) { X herror (av[1]); X exit (-1); X } X X host = strdup (target->h_name); X X if (n = rnusers (host) < 0) { X exit (-1); X } X X printf ("%s: %u users\n", host, n); X X exit (0); X} X X#endif X END-of-rnusers.c exit