From:	CSBVAX::MRGATE!RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP 11-AUG-1988 18:38
To:	ARISIA::EVERHART
Subj:	STATUS, part 3 of 7 parts


Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed, 10 AUG 88 11:54:08 PDT
Received: from uwavm.acs.washington.edu (oly.acs.washington.edu) by KL.SRI.COM with TCP; Wed, 10 Aug 88 11:19:36 PDT
Received: from UWAVM.ACS.WASHINGTON.EDU by uwavm.acs.washington.edu ; Wed, 10 Aug 88 11:18:22 PDT
Received: from UWAVM.ACS.WASHINGTON.EDU by UWAVM.ACS.WASHINGTON.EDU (Mailer
 X1.24) with BSMTP id 8242; Wed, 10 Aug 88 11:18:17 PDT
P1-Message-Id: US**EDU;UWAVM.ACS.WASHINGTON.EDU:LTh7d3Y6
Date:         Wed, 10 Aug 88 11:14-0700
X400-Trace:   US**EDU; arrival Wed, 10 Aug 88 11:14-0700 action Relayed
X400-Trace:   US**EDU; arrival Wed, 10 Aug 88 11:18-0700 action Relayed
From:         Joe Meadows</ADMD=/PRMD=BITNET/O=FHCRCVAX/PN=JOE/@US>
Subject:      STATUS, part 3 of 7 parts
To:           <info-vax@kl.sri.COM>
Message-Id:   <UWAVM.ACS.WASHINGTON.EDU:LTh7d3Y6*>
X-VMS-To: IN%"info-vax@kl.sri.com"


What follows is part 3 of 7 parts (of STATUS). See part 1 for more info.
        Joe Meadows     joe@fhcrcvax.bitnet

