home *** CD-ROM | disk | FTP | other *** search
- /*
- * getidle() - determine idle information for terminals (privileged)
- *
- * revision history
- *
- * 05b 18Jul86 cal .Modified to reference system variables as externs.
- * Wrote exe_ipid_to_epid() using asm()s.
- * 05a 01Apr86 cal .Converted to VMS V4.
- * 04a 19Mar84 cal .First "c" version.
- *
- * synopsis
- *
- * #include <sys/types.h>
- *
- * int status, getidle();
- * long *ap_tim;
- * u_long *ap_tim;
- *
- * status = getidle([&ap_tim], &ap_pid, [&ap_net]);
- *
- * ap_tim - pointer to receive idle time buffer (optional)
- * ap_pid - pointer to receive pid buffer
- * ap_net - pointer to receive net address buffer (optional)
- * status - returned VMS status
- *
- * The optional arguments may be replaced with "0". The idle times,
- * process ids, and net values are stored in the buffers in consecutive
- * elements with a zero longword in the pid buffer to mark end of the
- * list.
- *
- * The net address buffer contains either the Decnet logical link number
- * for a remote terminal or else the host address for a "nty" port.
- *
- * The information is ordered by terminal name.
- *
- * Note: Use of this routine requires the privilege CMKRNL.
- *
- */
-
- #include <sys/types.h>
- #include <netinet/in.h>
-
- #include "vms/ucbdef.h"
- #include "vms/ddbdef.h"
- #include "vms/ttyucbdef.h"
- #include "vms/dcdef.h"
- #include "vms/devdef.h"
- #include "vms/ssdef.h"
-
- static struct XUCB {
- char xucb_dummy[0x13c];
- u_long xucb$x_netaddr;
- };
-
- extern struct DDB *ioc$gl_devlist;
- extern int exe$gl_abstim;
-
- static int idlekrn();
- static u_long exe_ipid_to_epid();
-
- /*
- * Useful constants
- */
-
- #define FUDGE 2 /* add this to exe$gl_abstim */
- #define MAX_UNITS 128 /* max units to report about */
-
- static long bl_tim[MAX_UNITS];
- static u_long bl_pid[MAX_UNITS];
- static u_long bl_net[MAX_UNITS];
-
- getidle(ap_tim, ap_pid, ap_net)
- long **ap_tim;
- u_long **ap_pid;
- u_long **ap_net;
- {
- register int i;
-
- #ifdef notdef
- status = sys$lkwset();
- if (status != SS$_WASCLR && status != SS$_WASSET)
- return(status);
- #endif
- i = sys$cmkrnl(idlekrn, 0);
- #ifdef notdef
- status = sys$ulwset();
- if (status != SS$_WASCLR && status != SS$_WASSET)
- return(status);
- #endif
- if (i != SS$_NORMAL)
- return(i);
- if (ap_tim)
- *ap_tim = bl_tim;
- *ap_pid = bl_pid;
- if (ap_net)
- *ap_net = bl_net;
- return(SS$_NORMAL);
- }
-
- /*
- * Entry point for the privileged search and slurp.
- */
-
- static u_long *nty = (u_long *)"\003NTY";
- static u_long *nta = (u_long *)"\003NTA";
-
- static idlekrn()
- {
- register int i;
- register struct UCB *up;
- register struct DDB *dp;
- register u_long *p_pid;
- register long *p_tim;
- register u_long *p_net;
- char *cp;
- int now;
- int status;
-
- i = 0;
- status = SS$_NORMAL;
- p_tim = bl_tim;
- p_pid = bl_pid;
- p_net = bl_net;
-
- now = exe$gl_abstim + FUDGE;
- #ifdef notdef
- asm("jsb _sch$iolockr");
- #endif
-
- for (dp = ioc$gl_devlist; dp; dp = dp->ddb$l_link) {
- if ((up = dp->ddb$l_ucb) == 0 || up->ucb$b_devclass != DC$_TERM)
- continue;
- for ( ; up; up = up->ucb$l_link) {
- if (up->ucb$l_pid == 0)
- continue;
-
- /* Store process id */
- *p_pid++ = exe_ipid_to_epid(up->ucb$l_pid);
-
- /* Get idle time */
- if ((up->ucb$w_sts & UCB$M_TIM) != 0 ||
- (up->ucb$w_sts & UCB$M_BSY) == 0 ||
- (*p_tim = now - up->ucb$l_duetim) < 0)
- *p_tim = 0;
- p_tim++;
-
- /* Get network info (if a rta, nty, or nta) */
- *p_net = 0;
- if ((up->ucb$l_devchar2 & DEV$M_RTT) != 0)
- *p_net = ((struct TTYUCB *)up)->ucb$w_rtt_link;
- else if (*nty == *(u_long *)dp->ddb$t_name ||
- *nta == *(u_long *)dp->ddb$t_name)
- *p_net = ((struct XUCB *)up)->xucb$x_netaddr;
- p_net++;
-
- if (++i >= MAX_UNITS) {
- status = SS$_BUFFEROVF;
- goto done;
- }
- }
- }
- done:
-
- #ifdef notdef
- asm("jsb _sch$iounlock");
- #endif
- *p_pid = 0;
- return(status);
- }
-
- static u_long
- exe_ipid_to_epid(pid)
- u_long pid;
- {
- #ifdef lint
- return(pid);
- #else
- asm("movl 4(ap),r0");
- asm("jsb _exe$ipid_to_epid");
- asm("ret");
- #endif
- }
-