home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / NODEPROC.C < prev    next >
C/C++ Source or Header  |  1992-04-21  |  32KB  |  1,074 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-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                 This module was written by Vince Perriello                 */
  14. /*                                                                            */
  15. /*                                                                            */
  16. /*                   BinkleyTerm 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.240.    */
  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:132/491, 1:141/491    */
  37. /* P.O. Box 460398                  AlterNet 7:491/0                            */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                  Internet f491.n132.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 <sys\types.h>
  47. #include <sys\stat.h>
  48. #include <stdio.h>
  49. #include <fcntl.h>
  50. #include <signal.h>
  51. #include <ctype.h>
  52. #include <conio.h>
  53. #include <dos.h>
  54. #include <io.h>
  55. #include <string.h>
  56.  
  57. #ifdef OS_2
  58. #define  INCL_DOS
  59. #include <os2.h>
  60. #define _dos_read DosRead
  61. #endif
  62.  
  63. #ifdef __TURBOC__
  64. #include <alloc.h>
  65. #define _fmalloc(n) farmalloc (n)
  66. #define _ffree(n) farfree (n)
  67. #else
  68. #include <malloc.h>
  69. #endif
  70.  
  71. #include "com.h"
  72. #include "xfer.h"
  73. #include "zmodem.h"
  74. #include "keybd.h"
  75. #include "sbuf.h"
  76. #include "sched.h"
  77. #include "externs.h"
  78. #include "prototyp.h"
  79.  
  80. static char far *get_size (unsigned int);
  81. static int get_new_info (unsigned);
  82. static int get_old_info (unsigned);
  83. static int get_TBBS_info (unsigned, ADDR *);
  84. static int Quick_Next_Zone (void);
  85.  
  86. #ifdef __TURBOC__
  87. typedef long off_t;
  88. #endif
  89. static off_t  index_filesize = (off_t)    0L;
  90. static time_t index_filetime = (time_t) 0L;
  91. static char   index_filename[80];
  92.  
  93. static unsigned int idx_size = 0;                 /* number of entries in it   */
  94. static unsigned int zone_offset = 0;
  95. static int last_zone = -1;
  96. static int extra_bytes = 0;
  97. static char *curr_domain = NULL;
  98. static char *nodelist_name = "NODELIST";
  99. static char *nodelist_base = NULL;
  100.  
  101.  
  102. #define NIDX_BUFSIZE            8192        /* CML */
  103.  
  104. static struct _ndi far *nidx_buf = NULL;    /* CML - buffer for node records */
  105. static int nidx_start = 0;                    /* CML */
  106. static int nidx_recs = 0;                    /* CML */
  107.  
  108.  
  109.  
  110. static void get_nodelist_name(ADDR *opus_addr)
  111.     {
  112.     int i;
  113.  
  114.     if (curr_domain != opus_addr->Domain)
  115.         {
  116.         curr_domain = opus_addr->Domain;
  117.  
  118.         idx_size = 0;
  119.         zone_offset = 0;
  120.         last_zone = -1;
  121.         extra_bytes = 0;
  122.         }
  123.  
  124.     nodelist_base = nodelist_name;
  125.     for (i = 0; domain_name[i] != NULL; i++)
  126.         {
  127.         if (domain_name[i] == opus_addr->Domain)
  128.             {
  129.             nodelist_base = domain_nodelist[i];
  130.             if (nodelist_base == NULL)
  131.                 nodelist_base = nodelist_name;
  132.             }
  133.         }
  134.     }
  135.  
  136.  
  137.  
  138. static char far *get_size(unsigned int n)
  139.     {
  140.     /* If we get this far, then we have to use a straight far pointer */
  141.     return (_fmalloc (n));
  142.     }
  143.  
  144.  
  145.  
  146. /*---------------------------------------------------------------------------*/
  147. /* CHECKLIST                                                                 */
  148. /* See if nodelist has changed since we first tried to use it and if so,     */
  149. /* dismiss old copy and get a new one                                         */
  150. /*---------------------------------------------------------------------------*/
  151. int checklist(void)
  152.     {
  153.     struct stat idxstat;
  154.  
  155.     if (index_filesize == (off_t)0L)
  156.         return (0);
  157.     stat (index_filename, &idxstat);
  158.     if ((index_filesize == idxstat.st_size) && (index_filetime == idxstat.st_mtime))
  159.         return (0);
  160.     status_line (msgtxt[M_REFRESH_NODELIST]);
  161.  
  162.     if (newnodelist)        /* CML */
  163.         {
  164.         nidx_start = 0x7fff;
  165.         nidx_recs = 0;
  166.         }
  167.     else
  168.         {
  169.         _ffree ((char far *) node_index);
  170.         node_index = (char far *) NULL;
  171.         }
  172.     index_filesize = (off_t)0L;
  173.     return (1);
  174.     }
  175.  
  176.  
  177.  
  178. /*---------------------------------------------------------------------------*/
  179. /* NODEPROC                                                                  */
  180. /* Find nodelist entry and set baud to nodelist baud for dialing out         */
  181. /*---------------------------------------------------------------------------*/
  182.  
  183. int nodeproc(char *nodeaddr)
  184.     {
  185.     ADDR opus_addr;
  186.     char *c, *skip_blanks ();
  187.  
  188.     c = skip_blanks (nodeaddr);                     /* get rid of the blanks      */
  189.     if (!find_address (c, &opus_addr))
  190.         return (0);
  191.     if (!nodefind (&opus_addr, 1))  /* if we can't find the node */
  192.         return (0);                                 /* go away now               */
  193.     status_line (msgtxt[M_PROCESSING_NODE], Full_Addr_Str (&opus_addr), newnodedes.SystemName);
  194.     if (!CARRIER)                                 /* if no carrier yet,          */
  195.         {
  196.         if (autobaud)
  197.             set_baud (max_baud.rate_value, 1);    /* Set to our highest baud rate */
  198.         else
  199.             set_baud ((300 * newnodedes.BaudRate), 1);         /* set baud to nodelist baud */
  200.         }
  201.     return (1);                                     /* return success to caller  */
  202.     }
  203.  
  204.  
  205.  
  206. /*---------------------------------------------------------------------------*/
  207. /* NODEFIND                                                                  */
  208. /* Find nodelist entry for use by other routines (password, nodeproc)         */
  209. /* If found, result will be in "newnodedes".                                 */
  210. /*---------------------------------------------------------------------------*/
  211.  
  212. int nodefind(ADDR *bink_addr,int prtflag)
  213.     {
  214.     int i, j, k;
  215.     int have_boss_data = 0;
  216.     int need_boss_data = 0;
  217.  
  218.     checklist ();
  219.  
  220.     newnodedes.NetNumber = newnodedes.NodeNumber = found_zone = found_net = 0;
  221.  
  222.     CurrentOKFile = DEFAULT.rq_OKFile;     /* Set the default f.req paths */
  223.     CurrentFILES = DEFAULT.rq_FILES;
  224.     CurrentAbout = DEFAULT.rq_About;
  225.     CurrentReqTemplate = DEFAULT.rq_Template;
  226.     CurrentNetFiles = DEFAULT.sc_Inbound;
  227.     CurrentReqLim = DEFAULT.rq_Limit;
  228.     CurrentByteLim = DEFAULT.byte_Limit;
  229.  
  230.     if ((bink_addr->Net == boss_addr.Net) && (bink_addr->Node == boss_addr.Node) &&
  231.         (bink_addr->Zone == alias[0].Zone) && ((bink_addr->Domain == boss_addr.Domain) || (bink_addr->Domain == NULL)))
  232.         {
  233.         ++need_boss_data;
  234.         if (BOSSphone && strlen (BOSSphone) > 2)
  235.             ++have_boss_data;
  236.         if (BOSSpwd && strlen (BOSSpwd) > 2)
  237.             ++have_boss_data;
  238.         }
  239.  
  240.     if (!bink_addr->Zone)
  241.         {
  242.         bink_addr->Zone = alias[0].Zone;
  243.         i = (*nodefunc) (bink_addr, have_boss_data);
  244.         if (i)
  245.             goto lookup_done;
  246.         }
  247.     i = (*nodefunc) (bink_addr, have_boss_data);
  248.  
  249.  
  250. lookup_done:
  251.  
  252.     assumed = k = 0;                           /* Default to zone of first */
  253.     for (j = 0; j < num_addrs; j++)
  254.         {
  255.         if ((alias[j].Point != 0) &&
  256.             ((alias[j].Node != newnodedes.NodeNumber) ||
  257.             (alias[j].Net != found_net) ||
  258.             (alias[j].Zone != found_zone)))
  259.             {
  260.             /* Don't use our point address except to the boss! */
  261.             continue;
  262.             }
  263.  
  264.         if ((alias[j].Domain == curr_domain) ||
  265.             ((curr_domain == NULL) && (alias[j].Domain == my_addr.Domain)) ||
  266.             ((alias[j].Domain == NULL) && (curr_domain == my_addr.Domain)))
  267.             {
  268.             if (k == 0)
  269.                 {
  270.                 assumed = j;
  271.                 ++k;
  272.                 }
  273.  
  274.             if (alias[j].Zone == found_zone)
  275.                 {
  276.                 if (k == 1)
  277.                     {
  278.                     assumed = j;
  279.                     ++k;
  280.                     }
  281.  
  282.                 if (alias[j].Net == found_net)
  283.                     {
  284.                     assumed = j;
  285.                     break;
  286.                     }
  287.                 }
  288.             }
  289.         }
  290.  
  291.     if (!i && (have_boss_data != 2))
  292.         {
  293.         if (prtflag)
  294.             status_line (msgtxt[M_NO_ADDRESS], Full_Addr_Str (bink_addr));
  295.  
  296.         if (curmudgeon && CARRIER && (bink_addr->Net != -1) && (bink_addr->Node != -1) && (bink_addr->Node != 9999))
  297.             {
  298.             status_line (msgtxt[M_NUISANCE_CALLER]);
  299.             DTR_OFF ();                            /* Hang up right now      */
  300.             timer (2);                             /* Wait two secs          */
  301.             DTR_ON ();                             /* OK, turn modem back on */
  302.             }
  303.  
  304.         }
  305.  
  306.     if (bink_addr->Zone == (unsigned int) -1)
  307.         return i;
  308.  
  309.     /* If we found the entry, then we promote the file request
  310.         * to the "KNOWN" class. If the password field is non-zero,
  311.         * then promote to "PROT". It's OK to do that since the higher
  312.         * level code will hang up before f.req's if the password does
  313.         * not match.
  314.         */
  315.  
  316.     if (i)
  317.         {
  318.         if (newnodedes.Password[0])
  319.             {
  320.             CurrentOKFile = PROT.rq_OKFile;
  321.             CurrentFILES = PROT.rq_FILES;
  322.             CurrentAbout = PROT.rq_About;
  323.             CurrentReqTemplate = PROT.rq_Template;
  324.             CurrentNetFiles = PROT.sc_Inbound;
  325.             CurrentReqLim = PROT.rq_Limit;
  326.             CurrentByteLim = PROT.byte_Limit;
  327.             }
  328.         else
  329.             {
  330.             CurrentOKFile = KNOWN.rq_OKFile;
  331.             CurrentFILES = KNOWN.rq_FILES;
  332.             CurrentAbout = KNOWN.rq_About;
  333.             CurrentReqTemplate = KNOWN.rq_Template;
  334.             CurrentNetFiles = KNOWN.sc_Inbound;
  335.             CurrentReqLim = KNOWN.rq_Limit;
  336.             CurrentByteLim = KNOWN.byte_Limit;
  337.             }
  338.         }
  339.  
  340.     if (!need_boss_data)
  341.         return (i);
  342.  
  343.     /*
  344.     *    We can get here one of two ways:
  345.     *
  346.     *    1) No nodelist data was found and this is the BOSS.
  347.     *
  348.     *    2) Nodelist lookup occurred, but this is the BOSS.
  349.     *
  350.     *    For case (1), have_boss_data MUST be 2 (meaning we have
  351.     *    both a phone number and a password entry). If that is the
  352.     *    case, fill in newnodedes with mostly zeroes, plugging in
  353.     *    the BOSS net, node, phone number and password.
  354.     *
  355.     *    For case (2), just see if there is any substitution for
  356.     *    BOSSphone and/or BOSSpwd, then exit.
  357.     *
  358.     */
  359.  
  360.     if (BOSSphone && strlen (BOSSphone) > 2)
  361.         {
  362.         strncpy (newnodedes.PhoneNumber, BOSSphone, 40);
  363.         newnodedes.PhoneNumber[39] = '\0';
  364.         }
  365.  
  366.     if (BOSSpwd && strlen (BOSSpwd) > 2)
  367.         {
  368.         memset (newnodedes.Password, 0, sizeof (newnodedes.Password));
  369.         strncpy (newnodedes.Password, BOSSpwd, 8);
  370.         }
  371.  
  372.     if (i)
  373.         return (1);
  374.  
  375.     /* No BOSS in the nodelist */
  376.     if (have_boss_data != 2)
  377.         {
  378.         status_line (msgtxt[M_NO_BOSS]);
  379.         return (0);
  380.         }
  381.  
  382.     newnodedes.NodeNumber = bink_addr->Node;       /* Node Number */
  383.     newnodedes.NetNumber = bink_addr->Net;          /* Net Number  */
  384.     newnodedes.Cost = newnodedes.RealCost = 0;     /* Assume boss is free */
  385.     strcpy (newnodedes.SystemName, "Binkley's Boss");    /* System Name defaults */
  386.     strcpy (newnodedes.MiscInfo, "Somewhere out There"); /* As does City */
  387.     newnodedes.HubNode = 0;                         /* Don't know who is HUB */
  388.     newnodedes.BaudRate = (char) (max_baud.rate_value / 300);
  389.  
  390.     /* Assume boss speed = ours */
  391.     newnodedes.ModemType = 0;                     /* Or modem type */
  392.     newnodedes.NodeFlags = B_CM;                  /* Assume boss is CM */
  393.     newnodedes.NodeFiller = 0;                     /* Zero out filler */
  394.     return (1);
  395.     }
  396.  
  397.  
  398.  
  399. static int opus_next_zone(FILE *fd)        /* CML */
  400.     {
  401.     register unsigned int i;
  402.  
  403.     if (no_zones)
  404.         return (-1);
  405.  
  406.     if (zone_offset == 0)
  407.         zone_offset = 1;
  408.  
  409.  
  410.     for (i = zone_offset; i < idx_size; i++)        /* CML */
  411.         {
  412.         if (!nidx_recs || i < nidx_start || i >= (nidx_start + nidx_recs))
  413.             {
  414.             fseek(fd,(long)i * (long)sizeof(struct _ndi),SEEK_SET);
  415.             if (!(nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd)))
  416.                 break;
  417.             nidx_start = i;
  418.             }
  419.  
  420.         if (nidx_buf[i - nidx_start].node == -2)
  421.             {
  422.             last_zone = nidx_buf[i - nidx_start].net;
  423.             zone_offset = i + 1;
  424.             return last_zone;
  425.             }
  426.         }
  427.  
  428.     last_zone = -1;
  429.     zone_offset = 0;
  430.     return (-1);
  431.     }
  432.  
  433.  
  434.  
  435. int opusfind(ADDR *opus_addr,int have_boss_data)
  436.     {
  437.     struct stat f;
  438.     char temp[80];                                 /* where we build filenames  */
  439.     unsigned int i;
  440.     int current_zone = 0;
  441.     int nodeoff = 0;                              /* offset into nodelist.sys  */
  442.     int found = 0;                                 /* 'found the node' flag     */
  443.     int rtn;                    /* CML */
  444.     FILE *fd;        /* CML */
  445.  
  446.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  447.     if (nodelist_base == NULL)
  448.         nodelist_base = nodelist_name;
  449.  
  450.     /* CML - let's open the index file! */
  451.     get_nodelist_name (opus_addr);
  452.     index_filesize == (off_t) 0L;              /* Cover ourselves for error */
  453.     strcpy(index_filename, net_info);  /* take nodelist path          */
  454.     strcat(index_filename, nodelist_base); /* add in the file name  */
  455.     strcat(index_filename, ".IDX");    /* add in the file ext       */
  456.     if (!(fd = fopen(index_filename,"rb")))
  457.         {
  458.         if (have_boss_data != 2)
  459.             status_line (msgtxt[M_UNABLE_TO_OPEN], index_filename);
  460.         return (0);                             /* no file, no work to do      */
  461.         }
  462.     fstat(fileno(fd), &f);                        /* get file statistics         */
  463.     idx_size = (int)(f.st_size / (long)sizeof (struct _ndi));         /* number of index entries   */
  464.  
  465.     if (nidx_buf == NULL)
  466.         {
  467.         if (!(nidx_buf = (struct _ndi far *)get_size(NIDX_BUFSIZE * sizeof(struct _ndi))))        /* buffer 8192 recs at a time */
  468.             {
  469.             status_line (msgtxt[M_NODELIST_MEM]);
  470.             fclose(fd);
  471.             return 0;
  472.             }
  473.         nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd);        /* preload the cache */
  474.         nidx_start = 0;
  475.         }
  476.  
  477.     index_filesize = f.st_size;                 /* Save parameters for later */
  478.     index_filetime = f.st_mtime;
  479.  
  480.     /*
  481.     * Now take into account that the .DAT file can be bigger than we
  482.     * really expect it to be.  Just take the number of records, and
  483.     * divide into the size of the .DAT file to find the true record size
  484.     */
  485.  
  486.     if (newnodelist)
  487.         {
  488.         strcpy (temp, net_info);         /* take nodelist path          */
  489.         strcat (temp, nodelist_base);     /* add in the file name      */
  490.         strcat (temp, ".DAT");           /* add in the file name      */
  491.         if (!stat (temp, &f))
  492.             extra_bytes = (int)(f.st_size / (long)idx_size) - sizeof (newnodedes);
  493.         }
  494.  
  495.     /* If using the old nodelist, bypass zone stuff - it isn't there */
  496.     if (opus_addr->Zone == (unsigned int) -1)
  497.         {
  498.         rtn = opus_next_zone(fd);
  499.         fclose(fd);            /* CML */
  500.         return rtn;
  501.         }
  502.     else if (!newnodelist || alias[0].Zone == 0 || no_zones)
  503.         opus_addr->Zone = 0;
  504.  
  505.  
  506.     for (i = 1, nodeoff = 1; i <= idx_size; nodeoff++, i++)        /* CML */
  507.         {
  508.         if (!nidx_recs || i < nidx_start || i >= (nidx_start + nidx_recs))
  509.             {
  510.             fseek(fd,(long)i * (long)sizeof(struct _ndi),SEEK_SET);
  511.             if (!(nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd)))
  512.                 break;
  513.             nidx_start = i;
  514.             }
  515.  
  516.         if (nidx_buf[i - nidx_start].node == -2)
  517.             current_zone = nidx_buf[i - nidx_start].net;
  518.  
  519.         if (opus_addr->Zone > 0 && current_zone != opus_addr->Zone)
  520.             continue;
  521.  
  522.         if (nidx_buf[i - nidx_start].net == opus_addr->Net)                /* if a match on net,         */
  523.             {
  524.             if ((opus_addr->Node == 0 && nidx_buf[i - nidx_start].node <= 0) || (nidx_buf[i - nidx_start].node == opus_addr->Node))     /* see if we found the node  */
  525.                 {
  526.                 found_zone = current_zone;                     /* Keep track of found zone */
  527.                 found_net = nidx_buf[i - nidx_start].net;     /* CML: Keep track of found net  */
  528.                 found = 1;                             /* say we found it           */
  529.                 break;                                 /* get out                   */
  530.                 }
  531.             }
  532.         }
  533.  
  534.     fclose(fd);            /* CML */
  535.  
  536.     if (!found)
  537.         return (0);
  538.  
  539.     if (newnodelist)
  540.         i = get_new_info(nodeoff);
  541.     else
  542.         i = get_old_info(nodeoff);
  543.  
  544.     return i;
  545.     }
  546.  
  547.  
  548.  
  549. static int get_old_info(unsigned recno)
  550.     {
  551.     struct _node nodedes;                         /* desc. of node              */
  552.     long nodeoff;                                 /* Offset into NODELIST.SYS  */
  553.     char temp[80];                                 /* where we build filenames  */
  554.     char *c, *ch;
  555.     int i;
  556.     FILE *stream;
  557.  
  558.     nodeoff = (long) recno *(long) sizeof (nodedes);     /* actual file offset         */
  559.  
  560.     strcpy (temp, net_info);                        /* take nodelist path         */
  561.     strcat (temp, nodelist_base);                /* add in the file name        */
  562.     strcat (temp, ".SYS");                /* add in the file name      */
  563.     if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  564.         {
  565.         status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  566.         return (0);
  567.         }
  568.  
  569.     if (fseek (stream, nodeoff, SEEK_SET))         /* try to point at record      */
  570.         {
  571.         status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
  572.         fclose (stream);
  573.         return (0);
  574.         }
  575.  
  576.     if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  577.         {
  578.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  579.         fclose (stream);
  580.         return (0);
  581.         }
  582.     fclose (stream);
  583.  
  584.     /*
  585.     * Copy data from nodedes into newnodedes.
  586.     */
  587.  
  588.     newnodedes.NodeNumber = nodedes.number;         /* Node Number  */
  589.     newnodedes.NetNumber = nodedes.net;             /* Net Number     */
  590.     newnodedes.Cost = nodedes.cost;                 /* Cost         */
  591.  
  592.     strncpy (&newnodedes.SystemName[0], &nodedes.name[0], 20);
  593.     newnodedes.SystemName[19] = '\0';             /* System Name  */
  594.  
  595.     strncpy (&newnodedes.PhoneNumber[0], &nodedes.phone[0], 40);
  596.     newnodedes.PhoneNumber[39] = '\0';            /* Phone Number */
  597.  
  598.     strncpy (&newnodedes.MiscInfo[0], &nodedes.city[0], 30);
  599.     newnodedes.MiscInfo[29] = '\0';
  600.  
  601.     ch = NULL;                                     /* Pointer to password      */
  602.     c = nodedes.city;                             /* Point to start of city     */
  603.     i = 37;                                         /* No password if this = 0  */
  604.     while (i--)                                     /* Enforce that limit         */
  605.         {
  606.         if (*c++ != '\0')                          /* If not at end of city,   */
  607.             continue;                                 /* go on to next character  */
  608.         if (*c++ != '!')                           /* End of city, got '!' ??  */
  609.             break;                                  /* No, treat like a failure */
  610.         ch = c;                                     /* Got it, point to it      */
  611.         break;                                     /* Exit with success code     */
  612.         }
  613.     if (ch != NULL)
  614.         strncpy (&newnodedes.Password[0], ch, 8);    /* Copy the password        */
  615.     else
  616.         newnodedes.Password[0] = '\0';           /* Else set zero length     */
  617.  
  618.     newnodedes.RealCost = nodedes.cost;             /* Cost                     */
  619.     newnodedes.HubNode = 0;                         /* Don't know who is Hub    */
  620.     newnodedes.BaudRate = (char) (nodedes.rate / 300);    /* Baud Rate                */
  621.     newnodedes.ModemType = 0;                     /* Don't know modem type    */
  622.     newnodedes.NodeFlags = 0;                     /* Don't know any flags     */
  623.     newnodedes.NodeFiller = 0;                     /* Filler should be zero     */
  624.     return (1);
  625.     }
  626.  
  627.  
  628.  
  629. static int get_new_info(unsigned recno)
  630.     {
  631.     long nodeoff;                                 /* Offset into NODELIST.DAT  */
  632.     char temp[80];                                 /* where we build filenames  */
  633.     FILE *stream;
  634.  
  635.     /* actual file offset */
  636.     nodeoff = (long)recno * ((long)(sizeof (newnodedes) + (long)extra_bytes));
  637.  
  638.     strcpy(temp, net_info);                        /* take nodelist path         */
  639.     strcat(temp, nodelist_base);                /* add in the file name        */
  640.     strcat(temp, ".DAT");                /* add in the file name      */
  641.     if ((stream = fopen(temp, "rb")) == NULL)    /* OK, let's open the file   */
  642.         {
  643.         status_line(msgtxt[M_UNABLE_TO_OPEN], temp);
  644.         return 0;
  645.         }
  646.  
  647.     if (fseek(stream, nodeoff, SEEK_SET))         /* try to point at record      */
  648.         {
  649.         status_line(msgtxt[M_NODELIST_SEEK_ERR], temp);
  650.         fclose(stream);
  651.         return 0;
  652.         }
  653.  
  654.     if (!fread(&newnodedes, sizeof (newnodedes), 1, stream))
  655.         {
  656.         status_line(msgtxt[M_NODELIST_REC_ERR], temp);
  657.         fclose(stream);
  658.         return 0;
  659.         }
  660.  
  661.     fclose(stream);
  662.     return 1;
  663.     }
  664.  
  665.  
  666.  
  667. static int TBBS_next_zone(void)                /* CML - since opus_next_zone has been changed */
  668.     {
  669.     register struct _ndi far *nodeidx;             /* index file                  */
  670.     register unsigned int i;
  671.  
  672.     if (no_zones)
  673.         return (-1);
  674.  
  675.     if (zone_offset == 0)
  676.         zone_offset = 1;
  677.  
  678.     nodeidx = (struct _ndi far *) (node_index + (zone_offset *
  679.         sizeof (struct _ndi)));
  680.  
  681.     for (i = zone_offset; i < idx_size; ++nodeidx, i++)
  682.         {
  683.         if (nodeidx->node == -2)
  684.             {
  685.             last_zone = nodeidx->net;
  686.             zone_offset = i + 1;
  687.             return (last_zone);
  688.             }
  689.         }
  690.  
  691.     last_zone = -1;
  692.     zone_offset = 0;
  693.     return (-1);
  694.     }
  695.  
  696.  
  697.  
  698. static int get_TBBS_info(unsigned recno,ADDR *TBBS_addr)
  699.     {
  700.     struct nodels nodedes;                         /* desc. of node              */
  701.     struct extrastuff ext;                         /* Extra stuff for Binkley   */
  702.     long nodeoff;                                 /* Offset into NODELIST.DOG  */
  703.     char temp[80];                                 /* where we build filenames  */
  704.     FILE *stream;
  705.  
  706.     --recno;              /* TBBS list starts at first record - no filler */
  707.  
  708.     nodeoff = (long) recno *(long) sizeof (nodedes);     /* actual file offset         */
  709.  
  710.     strcpy (temp, net_info);                        /* take nodelist path         */
  711.     strcat (temp, "NODELIST.DOG");                /* add in the file name      */
  712.     if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  713.         {
  714.         status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  715.         return (0);
  716.         }
  717.  
  718.     if (fseek (stream, nodeoff, SEEK_SET))         /* try to point at record      */
  719.         {
  720.         status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
  721.         fclose (stream);
  722.         return (0);
  723.         }
  724.  
  725.     if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  726.         {
  727.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  728.         fclose (stream);
  729.         return (0);
  730.         }
  731.     fclose (stream);
  732.  
  733.     /*
  734.     * Copy data from nodedes into newnodedes.
  735.     */
  736.  
  737.     newnodedes.NodeNumber = TBBS_addr->Node;             /* Node Number    */
  738.     newnodedes.NetNumber = TBBS_addr->Net;                /* Net Number    */
  739.     newnodedes.Cost = nodedes.nodecost;             /* Cost         */
  740.  
  741.     strncpy (&newnodedes.SystemName[0], &nodedes.nodename[0], 14);
  742.     newnodedes.SystemName[19] = '\0';             /* System Name  */
  743.  
  744.     strncpy (&newnodedes.PhoneNumber[0], &nodedes.nodephone[0], 40);
  745.     newnodedes.PhoneNumber[39] = '\0';            /* Phone Number */
  746.  
  747.     strncpy (&newnodedes.MiscInfo[0], &nodedes.nodecity[0], 30);
  748.     newnodedes.MiscInfo[29] = '\0';
  749.  
  750.     newnodedes.Password[0] = '\0';                /* Else set zero length     */
  751.  
  752.     newnodedes.RealCost = nodedes.nodecost;         /* Cost                     */
  753.     newnodedes.HubNode = nodedes.nodehub;         /* Hub */
  754.     newnodedes.BaudRate = (char) (nodedes.nodebaud / 300);        /* Baud Rate                */
  755.     newnodedes.ModemType = 0;                     /* Don't know modem type    */
  756.     newnodedes.NodeFlags = 0;                     /* Don't know any flags     */
  757.     newnodedes.NodeFiller = 0;                     /* Filler should be zero     */
  758.  
  759.     /* Now get information from secondary file */
  760.     ++recno;
  761.     nodeoff = (long) recno *(long) sizeof (ext);  /* actual file offset          */
  762.  
  763.     strcpy (temp, net_info);                        /* take nodelist path         */
  764.     strcat (temp, "NODELIST.EXT");                /* add in the file name      */
  765.     newnodelist = 0;
  766.     if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  767.         return (1);
  768.  
  769.     if (fseek (stream, nodeoff, SEEK_SET))         /* try to point at record      */
  770.         {
  771.         fclose (stream);
  772.         return (1);
  773.         }
  774.  
  775.     if (!fread (&ext, sizeof (ext), 1, stream))
  776.         {
  777.         fclose (stream);
  778.         return (1);
  779.         }
  780.     fclose (stream);
  781.  
  782.     /*
  783.     * Copy data from ext into newnodedes.
  784.     */
  785.  
  786.     strncpy (newnodedes.Password, ext.password, 8);       /* Password */
  787.  
  788.     newnodedes.NodeFlags = ext.flags1;             /* Nodelist flags */
  789.     newnodedes.ModemType = ext.modem;             /* Modem type */
  790.     newnodelist = 1;                              /* We have all the information! */
  791.     return (1);
  792.     }
  793.  
  794.  
  795. int TBBSLookup(ADDR *TBBS_addr,int have_boss_data)
  796.     {
  797.     register struct _ndi far *nodeidx;             /* index file                  */
  798. /*    int foundnet = 0; */                          /* 'found the net' flag      */
  799.     int found = 0;                                 /* 'found the node' flag     */
  800.     int nodeoff = 0;                              /* offset into nodelist.sys  */
  801.     char temp[80];                                 /* where we build filenames  */
  802. #ifndef OS_2
  803.     int stream;
  804.     unsigned int i;
  805.     int got;
  806. #else
  807.     HFILE stream;
  808.     USHORT i;
  809.     USHORT got;
  810. #endif
  811.     struct stat f;
  812.     int current_zone = 0;
  813.  
  814.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  815.  
  816.     if (node_index == NULL)
  817.         {
  818.         temp[0] = '\0';                            /* "null-terminated string"  */
  819.         strcpy (temp, net_info);                    /* take nodelist path         */
  820.         strcat (temp, "NODELIST.IDX");             /* add in the file name      */
  821.         if ((stream = open(temp, O_RDONLY|O_BINARY)) == -1)
  822.             {
  823.             i = 0;                                  /* Need this later           */
  824.             if (have_boss_data != 2)
  825.                 status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  826.             return (0);                             /* no file, no work to do      */
  827.             }
  828.         fstat (stream, &f);                        /* get file statistics         */
  829.         i = (unsigned int) f.st_size;              /* size of index file,       */
  830.         idx_size = i / sizeof (struct _ndi);         /* number of index entries   */
  831.         node_index = get_size (i);
  832.         if (node_index == NULL)
  833.             {
  834.             status_line (msgtxt[M_NODELIST_MEM]);
  835.             close (stream);
  836.             return (0);
  837.             }
  838.         if (_dos_read (stream, node_index, i, &got) != 0)
  839.             {
  840.             status_line (msgtxt[M_NODELIST_READ_ERR]);
  841.             close (stream);
  842.             return (0);
  843.             }
  844.         close (stream);
  845.         }
  846.     nodeidx = (struct _ndi far *) node_index;
  847.  
  848.     if (TBBS_addr->Zone == (unsigned int) -1)
  849.         return (TBBS_next_zone());
  850.  
  851.     for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
  852.         {
  853.         if (nodeidx->node == -2)
  854.             current_zone = nodeidx->net;
  855.  
  856.         if (TBBS_addr->Zone > 0 && current_zone != TBBS_addr->Zone)
  857.             continue;
  858.  
  859.         if (nodeidx->net == TBBS_addr->Net)                /* if a match on net,         */
  860.             {
  861. /*            foundnet = 1;    */                         /* say we found the net      */
  862.             if (((TBBS_addr->Node == 0) && (nodeidx->node <= 0))
  863.                 || (nodeidx->node == TBBS_addr->Node))     /* see if we found the node  */
  864.                 {
  865.                 found = 1;                             /* say we found it           */
  866.                 break;                                 /* get out                   */
  867.                 }
  868.             }
  869.  
  870.         /*
  871.         * This code is good, but many people complained about not being able
  872.         * to add nodes to nets by adding them at the end of the nodelist.  So,
  873.         * I commented this stuff out for now. - Bob
  874.         */
  875. #if 0
  876.         else if (foundnet)        /* already past the net?      */
  877.             break;/* Yes, we failed...          */
  878. #endif
  879.         }
  880.  
  881.     if (!found)
  882.         return (0);
  883.  
  884.     found_zone = current_zone;                     /* Keep track of found zone */
  885.     found_net  = nodeidx->net;                     /* Keep track of found net  */
  886.  
  887.     i = get_TBBS_info (nodeoff, TBBS_addr);
  888.  
  889.     return (i);
  890.     }
  891.  
  892.  
  893.  
  894. static int Quick_Next_Zone(void)
  895.     {
  896.     register struct QuickNodeIdxRecord far *nodeidx;     /* index file */
  897.     register unsigned int i;
  898.  
  899.     if (no_zones)
  900.         return (-1);
  901.  
  902.     nodeidx = (struct QuickNodeIdxRecord far *) (node_index + (zone_offset *
  903.         sizeof (struct QuickNodeIdxRecord)));
  904.     for (i = zone_offset; i < idx_size; ++nodeidx, i++)
  905.         {
  906.         if (nodeidx->QI_Zone != last_zone)
  907.             {
  908.             last_zone = nodeidx->QI_Zone;
  909.             zone_offset = i + 1;
  910.             return (last_zone);
  911.             }
  912.         }
  913.  
  914.     last_zone = -1;
  915.     zone_offset = 0;
  916.     return (-1);
  917.     }
  918.  
  919.  
  920.  
  921. int QuickLookup(ADDR *Quick_addr,int have_boss_data)
  922.     {
  923.     register struct QuickNodeIdxRecord far *nodeidx;     /* index file          */
  924.     struct QuickNodeListRecord nodedes;             /* desc. of node       */
  925.     int foundnet = 0;                             /* 'found the net' flag      */
  926.     int found = 0;                                 /* 'found the node' flag     */
  927.     int idxrec = 0;                                 /* record in QNL_IDX.BBS      */
  928.     long nodeoff = 0L;                             /* offset into QNL_DAT.BBS   */
  929.     char temp[80];                                 /* where we build filenames  */
  930. #ifndef OS_2
  931.     int stream;
  932.     unsigned int i;
  933.     int got;
  934. #else
  935.     HFILE stream;
  936.     USHORT i;
  937.     USHORT got;
  938. #endif
  939.     FILE *stream1;
  940.     struct stat f;
  941.  
  942.     newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  943.  
  944.     if (node_index == NULL)
  945.         {
  946.         index_filesize == (off_t) 0L;              /* Cover ourselves for error */
  947.         index_filename[0] = '\0';                  /* "null-terminated string"  */
  948.         strcpy (index_filename, net_info);  /* take nodelist path          */
  949.         strcat (index_filename, "QNL_IDX.BBS"); /* add in the file name  */
  950.         if ((stream = open(index_filename, O_RDONLY|O_BINARY)) == -1)
  951.             {
  952.             if (have_boss_data != 2)
  953.                 status_line (msgtxt[M_UNABLE_TO_OPEN], index_filename);
  954.             return (0);                             /* no file, no work to do      */
  955.             }
  956.         fstat (stream, &f);                 /* get file statistics       */
  957.         i = (unsigned int) f.st_size;              /* size of index file,       */
  958.         idx_size = i / sizeof (*nodeidx);          /* number of index entries   */
  959.         node_index = get_size (i);
  960.         if (node_index == NULL)
  961.             {
  962.             status_line (msgtxt[M_NODELIST_MEM]);
  963.             close (stream);
  964.             return (0);
  965.             }
  966.         if (_dos_read (stream, node_index, i, &got) != 0)
  967.             {
  968.             status_line (msgtxt[M_NODELIST_READ_ERR]);
  969.             close (stream);
  970.             return (0);
  971.             }
  972.         close (stream);
  973.  
  974.         index_filesize = f.st_size;                 /* Save parameters for later */
  975.         index_filetime = f.st_mtime;
  976.         }
  977.  
  978.     nodeidx = (struct QuickNodeIdxRecord far *) node_index;
  979.  
  980.  
  981.     if (Quick_addr->Zone == (unsigned int) -1)
  982.         {
  983.         return (Quick_Next_Zone ());
  984.         }
  985.     else if (no_zones)
  986.         Quick_addr->Zone = 0;
  987.  
  988.     for (i = 1; i <= idx_size; idxrec++, nodeidx++, i++)
  989.         {
  990.         if (((Quick_addr->Zone == nodeidx->QI_Zone) || (Quick_addr->Zone == 0))
  991.             && (Quick_addr->Net == nodeidx->QI_Net))
  992.             {
  993.             foundnet = 1;                             /* say we found the net      */
  994.             if (((Quick_addr->Node == 0) && (nodeidx->QI_Node <= 0))
  995.                 || (nodeidx->QI_Node == Quick_addr->Node)) /* see if we found the node  */
  996.                 {
  997.                 found = 1;                             /* say we found it           */
  998.                 break;                                 /* get out                   */
  999.                 }
  1000.             }
  1001.         else if (foundnet)                         /* already past the net?      */
  1002.             break;                                  /* Yes, we failed...          */
  1003.         }
  1004.  
  1005.     if (!found)
  1006.         return (0);
  1007.  
  1008.     nodeoff = (long) idxrec *(long) sizeof (nodedes);    /* actual file offset    */
  1009.  
  1010.     strcpy (temp, net_info);                        /* take nodelist path         */
  1011.     strcat (temp, "QNL_DAT.BBS");                 /* add in the file name      */
  1012.     if ((stream1 = fopen (temp, "rb")) == NULL)   /* OK, let's open the file   */
  1013.         {
  1014.         status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
  1015.         return (0);
  1016.         }
  1017.  
  1018.     if (fseek (stream1, nodeoff, SEEK_SET))         /* try to point at record      */
  1019.         {
  1020.         status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
  1021.         fclose (stream1);
  1022.         return (0);
  1023.         }
  1024.  
  1025.     if (!fread (&nodedes, sizeof (nodedes), 1, stream1))
  1026.         {
  1027.         status_line (msgtxt[M_NODELIST_REC_ERR], temp);
  1028.         fclose (stream1);
  1029.         return (0);
  1030.         }
  1031.     fclose (stream1);
  1032.  
  1033.     /*
  1034.     * Copy data from nodedes into newnodedes.
  1035.     */
  1036.  
  1037.     newnodedes.NodeNumber = nodedes.QL_Node;      /* Node Number  */
  1038.     newnodedes.NetNumber = nodedes.QL_Net;         /* Net Number     */
  1039.     newnodedes.Cost = nodedes.QL_Cost;             /* Cost         */
  1040.  
  1041.     i = min (nodedes.QL_Name[0], 19);
  1042.     strncpy (&newnodedes.SystemName[0], &nodedes.QL_Name[1], i);
  1043.     newnodedes.SystemName[i] = '\0';              /* System Name  */
  1044.  
  1045.     i = min (nodedes.QL_Phone[0], 39);
  1046.     strncpy (&newnodedes.PhoneNumber[0], &nodedes.QL_Phone[1], i);
  1047.     newnodedes.PhoneNumber[i] = '\0';             /* Phone Number */
  1048.  
  1049.     i = min (nodedes.QL_City[0], 29);
  1050.     strncpy (&newnodedes.MiscInfo[0], &nodedes.QL_City[1], i);
  1051.     newnodedes.MiscInfo[i] = '\0';
  1052.  
  1053.     /* This field is not necessarily null terminated */
  1054.     i = min (nodedes.QL_Password[0], 8);
  1055.     strncpy (&newnodedes.Password[0], &nodedes.QL_Password[1], i);
  1056.     if (i < 8)
  1057.         newnodedes.Password[i] = '\0';
  1058.  
  1059.     /* Adam Hudson now gives us this, so we might as well use it */
  1060.     newnodedes.NodeFlags = nodedes.QL_Flags;
  1061.  
  1062.     /* Since we have the stuff we need! */
  1063.     newnodelist = 1;                              /* We have all the information! */
  1064.  
  1065.     newnodedes.RealCost = nodedes.QL_Cost;         /* Cost                     */
  1066.     newnodedes.HubNode = 0;                         /* Don't know who is Hub    */
  1067.     newnodedes.BaudRate = (char) (nodedes.QL_BaudRate / 300);    /* Baud      */
  1068.     newnodedes.ModemType = 0;                     /* Don't know modem type    */
  1069.     newnodedes.NodeFiller = 0;                     /* Filler should be zero     */
  1070.     found_zone = nodeidx -> QI_Zone;              /* Keep track of found zone */
  1071.     found_net = nodeidx -> QI_Net;                 /* And of found net         */
  1072.     return (1);
  1073.     }
  1074.