+-+-+-+ Beginning of part 3 +-+-+-+
X  item = &(items->item[itm]);
X
X  device.dsc$w_length = item->size;
X  device.dsc$a_pointer = get_address(item,link);
X  ptr = device.dsc$a_pointer + device.dsc$w_length;
X
X  while ((ptr-- > device.dsc$a_pointer) && ((*ptr == ' ') || (*ptr == '\0')))
X  {
X    --device.dsc$w_length;
X  }
X
X  status = term_info(&device,&terminfo);
X  if ((status & 1) && (terminfo.duetim > 0))
X  {
X    min = terminfo.duetim / 60;
X    hrs = min / 60;
X    day = hrs / 24;
X    sec = terminfo.duetim - (min * 60);
X    min = min - (hrs * 60);
X    hrs = hrs - (day * 24);
X    sprintf(string,"%4d %02d:%02d:%02d.00", day, hrs, min, sec);
X  }
X  else
X  {
X    if (status & 1)
X    {
X      sprintf(string,"   0 00:00:00.00");
X    }
X    else
X    {
X#ifdef DEBUG
Xprintf("cvt$idletime - error %d from term_info\n",status);
X#endif
X      string[0] = '\0';
X    }
X  };
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xcvt$idlecpu(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 now,time,day,hrs,min,sec;
X  int status;
X  char *ptr;
X
X  item = &(items->item[itm]);
X
X  memcpy(&time,get_address(item,link)+item->size,4);
X  now = *(int *)EXE$GL_ABSTIM;
X  time = now - time;
X
X  if (time > 0)
X  {
X    min = time / 60;
X    hrs = min / 60;
X    day = hrs / 24;
X    sec = time - (min * 60);
X    min = min - (hrs * 60);
X    hrs = hrs - (day * 24);
X    sprintf(string,"%4d %02d:%02d:%02d.00", day, hrs, min, sec);
X  }
X  else
X  {
X    sprintf(string,"   0 00:00:00.00");
X  };
X#if TIME_BLANKED == 1
X  convert_leading_zeros(string);
X#endif
X}
X
Xconvert_leading_zeros(string)
X  char *string;
X{
X  int i = 0,blanking = -1;
X
X  while(string[i] && blanking)
X  {
X    if ((string[i] == '0') || (string[i] == ':') || (string[i] == '.'))
X      string[i] = ' ';
X    if (isdigit(string[i]))
X    {
X      while(string[i] && (string[i] != ' '))
X        ++i;
X      if (string[i] != ' ')
X        blanking = 0;
X    }
X    ++i;
X  }
X}
X
Xcapitalize(string)
X  char *string;
X{
X  int i = 1;
X
X  while (string[i])
X  {
X    if (isalpha(string[i - 1]))
X      string[i] = tolower(string[i]);
X    ++i;
X  }
X}
X
Xget_address(item,link)
X  struct FmtItems *item;
X  int link;
X{
X  int addr, slot;
X
X  switch (item->flags.type) {
X    case FLAGTYPEABS:
X      return(item->address);
X    case FLAGTYPEJPI:
X      addr = system_jpi.data;
X      slot = *(int *)system_jpi.pcb_items[0].bufadr;
X      addr += (JPIMAXBUFFLEN + (4 * JPIMAXITEMCNT)) * slot;
X      return(item->address + addr);
X    case FLAGTYPESYI:
X      addr = syi_items[link][0].bufadr;
X      return(item->address + addr);
X  }
X}
X
Xlookup_user(node,user,name)
X  struct Tree *node;
X  char *user, *name;
X{
X  int cmp;
X
X  if (node && node->username)
X  {
X    cmp = strcmp(user,node->username);
X    if (cmp == 0)
X    {
X      strcpy(name,node->personal);
X      return(1);
X    };
X    if (cmp < 0)
X    {
X      return(lookup_user(node->left,user,name));
X    }
X    else
X    {
X      return(lookup_user(node->right,user,name));
X    }
X  }
X  else
X  {
X    return(0);
X  }
X}
X
Xadd_user(node,user,name)
X  struct Tree *node;
X  char *user, *name;
X{
X  int cmp;
X
X  if (node->username == 0) /* this is where it must go! */
X  {
X    node->username = malloc(strlen(user) + 1);
X    node->personal = malloc(strlen(name) + 1);
X    strcpy(node->username,user);
X    strcpy(node->personal,name);
X    return(1);
X  }
X
X  cmp = strcmp(user,node->username);
X  if (cmp == 0)
X  {
X    /* hey, we already added this sucker, don't do repeat business */
X    return(0);
X  }
X
X  if (cmp < 0)
X  {
X    if (node->left)
X    {
X      return(add_user(node->left,user,name));
X    }
X    else
X    { /* this is where it goes! */
X      node->left = calloc(1,sizeof(struct Tree));
X      return(add_user(node->left,user,name));
X    }
X  }
X  else
X  {
X    if (node->right)
X    {
X      return(add_user(node->right,user,name));
X    }
X    else
X    { /* this is where it goes! */
X      node->right = calloc(1,sizeof(struct Tree));
X      return(add_user(node->right,user,name));
X    }
X  }
X}
X
Xfix_personal_name(from,to)
X  char *from, *to;
X{
X  char *comma, tmp[80];
X  int len;
X
X  while (*from == ' ')
X    ++from; /* kill leading spaces */
X  len = strlen(from) - 1;
X  while (from[len] == ' ')
X    from[len--] = '\0'; /* kill trailing spaces */
X
X  /* look for a comma, if there, rearrange the name */
X  comma = strchr(from,',');
X  if (comma)
X  {
X    *comma++ = '\0';
X
X    while (*comma == ' ')
X      ++comma; /* kill leading spaces in first name */
X    len = strlen(comma) - 1;
X    while (comma[len] == ' ')
X      comma[len--] = '\0'; /* kill trailing spaces in first name */
X
X    /* copy strings together, first last */
X    sprintf(tmp,"%s %s",comma,from);
X    /* and output it.. */
X    strcpy(to,tmp);
X  }
X  else
X  {
X    strcpy(to,from);
X  };
X}
X$EOD
X$ create/log GET.C
X$DECK
X#include iodef
X#include ssdef
X#include "pcbdef.h"
X#include "starlet.h"
X#include "server.h"
X
Xglobalvalue EXE$GL_ABSTIM;
X
Xint io_complete();
X
Xget_header(indx)
X  int indx;
X{
X  static int zero = 0;
X  int i,status,size;
X
X  /* get_header - check for an syi list, if exists, call getsyi
X`009`009call getjpi on self */
X  if (syi_items[indx][0].code != 0) {
X    if (syi_items[indx][0].bufadr == 0) {
X      size = 0;
X      for (i = 0; syi_items[indx][i].code != 0; i++)
X        size += syi_items[indx][i].length;
X      syi_items[indx][0].bufadr = malloc(size);
X      for (i = 1; syi_items[indx][i].code != 0; i++)
X        syi_items[indx][i].bufadr += (int) syi_items[indx][0].bufadr;
X    };
X    status = sys$getsyi(0,0,0,syi_items[indx],0,0,0);
X    if (!(status & 1)) sys$exit(status);
X  };
X
X  getjpi(indx,&zero);
X
X  format_line(indx,&gbl_headers[indx],0);
X
X  zero = 0;
X  status = sys$qiow(0,gbl_links[indx].chan,IO$_WRITEVBLK,
X`009`009&gbl_links[indx].iosb,0,0,&zero,1,0,0,0,0);
X  if (!(status & 1)) sys$exit(status); /* couldn't queue? sanity check */
X
X  status = sys$qio(0,gbl_links[indx].chan,IO$_READVBLK,
X`009`009&gbl_links[indx].iosb,&io_complete,indx,
X`009`009gbl_links[indx].buffer,BUFFERSIZE,0,0,0,0);
X
X}
X
Xget_display(indx)
X  int indx;
X{
X  int i,status,nomatch;
X  int zero = 0;
X
X  if (gbl_links[indx].pid == 0) /* in case it was never initialized */
X    gbl_links[indx].pid = -1;
X
X  if ((status = getjpi(indx,&gbl_links[indx].pid)) == SS$_NOMOREPROC)
X  {
X    gbl_links[indx].pid = -1; /* hey, we're done, get ready for next */
X  }
X  else
X  {
X    nomatch = -1;
X    while (nomatch)
X    {
X      if ((status & 1) && matches(indx,&gbl_select[indx],1)
X          && !matches(indx,&gbl_reject[indx],0))
X      {
X        format_line(indx,&gbl_displays[indx],&get_display);
X        nomatch = 0;
X      }
X      else
X      {
X        if ((status = getjpi(indx,&gbl_links[indx].pid)) == SS$_NOMOREPROC)
X        {
X          gbl_links[indx].pid = -1; /* hey, we're done, get ready for next */
X          nomatch = 0;
X        }
X      }
X    }
X  }
X
X  if (gbl_links[indx].pid == -1) /* have we finished this round? */
X  {
X    status = sys$qiow(0,gbl_links[indx].chan,IO$_WRITEVBLK,
X`009`009&gbl_links[indx].iosb,0,0,&zero,1,0,0,0,0);
X    status = sys$qio(0,gbl_links[indx].chan,IO$_READVBLK,
X`009`009&gbl_links[indx].iosb,&io_complete,indx,
X`009`009gbl_links[indx].buffer,BUFFERSIZE,0,0,0,0);
X  }
X}
X
Xgetjpi(indx,pid)
X  int indx;
X  int *pid;
X{
X  struct iosbdef iosb;
X  unsigned int *slot,*sts, *thispid, *master;
X  unsigned char *buff,*jpi;
X  int i,offset,status,time,sameproc = -1;
X
X  time = *(int *)EXE$GL_ABSTIM;
X
X  status = sys$getjpiw(0,pid,0,system_jpi.pcb_items,&iosb,0,0);
X  if (status & 1)
X    status = iosb.status;
X  if (!(status & 1))
X  {
X    if (status != SS$_NOMOREPROC)
X      printf("Error getting PCB items, status = %d\n",status);
X    return(status);
X  }
X  slot = system_jpi.pcb_items[0].bufadr;
X  thispid = system_jpi.pcb_items[1].bufadr;
X  sts = system_jpi.pcb_items[2].bufadr;
X  master = system_jpi.pcb_items[3].bufadr;
X
X  jpi = system_jpi.data;
X
X  if (*pid)
X  {
X    while (*master == 0)
X    {
X      status = sys$getjpiw(0,pid,0,system_jpi.pcb_items,&iosb,0,0);
X      if (status & 1)
X        status = iosb.status;
X      if (!(status & 1))
X      {
X        if (status != SS$_NOMOREPROC)
X          printf("Error getting PCB items, status = %d\n",status);
X        return(status);
X      }
X    };
X  };
X
X  /* copy this data to the proper slot */
X  buff = jpi;
X  buff += (JPIMAXBUFFLEN + (4 * JPIMAXITEMCNT)) * *slot;
X
X  offset = system_jpi.pcb_items[1].bufadr - jpi;
X  if (*thispid != *(int *)(buff + offset))
X  {
X    sameproc = 0;
X  }
X
X  move_data(jpi, buff, system_jpi.pcb_items,time,sameproc);
X
X  if (! sameproc)
X  {
X    clear_data(buff,system_jpi.phd_items);
X    move_data(jpi, buff, system_jpi.phd_items,time,sameproc);
X  }
X  if (*sts & PCB$M_PHDRES)
X  {
X    status = sys$getjpiw(0,thispid,0,system_jpi.phd_items,&iosb,0,0);
X    if (status & 1)
X      status = iosb.status;
X    if (!(status & 1))
X    {
X      printf("Error getting PHD items, status = %d\n",status);
X      return(status | 1); /* Hey, we got enough to display something */
X    }
X    else
X    {
X      if (status != 1)
X        printf("Getting PHD items, status = %d\n");
X      move_data(jpi, buff, system_jpi.phd_items,time,sameproc);
X    }
X  }
X
X  if (! sameproc)
X  {
X    clear_data(buff,system_jpi.ctl_items);
X    move_data(jpi, buff, system_jpi.ctl_items,time,sameproc);
X  }
X  if (*sts & PCB$M_RES)
X  {
X    status = sys$getjpiw(0,thispid,0,system_jpi.ctl_items,&iosb,0,0);
X    if (status & 1)
X      status = iosb.status;
X    if (!(status & 1))
X    {
X      printf("Error getting CTL items, status = %d\n",status);
X      return(status | 1); /* Hey, we got enough to display something */
X    }
X    else
X    {
X      if (status != 1)
X        printf("Getting CTL items, status = %d\n");
X      move_data(jpi, buff, system_jpi.ctl_items,time,sameproc);
X    }
X  }
X
X  return(status);
X};
X
Xwrite_text(indx,msg,len,routine)
X  int indx;
X  unsigned char *msg;
X  int len;
X  int routine;
X{
X  int status,start;
X
X  start = 0;
X  if (len > 255) {
X    while (len > 255) {
X      msg[start] = 255;
X      len -= 254;
X      status = sys$qiow(0,gbl_links[indx].chan,IO$_WRITEVBLK,
X`009`009`009&gbl_links[indx].iosb,0,0,
X`009`009`009&msg[start],msg[start],0,0,0,0);
X      /* we need to add space for the leading byte count */
X      start += 254;
X    }
X  }
X
X  /* Okay, if we have an ast routine to use then do so */
X  msg[start] = len;
X  if (routine)
X  {
X    status = sys$qio(0,gbl_links[indx].chan,IO$_WRITEVBLK,
X`009`009&gbl_links[indx].iosb,routine,indx,
X`009`009&msg[start],msg[start],0,0,0,0);
X  }
X  else
X  {
X    status = sys$qiow(0,gbl_links[indx].chan,IO$_WRITEVBLK,
X`009`009&gbl_links[indx].iosb,0,0,
X`009`009&msg[start],msg[start],0,0,0,0);
X  }
X}
X
Xformat_line(indx,fmt,routine)
X  int indx;
X  struct FmtItemsList *fmt;
X  int routine;
X{
X  int eos,i;
X  unsigned char *msg;
X
X  msg = gbl_links[indx].buffer;
X
X  eos = 1;
X  msg[eos] = '\0';
X  for (i = 0; i < fmt->maxitems; ++i) {
X    if (fmt->item[i].keyindx != -1) {
X      (*keywords[fmt->item[i].keyindx].frmt_routine) (fmt,i,&msg[eos],indx);
X      final_format(fmt,i,&msg[eos],indx);
X      eos += strlen(&msg[eos]);
X    };
X  };
X
X  write_text(indx,msg,eos,routine);
X
X}
X
Xmatches(indx,fmt,nullaction)
X  int indx;
X  struct FmtItemsList *fmt;
X  int nullaction;
X{
X  struct LinkedList *list;
X  unsigned char string[1024];
X  int i;
X
X  if (fmt->maxitems == 0) return(nullaction);
X
X  for (i = 0; i < fmt->maxitems; ++i) {
X    if (fmt->item[i].keyindx != -1) {
X      (*keywords[fmt->item[i].keyindx].frmt_routine) (fmt,i,string,indx);
X      /* okay, compare string against list */
X      list = fmt->item[i].list;
X      while (list) {
X        if (compare(string, list->string, list->length))
X        {
X          return(1);
X        }
X        list = list->next;
X      };
X    };
X  };
X
X  return(0);
X}
X
Xmove_data(from, to, itemlist, when, same)
X  unsigned char *from, *to;
X  struct itmlst itemlist[];
X  int when,same;
X{
X  int i, offset;
X  char *src, *dst;
X
X  i = 0;
X  while (itemlist[i].code)
X  {
X    offset = itemlist[i].bufadr - from;
X    src = from + offset;
X    dst = to + offset;
X
X    /* compare new data with old data */
X    if (!same || memcmp(src, dst, itemlist[i].length))
X    {
X      if (itemlist[i].code == JPI$_CPUTIM)
X      {
X        if (same && ((*(int *)src) - (*(int *)dst)) < 2)
X        {
X          /* barely different, so store but don't save change time */
X          memcpy(dst, src, itemlist[i].length);
X        }
X        else
X        {
X          /* different, so store & save change time */
X          memcpy(dst, src, itemlist[i].length);
X          dst += itemlist[i].length;
X          memcpy(dst, &when, 4);
X        }
X      }
X      else
X      {
X        /* different, so store & save change time */
X        memcpy(dst, src, itemlist[i].length);
X        dst += itemlist[i].length;
X        memcpy(dst, &when, 4);
X      }
X    }
X    ++i;
X  }
X}
X
Xclear_data(from,itemlist)
X  char *from;
X  struct itmlst itemlist[];
X{
X  int i, offset;
X  char *dst;
X
X  i = 0;
X  while (itemlist[i].code)
X  {
X    offset = itemlist[i].bufadr - from;
X    dst = from + offset;
X    memset(dst, '\0', itemlist[i].length);
X    ++i;
X  }
X}
X
Xget_idle()
X{
X  static int pid = -1;
X  int status;
X
X  if ((status = getjpi_idleloop(&pid)) != SS$_NOMOREPROC)
X  {
X    status = sys$dclast(&get_idle,0,0);
X  }
X  else
X  {
X    pid = -1;
X  }
X}
X
Xgetjpi_idleloop(pid)
X  int *pid;
X{
X  struct iosbdef iosb;
X  unsigned int *slot,*sts, *thispid, *master;
X  unsigned char *buff,*jpi;
X  int i,offset,status,time,sameproc = -1;
X
X  time = *(int *)EXE$GL_ABSTIM;
X
X  status = sys$getjpiw(0,pid,0,system_jpi.pcb_items,&iosb,0,0);
X  if (status & 1)
X    status = iosb.status;
X  if (!(status & 1)) return(status);
X
X  slot = system_jpi.pcb_items[0].bufadr;
X  thispid = system_jpi.pcb_items[1].bufadr;
X  sts = system_jpi.pcb_items[2].bufadr;
X  master = system_jpi.pcb_items[3].bufadr;
X
X  jpi = system_jpi.data;
X
X  if (*pid)
X  {
X    while (*master == 0)
X    {
X      status = sys$getjpiw(0,pid,0,system_jpi.pcb_items,&iosb,0,0);
X      if (status & 1)
X        status = iosb.status;
X      if (!(status & 1))
X      {
X        return(status);
X      }
X    };
X  };
X
X  /* copy this data to the proper slot */
X  buff = jpi;
X  buff += (JPIMAXBUFFLEN + (4 * JPIMAXITEMCNT)) * *slot;
X
X  offset = system_jpi.pcb_items[1].bufadr - jpi;
X  if (*thispid != *(int *)(buff + offset))
X  {
X    sameproc = 0;
X  }
X  move_data(jpi, buff, system_jpi.pcb_items,time,sameproc);
X
X  if (! sameproc)
X  {
X    clear_data(buff,system_jpi.phd_items);
X  }
X  if (*sts & PCB$M_PHDRES)
X  {
X    status = sys$getjpiw(0,thispid,0,system_jpi.phd_items,&iosb,0,0);
X    if (status & 1)
X      status = iosb.status;
X    if (!(status & 1))
X    {
X      return(status);
X    }
X    else
X    {
X      move_data(jpi, buff, system_jpi.phd_items,time,sameproc);
X    }
X  }
X
X  return(status);
X};
X$EOD
X$ create/log GLOBALDEF.C
X$DECK
X#define GLOBAL globaldef
X#include "server.h"
X$EOD
X$ create/log GLOBALS.H
X$DECK
X#define HEADER 1
X#define DISPLAY 2
X#define SELECT 3
X#define REJECT 4
X#define SORT 5
X#define GET_HEADER 6
X#define GET_DISPLAY 7
X#define CLEANUP 8
X
Xstruct iosbdef {
X  unsigned short int status;
X  unsigned short int length; /* for mailbox read/write */
X  unsigned int pid;          /* for mailbox read/write */
X};
X
Xstruct itmlst {
X  unsigned short int length;
X  unsigned short int code;
X  char *bufadr;
X  int *retlen;
X};
X$EOD
X$ create/log GLOBAL_VALUES.H
X$DECK
Xglobalvalue SYS$GW_BJOBCNT;
Xglobalvalue SYS$GW_IJOBCNT;
Xglobalvalue SYS$GW_NJOBCNT;
Xglobalvalue SCH$GW_PROCCNT;
X$EOD
X$ create/log INIT.C
X$DECK
X#include "server.h"
X
Xinit$dummy(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  item = &(itemlist->item[itemindx]);
X  item->address = 0;
X  item->size = 0;
X  item->flags.type = FLAGTYPEABS;
X  ++itemlist->maxitems;
X}
X
Xinit$jpi(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  int index;
X
X  item = &(itemlist->item[itemindx]);
X
X  index = add_jpi_item(keywords[item->keyindx].ini_data);
X
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index  * 4);
X  item->size = JpiCodes[index].size;
X  item->flags.type = FLAGTYPEJPI;
X
X  ++itemlist->maxitems;
X}
X
Xadd_jpi_item(jpicod)
X  unsigned short int jpicod;
X{
X  int i,index;
X
X  index = lookup_jpi(jpicod);
X
X  ++system_jpi.refcnt[index];
X  switch (JpiCodes[index].avail) {
X    case 0: /* add to system_jpi.pcb_items[], increment pcb_itemcnt */
X      for (i = 0; (i < system_jpi.pcb_itemcnt)
X                 && (system_jpi.pcb_items[i].code != jpicod); i++);
X      if (i == system_jpi.pcb_itemcnt) {
X        system_jpi.pcb_items[i].code = jpicod;
X        system_jpi.pcb_items[i].length = JpiCodes[index].size;
X        system_jpi.pcb_items[i].bufadr = JpiCodes[index].offset
X`009`009`009`009`009+ system_jpi.data
X`009`009`009`009`009+ (index * 4);
X        system_jpi.tried[index] = 0;
X        ++system_jpi.pcb_itemcnt;
X      };
X      break;
X    case 1: /* add to system_jpi.phd_items[], increment phd_itemcnt */
X      for (i = 0; (i < system_jpi.phd_itemcnt)
X                 && (system_jpi.phd_items[i].code != jpicod); i++);
X      if (i == system_jpi.phd_itemcnt) {
X        system_jpi.phd_items[i].code = jpicod;
X        system_jpi.phd_items[i].length = JpiCodes[index].size;
X        system_jpi.phd_items[i].bufadr = JpiCodes[index].offset
X`009`009`009`009`009+ system_jpi.data
X`009`009`009`009`009+ (index * 4);
X        system_jpi.tried[index] = 0;
X        ++system_jpi.phd_itemcnt;
X      };
X      break;
X    case 2: /* add to system_jpi.ctl_items[], increment ctl_itemcnt */
X      for (i = 0; (i < system_jpi.ctl_itemcnt)
X                 && (system_jpi.ctl_items[i].code != jpicod); i++);
X      if (i == system_jpi.ctl_itemcnt) {
X        system_jpi.ctl_items[i].code = jpicod;
X        system_jpi.ctl_items[i].length = JpiCodes[index].size;
X        system_jpi.ctl_items[i].bufadr = JpiCodes[index].offset
X`009`009`009`009`009+ system_jpi.data
X`009`009`009`009`009+ (index * 4);
X        system_jpi.tried[index] = 0;
X        ++system_jpi.ctl_itemcnt;
X      };
X      break;
X  };
X  return(index);
X}
X
Xlookup_jpi(itmcod)
X  unsigned short int itmcod;
X{
X  int start = 0, fini = JPIMAXITEMCNT, mid;
X
X  /* do binary search of JpiCodes looking for item code */
X  while (start <= fini) {
X    mid = (start + fini) / 2;
X    if (JpiCodes[mid].itemcode == itmcod)
X      return(mid);
X    if (itmcod < JpiCodes[mid].itemcode) {
X      fini = mid - 1;
X    } else {
X      start = mid + 1;
X    };
X  };
X  printf("Unable to find item code %08x in JpiCodes!\n",itmcod);
X  sys$exit(4); /* should use an illegal item code type of error code */
X};
X
Xinit$syi(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  union {
X    unsigned long int l0;
X    variant_struct {
X      unsigned short int w0;
X      unsigned short int w1;
X    } word_struct;
X  } cvt;
X
X  int i;
X
X  item = &(itemlist->item[itemindx]);
X
X  for (i = 0; syi_items[linkindx][i].code; ++i);
X  if (i < MAXSYI) {
X    cvt.l0 = keywords[item->keyindx].ini_data;
X    syi_items[linkindx][i].length = cvt.w0;
X    syi_items[linkindx][i].code = cvt.w1;
X    if (i == 0)
X      syi_items[linkindx][i].bufadr = 0;
X    else
X      syi_items[linkindx][i].bufadr = syi_items[linkindx][i - 1].bufadr +
X`009syi_items[linkindx][i - 1].length;
X    item->address = syi_items[linkindx][i].bufadr;
X    item->flags.type = FLAGTYPESYI;
X    item->size = cvt.w0;
X
X    ++itemlist->maxitems;
X  }
X}
X
Xinit$pages(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  int index;
X
X  item = &(itemlist->item[itemindx]);
X  index = add_jpi_item(JPI$_PPGCNT);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X
X  item = &(itemlist->item[itemindx+1]);
X  item->keyindx = -1;
X  index = add_jpi_item(JPI$_GPGCNT);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X}
X
Xinit$io(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  int index;
X
X  item = &(itemlist->item[itemindx]);
X  index = add_jpi_item(JPI$_BUFIO);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X
X  item = &(itemlist->item[itemindx+1]);
X  item->keyindx = -1;
X  index = add_jpi_item(JPI$_DIRIO);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X}
X
Xinit$state(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  int index;
X
X  item = &(itemlist->item[itemindx]);
X  index = add_jpi_item(JPI$_STATE);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X
X  item = &(itemlist->item[itemindx+1]);
X  item->keyindx = -1;
X  index = add_jpi_item(JPI$_EFWM);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X}
X
Xinit$type(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X  int index;
X
X  item = &(itemlist->item[itemindx]);
X  index = add_jpi_item(JPI$_JOBTYPE);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X  item = &(itemlist->item[itemindx+1]);
X  item->keyindx = -1;
X  index = add_jpi_item(JPI$_MODE);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X  item = &(itemlist->item[itemindx+2]);
X  item->keyindx = -1;
X  index = add_jpi_item(JPI$_OWNER);
X  item->jpicod_index = index;
X  item->address = JpiCodes[index].offset + (index * 4);
X  item->flags.type = FLAGTYPEJPI;
X  ++itemlist->maxitems;
X}
X
Xinit$global(itemlist,itemindx,linkindx)
X  struct FmtItemsList *itemlist;
X  int itemindx;
X  int linkindx;
X{
X  struct FmtItems *item;
X
X  item = &(itemlist->item[itemindx]);
X  item->address = keywords[item->keyindx].ini_data;
X  item->flags.type = FLAGTYPEABS;
X  item->size = 2;
X
X  ++itemlist->maxitems;
X}
X$EOD
X$ create/log JPICODES.C
X$DECK
X/* this program is going to reorder this array, sorting by item code,
X   obtain a count of the items, and set the offsets properly. It
X   will output a text file for inclusion in the getjpi code */
X
X#include stdio
X#include jpidef
XFILE *outfile;
X
X#define QUOTE "
X#define JPI__(A) JPI$_/* ignore this */A,QUOTE A ",0
X/* the above macro just changes a line like:
X   JPI__(ACCOUNT) into JPI$_ACCOUNT,"ACCOUNT"
X   Amazing huh? Portable? Highly doubtful, but who cares with this?
X*/
X
Xstruct jpilst {
X  int itemcode;
X  char *itemname;
X  int offset;
X  int size;
X} JpiCodes[] = {
X`009{JPI__(ACCOUNT),8},
X`009{JPI__(APTCNT),4},
X`009{JPI__(ASTACT),4},
X`009{JPI__(ASTCNT),4},
X`009{JPI__(ASTEN),4},
X`009{JPI__(ASTLM),4},
X`009{JPI__(AUTHPRI),4},
X`009{JPI__(AUTHPRIV),8},
X`009{JPI__(BIOCNT),4},
X`009{JPI__(BIOLM),4},
X`009{JPI__(BUFIO),4},
X`009{JPI__(BYTCNT),4},
X`009{JPI__(BYTLM),4},
X`009{JPI__(CLINAME),39},
X`009{JPI__(CPULIM),4},
X`009{JPI__(CPUTIM),4},
X`009{JPI__(CREPRC_FLAGS),4},
X`009{JPI__(CURPRIV),8},
X`009{JPI__(DFPFC),4},
X`009{JPI__(DFWSCNT),4},
X`009{JPI__(DIOCNT),4},
X`009{JPI__(DIOLM),4},
X`009{JPI__(DIRIO),4},
X`009{JPI__(EFCS),4},
X`009{JPI__(EFCU),4},
X`009{JPI__(EFWM),4},
X`009{JPI__(ENQCNT),4},
X`009{JPI__(ENQLM),4},
X`009{JPI__(FILCNT),4},
X`009{JPI__(FILLM),4},
X`009{JPI__(FREP0VA),4},
X`009{JPI__(FREP1VA),4},
X`009{JPI__(FREPTECNT),4},
X`009{JPI__(GPGCNT),4},
X`009{JPI__(GRP),4},
X`009{JPI__(IMAGECOUNT),4},
X`009{JPI__(IMAGNAME),128},
X`009{JPI__(IMAGPRIV),8},
X`009{JPI__(JOBPRCCNT),4},
X`009{JPI__(JOBTYPE),4},
X`009{JPI__(LOGINTIM),8},
X`009{JPI__(MASTER_PID),4},
X`009{JPI__(MAXDETACH),4},
X`009{JPI__(MAXJOBS),4},
X`009{JPI__(MEM),4},
X`009{JPI__(MODE),4},
X`009{JPI__(MSGMASK),4},
X`009{JPI__(OWNER),4},
X`009{JPI__(PAGEFLTS),4},
X`009{JPI__(PAGFILCNT),4},
X`009{JPI__(PAGFILLOC),4},
X`009{JPI__(PGFLQUOTA),4},
X`009{JPI__(PHDFLAGS),4},
X`009{JPI__(PID),4},
X`009{JPI__(PPGCNT),4},
X`009{JPI__(PRCCNT),4},
X`009{JPI__(PRCLM),4},
X`009{JPI__(PRCNAM),16},
X`009{JPI__(PRI),4},
X`009{JPI__(PRIB),4},
X`009{JPI__(PROC_INDEX),4},
X`009{JPI__(PROCPRIV),8},
X`009{JPI__(SHRFILLM),4},
X`009{JPI__(SITESPEC),4},
X`009{JPI__(STATE),4},
X`009{JPI__(STS),4},
X`009{JPI__(SWPFILLOC),4},
X`009{JPI__(TABLENAME),252},
X`009{JPI__(TERMINAL),8},
X`009{JPI__(TMBU),4},
X`009{JPI__(TQCNT),4},
X`009{JPI__(TQLM),4},
X`009{JPI__(UAF_FLAGS),4},
X`009{JPI__(UIC),4},
X`009{JPI__(USERNAME),12},
X`009{JPI__(VIRTPEAK),4},
X`009{JPI__(VOLUMES),4},
X`009{JPI__(WSAUTH),4},
X`009{JPI__(WSAUTHEXT),4},
X`009{JPI__(WSEXTENT),4},
X`009{JPI__(WSPEAK),4},
X`009{JPI__(WSQUOTA),4},
X`009{JPI__(WSSIZE),4},
X  };
X
Xmain()
X{
X  int numitems = 0, buffersize = 0, numpcb = 0, numphd = 0, numctl = 0;
X  int i;
X
X  /* This program gets run once by MAKE and then never gets touched, until
X     new jpi items are added (or old ones removed. If your server task only
X     needs a few of these defined, then you can remove the codes not needed.
X     This should result in smaller code size, and smaller running size */
X
X  /* count the items */
X  for (numitems=0; JpiCodes[numitems].itemcode != 0; numitems++);
X
X  /* sort the items (by itemcode) */
X  sort(numitems);
X
X  /* initialize the buffersize and the offset values */
X  for (i = 0; i < numitems; i++) {
X    JpiCodes[i].offset = buffersize;
X    buffersize += JpiCodes[i].size;
X    switch (availability(JpiCodes[i].itemcode)) {
X      case 0: ++numpcb; break;
X      case 1: ++numphd; break;
X      case 2: ++numctl; break;
X    };
X  };
X
X  /* output the results */
X  if ((outfile=fopen("jpicodes.h","w")) == NULL) return;
X
X  fprintf(outfile,"#define JPIMAXITEMCNT %d\n",numitems);
X  fprintf(outfile,"#define JPIMAXPCBCNT %d\n",numpcb);
X  fprintf(outfile,"#define JPIMAXPHDCNT %d\n",numphd);
X  fprintf(outfile,"#define JPIMAXCTLCNT %d\n",numctl);
X  fprintf(outfile,"#define JPIMAXBUFFLEN %d\n",buffersize);
X  fprintf(outfile,"struct JPICodes {\n");
X  fprintf(outfile,"  short int itemcode;\n");
X  fprintf(outfile,"  short int size;\n");
X  fprintf(outfile,"  short int avail;\n");
X  fprintf(outfile,"  short int offset;\n");
X  fprintf(outfile,"};\n");
X  fprintf(outfile,"#ifdef GLOBAL\n");
X  fprintf(outfile,"globaldef struct JPICodes JpiCodes[JPIMAXITEMCNT] = {\n");
X  for (i=0; i < numitems; i++) {
X    fprintf(outfile,"  {0x%x,%d,%d,%d\t/*%s*/},\n",
X`009JpiCodes[i].itemcode,
X`009JpiCodes[i].size,
X`009availability(JpiCodes[i].itemcode),
X`009JpiCodes[i].offset,
X        JpiCodes[i].itemname);
X  };
X  fprintf(outfile,"};\n");
X  fprintf(outfile,"#else\n");
X  fprintf(outfile,"globalref struct JPICodes JpiCodes[];\n");
X  fprintf(outfile,"#endif\n");
X}
X
Xsort(itemcnt)
X  int itemcnt;
X{
X  int i,j;
X  /* remember any sorts? lets keep it real simple */
X  /* use JpiCodes[itemcnt] as temp storage */
X
X  for (i = 0; i < itemcnt; i++)
X    for (j = i; j < itemcnt; j++)
X      if (JpiCodes[j].itemcode < JpiCodes[i].itemcode)
X        swap(i,j,&JpiCodes[itemcnt]);
X};
X
Xswap(i,j,temp)
X  int i,j;
X  struct jpilst *temp;
X{
X  *temp = JpiCodes[i];
X  JpiCodes[i] = JpiCodes[j];
X  JpiCodes[j] = *temp;
X}
X
Xavailability(itmcod)
X  int itmcod;
X{
X  int retval,itmtyp;
X
X  retval = 3; /* signify unknown item type handling.. should be impossible */
X
X  itmtyp = itmcod >> 8;
X  switch (itmtyp) {
X    case JPI$C_JIBTYPE:`009`009/* 7 */
X    case JPI$C_PCBFLDTYPE:`009/* 5 */
X    case JPI$C_PCBTYPE:`009`009/* 3 */
X      retval = 0;
X      break;
X    case JPI$C_PHDTYPE:`009`009/* 4 */
X    case JPI$C_PHDFLDTYPE:`009/* 6 */
X      switch (itmcod) {
X        case JPI$_PRCLM:
X        case JPI$_PGFLQUOTA:
X        case JPI$_PAGFILCNT:
X        case JPI$_FILLM:
X        case JPI$_TQLM:
X          retval = 0;
X          break;
X        default:
X          retval = 1;
X          break;
-+-+-+-+-+ End of part 3 +-+-+-+-+-

