From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 23-AUG-1988 21:22
To:	ARISIA::EVERHART
Subj:	Status part 2 of 7 (repost)


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Tue, 23 AUG 88 10:27:32 PDT
Received: from uwavm.acs.washington.edu (oly.acs.washington.edu) by KL.SRI.COM with TCP; Tue, 23 Aug 88 10:14:24 PDT
Received: from UWAVM.ACS.WASHINGTON.EDU by uwavm.acs.washington.edu ; Tue, 23 Aug 88 10:13:54 PDT
Received: from UWAVM.ACS.WASHINGTON.EDU by UWAVM.ACS.WASHINGTON.EDU (Mailer
 X1.24) with BSMTP id 6327; Tue, 23 Aug 88 10:13:49 PDT
P1-Message-Id: US**EDU;UWAVM.ACS.WASHINGTON.EDU:LUje5cEk
Date:         Fri, 19 Aug 88 02:00-0700
X400-Trace:   US**EDU; arrival Fri, 19 Aug 88 02:00-0700 action Relayed
X400-Trace:   US**EDU; arrival Tue, 23 Aug 88 10:13-0700 action Relayed
From:         Joe Meadows</ADMD=/PRMD=BITNET/O=FHCRCVAX/PN=JOE/@US>
Subject:      Status part 2 of 7 (repost)
To:           <info-vax@kl.sri.COM>
Message-Id:   <UWAVM.ACS.WASHINGTON.EDU:LUje5cEk*>
X-VMS-To: IN%"info-vax@kl.sri.com"

It seems many people missed part 2 (one of my neighbors must have eaten it
on its way to info-vax), so here it is.

Some people have confirmed getting all but this part, so I won't be
reposting any of the other parts. If you didn't get all of them, then
try to find someone who did (!), failing that, feel free to contact
me and I will post to individuals as needed.

Note that the modified cvt$uic routine that I posted earlier has not
been applied to the version of FORMAT.C in this file. (I wasn't about
to screw around with something that would mess up the checksums!)

Cheers,
Joe Meadows     joe@fhcrcvax.bitnet

