home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / bbs_mail / bsrc_250.arj / VERSION7.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  16KB  |  477 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                  This module was adapted by Bill Andrus                  */
  14. /*                With the usual kibitzing by Vince Perriello               */
  15. /*                                                                          */
  16. /*              BinkleyTerm Version7 Nodelist processing module             */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n343.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. /* Include this file before any other includes or defines! */
  47.  
  48. #include "includes.h"
  49.  
  50. /* This table has been modified to minimize searches */
  51. char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";
  52.  
  53. long btree (char *, void *, int (*)(void *, void *, int));
  54. int get_ver7_info (unsigned long, ADDRP);
  55. struct _ndx far *get7node(HFILE, unsigned long, struct _ndx far *);
  56. void unpk(char *instr,char *outp,int many);
  57. int addr_compare (void *, void *, int);
  58. int name_compare (void *, void *, int);
  59. extern void get_nodelist_name (ADDRP);
  60.  
  61. extern char *nodelist_base;
  62. extern char *nodelist_name;
  63. static char  index_filename[260];
  64.  
  65. static int namelen;
  66.  
  67. static struct _ndx far *nodeidx = NULL;              /* index file             */
  68. static struct _ndx far *noderef = NULL;              /* index file             */
  69.  
  70.  
  71. int ver7find (ADDRP opus_addr, int have_boss_data)
  72. {
  73.     long record;
  74.     ADDR found_addr;
  75.  
  76.     have_boss_data = have_boss_data;
  77.  
  78.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  79.  
  80.     get_nodelist_name (opus_addr);              /* fill in nodelist.base  */
  81.     index_filename[0] = '\0';                   /* "null-terminated string*/
  82.     (void) strcpy (index_filename, net_info);   /* take nodelist path     */
  83.     (void) strcat (index_filename, nodelist_base); /* add in the file name*/
  84.     (void) strcat (index_filename, ".NDX");     /* add in the file ext    */
  85.  
  86.     record = btree (index_filename, (void *)opus_addr, addr_compare);
  87.  
  88.     if (record == -1)
  89.        return (0);
  90.     else
  91.        return (get_ver7_info((unsigned long)record, &found_addr));
  92. }
  93.  
  94. int addr_compare (void *key, void *desired, int len)
  95. {
  96.    int k;
  97.  
  98.    k = ((ADDRP)key)->Zone - ((ADDRP)desired)->Zone;
  99.    if (k)
  100.       return (k);
  101.  
  102.    k = ((ADDRP)key)->Net - ((ADDRP)desired)->Net;
  103.    if (k)
  104.       return (k);
  105.  
  106.    k = ((ADDRP)key)->Node - ((ADDRP)desired)->Node;
  107.    if (k)
  108.       return (k);
  109. /*
  110.  * Node matches.
  111.  *
  112.  * The rule for points:
  113.  *  1) If len == 6, treat key value for Point as Zero.
  114.  *  2) Return comparison of key Point and desired Point.
  115.  */
  116.    if (len == 6)
  117.       ((ADDRP)key)->Point = 0;
  118.  
  119.    return ((ADDRP)key)->Point - ((ADDRP)desired)->Point;
  120.  
  121. void opususer (char *name, ADDRP faddr)
  122. {
  123.    char last_name_first[80];
  124.    char midname[80];
  125.    char *c, *p, *m;
  126.    long record;
  127.  
  128.    faddr->Zone = faddr->Net = faddr->Node = faddr->Point = (unsigned int) -1;
  129.    faddr->Domain = NULL;
  130.  
  131.    c = midname;                                  /* Start of temp name buff   */
  132.    p = name;                                     /* Point to start of name    */
  133.    m = NULL;                                     /* Init pointer to space     */
  134.  
  135.    *c = *p++;
  136.    while (*c)                                    /* Go entire length of name  */
  137.    {
  138.       if (*c == ' ')                             /* Look for space            */
  139.          m = c;                                  /* Save location             */
  140.       c++;
  141.       *c = *p++;
  142.    }
  143.  
  144.    if (m != NULL)                                /* If we have a pointer,     */
  145.    {
  146.       *m++ = '\0';                               /* Terminate the first half  */
  147.       (void) strcpy (last_name_first, m);        /* Now copy the last name    */
  148.       (void) strcat (last_name_first, ", ");     /* Insert a comma and space  */
  149.       (void) strcat (last_name_first, midname);  /* Finally copy first half   */
  150.    }
  151.    else (void) strcpy (last_name_first, midname);/* Use whole name otherwise  */
  152.  
  153.    (void) fancy_str (last_name_first);           /* Get caps in where needed  */
  154.    namelen = (int) strlen (last_name_first);     /* Calc length now           */
  155.  
  156.    index_filename[0] = '\0';                     /* "null-terminated string"  */
  157.  
  158.    if (nodelist_base == NULL)
  159.       get_nodelist_name (&my_addr);              /* fill in nodelist.base     */
  160.    (void) strcpy (index_filename, net_info);     /* take nodelist path        */
  161.    (void) strcat (index_filename, "SYSOP.NDX");  /* add in the file name      */
  162.  
  163.    record = btree (index_filename, (void *)last_name_first, name_compare);
  164.  
  165.    if (record == -1)
  166.       return;
  167.  
  168.    (void) get_ver7_info((unsigned long)record, faddr);
  169. }
  170.  
  171. int name_compare (void *key, void *desired, int len)
  172. {
  173.    return (strnicmp ((char *)key, (char *)desired, (unsigned int) min (namelen,len)));
  174. }
  175.  
  176. /*
  177.  * General V7 nodelist engine. Used by both the by-node and by-sysop
  178.  * lookups.
  179.  *
  180.  * Thanks to Phil Becker for showing me how nice it looks in assembler.
  181.  * It helped me see how nice it could be in C.
  182.  *
  183.  * (I know, Phil, it's still nicer in assembler!)
  184.  *
  185.  */
  186.  
  187. long btree (char *filename, void *desired, int (*compare)(void *key, void *desired, int len))
  188. {
  189.     int j, k, l;
  190.     struct _IndxRef far *ip = NULL;
  191.     struct _LeafRef far *lp = NULL;
  192.     char aline[160];
  193.     char far *tp;
  194.     char *np;
  195.  
  196.     long record, foundrec = -1L;
  197.     int count;
  198.  
  199.     HFILE stream;
  200.  
  201.     if ((stream = share_open(filename, O_RDONLY|O_BINARY, DENY_WRITE)) == -1)
  202.         return (-1L);                            /* no file, no work to do */
  203.  
  204.     if (node_index == NULL)
  205.         node_index = _fmalloc ( sizeof (struct _ndx));
  206.     if (nodeidx == NULL)
  207.         nodeidx = _fmalloc ( sizeof (struct _ndx));
  208.     if (noderef == NULL)
  209.         noderef = _fmalloc ( sizeof (struct _ndx));
  210.  
  211.     if (node_index == NULL)
  212.     {
  213.         status_line (msgtxt[M_NODELIST_MEM]);
  214.         (void) close (stream);
  215.         return (-1L);
  216.     }
  217.  
  218.     /* Get CtlRec */
  219.     if (get7node (stream, 0L, noderef) != noderef)
  220.         {
  221.         close (stream);
  222.         return (-1L);
  223.         }
  224.  
  225.     /* The guts of the matter -- walk from CtlRec to Leaf */
  226.  
  227.     record = noderef->ndx.CtlBlk.CtlRoot;
  228.  
  229. /*
  230.  * Read the first Index node.
  231.  */
  232.     if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
  233.         {
  234.         close (stream);
  235.         return (-1L);
  236.         }
  237. /*
  238.  * Follow the node tree until we either match a key right in the index
  239.  * node, or locate the leaf node which must contain the entry.
  240.  */
  241.     while (nodeidx->ndx.INodeBlk.IndxFirst != -1)
  242.        {
  243.        if ((count = nodeidx->ndx.INodeBlk.IndxCnt) == 0)
  244.           {
  245.           close (stream);
  246.           return (-1L);
  247.           }
  248.  
  249.        for (j = 0; j < count; j++) /* check 20 or less */
  250.           {
  251.           ip = &(nodeidx->ndx.INodeBlk.IndxRef[j]);
  252.           tp = (char far *) nodeidx + ip->IndxOfs;
  253.  
  254.           k = l = ip->IndxLen;
  255.  
  256.           for (np = aline; k > 0; k--)
  257.               *np++ = *tp++;
  258.  
  259.           k = (*compare) ((void *)aline, desired, l);
  260.  
  261.           if (k > 0)
  262.              break;
  263.  
  264.           if (k == 0)
  265.              {
  266.  
  267. /* Key matches in the index node. Since we're just doing lookup, we
  268.  * can assume its pointer is valid. If we were doing updates, that
  269.  * assumption would not work, because leaf nodes update first. So in
  270.  * an update environment, the entire code segment relating to k == 0
  271.  * should not execute, and we should walk the tree all the way down.
  272.  */
  273.              close (stream);
  274.              return (nodeidx->ndx.INodeBlk.IndxRef[j].IndxData);
  275.              }
  276.           }
  277.  
  278.        if (j == 0)
  279.           record = nodeidx->ndx.INodeBlk.IndxFirst;
  280.        else
  281.           record = (nodeidx->ndx.INodeBlk.IndxRef[--j]).IndxPtr;
  282.  
  283.        if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
  284.           {
  285.           close (stream);
  286.           return (-1L);
  287.           }
  288.  
  289.        }
  290. /*
  291.  * We can only get here if we've found the leafnode which must
  292.  * contain our entry.
  293.  *
  294.  * Find our guy here or die trying.
  295.  */
  296.  
  297.     if ((count = nodeidx->ndx.LNodeBlk.IndxCnt) != 0)
  298.        {
  299.        /* Search for a higher key */
  300.  
  301.        for (j = 0; j < count; j++) /* check 30 or less */
  302.           {
  303.           lp = &(nodeidx->ndx.LNodeBlk.LeafRef[j]);
  304.           tp = (char far *) nodeidx + lp->KeyOfs;
  305.  
  306.           k = l = lp->KeyLen;
  307.  
  308.           for (np = aline; k > 0; k--)
  309.               *np++ = *tp++;
  310.  
  311.           k = (*compare) ((void *)aline, desired, l);
  312.  
  313.           if (k > 0)
  314.              break;
  315.           if (k == 0)
  316.              {
  317.              foundrec = (nodeidx->ndx.LNodeBlk.LeafRef[j]).KeyVal;
  318.              break;
  319.              }
  320.           }
  321.        }
  322.  
  323.     (void) close (stream);
  324.     return (foundrec);
  325. }
  326.  
  327. int get_ver7_info (unsigned long pos, ADDRP faddr)
  328. {
  329.     struct _vers7 vers7;
  330.     char my_phone[40];
  331.     char my_pwd[9];
  332.     char aline[160];
  333.     char aline2[160];
  334.     char *fst;
  335.     char temp[80];                                  /* we build filenames here*/
  336.     FILE *stream;
  337.  
  338.     (void) strcpy (temp, net_info);                     /* take nodelist path */
  339.     (void) strcat (temp, nodelist_base);                /* add in the filename*/
  340.     (void) strcat (temp, ".DAT");                       /* then the extension */
  341.     if ((stream = share_fopen (temp, "rb", DENY_WRITE)) == NULL)    /* open it*/
  342.     {
  343.         status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  344.         return (0);
  345.     }
  346.  
  347.     if (fseek (stream,(long int) pos, SEEK_SET))              /* point at record    */
  348.     {
  349.         status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
  350.         (void) fclose (stream);
  351.         return (0);
  352.     }
  353.  
  354.     if (!fread ((char *)&vers7, sizeof (struct _vers7), 1, stream))
  355.     {
  356.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  357.         (void) fclose (stream);
  358.         return (0);
  359.     }
  360.  
  361.     (void) memset(my_phone,'\0',40);
  362.     (void) fread (my_phone, vers7.Phone_len, 1, stream);
  363.  
  364.     (void) memset(my_pwd,'\0',9);
  365.     (void) fread (my_pwd, vers7.Password_len, 1, stream);
  366.  
  367.     (void) memset(aline,'\0',160);
  368.     (void) memset(aline2,'\0',160);
  369.     if (!fread (aline2, vers7.pack_len, 1, stream))
  370.         {
  371.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  372.         (void) fclose (stream);
  373.         return (0);
  374.         }
  375.  
  376.     (void) fclose (stream);
  377.  
  378.     unpk(aline2,aline,vers7.pack_len);
  379.  
  380.     (void) memset (&newnodedes, 0, sizeof (struct _newnode));
  381.  
  382.     newnodedes.NetNumber = vers7.Net;
  383.     newnodedes.NodeNumber = vers7.Node;
  384.     newnodedes.Cost = newnodedes.RealCost = vers7.CallCost;
  385.     (void) memcpy (newnodedes.SystemName, aline, min(33, vers7.Bname_len));
  386.     newnodedes.SystemName[min(33, vers7.Bname_len)] = '\0';
  387.     (void) fancy_str (newnodedes.SystemName);
  388.  
  389. #ifdef MILQ
  390.     fst = &aline[0] + vers7.Bname_len;
  391.     (void) memcpy (crnt_sysop, fst, min(25,vers7.Sname_len));
  392.     crnt_sysop[min(25,vers7.Sname_len)] = '\0';
  393.     (void)fancy_str( crnt_sysop );
  394. #endif
  395.  
  396.     fst = &aline[0] + vers7.Bname_len + vers7.Sname_len;
  397.     (void) memcpy (newnodedes.PhoneNumber, my_phone, min(39,vers7.Phone_len));
  398.     newnodedes.PhoneNumber[min(39,vers7.Phone_len)] = '\0';
  399.     (void) memcpy (newnodedes.MiscInfo, fst, min(29, vers7.Cname_len));
  400.     newnodedes.MiscInfo[min(29, vers7.Cname_len)] = '\0';
  401.     (void) fancy_str( newnodedes.MiscInfo );
  402.  
  403.     (void) memcpy (newnodedes.Password, my_pwd, min(8, vers7.Password_len));
  404.     newnodedes.HubNode = vers7.HubNode;
  405.     newnodedes.BaudRate = vers7.BaudRate;
  406.     newnodedes.ModemType = vers7.ModemType;
  407.     newnodedes.NodeFlags = vers7.NodeFlags;
  408.  
  409.     found_zone = faddr->Zone  = vers7.Zone;
  410.     found_net  = faddr->Net   = vers7.Net;
  411.     faddr->Node  = vers7.Node;
  412.     if (vers7.NodeFlags & B_point)
  413.         faddr->Point = vers7.HubNode;
  414.     else faddr->Point = 0;
  415.     faddr->Domain = NULL;
  416.  
  417.     return (1);
  418. }
  419.  
  420. struct _ndx far *get7node(HFILE stream, unsigned long pos, struct _ndx far *ndx)
  421. {
  422. #ifdef C386
  423.     unsigned long  got;
  424. #else
  425.     USHORT got;
  426. #endif
  427.  
  428.     (void) lseek (stream, (long) pos, SEEK_SET);
  429.  
  430.     if (_dos_read (stream, ndx,(unsigned int) sizeof (struct _ndx), &got) != 0)
  431.     {
  432.         status_line (msgtxt[M_NODELIST_READ_ERR]);
  433.         (void) close (stream);
  434.         return (NULL);
  435.     }
  436.     return (ndx);
  437. }
  438.  
  439.  
  440. /* ====================================================================
  441.  * unpack a dense version of a symbol (base 40 polynomial)
  442.  * ====================================================================
  443.  */
  444. void unpk(char *instr,char *outp,int count)
  445. {
  446.     struct chars {
  447.            unsigned char c1;
  448.            unsigned char c2;
  449.            };
  450.  
  451.     union {
  452.           unsigned w1;
  453.           struct chars d;
  454.           } u;
  455.  
  456.    register int i, j;
  457.    char obuf[4];
  458.  
  459.    outp[0] = '\0';
  460.  
  461.    while (count) {
  462.        u.d.c1 = *instr++;
  463.        u.d.c2 = *instr++;
  464.        count -= 2;
  465.        for(j=2;j>=0;j--) {
  466.            i = u.w1 % 40;
  467.            u.w1 /= 40;
  468.             obuf[j] = unwrk[i];
  469.            }
  470.        obuf[3] = '\0';
  471.        (void) strcat (outp, obuf);
  472.        }
  473. }
  474.  
  475.  
  476.