VERSION7.C

16 KB 6a861ecb6eea5e68…
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*                                                                          */
/*      ------------         Bit-Bucket Software, Co.                       */
/*      \ 10001101 /         Writers and Distributors of                    */
/*       \ 011110 /          Freely Available<tm> Software.                 */
/*        \ 1011 /                                                          */
/*         ------                                                           */
/*                                                                          */
/*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/*                                                                          */
/*                                                                          */
/*                  This module was adapted by Bill Andrus                  */
/*                With the usual kibitzing by Vince Perriello               */
/*                                                                          */
/*              BinkleyTerm Version7 Nodelist processing module             */
/*                                                                          */
/*                                                                          */
/*    For complete  details  of the licensing restrictions, please refer    */
/*    to the License  agreement,  which  is published in its entirety in    */
/*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
/*                                                                          */
/*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
/*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
/*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
/*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
/*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
/*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
/*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
/*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
/*                                                                          */
/*                                                                          */
/* You can contact Bit Bucket Software Co. at any one of the following      */
/* addresses:                                                               */
/*                                                                          */
/* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
/* P.O. Box 460398                AlterNet 7:491/0                          */
/* Aurora, CO 80046               BBS-Net  86:2030/1                        */
/*                                Internet f491.n343.z1.fidonet.org         */
/*                                                                          */
/* Please feel free to contact us at any time to share your comments about  */
/* our software and/or licensing policies.                                  */
/*                                                                          */
/*--------------------------------------------------------------------------*/

/* Include this file before any other includes or defines! */

#include "includes.h"

/* This table has been modified to minimize searches */
char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";

long btree (char *, void *, int (*)(void *, void *, int));
int get_ver7_info (unsigned long, ADDRP);
struct _ndx far *get7node(HFILE, unsigned long, struct _ndx far *);
void unpk(char *instr,char *outp,int many);
int addr_compare (void *, void *, int);
int name_compare (void *, void *, int);
extern void get_nodelist_name (ADDRP);

extern char *nodelist_base;
extern char *nodelist_name;
static char  index_filename[260];

static int namelen;

static struct _ndx far *nodeidx = NULL;              /* index file             */
static struct _ndx far *noderef = NULL;              /* index file             */


int ver7find (ADDRP opus_addr, int have_boss_data)
{
    long record;
    ADDR found_addr;

    have_boss_data = have_boss_data;

    newnodedes.NetNumber = newnodedes.NodeNumber = 0;

    get_nodelist_name (opus_addr);              /* fill in nodelist.base  */
    index_filename[0] = '\0';                   /* "null-terminated string*/
    (void) strcpy (index_filename, net_info);   /* take nodelist path     */
    (void) strcat (index_filename, nodelist_base); /* add in the file name*/
    (void) strcat (index_filename, ".NDX");     /* add in the file ext    */

    record = btree (index_filename, (void *)opus_addr, addr_compare);

    if (record == -1)
       return (0);
    else
       return (get_ver7_info((unsigned long)record, &found_addr));
}

int addr_compare (void *key, void *desired, int len)
{
   int k;

   k = ((ADDRP)key)->Zone - ((ADDRP)desired)->Zone;
   if (k)
      return (k);

   k = ((ADDRP)key)->Net - ((ADDRP)desired)->Net;
   if (k)
      return (k);

   k = ((ADDRP)key)->Node - ((ADDRP)desired)->Node;
   if (k)
      return (k);
/*
 * Node matches.
 *
 * The rule for points:
 *  1) If len == 6, treat key value for Point as Zero.
 *  2) Return comparison of key Point and desired Point.
 */
   if (len == 6)
      ((ADDRP)key)->Point = 0;

   return ((ADDRP)key)->Point - ((ADDRP)desired)->Point;
} 

void opususer (char *name, ADDRP faddr)
{
   char last_name_first[80];
   char midname[80];
   char *c, *p, *m;
   long record;

   faddr->Zone = faddr->Net = faddr->Node = faddr->Point = (unsigned int) -1;
   faddr->Domain = NULL;

   c = midname;                                  /* Start of temp name buff   */
   p = name;                                     /* Point to start of name    */
   m = NULL;                                     /* Init pointer to space     */

   *c = *p++;
   while (*c)                                    /* Go entire length of name  */
   {
      if (*c == ' ')                             /* Look for space            */
         m = c;                                  /* Save location             */
      c++;
      *c = *p++;
   }

   if (m != NULL)                                /* If we have a pointer,     */
   {
      *m++ = '\0';                               /* Terminate the first half  */
      (void) strcpy (last_name_first, m);        /* Now copy the last name    */
      (void) strcat (last_name_first, ", ");     /* Insert a comma and space  */
      (void) strcat (last_name_first, midname);  /* Finally copy first half   */
   }
   else (void) strcpy (last_name_first, midname);/* Use whole name otherwise  */

   (void) fancy_str (last_name_first);           /* Get caps in where needed  */
   namelen = (int) strlen (last_name_first);     /* Calc length now           */

   index_filename[0] = '\0';                     /* "null-terminated string"  */

   if (nodelist_base == NULL)
      get_nodelist_name (&my_addr);              /* fill in nodelist.base     */
   (void) strcpy (index_filename, net_info);     /* take nodelist path        */
   (void) strcat (index_filename, "SYSOP.NDX");  /* add in the file name      */

   record = btree (index_filename, (void *)last_name_first, name_compare);

   if (record == -1)
      return;

   (void) get_ver7_info((unsigned long)record, faddr);
}

