From:	CSBVAX::MRGATE!JOE%FHCRCVAX.BITNET@CUNYVM.CUNY.EDU@SMTP 17-JUN-1988 06:19
To:	ARISIA::EVERHART
Subj:	Latest batch of bug fixes (argh!)


Received: from UWAVM.ACS.WASHINGTON.EDU by oly.acs.washington.edu ; Fri, 17 Jun 88 03:03:46 PDT
Received: from UWAVM.ACS.WASHINGTON.EDU by UWAVM.ACS.WASHINGTON.EDU (Mailer
 X1.24) with BSMTP id 7562; Fri, 17 Jun 88 03:03:41 PDT
P1-Message-Id: US**EDU;UWAVM.ACS.WASHINGTON.EDU:LO2N0l49
Date:         Thu, 16 Jun 88 20:12-0700
X400-Trace:   US**EDU; arrival Thu, 16 Jun 88 20:12-0700 action Relayed
X400-Trace:   US**EDU; arrival Fri, 17 Jun 88 03:03-0700 action Relayed
From:         Joe Meadows<JOE%FHCRCVAX.BITNET@oly.acs.washington.edu>
Subject:      Latest batch of bug fixes (argh!)
To:           <Everhart%Arisia.decnet@GE-CRD.ARPA>
Message-Id:   <UWAVM.ACS.WASHINGTON.EDU:LO2N0l49*>
X-VMS-To: @SYS$LOGIN:GLENN.EVERHART

Hi Glenn,

I though you might like these bug fixed routines...
By the way, did the whole STATUS program make it over the
net to you? It being fairly large, I had some concerns that
it might not.. I sent it out last, uh, Thursday? the 9th...

How are things going? Pretty hectic I'd imagine..

Cheers,
Joe Meadows     joe@fhcrcvax.bitnet

$!
$! These routines all used SYS$ASSIGN, and often didn't SYS$DASSGN
$! afterwards. Hence, the updates. They now always DASSGN. I had a
$! slight problem with READPORT.C, in that if I put the DASSGN right
$! after the QIOW, I didn't get any results... It seemed weird, but
$! since I could work around it I didn't pursue it further.
$!
$ create/log DECNET.C
$DECK
#include descrip
#include iodef

#define NFB$C_FC_SHOW   0x00000022
#define NFB$M_NOUPD     0x00000004 /* don't update the database         */
#define NFB$C_DB_LLI    0x00000008 /* logical link information database */
#define NFB$C_OP_EQL    0x00000000 /* match the key exactly             */
#define NFB$C_LLI_LLN   0x08010012 /* the key is a logical link number  */
#define NFB$C_WILDCARD  0x00000001 /* search the whole database         */
#define NFB$C_LLI_PNN   0x08020043 /* partner's node name               */
#define NFB$C_ENDOFLIST 0x00000000

Get_DECnet_Node(link,site)
  unsigned short int link;
  char *site;
{
  $DESCRIPTOR(Net,"Net:");

  struct {
    unsigned char nfb$b_fct;
    unsigned char nfb$b_flags;
    unsigned char nfb$b_database;
    unsigned char nfb$b_oper;
    long int nfb$l_srch_key;
    long int nfb$l_srch2_key;
    unsigned char nfb$b_oper2;
    unsigned char nfb$b_mbz1;
    short int nfb$w_cell_size;
    long int nfb$l_fldid; /* first of the fields */
    long int f2;
  } nfb =
    {
      NFB$C_FC_SHOW, NFB$M_NOUPD, NFB$C_DB_LLI, NFB$C_OP_EQL,
      NFB$C_LLI_LLN, NFB$C_WILDCARD,
      0, 0, 0,
      NFB$C_LLI_PNN, NFB$C_ENDOFLIST
    };

  struct {
    short int len;
    char name[10];      /* shucks, how big can a nodename be? isn't it 6? */
  } buf;

  struct {
    long int k1;
    long int k2;
  } key = {0,link};

  struct dsc$descriptor nfbdesc = {sizeof(nfb), 0, 0, &nfb};
  struct dsc$descriptor keydesc = {sizeof(key), 0, 0, &key};
  struct dsc$descriptor bufdesc = {sizeof(buf), 0, 0, &buf};

  int status;
  short int chan, iosb[4];

  site[0] = '\0';

  status = sys$assign (&Net, &chan, 0, 0);
  if (!( status & 1))
  {
    lib$signal(status);
    return(status);
  }

  buf.len = 0;

  status = sys$qiow (0,chan,IO$_ACPCONTROL,iosb,0,0,
                        &nfbdesc,&keydesc,0,&bufdesc,0,0);
  sys$dassgn(chan);
  if (status & 1) status = iosb[0];
  if (!( status & 1))
  {
    lib$signal(status);
    return(status);
  }

  strncpy(site,buf.name,buf.len);
  site[buf.len] = '\0';
  return(1);
}
$EOD
$ create/log PSEUDO.C
$DECK
#include iodef
#include descrip
#include dvidef