+-+-+-+ Beginning of part 2 +-+-+-+
X; Check to see if we can read the device-type
X`009MOVL`009#SS$_ACCVIO,R0`009`009;Presume we can't
X`009IFNORD`009#4,@4(AP),10$`009`009;Probe the device type
X`009MOVL`009@4(AP),R9`009`009;save the device type
X
X; Check to see if we can read the PID
X`009MOVL`009#SS$_ACCVIO,R0`009`009;Presume we can't
X`009IFNORD`009#4,@4(AP),10$`009     `009;Probe the PID
X`009MOVL`009@8(AP),R3`009`009;save the PID
X
X; Check to see if we can read the 'number of elemnts in array'
X`009MOVL`009#SS$_ACCVIO,R0`009`009;Presume we can't
X`009IFNORD`009#4,@8(AP),10$`009`009;Probe the array size
X`009MOVL`009@12(AP),R8`009`009;save the array size
X
X; Check to see if we can read the 'size of elemnts in array'
X`009MOVL`009#SS$_ACCVIO,R0`009`009;Presume we can't
X`009IFNORD`009#4,@8(AP),10$`009`009;Probe the size
X`009MOVL`009@16(AP),R6`009`009;save the size
X
X`009; make sure R6 is bigger than 6
X`009MOVL`009#SS$_BUFFEROVF,R0`009`009;Presume it isnt
X`009CMPL`009R6,#6
X`009BLSS`00910$
X
X; multiply to get the size of the array in bytes
X`009MULL3`009R6,R8,R1
X
X; Check to see if we can write the device-name-array
X`009MOVL`009#SS$_ACCVIO,R0`009`009;Presume we can't
X`009IFNOWRT`009R1,@20(AP),10$`009`009;Probe the device name array
X`009MOVL`00920(AP),R7`009`009;save the address of array
X
X; Ok.  Now go though the I/O database!
X`009MOVL`009G^SCH$GL_CURPCB,R4`009;Get my PCB address
X`009JSB`009G^SCH$IOLOCKR`009`009;Lock the I/O database mutex
X`009; we are now at IPL 2, and we can happily page fault!
X
X`009CLRQ`009R10`009`009; clear r10, and r11 - for ioc$scan_iodb
X30$:`009JSB`009G^IOC$SCAN_IODB
X`009BLBC`009R0,50$`009`009; well, we're done.
X
X`009; R9 contains device class, if -1 then go ahead and take this
X`009; otherwise, check class, if not equal skip to next ddb
X`009CMPL`009R9,#-1
X`009BEQL`00935$
X`009CMPB`009R9,UCB$B_DEVCLASS(R10)
X`009BEQL`00935$
X`009CLRL`009R10`009; Implies end of ucb chain
X`009BRB`00930$
X
X35$:`009; match on any PID? (even zero)
X`009TSTL`009R3
X`009BEQL`00937$`009; yes, go get it
X
X`009; PID must be non-zero, else skip this device
X`009MOVL`009UCB$L_PID(R10),R0`009; may as well prepare for conversion
X`009BEQL`00930$`009; go on to the next device
X
X`009; match on any PID?
X`009CMPL`009#-1,R3
X`009BEQL`00937$`009; yes, don't bother checking it..
X
X`009; must have exact PID match, convert pid to proper format
X`009JSB`009G^EXE$IPID_TO_EPID`009; Convert to extended PID
X`009CMPL`009R3,R0`009`009`009; exact match?
X`009BNEQ`00930$`009`009`009; nope, skip to next device
X
X37$:`009MOVL`009#SS$_BUFFEROVF,R0`009; need a better error - too many units
X`009TSTL`009R8
X`009BEQL`00960$
X
X40$:`009; r6 contains length, r7 = address of string
X`009; need to move length to R0, and address to R1
X`009MOVQ`009R6,R0
X`009SUBL`009#6,R0`009; decrement size
X`009ADDL`009#6,R1`009; leave room for length
X
X`009MOVL`009#-1,R4`009; type of device name wanted
X
X`009; okay, we have a UCB in R10, ioc$cvt_devnam needs it in R5
X`009MOVL`009R10,R5
X
X`009JSB`009G^IOC$CVT_DEVNAM
X
X`009MOVW`009R1,4(R7)`009`009; save length
X`009BLBS`009R0,45$`009`009; everything okay?
X`009MOVW`009#-1,4(R7)`009; if overflow, set length to -1
X
X45$:`009MOVL`009UCB$L_PID(R10),R0
X`009JSB`009G^EXE$IPID_TO_EPID`009; Convert to extended PID
X`009MOVL`009R0,(R7)
X
X`009; move pointer into array ahead by one string length
X`009ADDL`009R6,R7
X`009; r8 = number of elements left in the array
X`009DECL`009R8
X`009BRB`00930$
X
X50$:`009MOVL`009#SS$_NORMAL,R0`009`009 ;Success!
X60$:`009MOVL`009G^SCH$GL_CURPCB,R4`009 ;Get my PCB address again
X
X`009PUSHL`009R0`009`009`009;Save the return status
X`009JSB`009G^SCH$IOUNLOCK`009`009;Unlock the I/O database mutex
X`009SETIPL`009#0`009`009`009;Drop back down from IPL$_ASTDEL
X`009POPL`009R0`009`009`009;Restore the return status
X`009RET`009`009`009`009;Back to user mode
X
X`009.END
X$EOD
X$ create/log EPID_TO_IPID.MAR
X$DECK
X`009.entry`009epid_to_ipid,0
X`009; this needs to be linked against sys$system:sys.stb
X
X`009movl`009@4(ap),r0
X`009jsb`009g^exe$epid_to_ipid
X`009ret
X`009.end
X$EOD
X$ create/log FORMAT.C
X$DECK
X#include ctype
X#include descrip
X#include dvidef
X#include "server.h"
X
X#define IMAGE_CAPITALIZE 1 /* compile in the image capitalization */
X#define TIME_BLANKED 1 /* compile in the leading zero to blank conversion */
X
X#define WHO_DATABASE 1`009/* compile in the status_who.names database lookup *
/
X#define WHO_SYSUAF 1    /* compile in the sysuaf lookup */
X/* note, if both above are set, then a database lookup is done first,
X   followed by a lookup in the sysuaf if nothing was returned.. */
X
X#define WHO_FIXNAME 1 /* if 1, names with comma assumed to be last, first */
X
X#if WHO_SYSUAF == 1
X
Xstatic struct Tree {
X  char *username;
X  char *personal;
X  struct Tree *left, *right;
X} uaf_head = {0,0,0,0};
X
X#endif
X
Xglobalvalue EXE$GL_ABSTIM;
X
Xfinal_format(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  int pad,size,i,j;
X  struct FmtItems *item;
X
X  item = &(items->item[itm]);
X
X  size = strlen(string);
X  if (item->start) { /* was an offset specified? */
X    if (item->start < 0) { /* was it from right? */
X      size += item->start; /* remember, item->start < 0 */
X      if (size < 0) size = 0;
X      string[size] = '\0'; /* 'offset' in from right (truncate end) */
X    } else { /* offset was from left */
X      if (item->start < size) {
X        size -= item->start;
X        strcpy(string,&string[item->start]); /* chop off the first chars */
X      } else {
X        size = 0;
X        string[0] = '\0';
X      }
X    }
X  }
X
X  if (item->width > 0) { /* string needs to be padded out to fit */
X    pad = item->width - size;
X    if (pad) {
X      if (pad > 0) {
X        switch (item->just) {
X          case -1: /* add spaces to end */
X            for (i=size; i < (size + pad); string[i++] = ' ');
X            size += pad;
X            string[size] = '\0';
X            break;
X          case 0: /* add spaces on both ends */
X            i = pad / 2;
X            strcpy(&string[i],string);
X            for (j = 0; j < i; string[j++] = ' ');
X            size += i;
X            pad -= i;
X            for (i=size; i < (size + pad); string[i++] = ' ');
X            size += pad;
X            string[size] = '\0';
X            break;
X          case 1: /* add spaces to front */
X            strcpy(&string[pad],string);
X            for (i = 0; i < pad; string[i++] = ' ');
X            size += i;
X            break;
X        }
X      } else { /* string is too big (pad < 0) */
X        pad *= -1;
X        switch (item->just) {
X          case -1: /* truncate string to fit */
X            string[size - pad] = '\0';
X            size -= pad;
X            break;
X          case 0:  /* cut from both ends */
X            i = pad / 2;
X            string[size - i] = '\0'; /* truncate end */
X            strcpy(string,&string[pad - i]); /* move over to start */
X            size -= pad;
X            break;
X          case 1:  /* cut off start of string */
X            strcpy(string,&string[pad]);
X            size -= pad;
X            break;
X        }
X      }
X    }
X  }
X}
X
X/* the following is used for literals, (keywords[KEYWORDS] points to it) */
Xformat_literal(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  item = &(items->item[itm]);
X
X  sprintf(string,"%.*s",item->width,get_address(item,link));
X}
X
Xcvt$access_mode(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *modes[] = {"Kernel","Executive","Supervisor","User"};
X  int *asts, i, comma = 0;
X
X  item = &(items->item[itm]);
X
X  asts = get_address(item,link);
X  for (i=0; i<4; i++) {
X    if ((*asts >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,modes[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  }
X  if (! comma) {
X    strcpy(string,"none");
X  };
X}
X
Xcvt$boolean(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int val;
X
X  item = &(items->item[itm]);
X  val = *(int *)get_address(item,link);
X
X  strcpy(string,val?"true":"false");
X}
X
Xcvt$cputim (items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  $DESCRIPTOR(date,"!%D");
X  struct dsc$descriptor time = {23,DSC$K_DTYPE_T,DSC$K_CLASS_S,string};
X  int val,cputim[2];
X  short int len = 0;
X  static int factor = -100000, zero = 0;
X
X  item = &(items->item[itm]);
X  val = *(int *)get_address(item,link);
X  lib$emul(&factor,&val,&zero,cputim);
X  sys$fao(&date,&len,&time,cputim);
X  string[len] = '\0';
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xcvt$creprc_flags(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int flags, i, comma = 0;
X  char *creflg[] = { "ssrwait", "ssfexcu", "pswapm", "noacnt", "batch",
X                     "hiber", "nouaf", "netwrk", "disaws", "detach",
X                     "inter", "imgdmp", "clispec", "nopassword" };
X
X  item = &(items->item[itm]);
X  flags = *(int *)get_address(item,link);
X
X  for (i=0; i<14; i++) {
X    if ((flags >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,creflg[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  }
X  if (! comma) {
X    strcpy(string,"none");
X  }
X}
X
Xcvt$elapsed_time(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  $DESCRIPTOR(date,"!%D");
X  struct dsc$descriptor time = {23,DSC$K_DTYPE_T,DSC$K_CLASS_S,string};
X  int logintim[2] = {0,0}, now[2];
X  short int len = 0;
X
X  item = &(items->item[itm]);
X  memcpy(logintim, get_address(item,link),8);
X  sys$gettim(now);
X  lib$subx(logintim,now,logintim);
X  sys$fao(&date,&len,&time,logintim);
X  string[len] = '\0';
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xcvt$epid_to_ipid(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  item = &(items->item[itm]);
X
X  sprintf(string,"%08X",epid_to_ipid(get_address(item,link)));
X}
X
Xcvt$hex_6(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned short int val[3] = {0,0,0};
X  item = &(items->item[itm]);
X
X  memcpy(val, get_address(item,link), 6);
X  sprintf(string,"%04X%04X%04X", val[0], val[1], val[2]);
X}
X
Xcvt$hex_8(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned int val[2] = {0,0};
X  item = &(items->item[itm]);
X
X  memcpy(val, get_address(item,link), 8);
X  sprintf(string,"%08X%08X", val[0], val[1]);
X}
X
Xcvt$hex_12(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned int val[3] = {0,0,0};
X  item = &(items->item[itm]);
X
X  memcpy(val, get_address(item,link), 12);
X  sprintf(string,"%08X%08X%08X", val[0], val[1], val[2]);
X}
X
Xcvt$image(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int i,j, pid;
X  char *s;
X
X  item = &(items->item[itm]);
X
X  /* "trim" off trailing spaces and nulls */
X  s = get_address(item,link);
X  i = item->size - 1;
X
X  /* pull off the .EXE; part */
X  while ((i > 0) && (s[i] != '.'))
X    --i;
X
X  /* get rid of the disk and directory */
X  j = i;
X  while ((j > 0) && (s[j] != ']'))
X    --j;
X
X  if (s[j] == ']') ++j;
X
X  sprintf(string,"%.*s",i - j,&s[j]);
X
X  /* if image = RTPAD, let's display where they are going! */
X  if (strcmp("RTPAD",string) == 0)
X  {
X    /* grab the PID, and call Get_RTPAD_Destination */
X    pid = *(int *)system_jpi.pcb_items[1].bufadr;
X    Get_RTPAD_Destination(pid,&string[6]);
X    if (strlen(&string[6]))
X    {
X      /* a string was returned, so, let's surround it with () */
X      string[5] = '(';
X      strcat(string,")");
X    }
X  }
X  else
X  {
X    if (strcmp("TELNET",string) == 0)
X    {
X      /* grab the PID, and call Get_TELNET_Destination */
X      pid = *(int *)system_jpi.pcb_items[1].bufadr;
X      Get_TELNET_Destination(pid,&string[7]);
X      if (strlen(&string[7]))
X      {
X        /* a string was returned, so, let's surround it with () */
X        string[6] = '(';
X        strcat(string,")");
X      }
X    }
X  }
X#if IMAGE_CAPITALIZE == 1
X  capitalize(string);
X#endif
X}
X
Xcvt$jobtype(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  static char *jobtype[] = { "Detached", "Network", "Batch",
X                             "Local", "Dialup", "Remote" };
X
X  item = &(items->item[itm]);
X  strcpy(string,jobtype[*(unsigned char *)get_address(item,link)]);
X}
X
Xcvt$type(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int *jobtyp, *mode, *owner, typ;
X  static char *jobtype[] = { "Detached", "Network", "Batch",
X                             "Local", "Modem", "Remote" };
X
X  item = &(items->item[itm]);
X  jobtyp = get_address(&(items->item[itm]));
X  mode = get_address(&(items->item[itm+1]));
X  owner = get_address(&(items->item[itm+2]));
X
X  typ = *jobtyp;
X  if ((*jobtyp == 0) && (*mode == 1))
X    typ = 1;
X
X  strcpy(string,(*owner)?"Subprocess":jobtype[typ]);
X}
X
Xcvt$mode(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  static char *mode[] = { "Other", "Remote", "Batch", "Interactive" };
X
X  item = &(items->item[itm]);
X  strcpy(string,mode[*(unsigned char *)get_address(item,link)]);
X}
X
Xcvt$msgmsk(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *msg[] = { "text", "ident", "severity", "facility" };
X  int flags, i, comma = 0;
X
X  item = &(items->item[itm]);
X
X  flags = *(int *)get_address(item,link);
X
X  for (i=0; i<4; i++)
X    if ((flags >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,msg[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  if (! comma)
X    strcpy(string,"none");
X}
X
Xcvt$numeric(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned long int l;
X
X  item = &(items->item[itm]);
X
X  memcpy(&l,get_address(item,link),item->size);
X  sprintf(string,"%d",l);
X}
X
Xcvt$numeric_hex(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned long int l;
X
X  item = &(items->item[itm]);
X
X  memcpy(&l,get_address(item,link),item->size);
X  sprintf(string,"%0*X",item->size * 2,l);
X}
X
Xcvt$numeric_oct(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  unsigned long int l;
X
X  item = &(items->item[itm]);
X
X  memcpy(&l,get_address(item,link),item->size);
X  sprintf(string,"%0*o",item->size * 8 / 3,l);
X}
X
Xcvt$pages(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  int ppgcnt, gpgcnt;
X  struct FmtItems *item;
X
X  ppgcnt = *(int *)get_address(&items->item[itm],link);
X  gpgcnt = *(int *)get_address(&items->item[itm+1],link);
X  sprintf(string,"%d",ppgcnt + gpgcnt);
X}
X
Xcvt$io(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  int bufio, dirio;
X  struct FmtItems *item;
X
X  bufio = *(int *)get_address(&items->item[itm],link);
X  dirio = *(int *)get_address(&items->item[itm+1],link);
X  sprintf(string,"%d",bufio + dirio);
X}
X
Xcvt$phdflags(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *phdflg[] = { "pfmflg", "dalcstx", "wspeakchk", "noaccvio",
X                     "iwspeakck", "imgdmp", "no_ws_chng" };
X  int flags, i, comma = 0;
X
X  item = &(items->item[itm]);
X
X  flags = *(int *)get_address(item,link);
X  for (i=0; i < 7; i++)
X    if ((flags >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,phdflg[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  if (! comma)
X    strcpy(string,"none");
X}
X
Xcvt$physical_terminal(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char buff[64];
X  char node[128];
X  int status,len, i;
X  struct itmlst dvi[2];
X  struct dsc$descriptor devname = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0} ;
X  struct TermInfo {
X    long int duetim;
X    long int pid;
X    unsigned short int rtt_link;
X  } terminfo;
X  char *ptr,*start;
X
X  item = &(items->item[itm]);
X
X  dvi[0].length = sizeof(buff);
X  dvi[0].code = DVI$_TT_PHYDEVNAM;
X  dvi[0].bufadr = buff;
X  dvi[0].retlen = &len;
X  dvi[1].code = 0;
X  dvi[1].length = 0;
X
X  /* figure out length of string */
X  len = item->size;
X  start = get_address(item,link);
X  ptr = start + len;
X  while ((--ptr >= start) && ((*ptr == ' ') || (*ptr == '\0')))
X    --len;
X
X  ptr = start;
X  if (*ptr == '_') {
X    ++ptr;
X    --len;
X  };
X
X  for (i=0; i < len; i++) {
X    string[i] = *ptr++;
X  };
X  string[len] = '\0';
X
X  if (string[len - 1] == ':')
X    string[--len] = '\0';
X
X  devname.dsc$w_length = len;
X  devname.dsc$a_pointer = string;
X
X  status = term_info(&devname,&terminfo); `009/* get rtt_link if remote */
X  if ((status & 1) && terminfo.rtt_link)
X  {
X    for (i=0; i < 10; ++i) node[i] = '\0';
X    /* here we need to call decnetinfo passing it the link number */
X    status = Get_DECnet_Node(terminfo.rtt_link,node);
X    if (status & 1)
X    {
X      /* trim off trailing spaces */
X      for( i = strlen(node);
X           (i > 0) && ((node[i] == ' ') || (node[i] == '\0'));
X           --i)
X      {
X        node[i] = '\0';
X      }
X      strcpy(string,node);
X      strcat(string,".decnet");
X    }
X  } else { /* not a remote terminal, let's see if its a TPA/TZA device */
X    if ((strncmp(string,"TPA",3) == 0) || (strncmp(string,"TZA",3) == 0))
X    {
X      if (convert_pseudo_terminal(string,node) & 1)
X      {
X        strcpy(string,node);
X      }
X    }
X    else
X    {
X      if ((status = sys$getdviw(0,0,&devname,dvi,0,0,0,0)) & 1) {
X        if (len) {
X          buff[len] = '\0';
X          if (buff[len - 1] == ':')
X            buff[--len] = '\0';
X          if (buff[0] == '_')
X            sprintf(string,"%s",&buff[1]);
X          else
X            sprintf(string,"%s",buff);
X        } else {
X          sprintf(string,"Disconnected");
X        }
X      }
X    }
X  }
X
X}
X
Xcvt$privilege(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *privs[] = {"cmkrnl", "cmexec", "sysnam", "grpnam", "allspool",
X                   "detach", "diagnose", "log_io", "group", "acnt",
X                   "prmceb", "prmmbx", "pswapm", "altpri", "setprv",
X                   "tmpmbx", "world", "mount", "oper", "exquota",
X                   "netmbx", "volpro", "phy_io", "bugchk", "prmgbl",
X                   "sysgbl", "pfnmap", "shmem", "sysprv", "bypass",
X                   "syslck", "share", "upgrade", /* <- 32 not used */
X                   "downgrade", /* <- 33 not used */ "grpprv", "readall",
X                   "", "", /* <- 36 & 37 not used */ "security" };
X  int priv0, priv1, i, comma = 0;
X
X  item = &(items->item[itm]);
X
X  priv0 = *(int *)get_address(item,link);
X  for (i=0; i<32; i++)
X    if ((priv0 >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,privs[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X
X  priv1 = *(int *)(get_address(item,link) + 4);
X  for (i=34; i<36; i++)
X    if ((priv1 >> (i-32)) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,privs[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X
X  if (! comma)
X    strcpy(string,"none");
X}
X
Xcvt$state(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  static char *states[] = {"", "colpg","mwait","cef","pfw","lef","lefo","hib",
X                           "hibo","susp","suspo","fpg","com","como","cur" };
X
V  static char *mwaits[] = {"unk","ast","mbx","npg","pff","pag","brk","img","qu
o
X",
X                           "lck","swp","mpe","mpb","scs","clu"};
X  int mutex,state;
X
X  item = &(items->item[itm]);
X  state = *(unsigned char *)get_address(item,link);
X
X  state = *(int *)get_address(&items->item[itm],link);
X  mutex = *(int *)get_address(&items->item[itm+1],link);
X
X  if (state == 2)
X  {
X    if ((mutex < 15) && (mutex > 0))
X    {
X      strcpy(string,"rw");
X      strcat(string,mwaits[mutex]);
X    }
X    else
X    {
X      sprintf(string,"mwait(%08X)",mutex);
X    }
X  }
X  else
X    strcpy(string,states[state]);
X}
X
Xcvt$sts(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *sts[] = { "res", "delpen", "forcpen", "inquan", "pswapm", "respen",
X                  "ssfexc", "ssfexce", "ssfexcs", "ssfexcu", "ssrwait",
X                  "suspen", "wakepen", "wall", "batch", "noacnt", "swpvbn",
X                  "astpen", "phdres", "hiber", "login", "netwrk", "pwrast",
X                  "nodelet", "disaws", "inter", "recover", "secaudit" };
X  int flag, i, comma = 0;
X
X  item = &(items->item[itm]);
X  flag = *(int *)get_address(item,link);
X  for (i=0; i<27; i++)
X    if ((flag >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,sts[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  if (! comma)
X    strcpy(string,"none");
X}
X
Xcvt$text(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int i;
X  char *s;
X
X  item = &(items->item[itm]);
X
X  /* trim off trailing spaces and nulls */
X  s = get_address(item,link);
X  i = item->size - 1;
X  while ((i >= 0) && ((s[i] == ' ') || (s[i] == '\0')))
X    s[i--] = '\0';
X
X  sprintf(string,"%.*s",i + 1,s);
X}
X
Xcvt$nodename(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  int i;
X  char *s;
X
X  item = &(items->item[itm]);
X
X  /* trim off trailing spaces and nulls */
X  s = get_address(item,link);
X  i = item->size - 1;
X  while ((i >= 0) && ((s[i] == ' ') || (s[i] == '\0')))
X    s[i--] = '\0';
X
X  if (i < 0) /* gosh, there's no nodename.. */
X  {
X    strcpy(string,getenv("SYS$NODE"));
X    i = strlen(string);
X    while((i > 0) && (string[--i] == ':')) /* trim off trailing colons */
X    {
X      string[i] = '\0';
X    }
X  }
X  else /* gosh, the nodename exists, copy it.. */
X  {
X    sprintf(string,"%.*s",i + 1,s);
X  }
X}
X
Xcvt$time(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  $DESCRIPTOR(date,"!%D");
X  struct dsc$descriptor time = {23,DSC$K_DTYPE_T,DSC$K_CLASS_S,string};
X  int bintim[2] = {0, 0};
X  short int len = 0;
X
X  item = &(items->item[itm]);
X  memcpy(bintim, get_address(item,link), item->size);
X  sys$fao(&date,&len,&time,bintim);
X  string[len] = '\0';
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xcvt$uaf_flags(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char *uaf[] = { "disctly", "defcli", "lockpwd", "captive", "disacnt",
X                  "diswelcom", "dismail", "nomail", "genpwd", "pwd_expired",
X                  "pwd2_expired", "audit", "disreport", "disreconnect",
X                  "autologin" };
X  int flag, i, comma = 0;
X
X  item = &(items->item[itm]);
X  flag = *(int *)get_address(item,link);
X  for (i=0; i<4; i++)
X    if ((flag >> i) & 1) {
X      if (comma) *string++ = ',';
X      strcpy(string,uaf[i]);
X      string += strlen(string);
X      comma = 1;
X    }
X  if (! comma)
X    strcpy(string,"none");
X}
X
Xcvt$uic(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  $DESCRIPTOR(uicfmt, "!%I");
X  short int len = 0;
X
X  item = &(items->item[itm]);
X  sys$fao(&uicfmt,&len,string,*(int *)get_address(item,link));
X  string[len] = '\0';
X}
X
Xcvt$where(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  char server[16], port[16];
X
X  item = &(items->item[itm]);
X  cvt$physical_terminal(items,itm,string,link);
X
X  /* see if it's a LT type terminal, if not, then just format it */
X  if (strncmp(string,"LT",2) == 0) {
X    if (readport(string ,server ,port) & 1) {
X      strcpy(string, server);
X      strcat(string, "/");
X      strcat(string, port);
X    }
X  }
X
X  lookup_terminal(string,string,132); /* bogus max. length, just a guess */
X}
X
Xcvt$who(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct dsc$descriptor user = {0,0,0,string};
X#define UAI$_OWNER 12
X  struct itmlst uailst[] = {32,UAI$_OWNER,&string[13],0,0,0,0,0};
X  char *ptr;
X  int length,status;
X
X  cvt$text(items,itm,string,link); /* trim username and such */
X  status = 0;
X
X#if WHO_DATABASE == 1
X  status = lookup_who(string,string,128); /* 128 is just a guess at max len */
X#endif
X
X#if WHO_SYSUAF == 1
X  if (!status)
X  {
X    /* lookup user in local tree */
X    status = lookup_user(&uaf_head,string,string);
X    if (!(status & 1))
X    {
X      user.dsc$w_length = strlen(string);
X      status = sys$getuai(0,0,&user,uailst,0,0,0);
X      if (status & 1)
X      {
X        ptr = &string[14];
X        ptr[string[13]] = '\0';
X#if WHO_FIXNAME == 1
X`009fix_personal_name(ptr,ptr);
X#endif
Xprintf("Adding user %s\n",string);
X        add_user(&uaf_head,string,ptr);
X        strcpy(string,ptr);
X      }
X    }
X  }
X#endif
X}
X
Xcvt$global_word(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X{
X  struct FmtItems *item;
X  unsigned short int *wordptr;
X
X  item = &(items->item[itm]);
X  wordptr = get_address(item,link);
X
X  sprintf(string,"%d",wordptr?*wordptr:0);
X}
X
Xcvt$current_time(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  $DESCRIPTOR(date,"!%D");
X  struct dsc$descriptor time = {23,DSC$K_DTYPE_T,DSC$K_CLASS_S,string};
X  int now[2];
X  short int len = 0;
X
X  item = &(items->item[itm]);
X  sys$gettim(now);
X  sys$fao(&date,&len,&time,now);
X  string[len] = '\0';
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xcvt$devices(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  static struct DevInfo {
X    long int pid;
X    short int len;
X    char name[64];
X  } devinfo[20];
X  static int devinfosize = sizeof(struct DevInfo);
X  static int class = -1, devinfocnt = 20;
X  int *pid, status, i, indx;
X  struct FmtItems *item;
X
X  item = &(items->item[itm]);
X
X  indx = 0;
X  pid = get_address(item,link);
X
X  /* find all devices owned by this PID */
X  status = devices(&class, pid, &devinfocnt, &devinfosize, devinfo);
X  if (status & 1) {
X    /* okay, move all the device names into the tmp buffer */
X    i = 0;
X    while (devinfo[i].len) {
X      /* strip the leading underscore and trailing colon while moving */
X      indx += sprintf(&string[indx],"%.*s,",
X`009`009`009devinfo[i].len-2,&devinfo[i].name[1]);
X      devinfo[i].len = 0;
X      ++i;
X    };
X    if (indx) --indx;
X  };
X  string[indx] = '\0';
X}
X
Xcvt$cluster_members(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct {
X    short int BufferLength;
X    short int ItemCode;
X    long int BufferAddress;
X    long int ReturnLengthAddress;
X  } ItemList[]={15,SYI$_NODENAME,0,0,0,0,0,0};
X  long int status = 1;
X  long int iosb[2];
X  long int csid = -1;
X  char *node;
X  int nodelen;
X
X  node = string;
X
X  while (status & 1)
X  {
X    nodelen = 0;
X    ItemList[0].BufferAddress = node;
X    ItemList[0].ReturnLengthAddress = &nodelen;
X    status=sys$getsyiw(0,&csid,0,&ItemList,iosb,0,0);
X    if (status & 1)
X      status = iosb[0];
X    if (status & 1)
X    {
X      node += nodelen;
X      *node = ',';
X      ++node;
X    }
X  }
X  if (node > string)
X    --node;
X  *node = '\0';
X}
X
Xcvt$idleterminal(items,itm,string,link)
X  struct FmtItemsList *items;
X  int itm;
X  char *string;
X  int link;
X{
X  struct FmtItems *item;
X  struct dsc$descriptor device = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0} ;
X  struct TermInfo {
X    long int duetim;
X    long int pid;
X    short int rtt_link;
X  } terminfo;
X  int day,hrs,min,sec;
X  int status;
X  char *ptr;
X
-+-+-+-+-+ End of part 2 +-+-+-+-+-

