home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_mail
/
bsrc_250.arj
/
VERSION7.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
16KB
|
477 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/* */
/* */
/* This module was adapted by Bill Andrus */
/* With the usual kibitzing by Vince Perriello */
/* */
/* BinkleyTerm Version7 Nodelist processing module */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.250. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:491/0 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
/* This table has been modified to minimize searches */
char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";
long btree (char *, void *, int (*)(void *, void *, int));
int get_ver7_info (unsigned long, ADDRP);
struct _ndx far *get7node(HFILE, unsigned long, struct _ndx far *);
void unpk(char *instr,char *outp,int many);
int addr_compare (void *, void *, int);
int name_compare (void *, void *, int);
extern void get_nodelist_name (ADDRP);
extern char *nodelist_base;
extern char *nodelist_name;
static char index_filename[260];
static int namelen;
static struct _ndx far *nodeidx = NULL; /* index file */
static struct _ndx far *noderef = NULL; /* index file */
int ver7find (ADDRP opus_addr, int have_boss_data)
{
long record;
ADDR found_addr;
have_boss_data = have_boss_data;
newnodedes.NetNumber = newnodedes.NodeNumber = 0;
get_nodelist_name (opus_addr); /* fill in nodelist.base */
index_filename[0] = '\0'; /* "null-terminated string*/
(void) strcpy (index_filename, net_info); /* take nodelist path */
(void) strcat (index_filename, nodelist_base); /* add in the file name*/
(void) strcat (index_filename, ".NDX"); /* add in the file ext */
record = btree (index_filename, (void *)opus_addr, addr_compare);
if (record == -1)
return (0);
else
return (get_ver7_info((unsigned long)record, &found_addr));
}
int addr_compare (void *key, void *desired, int len)
{
int k;
k = ((ADDRP)key)->Zone - ((ADDRP)desired)->Zone;
if (k)
return (k);
k = ((ADDRP)key)->Net - ((ADDRP)desired)->Net;
if (k)
return (k);
k = ((ADDRP)key)->Node - ((ADDRP)desired)->Node;
if (k)
return (k);
/*
* Node matches.
*
* The rule for points:
* 1) If len == 6, treat key value for Point as Zero.
* 2) Return comparison of key Point and desired Point.
*/
if (len == 6)
((ADDRP)key)->Point = 0;
return ((ADDRP)key)->Point - ((ADDRP)desired)->Point;
}
void opususer (char *name, ADDRP faddr)
{
char last_name_first[80];
char midname[80];
char *c, *p, *m;
long record;
faddr->Zone = faddr->Net = faddr->Node = faddr->Point = (unsigned int) -1;
faddr->Domain = NULL;
c = midname; /* Start of temp name buff */
p = name; /* Point to start of name */
m = NULL; /* Init pointer to space */
*c = *p++;
while (*c) /* Go entire length of name */
{
if (*c == ' ') /* Look for space */
m = c; /* Save location */
c++;
*c = *p++;
}
if (m != NULL) /* If we have a pointer, */
{
*m++ = '\0'; /* Terminate the first half */
(void) strcpy (last_name_first, m); /* Now copy the last name */
(void) strcat (last_name_first, ", "); /* Insert a comma and space */
(void) strcat (last_name_first, midname); /* Finally copy first half */
}
else (void) strcpy (last_name_first, midname);/* Use whole name otherwise */
(void) fancy_str (last_name_first); /* Get caps in where needed */
namelen = (int) strlen (last_name_first); /* Calc length now */
index_filename[0] = '\0'; /* "null-terminated string" */
if (nodelist_base == NULL)
get_nodelist_name (&my_addr); /* fill in nodelist.base */
(void) strcpy (index_filename, net_info); /* take nodelist path */
(void) strcat (index_filename, "SYSOP.NDX"); /* add in the file name */
record = btree (index_filename, (void *)last_name_first, name_compare);
if (record == -1)
return;
(void) get_ver7_info((unsigned long)record, faddr);
}
int name_compare (void *key, void *desired, int len)
{
return (strnicmp ((char *)key, (char *)desired, (unsigned int) min (namelen,len)));
}
/*
* General V7 nodelist engine. Used by both the by-node and by-sysop
* lookups.
*
* Thanks to Phil Becker for showing me how nice it looks in assembler.
* It helped me see how nice it could be in C.
*
* (I know, Phil, it's still nicer in assembler!)
*
*/
long btree (char *filename, void *desired, int (*compare)(void *key, void *desired, int len))
{
int j, k, l;
struct _IndxRef far *ip = NULL;
struct _LeafRef far *lp = NULL;
char aline[160];
char far *tp;
char *np;
long record, foundrec = -1L;
int count;
HFILE stream;
if ((stream = share_open(filename, O_RDONLY|O_BINARY, DENY_WRITE)) == -1)
return (-1L); /* no file, no work to do */
if (node_index == NULL)
node_index = _fmalloc ( sizeof (struct _ndx));
if (nodeidx == NULL)
nodeidx = _fmalloc ( sizeof (struct _ndx));
if (noderef == NULL)
noderef = _fmalloc ( sizeof (struct _ndx));
if (node_index == NULL)
{
status_line (msgtxt[M_NODELIST_MEM]);
(void) close (stream);
return (-1L);
}
/* Get CtlRec */
if (get7node (stream, 0L, noderef) != noderef)
{
close (stream);
return (-1L);
}
/* The guts of the matter -- walk from CtlRec to Leaf */
record = noderef->ndx.CtlBlk.CtlRoot;
/*
* Read the first Index node.
*/
if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
{
close (stream);
return (-1L);
}
/*
* Follow the node tree until we either match a key right in the index
* node, or locate the leaf node which must contain the entry.
*/
while (nodeidx->ndx.INodeBlk.IndxFirst != -1)
{
if ((count = nodeidx->ndx.INodeBlk.IndxCnt) == 0)
{
close (stream);
return (-1L);
}
for (j = 0; j < count; j++) /* check 20 or less */
{
ip = &(nodeidx->ndx.INodeBlk.IndxRef[j]);
tp = (char far *) nodeidx + ip->IndxOfs;
k = l = ip->IndxLen;
for (np = aline; k > 0; k--)
*np++ = *tp++;
k = (*compare) ((void *)aline, desired, l);
if (k > 0)
break;
if (k == 0)
{
/* Key matches in the index node. Since we're just doing lookup, we
* can assume its pointer is valid. If we were doing updates, that
* assumption would not work, because leaf nodes update first. So in
* an update environment, the entire code segment relating to k == 0
* should not execute, and we should walk the tree all the way down.
*/
close (stream);
return (nodeidx->ndx.INodeBlk.IndxRef[j].IndxData);
}
}
if (j == 0)
record = nodeidx->ndx.INodeBlk.IndxFirst;
else
record = (nodeidx->ndx.INodeBlk.IndxRef[--j]).IndxPtr;
if (get7node(stream, (unsigned long) (record * noderef->ndx.CtlBlk.CtlBlkSize), nodeidx) != nodeidx)
{
close (stream);
return (-1L);
}
}
/*
* We can only get here if we've found the leafnode which must
* contain our entry.
*
* Find our guy here or die trying.
*/
if ((count = nodeidx->ndx.LNodeBlk.IndxCnt) != 0)
{
/* Search for a higher key */
for (j = 0; j < count; j++) /* check 30 or less */
{
lp = &(nodeidx->ndx.LNodeBlk.LeafRef[j]);
tp = (char far *) nodeidx + lp->KeyOfs;
k = l = lp->KeyLen;
for (np = aline; k > 0; k--)
*np++ = *tp++;
k = (*compare) ((void *)aline, desired, l);
if (k > 0)
break;
if (k == 0)
{
foundrec = (nodeidx->ndx.LNodeBlk.LeafRef[j]).KeyVal;
break;
}
}
}
(void) close (stream);
return (foundrec);
}
int get_ver7_info (unsigned long pos, ADDRP faddr)
{
struct _vers7 vers7;
char my_phone[40];
char my_pwd[9];
char aline[160];
char aline2[160];
char *fst;
char temp[80]; /* we build filenames here*/
FILE *stream;
(void) strcpy (temp, net_info); /* take nodelist path */
(void) strcat (temp, nodelist_base); /* add in the filename*/
(void) strcat (temp, ".DAT"); /* then the extension */
if ((stream = share_fopen (temp, "rb", DENY_WRITE)) == NULL) /* open it*/
{
status_line (msgtxt[M_UNABLE_TO_OPEN], temp);
return (0);
}
if (fseek (stream,(long int) pos, SEEK_SET)) /* point at record */
{
status_line (msgtxt[M_NODELIST_SEEK_ERR], temp);
(void) fclose (stream);
return (0);
}
if (!fread ((char *)&vers7, sizeof (struct _vers7), 1, stream))
{
status_line (msgtxt[M_NODELIST_REC_ERR], temp);
(void) fclose (stream);
return (0);
}
(void) memset(my_phone,'\0',40);
(void) fread (my_phone, vers7.Phone_len, 1, stream);
(void) memset(my_pwd,'\0',9);
(void) fread (my_pwd, vers7.Password_len, 1, stream);
(void) memset(aline,'\0',160);
(void) memset(aline2,'\0',160);
if (!fread (aline2, vers7.pack_len, 1, stream))
{
status_line (msgtxt[M_NODELIST_REC_ERR], temp);
(void) fclose (stream);
return (0);
}
(void) fclose (stream);
unpk(aline2,aline,vers7.pack_len);
(void) memset (&newnodedes, 0, sizeof (struct _newnode));
newnodedes.NetNumber = vers7.Net;
newnodedes.NodeNumber = vers7.Node;
newnodedes.Cost = newnodedes.RealCost = vers7.CallCost;
(void) memcpy (newnodedes.SystemName, aline, min(33, vers7.Bname_len));
newnodedes.SystemName[min(33, vers7.Bname_len)] = '\0';
(void) fancy_str (newnodedes.SystemName);
#ifdef MILQ
fst = &aline[0] + vers7.Bname_len;
(void) memcpy (crnt_sysop, fst, min(25,vers7.Sname_len));
crnt_sysop[min(25,vers7.Sname_len)] = '\0';
(void)fancy_str( crnt_sysop );
#endif
fst = &aline[0] + vers7.Bname_len + vers7.Sname_len;
(void) memcpy (newnodedes.PhoneNumber, my_phone, min(39,vers7.Phone_len));
newnodedes.PhoneNumber[min(39,vers7.Phone_len)] = '\0';
(void) memcpy (newnodedes.MiscInfo, fst, min(29, vers7.Cname_len));
newnodedes.MiscInfo[min(29, vers7.Cname_len)] = '\0';
(void) fancy_str( newnodedes.MiscInfo );
(void) memcpy (newnodedes.Password, my_pwd, min(8, vers7.Password_len));
newnodedes.HubNode = vers7.HubNode;
newnodedes.BaudRate = vers7.BaudRate;
newnodedes.ModemType = vers7.ModemType;
newnodedes.NodeFlags = vers7.NodeFlags;
found_zone = faddr->Zone = vers7.Zone;
found_net = faddr->Net = vers7.Net;
faddr->Node = vers7.Node;
if (vers7.NodeFlags & B_point)
faddr->Point = vers7.HubNode;
else faddr->Point = 0;
faddr->Domain = NULL;
return (1);
}
struct _ndx far *get7node(HFILE stream, unsigned long pos, struct _ndx far *ndx)
{
#ifdef C386
unsigned long got;
#else
USHORT got;
#endif
(void) lseek (stream, (long) pos, SEEK_SET);
if (_dos_read (stream, ndx,(unsigned int) sizeof (struct _ndx), &got) != 0)
{
status_line (msgtxt[M_NODELIST_READ_ERR]);
(void) close (stream);
return (NULL);
}
return (ndx);
}
/* ====================================================================
* unpack a dense version of a symbol (base 40 polynomial)
* ====================================================================
*/
void unpk(char *instr,char *outp,int count)
{
struct chars {
unsigned char c1;
unsigned char c2;
};
union {
unsigned w1;
struct chars d;
} u;
register int i, j;
char obuf[4];
outp[0] = '\0';
while (count) {
u.d.c1 = *instr++;
u.d.c2 = *instr++;
count -= 2;
for(j=2;j>=0;j--) {
i = u.w1 % 40;
u.w1 /= 40;
obuf[j] = unwrk[i];
}
obuf[3] = '\0';
(void) strcat (outp, obuf);
}
}