#include "globals.h" /* for itmlst */

#define TCP$INFO IO$_MODIFY
#define GETHST IO$_SKIPFILE

struct tcp_info {
  unsigned char ForeignHostSize;
  unsigned char LocalHostSize;
  char ForeignHost[128];
  long int ForeignPort;
  short int unused;
  char LocalHost[128];
  long int LocalPort;
  unsigned long int LocalAddress;
  unsigned long int ForeignAddress;
};

struct gethst_info {
  unsigned long int NameLen;
  char Name[128];
};


convert_pseudo_terminal(terminal,where)
  char *terminal,*where;
{
  char device[10]; /* that oughta hold the device name */
  struct dsc$descriptor dev = {0,0,0,device};
  static struct DevInfo {
    long int pid;
    short int len;
    char name[64];
  } devinfo[20];
  static int devinfosize = sizeof(struct DevInfo);
  static int class = -1, devinfocnt = 20;
  int pid, status, i, indx, chan, notfound;
  struct tcp_info info;
  struct gethst_info host;
  short int iosb[4];
  struct itmlst dvilst[] = {4,DVI$_PID,&pid,0,0,0,0,0};

  if (terminal[0] != 'T' || terminal[1] != 'P' || terminal[2] != 'A')
    return(0);

  strcpy(device,terminal);
  device[0] = 'P';
  device[1] = 'Y';
  dev.dsc$w_length = strlen(device);

  /* getdvi to find out who owns PYAnnn */
  status = sys$getdviw(0,0,&dev,dvilst,iosb,0,0,0);
  if (!(status & 1)) return(status);
  if (!(iosb[0] & 1)) return(iosb[0]);

  /* find all devices owned by this PID */
  status = devices(&class, &pid, &devinfocnt, &devinfosize, devinfo);
  if (status & 1) {
    i = 0;
    notfound = -1;
    while (notfound && devinfo[i].len) {
      if (devinfo[i].name[0] == '_' &&
          devinfo[i].name[1] == 'I' &&
          devinfo[i].name[2] == 'P')
      {
        dev.dsc$w_length = devinfo[i].len;
        dev.dsc$a_pointer = devinfo[i].name;
        notfound = 0;
      }
      else
        ++i;
    };
    if (notfound) return(0);

    status = sys$assign(&dev, &chan, 0, 0);
    if (!(status & 1))
      return(status);

    status = sys$qiow(0,chan,TCP$INFO,iosb,0,0,&info,sizeof(info),0,0,0,0);

    sys$dassgn(chan);

    if (status & 1)
      status = iosb[0];
    if (!(status & 1))
      return(status);

    sprintf(where,"%.*s",info.ForeignHostSize, info.ForeignHost);
    return(1);
  };

    /* viola .. */
  /* else */
    /* perhaps display owner username, imagname, or better - terminal ? */


  return(0);
}
$EOD
$ create/log READPORT.C
$DECK
#include descrip
#define IO$_TTY_PORT 41
#define IO$M_LT_READPORT 256

readport(terminal,server,port)
  char *terminal, *server, *port;
{
  short int chan;
  short int iosb[4];
  char portinfo[1+16+1+16];
  struct dsc$descriptor term =
    {strlen(terminal),DSC$K_DTYPE_T,DSC$K_CLASS_S,terminal} ;
  long int status;
  short int i,j;

  status = sys$assign(&term ,&chan ,0 ,0);
  if ((status & 1) == 0)
    return(status);

  status = sys$qiow(0 ,chan ,IO$_TTY_PORT | IO$M_LT_READPORT ,iosb
                    ,0 ,0 ,portinfo ,sizeof(portinfo) ,0 ,0 ,0 ,0);

  /* portinfo[] = (count byte), "port name", (count byte), "server name" */
  for (i=0; i<portinfo[0]; ++i)
    port[i] = portinfo[i+1];
  port[i] = '\0';

  j = i + 1;
  for (i = 0; i<portinfo[j]; ++i)
    server[i] = portinfo[i+j+1];
  server[i] = '\0';

  sys$dassgn(chan);

  if (!(status & 1))
    status = iosb[0];
  if (!(status & 1))
  {
    port[0] = '\0';
    server[0] = '\0';
    return(status);
  }
}
$EOD
$ create/log RTPAD.C
$DECK
#include descrip
#include iodef

