home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
BTMTSRC3.ZIP
/
NODEPROC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-21
|
32KB
|
1,074 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
/* */
/* */
/* This module was written by Vince Perriello */
/* */
/* */
/* BinkleyTerm Nodelist processing module */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.240. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:132/491, 1:141/491 */
/* P.O. Box 460398 AlterNet 7:491/0 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n132.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/*--------------------------------------------------------------------------*/
#include <sys\types.h>
#include <sys\stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include <string.h>
#ifdef OS_2
#define INCL_DOS
#include <os2.h>
#define _dos_read DosRead
#endif
#ifdef __TURBOC__
#include <alloc.h>
#define _fmalloc(n) farmalloc (n)
#define _ffree(n) farfree (n)
#else
#include <malloc.h>
#endif
#include "com.h"
#include "xfer.h"
#include "zmodem.h"
#include "keybd.h"
#include "sbuf.h"
#include "sched.h"
#include "externs.h"
#include "prototyp.h"
static char far *get_size (unsigned int);
static int get_new_info (unsigned);
static int get_old_info (unsigned);
static int get_TBBS_info (unsigned, ADDR *);
static int Quick_Next_Zone (void);
#ifdef __TURBOC__
typedef long off_t;
#endif
static off_t index_filesize = (off_t) 0L;
static time_t index_filetime = (time_t) 0L;
static char index_filename[80];
static unsigned int idx_size = 0; /* number of entries in it */
static unsigned int zone_offset = 0;
static int last_zone = -1;
static int extra_bytes = 0;
static char *curr_domain = NULL;
static char *nodelist_name = "NODELIST";
static char *nodelist_base = NULL;
#define NIDX_BUFSIZE 8192 /* CML */
static struct _ndi far *nidx_buf = NULL; /* CML - buffer for node records */
static int nidx_start = 0; /* CML */
static int nidx_recs = 0; /* CML */
static void get_nodelist_name(ADDR *opus_addr)
{
int i;
if (curr_domain != opus_addr->Domain)
{
curr_domain = opus_addr->Domain;
idx_size = 0;
zone_offset = 0;
last_zone = -1;
extra_bytes = 0;
}
nodelist_base = nodelist_name;
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == opus_addr->Domain)
{
nodelist_base = domain_nodelist[i];
if (nodelist_base == NULL)
nodelist_base = nodelist_name;
}
}
}
static char far *get_size(unsigned int n)
{
/* If we get this far, then we have to use a straight far pointer */
return (_fmalloc (n));
}
/*---------------------------------------------------------------------------*/
/* CHECKLIST */
/* See if nodelist has changed since we first tried to use it and if so, */
/* dismiss old copy and get a new one */
/*---------------------------------------------------------------------------*/
int checklist(void)
{
struct stat idxstat;
if (index_filesize == (off_t)0L)
return (0);
stat (index_filename, &idxstat);
if ((index_filesize == idxstat.st_size) && (index_filetime == idxstat.st_mtime))
return (0);
status_line (msgtxt[M_REFRESH_NODELIST]);
if (newnodelist) /* CML */
{
nidx_start = 0x7fff;
nidx_recs = 0;
}
else
{
_ffree ((char far *) node_index);
node_index = (char far *) NULL;
}
index_filesize = (off_t)0L;
return (1);
}
/*---------------------------------------------------------------------------*/
/* NODEPROC */
/* Find nodelist entry and set baud to nodelist baud for dialing out */
/*---------------------------------------------------------------------------*/
int nodeproc(char *nodeaddr)
{
ADDR opus_addr;
char *c, *skip_blanks ();
c = skip_blanks (nodeaddr); /* get rid of the blanks */
if (!find_address (c, &opus_addr))
return (0);
if (!nodefind (&opus_addr, 1)) /* if we can't find the node */
return (0); /* go away now */
status_line (msgtxt[M_PROCESSING_NODE], Full_Addr_Str (&opus_addr), newnodedes.SystemName);
if (!CARRIER) /* if no carrier yet, */
{
if (autobaud)
set_baud (max_baud.rate_value, 1); /* Set to our highest baud rate */
else
set_baud ((300 * newnodedes.BaudRate), 1); /* set baud to nodelist baud */
}
return (1); /* return success to caller */
}
/*---------------------------------------------------------------------------*/
/* NODEFIND */
/* Find nodelist entry for use by other routines (password, nodeproc) */
/* If found, result will be in "newnodedes". */
/*---------------------------------------------------------------------------*/
int nodefind(ADDR *bink_addr,int prtflag)
{
int i, j, k;
int have_boss_data = 0;
int need_boss_data = 0;
checklist ();
newnodedes.NetNumber = newnodedes.NodeNumber = found_zone = found_net = 0;
CurrentOKFile = DEFAULT.rq_OKFile; /* Set the default f.req paths */
CurrentFILES = DEFAULT.rq_FILES;
CurrentAbout = DEFAULT.rq_About;
CurrentReqTemplate = DEFAULT.rq_Template;
CurrentNetFiles = DEFAULT.sc_Inbound;
CurrentReqLim = DEFAULT.rq_Limit;
CurrentByteLim = DEFAULT.byte_Limit;
if ((bink_addr->Net == boss_addr.Net) && (bink_addr->Node == boss_addr.Node) &&
(bink_addr->Zone == alias[0].Zone) && ((bink_addr->Domain == boss_addr.Domain) || (bink_addr->Domain == NULL)))
{
++need_boss_data;
if (BOSSphone && strlen (BOSSphone) > 2)
++have_boss_data;
if (BOSSpwd && strlen (BOSSpwd) > 2)
++have_boss_data;
}
if (!bink_addr->Zone)
{
bink_addr->Zone = alias[0].Zone;
i = (*nodefunc) (bink_addr, have_boss_data);
if (i)
goto lookup_done;
}
i = (*nodefunc) (bink_addr, have_boss_data);
lookup_done:
assumed = k = 0; /* Default to zone of first */
for (j = 0; j < num_addrs; j++)
{
if ((alias[j].Point != 0) &&
((alias[j].Node != newnodedes.NodeNumber) ||
(alias[j].Net != found_net) ||
(alias[j].Zone != found_zone)))
{
/* Don't use our point address except to the boss! */
continue;
}
if ((alias[j].Domain == curr_domain) ||
((curr_domain == NULL) && (alias[j].Domain == my_addr.Domain)) ||
((alias[j].Domain == NULL) && (curr_domain == my_addr.Domain)))
{
if (k == 0)
{
assumed = j;
++k;
}
if (alias[j].Zone == found_zone)
{
if (k == 1)
{
assumed = j;
++k;
}
if (alias[j].Net == found_net)
{
assumed = j;
break;
}
}
}
}
if (!i && (have_boss_data != 2))
{
if (prtflag)
status_line (msgtxt[M_NO_ADDRESS], Full_Addr_Str (bink_addr));
if (curmudgeon && CARRIER && (bink_addr->Net != -1) && (bink_addr->Node != -1) && (bink_addr->Node != 9999))
{
status_line (msgtxt[M_NUISANCE_CALLER]);
DTR_OFF (); /* Hang up right now */
timer (2); /* Wait two secs */
DTR_ON (); /* OK, turn modem back on */
}
}
if (bink_addr->Zone == (unsigned int) -1)
return i;
/* If we found the entry, then we promote the file request
* to the "KNOWN" class. If the password field is non-zero,
* then promote to "PROT". It's OK to do that since the higher
* level code will hang up before f.req's if the password does
* not match.
*/
if (i)
{
if (newnodedes.Password[0])
{
CurrentOKFile = PROT.rq_OKFile;
CurrentFILES = PROT.rq_FILES;
CurrentAbout = PROT.rq_About;
CurrentReqTemplate = PROT.rq_Template;
CurrentNetFiles = PROT.sc_Inbound;
CurrentReqLim = PROT.rq_Limit;
CurrentByteLim = PROT.byte_Limit;
}
else
{
CurrentOKFile = KNOWN.rq_OKFile;
CurrentFILES = KNOWN.rq_FILES;
CurrentAbout = KNOWN.rq_About;
CurrentReqTemplate = KNOWN.rq_Template;
CurrentNetFiles = KNOWN.sc_Inbound;
CurrentReqLim = KNOWN.rq_Limit;
CurrentByteLim = KNOWN.byte_Limit;
}
}
if (!need_boss_data)
return (i);
/*
* We can get here one of two ways:
*
* 1) No nodelist data was found and this is the BOSS.
*
* 2) Nodelist lookup occurred, but this is the BOSS.
*
* For case (1), have_boss_data MUST be 2 (meaning we have
* both a phone number and a password entry). If that is the
* case, fill in newnodedes with mostly zeroes, plugging in
* the BOSS net, node, phone number and password.
*
* For case (2), just see if there is any substitution for
* BOSSphone and/or BOSSpwd, then exit.
*
*/
if (BOSSphone && strlen (BOSSphone) > 2)
{
strncpy (newnodedes.PhoneNumber, BOSSphone, 40);
newnodedes.PhoneNumber[39] = '\0';
}
if (BOSSpwd && strlen (BOSSpwd) > 2)
{
memset (newnodedes.Password, 0, sizeof (newnodedes.Password));
strncpy (newnodedes.Password, BOSSpwd, 8);
}
if (i)
return (1);
/* No BOSS in the nodelist */
if (have_boss_data != 2)
{
status_line (msgtxt[M_NO_BOSS]);
return (0);
}
newnodedes.NodeNumber = bink_addr->Node; /* Node Number */
newnodedes.NetNumber = bink_addr->Net; /* Net Number */
newnodedes.Cost = newnodedes.RealCost = 0; /* Assume boss is free */
strcpy (newnodedes.SystemName, "Binkley's Boss"); /* System Name defaults */
strcpy (newnodedes.MiscInfo, "Somewhere out There"); /* As does City */
newnodedes.HubNode = 0; /* Don't know who is HUB */
newnodedes.BaudRate = (char) (max_baud.rate_value / 300);
/* Assume boss speed = ours */
newnodedes.ModemType = 0; /* Or modem type */
newnodedes.NodeFlags = B_CM; /* Assume boss is CM */
newnodedes.NodeFiller = 0; /* Zero out filler */
return (1);
}
static int opus_next_zone(FILE *fd) /* CML */
{
register unsigned int i;
if (no_zones)
return (-1);
if (zone_offset == 0)
zone_offset = 1;
for (i = zone_offset; i < idx_size; i++) /* CML */
{
if (!nidx_recs || i < nidx_start || i >= (nidx_start + nidx_recs))
{
fseek(fd,(long)i * (long)sizeof(struct _ndi),SEEK_SET);
if (!(nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd)))
break;
nidx_start = i;
}
if (nidx_buf[i - nidx_start].node == -2)
{
last_zone = nidx_buf[i - nidx_start].net;
zone_offset = i + 1;
return last_zone;
}
}
last_zone = -1;
zone_offset = 0;
return (-1);
}
int opusfind(ADDR *opus_addr,int have_boss_data)
{
struct stat f;
char temp[80]; /* where we build filenames */
unsigned int i;
int current_zone = 0;
int nodeoff = 0; /* offset into nodelist.sys */
int found = 0; /* 'found the node' flag */
int rtn; /* CML */
FILE *fd; /* CML */
newnodedes.NetNumber = newnodedes.NodeNumber = 0;
if (nodelist_base == NULL)
nodelist_base = nodelist_name;
/* CML - let's open the index file! */
get_nodelist_name (opus_addr);
index_filesize == (off_t) 0L; /* Cover ourselves for error */
strcpy(index_filename, net_info); /* take nodelist path */
strcat(index_filename, nodelist_base); /* add in the file name */
strcat(index_filename, ".IDX"); /* add in the file ext */
if (!(fd = fopen(index_filename,"rb")))
{
if (have_boss_data != 2)
status_line (msgtxt[M_UNABLE_TO_OPEN], index_filename);
return (0); /* no file, no work to do */
}
fstat(fileno(fd), &f); /* get file statistics */
idx_size = (int)(f.st_size / (long)sizeof (struct _ndi)); /* number of index entries */
if (nidx_buf == NULL)
{
if (!(nidx_buf = (struct _ndi far *)get_size(NIDX_BUFSIZE * sizeof(struct _ndi)))) /* buffer 8192 recs at a time */
{
status_line (msgtxt[M_NODELIST_MEM]);
fclose(fd);
return 0;
}
nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd); /* preload the cache */
nidx_start = 0;
}
index_filesize = f.st_size; /* Save parameters for later */
index_filetime = f.st_mtime;
/*
* Now take into account that the .DAT file can be bigger than we
* really expect it to be. Just take the number of records, and
* divide into the size of the .DAT file to find the true record size
*/
if (newnodelist)
{
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, nodelist_base); /* add in the file name */
strcat (temp, ".DAT"); /* add in the file name */
if (!stat (temp, &f))
extra_bytes = (int)(f.st_size / (long)idx_size) - sizeof (newnodedes);
}
/* If using the old nodelist, bypass zone stuff - it isn't there */
if (opus_addr->Zone == (unsigned int) -1)
{
rtn = opus_next_zone(fd);
fclose(fd); /* CML */
return rtn;
}
else if (!newnodelist || alias[0].Zone == 0 || no_zones)
opus_addr->Zone = 0;
for (i = 1, nodeoff = 1; i <= idx_size; nodeoff++, i++) /* CML */
{
if (!nidx_recs || i < nidx_start || i >= (nidx_start + nidx_recs))
{
fseek(fd,(long)i * (long)sizeof(struct _ndi),SEEK_SET);
if (!(nidx_recs = fread(nidx_buf,sizeof(struct _ndi),NIDX_BUFSIZE,fd)))
break;
nidx_start = i;
}
if (nidx_buf[i - nidx_start].node == -2)
current_zone = nidx_buf[i - nidx_start].net;
if (opus_addr->Zone > 0 && current_zone != opus_addr->Zone)
continue;
if (nidx_buf[i - nidx_start].net == opus_addr->Net) /* if a match on net, */
{
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 */
{
found_zone = current_zone; /* Keep track of found zone */
found_net = nidx_buf[i - nidx_start].net; /* CML: Keep track of found net */
found = 1; /* say we found it */
break; /* get out */
}
}
}
fclose(fd); /* CML */
if (!found)
return (0);
if (newnodelist)
i = get_new_info(nodeoff);
else
i = get_old_info(nodeoff);
return i;
}
static int get_old_info(unsigned recno)
{
struct _node nodedes; /* desc. of node */
long nodeoff; /* Offset into NODELIST.SYS */
char temp[80]; /* where we build filenames */
char *c, *ch;
int i;
FILE *stream;
nodeoff = (long) recno *(long) sizeof (nodedes); /* actual file offset */
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, nodelist_base); /* add in the file name */
strcat (temp, ".SYS"); /* add in the file name */
if ((stream = fopen (temp, "rb")) == NULL) /* OK, let's open the file */
{
status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
return (0);
}
if (fseek (stream, nodeoff, SEEK_SET)) /* try to point at record */
{
status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
fclose (stream);
return (0);
}
if (!fread (&nodedes, sizeof (nodedes), 1, stream))
{
status_line (msgtxt[M_NODELIST_REC_ERR], temp);
fclose (stream);
return (0);
}
fclose (stream);
/*
* Copy data from nodedes into newnodedes.
*/
newnodedes.NodeNumber = nodedes.number; /* Node Number */
newnodedes.NetNumber = nodedes.net; /* Net Number */
newnodedes.Cost = nodedes.cost; /* Cost */
strncpy (&newnodedes.SystemName[0], &nodedes.name[0], 20);
newnodedes.SystemName[19] = '\0'; /* System Name */
strncpy (&newnodedes.PhoneNumber[0], &nodedes.phone[0], 40);
newnodedes.PhoneNumber[39] = '\0'; /* Phone Number */
strncpy (&newnodedes.MiscInfo[0], &nodedes.city[0], 30);
newnodedes.MiscInfo[29] = '\0';
ch = NULL; /* Pointer to password */
c = nodedes.city; /* Point to start of city */
i = 37; /* No password if this = 0 */
while (i--) /* Enforce that limit */
{
if (*c++ != '\0') /* If not at end of city, */
continue; /* go on to next character */
if (*c++ != '!') /* End of city, got '!' ?? */
break; /* No, treat like a failure */
ch = c; /* Got it, point to it */
break; /* Exit with success code */
}
if (ch != NULL)
strncpy (&newnodedes.Password[0], ch, 8); /* Copy the password */
else
newnodedes.Password[0] = '\0'; /* Else set zero length */
newnodedes.RealCost = nodedes.cost; /* Cost */
newnodedes.HubNode = 0; /* Don't know who is Hub */
newnodedes.BaudRate = (char) (nodedes.rate / 300); /* Baud Rate */
newnodedes.ModemType = 0; /* Don't know modem type */
newnodedes.NodeFlags = 0; /* Don't know any flags */
newnodedes.NodeFiller = 0; /* Filler should be zero */
return (1);
}
static int get_new_info(unsigned recno)
{
long nodeoff; /* Offset into NODELIST.DAT */
char temp[80]; /* where we build filenames */
FILE *stream;
/* actual file offset */
nodeoff = (long)recno * ((long)(sizeof (newnodedes) + (long)extra_bytes));
strcpy(temp, net_info); /* take nodelist path */
strcat(temp, nodelist_base); /* add in the file name */
strcat(temp, ".DAT"); /* add in the file name */
if ((stream = fopen(temp, "rb")) == NULL) /* OK, let's open the file */
{
status_line(msgtxt[M_UNABLE_TO_OPEN], temp);
return 0;
}
if (fseek(stream, nodeoff, SEEK_SET)) /* try to point at record */
{
status_line(msgtxt[M_NODELIST_SEEK_ERR], temp);
fclose(stream);
return 0;
}
if (!fread(&newnodedes, sizeof (newnodedes), 1, stream))
{
status_line(msgtxt[M_NODELIST_REC_ERR], temp);
fclose(stream);
return 0;
}
fclose(stream);
return 1;
}
static int TBBS_next_zone(void) /* CML - since opus_next_zone has been changed */
{
register struct _ndi far *nodeidx; /* index file */
register unsigned int i;
if (no_zones)
return (-1);
if (zone_offset == 0)
zone_offset = 1;
nodeidx = (struct _ndi far *) (node_index + (zone_offset *
sizeof (struct _ndi)));
for (i = zone_offset; i < idx_size; ++nodeidx, i++)
{
if (nodeidx->node == -2)
{
last_zone = nodeidx->net;
zone_offset = i + 1;
return (last_zone);
}
}
last_zone = -1;
zone_offset = 0;
return (-1);
}
static int get_TBBS_info(unsigned recno,ADDR *TBBS_addr)
{
struct nodels nodedes; /* desc. of node */
struct extrastuff ext; /* Extra stuff for Binkley */
long nodeoff; /* Offset into NODELIST.DOG */
char temp[80]; /* where we build filenames */
FILE *stream;
--recno; /* TBBS list starts at first record - no filler */
nodeoff = (long) recno *(long) sizeof (nodedes); /* actual file offset */
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, "NODELIST.DOG"); /* add in the file name */
if ((stream = fopen (temp, "rb")) == NULL) /* OK, let's open the file */
{
status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
return (0);
}
if (fseek (stream, nodeoff, SEEK_SET)) /* try to point at record */
{
status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
fclose (stream);
return (0);
}
if (!fread (&nodedes, sizeof (nodedes), 1, stream))
{
status_line (msgtxt[M_NODELIST_REC_ERR], temp);
fclose (stream);
return (0);
}
fclose (stream);
/*
* Copy data from nodedes into newnodedes.
*/
newnodedes.NodeNumber = TBBS_addr->Node; /* Node Number */
newnodedes.NetNumber = TBBS_addr->Net; /* Net Number */
newnodedes.Cost = nodedes.nodecost; /* Cost */
strncpy (&newnodedes.SystemName[0], &nodedes.nodename[0], 14);
newnodedes.SystemName[19] = '\0'; /* System Name */
strncpy (&newnodedes.PhoneNumber[0], &nodedes.nodephone[0], 40);
newnodedes.PhoneNumber[39] = '\0'; /* Phone Number */
strncpy (&newnodedes.MiscInfo[0], &nodedes.nodecity[0], 30);
newnodedes.MiscInfo[29] = '\0';
newnodedes.Password[0] = '\0'; /* Else set zero length */
newnodedes.RealCost = nodedes.nodecost; /* Cost */
newnodedes.HubNode = nodedes.nodehub; /* Hub */
newnodedes.BaudRate = (char) (nodedes.nodebaud / 300); /* Baud Rate */
newnodedes.ModemType = 0; /* Don't know modem type */
newnodedes.NodeFlags = 0; /* Don't know any flags */
newnodedes.NodeFiller = 0; /* Filler should be zero */
/* Now get information from secondary file */
++recno;
nodeoff = (long) recno *(long) sizeof (ext); /* actual file offset */
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, "NODELIST.EXT"); /* add in the file name */
newnodelist = 0;
if ((stream = fopen (temp, "rb")) == NULL) /* OK, let's open the file */
return (1);
if (fseek (stream, nodeoff, SEEK_SET)) /* try to point at record */
{
fclose (stream);
return (1);
}
if (!fread (&ext, sizeof (ext), 1, stream))
{
fclose (stream);
return (1);
}
fclose (stream);
/*
* Copy data from ext into newnodedes.
*/
strncpy (newnodedes.Password, ext.password, 8); /* Password */
newnodedes.NodeFlags = ext.flags1; /* Nodelist flags */
newnodedes.ModemType = ext.modem; /* Modem type */
newnodelist = 1; /* We have all the information! */
return (1);
}
int TBBSLookup(ADDR *TBBS_addr,int have_boss_data)
{
register struct _ndi far *nodeidx; /* index file */
/* int foundnet = 0; */ /* 'found the net' flag */
int found = 0; /* 'found the node' flag */
int nodeoff = 0; /* offset into nodelist.sys */
char temp[80]; /* where we build filenames */
#ifndef OS_2
int stream;
unsigned int i;
int got;
#else
HFILE stream;
USHORT i;
USHORT got;
#endif
struct stat f;
int current_zone = 0;
newnodedes.NetNumber = newnodedes.NodeNumber = 0;
if (node_index == NULL)
{
temp[0] = '\0'; /* "null-terminated string" */
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, "NODELIST.IDX"); /* add in the file name */
if ((stream = open(temp, O_RDONLY|O_BINARY)) == -1)
{
i = 0; /* Need this later */
if (have_boss_data != 2)
status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
return (0); /* no file, no work to do */
}
fstat (stream, &f); /* get file statistics */
i = (unsigned int) f.st_size; /* size of index file, */
idx_size = i / sizeof (struct _ndi); /* number of index entries */
node_index = get_size (i);
if (node_index == NULL)
{
status_line (msgtxt[M_NODELIST_MEM]);
close (stream);
return (0);
}
if (_dos_read (stream, node_index, i, &got) != 0)
{
status_line (msgtxt[M_NODELIST_READ_ERR]);
close (stream);
return (0);
}
close (stream);
}
nodeidx = (struct _ndi far *) node_index;
if (TBBS_addr->Zone == (unsigned int) -1)
return (TBBS_next_zone());
for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
{
if (nodeidx->node == -2)
current_zone = nodeidx->net;
if (TBBS_addr->Zone > 0 && current_zone != TBBS_addr->Zone)
continue;
if (nodeidx->net == TBBS_addr->Net) /* if a match on net, */
{
/* foundnet = 1; */ /* say we found the net */
if (((TBBS_addr->Node == 0) && (nodeidx->node <= 0))
|| (nodeidx->node == TBBS_addr->Node)) /* see if we found the node */
{
found = 1; /* say we found it */
break; /* get out */
}
}
/*
* This code is good, but many people complained about not being able
* to add nodes to nets by adding them at the end of the nodelist. So,
* I commented this stuff out for now. - Bob
*/
#if 0
else if (foundnet) /* already past the net? */
break;/* Yes, we failed... */
#endif
}
if (!found)
return (0);
found_zone = current_zone; /* Keep track of found zone */
found_net = nodeidx->net; /* Keep track of found net */
i = get_TBBS_info (nodeoff, TBBS_addr);
return (i);
}
static int Quick_Next_Zone(void)
{
register struct QuickNodeIdxRecord far *nodeidx; /* index file */
register unsigned int i;
if (no_zones)
return (-1);
nodeidx = (struct QuickNodeIdxRecord far *) (node_index + (zone_offset *
sizeof (struct QuickNodeIdxRecord)));
for (i = zone_offset; i < idx_size; ++nodeidx, i++)
{
if (nodeidx->QI_Zone != last_zone)
{
last_zone = nodeidx->QI_Zone;
zone_offset = i + 1;
return (last_zone);
}
}
last_zone = -1;
zone_offset = 0;
return (-1);
}
int QuickLookup(ADDR *Quick_addr,int have_boss_data)
{
register struct QuickNodeIdxRecord far *nodeidx; /* index file */
struct QuickNodeListRecord nodedes; /* desc. of node */
int foundnet = 0; /* 'found the net' flag */
int found = 0; /* 'found the node' flag */
int idxrec = 0; /* record in QNL_IDX.BBS */
long nodeoff = 0L; /* offset into QNL_DAT.BBS */
char temp[80]; /* where we build filenames */
#ifndef OS_2
int stream;
unsigned int i;
int got;
#else
HFILE stream;
USHORT i;
USHORT got;
#endif
FILE *stream1;
struct stat f;
newnodedes.NetNumber = newnodedes.NodeNumber = 0;
if (node_index == NULL)
{
index_filesize == (off_t) 0L; /* Cover ourselves for error */
index_filename[0] = '\0'; /* "null-terminated string" */
strcpy (index_filename, net_info); /* take nodelist path */
strcat (index_filename, "QNL_IDX.BBS"); /* add in the file name */
if ((stream = open(index_filename, O_RDONLY|O_BINARY)) == -1)
{
if (have_boss_data != 2)
status_line (msgtxt[M_UNABLE_TO_OPEN], index_filename);
return (0); /* no file, no work to do */
}
fstat (stream, &f); /* get file statistics */
i = (unsigned int) f.st_size; /* size of index file, */
idx_size = i / sizeof (*nodeidx); /* number of index entries */
node_index = get_size (i);
if (node_index == NULL)
{
status_line (msgtxt[M_NODELIST_MEM]);
close (stream);
return (0);
}
if (_dos_read (stream, node_index, i, &got) != 0)
{
status_line (msgtxt[M_NODELIST_READ_ERR]);
close (stream);
return (0);
}
close (stream);
index_filesize = f.st_size; /* Save parameters for later */
index_filetime = f.st_mtime;
}
nodeidx = (struct QuickNodeIdxRecord far *) node_index;
if (Quick_addr->Zone == (unsigned int) -1)
{
return (Quick_Next_Zone ());
}
else if (no_zones)
Quick_addr->Zone = 0;
for (i = 1; i <= idx_size; idxrec++, nodeidx++, i++)
{
if (((Quick_addr->Zone == nodeidx->QI_Zone) || (Quick_addr->Zone == 0))
&& (Quick_addr->Net == nodeidx->QI_Net))
{
foundnet = 1; /* say we found the net */
if (((Quick_addr->Node == 0) && (nodeidx->QI_Node <= 0))
|| (nodeidx->QI_Node == Quick_addr->Node)) /* see if we found the node */
{
found = 1; /* say we found it */
break; /* get out */
}
}
else if (foundnet) /* already past the net? */
break; /* Yes, we failed... */
}
if (!found)
return (0);
nodeoff = (long) idxrec *(long) sizeof (nodedes); /* actual file offset */
strcpy (temp, net_info); /* take nodelist path */
strcat (temp, "QNL_DAT.BBS"); /* add in the file name */
if ((stream1 = fopen (temp, "rb")) == NULL) /* OK, let's open the file */
{
status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
return (0);
}
if (fseek (stream1, nodeoff, SEEK_SET)) /* try to point at record */
{
status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
fclose (stream1);
return (0);
}
if (!fread (&nodedes, sizeof (nodedes), 1, stream1))
{
status_line (msgtxt[M_NODELIST_REC_ERR], temp);
fclose (stream1);
return (0);
}
fclose (stream1);
/*
* Copy data from nodedes into newnodedes.
*/
newnodedes.NodeNumber = nodedes.QL_Node; /* Node Number */
newnodedes.NetNumber = nodedes.QL_Net; /* Net Number */
newnodedes.Cost = nodedes.QL_Cost; /* Cost */
i = min (nodedes.QL_Name[0], 19);
strncpy (&newnodedes.SystemName[0], &nodedes.QL_Name[1], i);
newnodedes.SystemName[i] = '\0'; /* System Name */
i = min (nodedes.QL_Phone[0], 39);
strncpy (&newnodedes.PhoneNumber[0], &nodedes.QL_Phone[1], i);
newnodedes.PhoneNumber[i] = '\0'; /* Phone Number */
i = min (nodedes.QL_City[0], 29);
strncpy (&newnodedes.MiscInfo[0], &nodedes.QL_City[1], i);
newnodedes.MiscInfo[i] = '\0';
/* This field is not necessarily null terminated */
i = min (nodedes.QL_Password[0], 8);
strncpy (&newnodedes.Password[0], &nodedes.QL_Password[1], i);
if (i < 8)
newnodedes.Password[i] = '\0';
/* Adam Hudson now gives us this, so we might as well use it */
newnodedes.NodeFlags = nodedes.QL_Flags;
/* Since we have the stuff we need! */
newnodelist = 1; /* We have all the information! */
newnodedes.RealCost = nodedes.QL_Cost; /* Cost */
newnodedes.HubNode = 0; /* Don't know who is Hub */
newnodedes.BaudRate = (char) (nodedes.QL_BaudRate / 300); /* Baud */
newnodedes.ModemType = 0; /* Don't know modem type */
newnodedes.NodeFiller = 0; /* Filler should be zero */
found_zone = nodeidx -> QI_Zone; /* Keep track of found zone */
found_net = nodeidx -> QI_Net; /* And of found net */
return (1);
}