home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1996 October / PCO_10.ISO / filesbbs / bsrc_260.arj / SRC.ZIP / nodeproc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-23  |  30.2 KB  |  975 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-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*               This module was written by Vince Perriello                 */
  13. /*                                                                          */
  14. /*                 BinkleyTerm Nodelist processing module                   */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. static char far *LOCALFUNC get_size (unsigned int);
  49. static int LOCALFUNC get_new_info (unsigned);
  50.  
  51. #ifdef OLDTBBSLIST
  52. static int LOCALFUNC get_TBBS_info (unsigned, ADDR *);
  53. #endif
  54.  
  55. #ifdef V5_LIST
  56. static int LOCALFUNC get_old_info (unsigned);
  57. #endif
  58.  
  59. static off_t index_filesize = (off_t) 0L;
  60. static time_t index_filetime = (time_t) 0L;
  61. static char index_filename[80];
  62.  
  63. static unsigned int idx_size = 0;    /* number of entries  */
  64. static int extra_bytes = 0;
  65. static char *curr_domain = NULL;
  66.  
  67. int get_nodelist_name (ADDR *);
  68.  
  69. int 
  70. get_nodelist_name (ADDRP opus_addr)
  71. {
  72.     int i;
  73.  
  74.     if (opus_addr->Domain == NULL)
  75.     {
  76.         opus_addr->Domain = domain_name[0];
  77.         for (i = 0; i < num_domain_kludge; i++)
  78.         {
  79.             if (opus_addr->Zone == domainkludge[i].zone)
  80.             {
  81.                 opus_addr->Domain = domain_name[domainkludge[i].domain];
  82.                 break;
  83.             }
  84.         }
  85.     }
  86.  
  87.     curr_domain = opus_addr->Domain;
  88.  
  89.     idx_size = 0;
  90.     extra_bytes = 0;
  91.     nodelist_base = nodelist_name;
  92.     for (i = 0; domain_name[i] != NULL; i++)
  93.     {
  94.         if (domain_name[i] == opus_addr->Domain)
  95.         {
  96.             nodelist_base = domain_nodelist[i];
  97.             if (nodelist_base == NULL)
  98.                 nodelist_base = nodelist_name;
  99.             return 1;
  100.         }
  101.     }
  102.     return (i && domain_name[i] == NULL) ? 0 : 1;
  103. }
  104.  
  105. static char far *LOCALFUNC 
  106. get_size (unsigned int n)
  107. {
  108.     /* If we get this far, then we have to use a straight far pointer */
  109.     return (_fmalloc (n));
  110. }
  111.  
  112. /*---------------------------------------------------------------------------*/
  113. /* CHECKLIST                                                                 */
  114. /* See if nodelist has changed since we first tried to use it and if so,     */
  115. /* dismiss old copy and get a new one                                        */
  116. /*---------------------------------------------------------------------------*/
  117.  
  118. int 
  119. checklist ()
  120. {
  121.     struct stat idxstat;
  122.  
  123.     if (index_filesize == (off_t) 0L)
  124.         return (0);
  125.     (void) stat (index_filename, &idxstat);
  126.     if ((index_filesize == idxstat.st_size) && (index_filetime == idxstat.st_mtime))
  127.         return (0);
  128.     status_line (MSG_TXT (M_REFRESH_NODELIST));
  129.     _ffree (node_index);
  130.     node_index = (char far *) NULL;
  131.     index_filesize = (off_t) 0L;
  132.     return (1);
  133. }
  134.  
  135. /*---------------------------------------------------------------------------*/
  136. /* NODEPROC                                                                  */
  137. /* Find nodelist entry and set baud to nodelist baud for dialing out         */
  138. /*---------------------------------------------------------------------------*/
  139.  
  140. int 
  141. nodeproc (char *nodeaddr)
  142. {
  143.     ADDR opus_addr;
  144.     char *c;
  145.  
  146.     c = skip_blanks (nodeaddr);        /* get rid of the blanks      */
  147.     if (!find_address (c, &opus_addr))
  148.     {
  149.         return (0);
  150.     }
  151.     if (!nodefind (&opus_addr, 1))    /* if we can't find the node  */
  152.         return (0);                    /* go away now                */
  153.     status_line (MSG_TXT (M_PROCESSING_NODE), Full_Addr_Str (&opus_addr), newnodedes.SystemName);
  154.     if (!CARRIER)                    /* if no carrier yet,         */
  155.     {
  156.         if (autobaud)
  157.         {
  158.             /* Set to highest rate for autobaud */
  159.             (void) set_baud (max_baud.rate_value, 1);
  160.         }
  161.         else
  162.         {
  163.             /* Otherwise use the nodelisted rate */
  164.             (void) set_baud ((300 * newnodedes.BaudRate), 1);
  165.         }
  166.     }
  167.     return (1);                        /* return success to caller   */
  168. }
  169.  
  170. /*---------------------------------------------------------------------------*/
  171. /* NODEFIND                                                                  */
  172. /* Find nodelist entry for use by other routines (password, nodeproc)        */
  173. /* If found, result will be in "newnodedes".                                 */
  174. /*---------------------------------------------------------------------------*/
  175.  
  176. int 
  177. nodefind (ADDRP bink_addr, int prtflag)
  178. {
  179.     int i, j, k;
  180.     int have_boss_data = 0;
  181.     int need_boss_data = 0;
  182.  
  183.     (void) checklist ();
  184.  
  185.     newnodedes.NetNumber = newnodedes.NodeNumber = found_zone = found_net = 0;
  186.  
  187.     CURRENT = DEFAULT;                /* Set default paths, quotas  */
  188.  
  189.     if ((bink_addr->Net == boss_addr.Net)
  190.         && (bink_addr->Node == boss_addr.Node)
  191.         && (bink_addr->Zone == alias[0].Zone)
  192.         && ((bink_addr->Domain == boss_addr.Domain) || (bink_addr->Domain == NULL)))
  193.     {
  194.         ++need_boss_data;
  195.         if (BOSSphone && strlen (BOSSphone) > 2)
  196.             ++have_boss_data;
  197.         if (BOSSpwd && strlen (BOSSpwd) > 2)
  198.             ++have_boss_data;
  199.     }
  200.  
  201.     if (!bink_addr->Zone)
  202.     {
  203.         bink_addr->Zone = alias[0].Zone;
  204.         i = (*nodefunc) (bink_addr, have_boss_data);
  205.         if (i)
  206.             goto lookup_done;
  207.     }
  208.     i = (*nodefunc) (bink_addr, have_boss_data);
  209.  
  210. lookup_done:
  211.  
  212.     assumed = k = 0;                /* Default to zone of first   */
  213.     for (j = 0; j < num_addrs; j++)
  214.     {
  215.         if ((alias[j].Point != 0)
  216.             && ((alias[j].Node != newnodedes.NodeNumber)
  217.                 || (alias[j].Net != found_net)
  218.                 || (alias[j].Zone != found_zone)))
  219.         {
  220.             /* Don't use our point address except to the boss! */
  221.             continue;
  222.         }
  223.  
  224.         if ((alias[j].Domain == curr_domain)
  225.             || ((curr_domain == NULL) && (alias[j].Domain == my_addr.Domain))
  226.             || ((alias[j].Domain == NULL) && (curr_domain == my_addr.Domain)))
  227.         {
  228.             if (k == 0)
  229.             {
  230.                 assumed = j;
  231.                 ++k;
  232.             }
  233.  
  234.             if (alias[j].Zone == found_zone)
  235.             {
  236.                 if (k == 1)
  237.                 {
  238.                     assumed = j;
  239.                     ++k;
  240.                 }
  241.  
  242.                 if (alias[j].Net == found_net)
  243.                 {
  244.                     assumed = j;
  245.                     break;
  246.                 }
  247.             }
  248.         }
  249.     }
  250.  
  251.     /* Another point of your boss? */
  252.     if (!i && need_boss_data && bink_addr->Point)
  253.         return (i);                    /* Don't use your bosspw ! */
  254.  
  255.     if (!i && (have_boss_data != 2))
  256.     {
  257.         if (prtflag)
  258.             status_line (MSG_TXT (M_NO_ADDRESS), Full_Addr_Str (bink_addr));
  259.  
  260.         if (curmudgeon && CARRIER && (bink_addr->Net != 0xffff) && (bink_addr->Node != 0xffff) && (bink_addr->Node != 9999)
  261.             && ((bink_addr->Zone != alias[0].Zone) || (bink_addr->Net != alias[0].Net)))
  262.         {
  263.             return (-1);
  264.         }
  265.  
  266.     }
  267.  
  268.     if (bink_addr->Zone == (unsigned short) -1)
  269.         return i;
  270.  
  271.     /* If we found the entry, then we promote the file request
  272.      * to the "KNOWN" class. If the password field is non-zero,
  273.      * then promote to "PROT". It's OK to do that since the higher
  274.      * level code will hang up before f.req's if the password does
  275.      * not match.
  276.      *
  277.      */
  278.  
  279.     if (i)
  280.         CURRENT = (newnodedes.Password[0] ? PROT : KNOWN);
  281.  
  282.     if (!need_boss_data)
  283.         return (i);
  284.  
  285. /*
  286.  *    We can get here one of two ways:
  287.  *
  288.  *    1) No nodelist data was found and this is the BOSS.
  289.  *
  290.  *    2) Nodelist lookup occurred, but this is the BOSS.
  291.  *
  292.  *    For case (1), have_boss_data MUST be 2 (meaning we have
  293.  *    both a phone number and a password entry). If that is the
  294.  *    case, fill in newnodedes with mostly zeroes, plugging in
  295.  *    the BOSS net, node, phone number and password.
  296.  *
  297.  *    For case (2), just see if there is any substitution for
  298.  *    BOSSphone and/or BOSSpwd, then exit.
  299.  *
  300.  */
  301.  
  302.     if (BOSSphone && strlen (BOSSphone) > 2)
  303.     {
  304.         (void) strncpy (newnodedes.PhoneNumber, BOSSphone, 40);
  305.         newnodedes.PhoneNumber[39] = '\0';
  306.     }
  307.  
  308.     if (BOSSpwd && strlen (BOSSpwd) > 2)
  309.     {
  310.         (void) memset (newnodedes.Password, 0, sizeof (newnodedes.Password));
  311.         (void) strncpy (newnodedes.Password, BOSSpwd, 8);
  312.     }
  313.  
  314.     if (i)
  315.         return (1);
  316.  
  317.     /* No BOSS in the nodelist */
  318.     if (have_boss_data != 2)
  319.     {
  320.         status_line (MSG_TXT (M_NO_BOSS));
  321.         return (0);
  322.     }
  323.  
  324.     newnodedes.NodeNumber = bink_addr->Node;    /* Node Number */
  325.     newnodedes.NetNumber = bink_addr->Net;        /* Net Number  */
  326.     newnodedes.Cost = newnodedes.RealCost = 0;    /* Assume boss is free  */
  327.  
  328.     /* Default System Name and City */
  329.     (void) strcpy (newnodedes.SystemName, PRDCT_PRTY "'s Boss");
  330.     (void) strcpy (newnodedes.MiscInfo, "Somewhere out There");
  331.  
  332.     newnodedes.HubNode = 0;                        /* Don't know who's HUB */
  333.     newnodedes.BaudRate = (char) (max_baud.rate_value / 300);
  334.  
  335.     /* Assume boss speed = ours */
  336.     newnodedes.ModemType = 0;                    /* Or modem type        */
  337.     newnodedes.NodeFlags = B_CM;                /* Assume boss is CM    */
  338.     newnodedes.NodeFiller = 0;                    /* Zero out filler      */
  339.     return (1);
  340. }
  341.  
  342. #ifdef QUICK_LIST
  343.  
  344. int 
  345. QuickLookup (ADDRP Quick_addr, int have_boss_data)
  346. {
  347.     register struct QuickNodeIdxRecord far *nodeidx;    /* index file   */
  348.     struct QuickNodeListRecord nodedes;            /* desc. of node        */
  349.  
  350.     int foundnet = 0;                            /* 'found the net' flag   */
  351.     int found = 0;                                /* 'found the node' flag  */
  352.     int idxrec = 0;                                /* record in QNL_IDX.BBS  */
  353.     long nodeoff = 0L;                            /* offset into QNL_DAT.BBS*/
  354.     char temp[80];                                /* we build filenames here*/
  355.  
  356.     HFILE stream;
  357.     USHORT i;
  358.     unsigned long got;
  359.  
  360.     FILE *stream1;
  361.     struct stat f;
  362.  
  363.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  364.  
  365.     if (node_index == NULL)
  366.     {
  367.         index_filesize = (off_t) 0L;            /* Cover error condition  */
  368.         index_filename[0] = '\0';                /* "null-terminated string*/
  369.         (void) strcpy (index_filename, net_info);    /* take nodelist path */
  370.         (void) strcat (index_filename, "QNL_IDX.BBS");    /* add file name  */
  371.         if ((stream = (HFILE) share_open (index_filename, O_RDONLY | O_BINARY, DENY_WRITE)) == -1)
  372.         {
  373.             if (have_boss_data != 2)
  374.                 status_line (MSG_TXT (M_UNABLE_TO_OPEN), index_filename);
  375.             return (0);                            /* no file, no work to do */
  376.         }
  377.         (void) stat (index_filename, &f);        /* get file statistics    */
  378.         if (f.st_size > 65472L)                    /* modulo max index size, */
  379.             i = 65472;
  380.         else
  381.             i = (unsigned int) f.st_size;        /* size of index file,    */
  382.         idx_size = i / sizeof (*nodeidx);        /* number of index entries*/
  383.         node_index = get_size (i);
  384.         if (node_index == NULL)
  385.         {
  386.             status_line (MSG_TXT (M_NODELIST_MEM));
  387.             (void) close (stream);
  388.             return (0);
  389.         }
  390.  
  391.         /* Note, we do not use "got". Some platforms want it to be a long
  392.            and some want it to be a int. We don't care, so we make it a
  393.            long (see above) so there's enough room, then use a void * so
  394.            the compiler won't complain about an argument we don't even want */
  395.  
  396.         if (_dos_read (stream, node_index, i, (void *)&got) != 0)
  397.         {
  398.             status_line (MSG_TXT (M_NODELIST_READ_ERR));
  399.             (void) close (stream);
  400.             return (0);
  401.         }
  402.         (void) close (stream);
  403.  
  404.         index_filesize = f.st_size;                /* Save params for later  */
  405.         index_filetime = f.st_mtime;
  406.     }
  407.  
  408.     nodeidx = (struct QuickNodeIdxRecord far *) node_index;
  409.  
  410.     if (no_zones)
  411.         Quick_addr->Zone = 0;
  412.  
  413.     for (i = 1; i <= idx_size; idxrec++, nodeidx++, i++)
  414.     {
  415.         if (((Quick_addr->Zone == nodeidx->QI_Zone) || (Quick_addr->Zone == 0))
  416.             && (Quick_addr->Net == nodeidx->QI_Net))
  417.         {
  418.             foundnet = 1;                        /* say we found the net   */
  419.             if (((Quick_addr->Node == 0) && (nodeidx->QI_Node <= 0))
  420.                 || (nodeidx->QI_Node == Quick_addr->Node))    /* is it the node?*/
  421.             {
  422.                 found = 1;                        /* say we found it        */
  423.                 break;                            /* get out                */
  424.             }
  425.         }
  426.         else if (foundnet)                        /* already past the net?  */
  427.             break;                                /* Yes, we failed...      */
  428.     }
  429.  
  430.     if (!found)
  431.     {
  432.         return (0);
  433.     }
  434.  
  435.     nodeoff = (long) idxrec *(long) sizeof (nodedes);    /* file offset    */
  436.  
  437.     (void) strcpy (temp, net_info);                /* take nodelist path     */
  438.     (void) strcat (temp, "QNL_DAT.BBS");        /* add in the file name   */
  439.     if ((stream1 = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  440.     {
  441.         status_line (MSG_TXT (M_UNABLE_TO_OPEN), temp);
  442.         return (0);
  443.     }
  444.  
  445.     if (fseek (stream1, nodeoff, SEEK_SET))        /* try to point at record */
  446.     {
  447.         status_line (MSG_TXT (M_NODELIST_SEEK_ERR), temp);
  448.         (void) fclose (stream1);
  449.         return (0);
  450.     }
  451.  
  452.     if (!fread (&nodedes, sizeof (nodedes), 1, stream1))
  453.     {
  454.         status_line (MSG_TXT (M_NODELIST_REC_ERR), temp);
  455.         (void) fclose (stream1);
  456.         return (0);
  457.     }
  458.     (void) fclose (stream1);
  459.  
  460.     /*
  461.      * Copy data from nodedes into newnodedes.
  462.      */
  463.  
  464.     newnodedes.NodeNumber = nodedes.QL_Node;    /* Node Number  */
  465.     newnodedes.NetNumber = nodedes.QL_Net;        /* Net Number    */
  466.     newnodedes.Cost = nodedes.QL_Cost;            /* Cost            */
  467.  
  468.     i = min (nodedes.QL_Name[0], 19);
  469.     (void) strncpy (&newnodedes.SystemName[0], &nodedes.QL_Name[1], i);
  470.     newnodedes.SystemName[i] = '\0';            /* System Name  */
  471.  
  472.     i = min (nodedes.QL_Phone[0], 39);
  473.     (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.QL_Phone[1], i);
  474.     newnodedes.PhoneNumber[i] = '\0';            /* Phone Number */
  475.  
  476.     i = min (nodedes.QL_City[0], 29);
  477.     (void) strncpy (&newnodedes.MiscInfo[0], &nodedes.QL_City[1], i);
  478.     newnodedes.MiscInfo[i] = '\0';
  479.  
  480.     /* This field is not necessarily null terminated */
  481.     i = min (nodedes.QL_Password[0], 8);
  482.     (void) strncpy (&newnodedes.Password[0], &nodedes.QL_Password[1], i);
  483.     if (i < 8)
  484.         newnodedes.Password[i] = '\0';
  485.  
  486.     /* Adam Hudson now gives us this, so we might as well use it */
  487.     newnodedes.NodeFlags = nodedes.QL_Flags;
  488.  
  489.     /* Since we have the stuff we need! */
  490.     newnodelist = 1;                            /* We have all the info   */
  491.  
  492.     newnodedes.RealCost = nodedes.QL_Cost;        /* Cost                   */
  493.     newnodedes.HubNode = 0;                        /* Don't know who is Hub  */
  494.     newnodedes.BaudRate = (char) (nodedes.QL_BaudRate / 300);    /* Baud   */
  495.     newnodedes.ModemType = 0;                    /* Don't know modem type  */
  496.     newnodedes.NodeFiller = 0;                    /* Filler should be zero  */
  497.     found_zone = nodeidx->QI_Zone;                /* Retain the found zone  */
  498.     found_net = nodeidx->QI_Net;                /* And the found net      */
  499.     return (1);
  500. }
  501. #endif                            /* QUICK_LIST */
  502.  
  503. int 
  504. opusfind (ADDRP opus_addr, int have_boss_data)
  505. {
  506.     register struct _ndi far *nodeidx;            /* index file             */
  507.     int found = 0;                                /* 'found the node' flag  */
  508.     int found_boss = 0;                            /* 'found the boss' flag  */
  509.     int nodeoff = 0;                            /* offset in nodelist.sys */
  510.     char temp[80];                                /* we build filenames here*/
  511.     unsigned long full_idx_size;
  512.  
  513.     HFILE stream;
  514.     USHORT i;
  515.  
  516.     unsigned long got;
  517.  
  518.     struct stat f;
  519.     unsigned short current_zone = 0;
  520.  
  521.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  522.  
  523.     if (nodelist_base == NULL)
  524.         nodelist_base = nodelist_name;
  525.  
  526.     if ((node_index == NULL)
  527.         || ((curr_domain != opus_addr->Domain) && ((opus_addr->Domain != NULL) || (curr_domain != my_addr.Domain))))
  528.     {
  529.         if (node_index != NULL)
  530.         {
  531.             _ffree (node_index);
  532.         }
  533.  
  534.         if (!get_nodelist_name (opus_addr))
  535.             return 0;
  536.         index_filesize = (off_t) 0L;            /* Cover the error case   */
  537.         index_filename[0] = '\0';                /* "null-terminated string*/
  538.         (void) strcpy (index_filename, net_info);    /* take nodelist path */
  539.         (void) strcat (index_filename, nodelist_base);    /* add file name  */
  540.         (void) strcat (index_filename, ".IDX");    /* add in the file ext    */
  541.         if ((stream = (HFILE) share_open (index_filename, O_RDONLY | O_BINARY, DENY_WRITE)) == (HFILE) - 1)
  542.         {
  543.             i = 0;                                /* Need this later        */
  544.             if (have_boss_data != 2)
  545.                 status_line (MSG_TXT (M_UNABLE_TO_OPEN), index_filename);
  546.             return (0);                            /* no file, no work to do */
  547.         }
  548.         (void) stat (index_filename, &f);        /* get file statistics    */
  549.         if (f.st_size > 65472L)                    /* modulo max index size, */
  550.             i = (USHORT) 65472;
  551.         else
  552.             i = (USHORT) f.st_size;                /* size of index file,    */
  553.         idx_size = i / sizeof (struct _ndi);    /* number of index entries*/
  554.         full_idx_size = f.st_size / sizeof (struct _ndi);
  555.  
  556.         node_index = get_size (i);
  557.         if (node_index == NULL)
  558.         {
  559.             status_line (MSG_TXT (M_NODELIST_MEM));
  560.             (void) close (stream);
  561.             return (0);
  562.         }
  563.  
  564.         /* Note, we do not use "got". Some platforms want it to be a long
  565.            and some want it to be a int. We don't care, so we make it a
  566.            long (see above) so there's enough room, then use a void * so
  567.            the compiler won't complain about an argument we don't even want */
  568.  
  569.         if (_dos_read (stream, node_index, i, (void *)&got) != 0)
  570.         {
  571.             status_line (MSG_TXT (M_NODELIST_READ_ERR));
  572.             (void) close (stream);
  573.             return (0);
  574.         }
  575.         (void) close (stream);
  576.  
  577.         index_filesize = f.st_size;                /* Save params for later  */
  578.         index_filetime = f.st_mtime;
  579.  
  580.         /*
  581.          * Now take into account that the .DAT file can be bigger than we
  582.          * really expect it to be.  Just take the number of records, and
  583.          * divide into the size of the .DAT file to find the true record size
  584.          */
  585.         if (newnodelist)
  586.         {
  587.             temp[0] = '\0';                        /* "null-terminated string*/
  588.             (void) strcpy (temp, net_info);        /* take nodelist path     */
  589.             (void) strcat (temp, nodelist_base);/* add in the file name   */
  590.             (void) strcat (temp, ".DAT");        /* add in the file name   */
  591.             if (!stat (temp, &f))
  592.             {
  593.                 extra_bytes = ((int) (f.st_size / full_idx_size)) - sizeof (newnodedes);
  594.             }
  595.         }
  596.     }
  597.  
  598.     nodeidx = (struct _ndi far *) node_index;
  599.  
  600.     if ((!newnodelist) || (alias[0].Zone == 0) || (no_zones))
  601.     {
  602.         opus_addr->Zone = 0;
  603.     }
  604.  
  605.     for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
  606.     {
  607.         if (nodeidx->node == -2)
  608.             current_zone = nodeidx->net;
  609.  
  610.         if (opus_addr->Zone > 0 && current_zone != opus_addr->Zone)
  611.             continue;
  612.  
  613.         if ((unsigned) nodeidx->net == opus_addr->Net) /* if match on net,*/
  614.         {
  615.             if (((opus_addr->Node == 0) && (nodeidx->node <= 0))
  616.                 || ((unsigned) nodeidx->node == opus_addr->Node))
  617.             {
  618.                 if (opus_addr->Point == 0)
  619.                 {
  620.                     found = 1;                    /* Say we found Node  */
  621.                     break;
  622.                 }
  623.                 found_boss = 1;                    /* say we found Boss  */
  624.                 continue;
  625.             }
  626.         }
  627.  
  628.         if (nodeidx->net != -1)
  629.         {
  630.             found_boss = 0;
  631.             continue;
  632.         }
  633.  
  634.         if ((found_boss == 1)
  635.             && ((unsigned) nodeidx->node == opus_addr->Point))
  636.         {
  637.             found = 1;
  638.             break;
  639.         }
  640.  
  641.     }
  642.  
  643.     if (!found)
  644.         return (0);
  645.  
  646.     found_zone = current_zone;                    /* Retain the found zone  */
  647.     found_net = nodeidx->net;                    /* Keep track of found net*/
  648.  
  649.     if (newnodelist)
  650.         i = (USHORT) (get_new_info (nodeoff));
  651. #ifdef V5_LIST
  652.     else
  653.         i = (USHORT) (get_old_info (nodeoff));
  654. #endif
  655.  
  656.     return (i);
  657. }
  658.  
  659. #ifdef V5_LIST
  660.  
  661. static int LOCALFUNC 
  662. get_old_info (unsigned recno)
  663. {
  664.     struct _node nodedes;                        /* desc. of node          */
  665.     long nodeoff;                                /* Offset in NODELIST.SYS */
  666.     char temp[80];                                /* we build filenames here*/
  667.     char *c, *ch;
  668.     int i;
  669.     FILE *stream;
  670.  
  671.     nodeoff = (long) recno *(long) sizeof (nodedes); /* actual file offset*/
  672.  
  673.     (void) strcpy (temp, net_info);                /* take nodelist path    */
  674.     (void) strcat (temp, nodelist_base);        /* add in the file name  */
  675.     (void) strcat (temp, ".SYS");                /* add in the file name  */
  676.     if ((stream = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  677.     {
  678.         status_line (MSG_TXT (M_UNABLE_TO_OPEN), temp);
  679.         return (0);
  680.     }
  681.  
  682.     if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record*/
  683.     {
  684.         status_line (MSG_TXT (M_NODELIST_SEEK_ERR), temp);
  685.         (void) fclose (stream);
  686.         return (0);
  687.     }
  688.  
  689.     if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  690.     {
  691.         status_line (MSG_TXT (M_NODELIST_REC_ERR), temp);
  692.         (void) fclose (stream);
  693.         return (0);
  694.     }
  695.     (void) fclose (stream);
  696.  
  697.     /*
  698.      * Copy data from nodedes into newnodedes.
  699.      */
  700.  
  701.     newnodedes.NodeNumber = (word) nodedes.number;    /* Node Number    */
  702.     newnodedes.NetNumber = (word) nodedes.net;    /* Net Number         */
  703.     newnodedes.Cost = (word) nodedes.cost;        /* Cost               */
  704.  
  705.     (void) strncpy (&newnodedes.SystemName[0], &nodedes.name[0], 20);
  706.     newnodedes.SystemName[19] = '\0';            /* System Name        */
  707.  
  708.     (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.phone[0], 40);
  709.     newnodedes.PhoneNumber[39] = '\0';            /* Phone Number       */
  710.  
  711.     (void) strncpy (&newnodedes.MiscInfo[0], &nodedes.city[0], 30);
  712.     newnodedes.MiscInfo[29] = '\0';
  713.  
  714.     ch = NULL;                                    /* password           */
  715.     c = nodedes.city;                            /* start of city      */
  716.     i = 37;                                        /* No password if =0  */
  717.     while (i--)                                    /* Enforce that limit */
  718.     {
  719.         if (*c++ != '\0')                        /* If not end of city,*/
  720.             continue;                            /* go on to next char */
  721.         if (*c++ != '!')                        /* End city, got '!' ?*/
  722.             break;                                /* No, failure        */
  723.         ch = c;                                    /* Got it, point to it*/
  724.         break;                                    /* Exit with success  */
  725.     }
  726.     if (ch != NULL)
  727.     {
  728.         /* Copy the password if any */
  729.         (void) strncpy (&newnodedes.Password[0], ch, 8);
  730.     }
  731.     else
  732.         newnodedes.Password[0] = '\0';            /* Else none          */
  733.  
  734.     newnodedes.RealCost = nodedes.cost;            /* Cost               */
  735.     newnodedes.HubNode = 0;                        /* Don't know Hub     */
  736.     newnodedes.BaudRate = (char) (nodedes.rate / 300);    /* Baud Rate  */
  737.     newnodedes.ModemType = 0;                    /* Don't know modem   */
  738.     newnodedes.NodeFlags = 0;                    /* Don't know flags   */
  739.     newnodedes.NodeFiller = 0;                    /* Filler must be zero*/
  740.     return (1);
  741. }
  742. #endif                            /* V5_LIST */
  743.  
  744. static int LOCALFUNC 
  745. get_new_info (unsigned recno)
  746. {
  747.     long nodeoff;                                /* Offset in NODELIST.DAT */
  748.     char temp[80];                                /* we build filenames here*/
  749.     FILE *stream;
  750.  
  751.     /* actual file offset */
  752.     nodeoff = (long) recno *((long) (sizeof (newnodedes) + extra_bytes));
  753.  
  754.     (void) strcpy (temp, net_info);                /* take nodelist path */
  755.     (void) strcat (temp, nodelist_base);        /* add in the filename*/
  756.     (void) strcat (temp, ".DAT");                /* then the extension */
  757.     if ((stream = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  758.     {
  759.         status_line (MSG_TXT (M_UNABLE_TO_OPEN), temp);
  760.         return (0);
  761.     }
  762.  
  763.     if (fseek (stream, nodeoff, SEEK_SET))        /* point at record    */
  764.     {
  765.         status_line (MSG_TXT (M_NODELIST_SEEK_ERR), temp);
  766.         (void) fclose (stream);
  767.         return (0);
  768.     }
  769.  
  770.     if (!fread (&newnodedes, sizeof (newnodedes), 1, stream))
  771.     {
  772.         status_line (MSG_TXT (M_NODELIST_REC_ERR), temp);
  773.         (void) fclose (stream);
  774.         return (0);
  775.     }
  776.     (void) fclose (stream);
  777.     return (1);
  778. }
  779.  
  780. #ifdef OLDTBBSLIST
  781. static int LOCALFUNC 
  782. get_TBBS_info (unsigned recno, ADDRP TBBS_addr)
  783. {
  784.     struct nodels nodedes;                        /* desc. of node          */
  785.     struct extrastuff ext;                        /* Extra stuff for Binkley*/
  786.     long nodeoff;                                /* Offset in NODELIST.DOG */
  787.     char temp[80];                                /* we build filenames here*/
  788.     FILE *stream;
  789.  
  790.     --recno;                    /* TBBS starts at 1st record - no filler  */
  791.  
  792.     nodeoff = (long) recno *(long) sizeof (nodedes);/* actual file offset */
  793.  
  794.     (void) strcpy (temp, net_info);                /* take nodelist path     */
  795.     (void) strcat (temp, "NODELIST.DOG");        /* add in the filename    */
  796.     if ((stream = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  797.     {
  798.         status_line (MSG_TXT (M_UNABLE_TO_OPEN), temp);
  799.         return (0);
  800.     }
  801.  
  802.     if (fseek (stream, nodeoff, SEEK_SET))        /* point at record        */
  803.     {
  804.         status_line (MSG_TXT (M_NODELIST_SEEK_ERR), temp);
  805.         (void) fclose (stream);
  806.         return (0);
  807.     }
  808.  
  809.     if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  810.     {
  811.         status_line (MSG_TXT (M_NODELIST_REC_ERR), temp);
  812.         (void) fclose (stream);
  813.         return (0);
  814.     }
  815.     (void) fclose (stream);
  816.  
  817.     /*
  818.      * Copy data from nodedes into newnodedes.
  819.      */
  820.  
  821.     newnodedes.NodeNumber = TBBS_addr->Node;    /* Node Number            */
  822.     newnodedes.NetNumber = TBBS_addr->Net;        /* Net Number             */
  823.     newnodedes.Cost = nodedes.nodecost;            /* Cost                   */
  824.  
  825.     (void) strncpy (&newnodedes.SystemName[0], &nodedes.nodename[0], 14);
  826.     newnodedes.SystemName[19] = '\0';            /* System Name            */
  827.  
  828.     (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.nodephone[0], 40);
  829.     newnodedes.PhoneNumber[39] = '\0';            /* Phone Number           */
  830.  
  831.     (void) strncpy (&newnodedes.MiscInfo[0], &nodedes.nodecity[0], 30);
  832.     newnodedes.MiscInfo[29] = '\0';
  833.  
  834.     newnodedes.Password[0] = '\0';                /* Else set zero length   */
  835.  
  836.     newnodedes.RealCost = nodedes.nodecost;        /* Cost                   */
  837.     newnodedes.HubNode = nodedes.nodehub;        /* Hub                    */
  838.     newnodedes.BaudRate = (char) (nodedes.nodebaud / 300);    /* Baud Rate  */
  839.     newnodedes.ModemType = 0;                    /* Don't know modem       */
  840.     newnodedes.NodeFlags = 0;                    /* Don't know flags       */
  841.     newnodedes.NodeFiller = 0;                    /* Filler must be zero    */
  842.  
  843.     /* Now get information from secondary file */
  844.     ++recno;
  845.     nodeoff = (long) recno *(long) sizeof (ext);    /* actual file offset */
  846.  
  847.     (void) strcpy (temp, net_info);                /* take nodelist path     */
  848.     (void) strcat (temp, "NODELIST.EXT");        /* add in the filename    */
  849.     newnodelist = 0;
  850.     if ((stream = share_fopen (temp, read_binary, DENY_WRITE)) == NULL)
  851.     {
  852.         return (1);
  853.     }
  854.  
  855.     if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record */
  856.     {
  857.         (void) fclose (stream);
  858.         return (1);
  859.     }
  860.  
  861.     if (!fread (&ext, sizeof (ext), 1, stream))
  862.     {
  863.         (void) fclose (stream);
  864.         return (1);
  865.     }
  866.     (void) fclose (stream);
  867.  
  868.     /*
  869.      * Copy data from ext into newnodedes.
  870.      */
  871.  
  872.     (void) strncpy (newnodedes.Password, ext.password, 8);    /* Password   */
  873.  
  874.     newnodedes.NodeFlags = ext.flags1;            /* Nodelist flags         */
  875.     newnodedes.ModemType = ext.modem;            /* Modem type             */
  876.     newnodelist = 1;                            /* We've all the info     */
  877.     return (1);
  878. }
  879.  
  880. int 
  881. TBBSLookup (ADDRP TBBS_addr, int have_boss_data)
  882. {
  883.     register struct _ndi far *nodeidx;            /* index file             */
  884.     int found = 0;                                /* 'found the node' flag  */
  885.     int nodeoff = 0;                            /* offset in nodelist.sys */
  886.     char temp[80];                                /* we build filenames here*/
  887.  
  888.     HFILE stream;
  889.     USHORT i;
  890.     unsigned long got;
  891.  
  892.     struct stat f;
  893.     unsigned short current_zone = 0;
  894.  
  895.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  896.  
  897.     if (node_index == NULL)
  898.     {
  899.         temp[0] = '\0';                            /* "null-terminated string*/
  900.         (void) strcpy (temp, net_info);            /* take nodelist path     */
  901.         (void) strcat (temp, "NODELIST.IDX");    /* add in the file name   */
  902.         if ((stream = share_open (temp, O_RDONLY | O_BINARY, DENY_WRITE)) == -1)
  903.         {
  904.             i = 0;                                /* Need this later        */
  905.             if (have_boss_data != 2)
  906.                 status_line (MSG_TXT (M_UNABLE_TO_OPEN), temp);
  907.             return (0);                            /* no file, no work to do */
  908.         }
  909.         (void) stat (temp, &f);                    /* get file statistics    */
  910.         if (f.st_size > 65472L)                    /* modulo max index size, */
  911.             i = 65472;
  912.         else
  913.             i = (unsigned int) f.st_size;        /* size of index file,    */
  914.         idx_size = i / sizeof (struct _ndi);    /* number of index entries*/
  915.  
  916.         node_index = get_size (i);
  917.         if (node_index == NULL)
  918.         {
  919.             status_line (MSG_TXT (M_NODELIST_MEM));
  920.             (void) close (stream);
  921.             return (0);
  922.         }
  923.  
  924.         /* Note, we do not use "got". Some platforms want it to be a long
  925.            and some want it to be a int. We don't care, so we make it a
  926.            long (see above) so there's enough room, then use a void * so
  927.            the compiler won't complain about an argument we don't even want */
  928.  
  929.         if (_dos_read (stream, node_index, i, (void *)&got) != 0)
  930.         {
  931.             status_line (MSG_TXT (M_NODELIST_READ_ERR));
  932.             (void) close (stream);
  933.             return (0);
  934.         }
  935.         (void) close (stream);
  936.     }
  937.     nodeidx = (struct _ndi far *) node_index;
  938.  
  939.     if (TBBS_addr->Zone == (unsigned int) -1)
  940.     {
  941.         return (opus_next_zone ());
  942.     }
  943.  
  944.     for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
  945.     {
  946.         if (nodeidx->node == -2)
  947.             current_zone = nodeidx->net;
  948.  
  949.         if (TBBS_addr->Zone > 0 && current_zone != TBBS_addr->Zone)
  950.             continue;
  951.  
  952.         if ((unsigned) nodeidx->net == TBBS_addr->Net)    /* if a match on net, */
  953.         {
  954.             if (((TBBS_addr->Node == 0) && (nodeidx->node <= 0))
  955.                 || ((unsigned) nodeidx->node == TBBS_addr->Node))
  956.             {
  957.                 found = 1;                                /* say we found it    */
  958.                 break;                                    /* get out            */
  959.             }
  960.         }
  961.     }
  962.  
  963.     if (!found)
  964.         return (0);
  965.  
  966.     found_zone = current_zone;                    /* Retain the found zone  */
  967.     found_net = nodeidx->net;                    /* Keep track of found net*/
  968.  
  969.     i = get_TBBS_info (nodeoff, TBBS_addr);
  970.  
  971.     return (i);
  972. }
  973. #endif                            /* defined OLDTBBSLIST */
  974.  
  975.