int name_compare (void *key, void *desired, int len)
{
   return (strnicmp ((char *)key, (char *)desired, (unsigned int) min (namelen,len)));
}

/*
 * General V7 nodelist engine. Used by both the by-node and by-sysop
 * lookups.
 *
 * Thanks to Phil Becker for showing me how nice it looks in assembler.
 * It helped me see how nice it could be in C.
 *
 * (I know, Phil, it's still nicer in assembler!)
 *
 */

long btree (char *filename, void *desired, int (*compare)(void *key, void *desired, int len))
{
    int j, k, l;
    struct _IndxRef far *ip = NULL;
    struct _LeafRef far *lp = NULL;
    char aline[160];
    char far *tp;
    char *np;

    long record, foundrec = -1L;
    int count;

    HFILE stream;

    if ((stream = share_open(filename, O_RDONLY|O_BINARY, DENY_WRITE)) == -1)
        return (-1L);                            /* no file, no work to do */

    if (node_index == NULL)
        node_index = _fmalloc ( sizeof (struct _ndx));
    if (nodeidx == NULL)
        nodeidx = _fmalloc ( sizeof (struct _ndx));
    if (noderef == NULL)
        noderef = _fmalloc ( sizeof (struct _ndx));

    if (node_index == NULL)
    {
        status_line (msgtxt[M_NODELIST_MEM]);
        (void) close (stream);
        return (-1L);
    }

    /* Get CtlRec */
    if (get7node (stream, 0L, noderef) != noderef)
        {
        close (stream);
        return (-1L);
        }

    /* The guts of the matter -- walk from CtlRec to Leaf */

    record = noderef->ndx.CtlBlk.CtlRoot;

/*
 * Read the first Index node.
 */
    if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
        {
        close (stream);
        return (-1L);
        }
/*
 * Follow the node tree until we either match a key right in the index
 * node, or locate the leaf node which must contain the entry.
 */
    while (nodeidx->ndx.INodeBlk.IndxFirst != -1)
       {
       if ((count = nodeidx->ndx.INodeBlk.IndxCnt) == 0)
          {
          close (stream);
          return (-1L);
          }

       for (j = 0; j < count; j++) /* check 20 or less */
          {
          ip = &(nodeidx->ndx.INodeBlk.IndxRef[j]);
          tp = (char far *) nodeidx + ip->IndxOfs;

          k = l = ip->IndxLen;

          for (np = aline; k > 0; k--)
              *np++ = *tp++;

          k = (*compare) ((void *)aline, desired, l);

          if (k > 0)
             break;

          if (k == 0)
             {

/* Key matches in the index node. Since we're just doing lookup, we
 * can assume its pointer is valid. If we were doing updates, that
 * assumption would not work, because leaf nodes update first. So in
 * an update environment, the entire code segment relating to k == 0
 * should not execute, and we should walk the tree all the way down.
 */
             close (stream);
             return (nodeidx->ndx.INodeBlk.IndxRef[j].IndxData);
             }
          }

       if (j == 0)
          record = nodeidx->ndx.INodeBlk.IndxFirst;
       else
          record = (nodeidx->ndx.INodeBlk.IndxRef[--j]).IndxPtr;

       if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
          {
          close (stream);
          return (-1L);
          }

       }
/*
 * We can only get here if we've found the leafnode which must
 * contain our entry.
 *
 * Find our guy here or die trying.
 */

    if ((count = nodeidx->ndx.LNodeBlk.IndxCnt) != 0)
       {
       /* Search for a higher key */

       for (j = 0; j < count; j++) /* check 30 or less */
          {
          lp = &(nodeidx->ndx.LNodeBlk.LeafRef[j]);
          tp = (char far *) nodeidx + lp->KeyOfs;

          k = l = lp->KeyLen;

          for (np = aline; k > 0; k--)
              *np++ = *tp++;

          k = (*compare) ((void *)aline, desired, l);

          if (k > 0)
             break;
          if (k == 0)
             {
             foundrec = (nodeidx->ndx.LNodeBlk.LeafRef[j]).KeyVal;
             break;
             }
          }
       }

    (void) close (stream);
    return (foundrec);
}