#define NFB$C_FC_SHOW   0x00000022
#define NFB$M_NOUPD     0x00000004 /* don't update the database         */
#define NFB$C_DB_LLI    0x00000008 /* logical link information database */
#define NFB$C_OP_EQL    0x00000000 /* match the key exactly             */
#define NFB$C_LLI_PID   0x08010015 /* the key is PID of process         */
#define NFB$C_WILDCARD  0x00000001 /* search the whole database         */
#define NFB$C_LLI_PNN   0x08020043 /* partner's node name               */
#define NFB$C_ENDOFLIST 0x00000000

Get_RTPAD_Destination(pid,site)
  int pid;
  char *site;
{
  $DESCRIPTOR(Net,"Net:");

  struct {
    unsigned char nfb$b_fct;
    unsigned char nfb$b_flags;
    unsigned char nfb$b_database;
    unsigned char nfb$b_oper;
    long int nfb$l_srch_key;
    long int nfb$l_srch2_key;
    unsigned char nfb$b_oper2;
    unsigned char nfb$b_mbz1;
    short int nfb$w_cell_size;
    long int nfb$l_fldid; /* first of the fields */
    long int f2;
  } nfb =
    {
      NFB$C_FC_SHOW, NFB$M_NOUPD, NFB$C_DB_LLI, NFB$C_OP_EQL,
      NFB$C_LLI_PID, NFB$C_WILDCARD,
      0, 0, 0,
      NFB$C_LLI_PNN, NFB$C_ENDOFLIST
    };

  struct {
    short int len;
    char name[6];
  } buf;

  struct {
    long int k1;
    long int k2;
  } key = {0,pid};

  struct dsc$descriptor nfbdesc = {sizeof(nfb), 0, 0, &nfb};
  struct dsc$descriptor keydesc = {sizeof(key), 0, 0, &key};
  struct dsc$descriptor bufdesc = {sizeof(buf), 0, 0, &buf};

  int status;
  short int chan, iosb[4];

  site[0] = '\0';

  status = sys$assign (&Net, &chan, 0, 0);
  if (!( status & 1))
  {
    lib$signal(status);
    return(status);
  }

  buf.len = 0;
  status = sys$qiow (0,chan,IO$_ACPCONTROL,iosb,0,0,
                        &nfbdesc,&keydesc,0,&bufdesc,0,0);
  sys$dassgn(chan);
  if ( status & 1)
    status = iosb[0];

  if (!( status & 1))
  {
    lib$signal(status);
    return(status);
  }

  strncpy(site,buf.name,buf.len);
  site[buf.len] = '\0';
  return(1);
}
$EOD
$ create/log TELNET.C
$DECK
#include iodef
#include descrip
#include dvidef
#include dcdef

#include "globals.h" /* for itmlst */

#define TCP$INFO IO$_MODIFY
#define GETHST IO$_SKIPFILE

struct tcp_info {
  unsigned char ForeignHostSize;
  unsigned char LocalHostSize;
  char ForeignHost[128];
  long int ForeignPort;
  short int unused;
  char LocalHost[128];
  long int LocalPort;
  unsigned long int LocalAddress;
  unsigned long int ForeignAddress;
};

struct gethst_info {
  unsigned long int NameLen;
  char Name[128];
};


Get_TELNET_Destination(pid,where)
  int pid;
  char *where;
{
  static struct DevInfo {
    long int pid;
    short int len;
    char name[64];
  } devinfo[20];
  struct dsc$descriptor dev = {0,0,0,0};
  static int devinfosize = sizeof(struct DevInfo);
  static int class = DC$_REALTIME, devinfocnt = 20;
  int status, i, indx, chan, notfound;
  struct tcp_info info;
  struct gethst_info host;
  short int iosb[4];

  /* find all devices owned by this PID */
  status = devices(&class, &pid, &devinfocnt, &devinfosize, devinfo);
  if (status & 1) {
    i = 0;
    notfound = -1;
    while (notfound && devinfo[i].len) {
      if (devinfo[i].name[0] == '_' &&
          devinfo[i].name[1] == 'I' &&
          devinfo[i].name[2] == 'P')
      {
        dev.dsc$w_length = devinfo[i].len;
        dev.dsc$a_pointer = devinfo[i].name;
        notfound = 0;
      }
      else
        ++i;
    };
    if (notfound) return(0);

    status = sys$assign(&dev, &chan, 0, 0);
    if (!(status & 1)) return(status);

    status = sys$qiow(0,chan,TCP$INFO,iosb,0,0,&info,sizeof(info),0,0,0,0);
    sys$dassgn(chan);
    if (status & 1)
      status = iosb[0];
    if (!(status & 1))
      return(status);

    sprintf(where,"%.*s",info.ForeignHostSize, info.ForeignHost);
    return(1);
  };

  /* otherwise, some kind of error.. */
  return(0);
}
$EOD