int get_ver7_info (unsigned long pos, ADDRP faddr)
{
    struct _vers7 vers7;
    char my_phone[40];
    char my_pwd[9];
    char aline[160];
    char aline2[160];
    char *fst;
    char temp[80];                                  /* we build filenames here*/
    FILE *stream;

    (void) strcpy (temp, net_info);                     /* take nodelist path */
    (void) strcat (temp, nodelist_base);                /* add in the filename*/
    (void) strcat (temp, ".DAT");                       /* then the extension */
    if ((stream = share_fopen (temp, "rb", DENY_WRITE)) == NULL)    /* open it*/
    {
        status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
        return (0);
    }

    if (fseek (stream,(long int) pos, SEEK_SET))              /* point at record    */
    {
        status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
        (void) fclose (stream);
        return (0);
    }

    if (!fread ((char *)&vers7, sizeof (struct _vers7), 1, stream))
    {
        status_line (msgtxt[M_NODELIST_REC_ERR], temp);
        (void) fclose (stream);
        return (0);
    }

    (void) memset(my_phone,'\0',40);
    (void) fread (my_phone, vers7.Phone_len, 1, stream);

    (void) memset(my_pwd,'\0',9);
    (void) fread (my_pwd, vers7.Password_len, 1, stream);

    (void) memset(aline,'\0',160);
    (void) memset(aline2,'\0',160);
    if (!fread (aline2, vers7.pack_len, 1, stream))
        {
        status_line (msgtxt[M_NODELIST_REC_ERR], temp);
        (void) fclose (stream);
        return (0);
        }

    (void) fclose (stream);

    unpk(aline2,aline,vers7.pack_len);

    (void) memset (&newnodedes, 0, sizeof (struct _newnode));

    newnodedes.NetNumber = vers7.Net;
    newnodedes.NodeNumber = vers7.Node;
    newnodedes.Cost = newnodedes.RealCost = vers7.CallCost;
    (void) memcpy (newnodedes.SystemName, aline, min(33, vers7.Bname_len));
    newnodedes.SystemName[min(33, vers7.Bname_len)] = '\0';
    (void) fancy_str (newnodedes.SystemName);

#ifdef MILQ
    fst = &aline[0] + vers7.Bname_len;
    (void) memcpy (crnt_sysop, fst, min(25,vers7.Sname_len));
    crnt_sysop[min(25,vers7.Sname_len)] = '\0';
    (void)fancy_str( crnt_sysop );
#endif

    fst = &aline[0] + vers7.Bname_len + vers7.Sname_len;
    (void) memcpy (newnodedes.PhoneNumber, my_phone, min(39,vers7.Phone_len));
    newnodedes.PhoneNumber[min(39,vers7.Phone_len)] = '\0';
    (void) memcpy (newnodedes.MiscInfo, fst, min(29, vers7.Cname_len));
    newnodedes.MiscInfo[min(29, vers7.Cname_len)] = '\0';
    (void) fancy_str( newnodedes.MiscInfo );

    (void) memcpy (newnodedes.Password, my_pwd, min(8, vers7.Password_len));
    newnodedes.HubNode = vers7.HubNode;
    newnodedes.BaudRate = vers7.BaudRate;
    newnodedes.ModemType = vers7.ModemType;
    newnodedes.NodeFlags = vers7.NodeFlags;

    found_zone = faddr->Zone  = vers7.Zone;
    found_net  = faddr->Net   = vers7.Net;
    faddr->Node  = vers7.Node;
    if (vers7.NodeFlags & B_point)
        faddr->Point = vers7.HubNode;
    else faddr->Point = 0;
    faddr->Domain = NULL;

    return (1);
}

struct _ndx far *get7node(HFILE stream, unsigned long pos, struct _ndx far *ndx)
{
#ifdef C386
    unsigned long  got;
#else
    USHORT got;
#endif

    (void) lseek (stream, (long) pos, SEEK_SET);

    if (_dos_read (stream, ndx,(unsigned int) sizeof (struct _ndx), &got) != 0)
    {
        status_line (msgtxt[M_NODELIST_READ_ERR]);
        (void) close (stream);
        return (NULL);
    }
    return (ndx);
}


/* ====================================================================
 * unpack a dense version of a symbol (base 40 polynomial)
 * ====================================================================
 */
void unpk(char *instr,char *outp,int count)
{
    struct chars {
           unsigned char c1;
           unsigned char c2;
           };

    union {
          unsigned w1;
          struct chars d;
          } u;

   register int i, j;
   char obuf[4];

   outp[0] = '\0';

   while (count) {
       u.d.c1 = *instr++;
       u.d.c2 = *instr++;
       count -= 2;
       for(j=2;j>=0;j--) {
           i = u.w1 % 40;
           u.w1 /= 40;
            obuf[j] = unwrk[i];
           }
       obuf[3] = '\0';
       (void) strcat (outp, obuf);
       }
}