home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
bos2_xr5.zip
/
developr
/
v7plus
/
version7.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-09
|
28KB
|
932 lines
//--------------------------------------------------------------------------//
// //
// //
// ------------ Bit-Bucket Software, Co. //
// \ 10001101 / Writers and Distributors of //
// \ 011110 / Freely Available<tm> Software. //
// \ 1011 / //
// ------ //
// //
// (C) Copyright 1987-96, Bit Bucket Software Co. //
// //
// This module was adapted by Bill Andrus //
// With the usual kibitzing by Vince Perriello //
// BinkleyTerm Version7 Nodelist processing module //
// //
// V7 reimplementation and V7+ support by Thomas Waldmann //
// Attention: V7+ works, but is far from being completed. //
// //
// 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.260. //
// //
// 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:42/1491 //
// 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"
static int LOCALFUNC btree (PV7RCB);
static int LOCALFUNC _btree (PV7RCB, long);
static int LOCALFUNC get7node (PV7RCB, long, struct _ndx far *);
static int LOCALFUNC unpk (char *instr, char *outp, int many);
static int LOCALFUNC addr_compare (void *, void *, int);
static int LOCALFUNC name_compare (void *, void *, int);
static void LOCALFUNC set_vars(PV7NODE, ADDRP);
extern int get_nodelist_name (ADDRP);
extern char *nodelist_base;
extern char *nodelist_name;
// r. hoerner: added "far" statement 1/3/97
static struct _ndx far *noderef = NULL; // far pointer index file
static char aline[160];
static FILE *idx_fp, *dat_fp, *dtp_fp;
static int find_first; // is this findfirst or findnext ?
static ADDR searchaddr;
static char searchname[40];
static void *desired;
static int desired_len;
static int (LOCALFUNC * compare_fn) (void *key, void *desired, int len);
static PV7NODEL beginp, lastp, actp;
static DTPHEADER dtphdr;
// call this function before you use any other V7* function!
int V7Initialize(void){
if (node_index == NULL)
node_index = _fmalloc (sizeof (struct _ndx));
if (!node_index)
{
status_line (MSG_TXT(M_NODELIST_MEM));
return V7_OUT_OF_MEMORY;
}
if (noderef == NULL)
noderef = _fmalloc (sizeof (struct _ndx));
if (!noderef)
{
status_line (MSG_TXT(M_NODELIST_MEM));
return V7_OUT_OF_MEMORY;
}
return V7_SUCCESS;
}
// call this function when you're finished with V7* functions
int V7Finish(void){
if (node_index)
_ffree (node_index);
node_index = NULL;
if (noderef)
_ffree (noderef);
noderef = NULL;
return V7_SUCCESS;
}
// builds names of V7 / V7+ files
void V7buildnames(PV7RCB p, char *IndexName, char *DataName, char *DTPName){
char *fmt="%s%s.%s";
sprintf(DataName,fmt,p->pszPath,p->pszName,"DAT");
if((p->miscflags&MF_v7plus)>0)
sprintf(DTPName, fmt,p->pszPath,p->pszName,"DTP");
switch(p->whichindex){
case WI_ndx:
sprintf(IndexName,fmt,p->pszPath,p->pszName,"NDX");
break;
case WI_sdx:
if(p->miscflags & MF_sysopndx)
sprintf(IndexName,fmt,p->pszPath,"SYSOP","NDX");
else
sprintf(IndexName,fmt,p->pszPath,p->pszName,"SDX");
break;
case WI_pdx:
sprintf(IndexName,fmt,p->pszPath,p->pszName,"PDX");
break;
}
}
// find all matching V7 entries and return first of them
int V7FindFirst(PV7RCB p){
char IndexName[PATHLEN], DataName[PATHLEN], DTPName[PATHLEN];
char last_name_first[26], midname[26], *c, *p2, *m;
int namelen;
V7buildnames(p,IndexName,DataName,DTPName);
if ((idx_fp = share_fopen (IndexName, read_binary, DENY_WRITE)) == NULL){
status_line (MSG_TXT(M_UNABLE_TO_OPEN), IndexName);
return (V7_IDX_OPENFAILED); // no file, no work to do
}
if ((dat_fp = share_fopen (DataName, read_binary, DENY_WRITE)) == NULL){
status_line (MSG_TXT(M_UNABLE_TO_OPEN), DataName);
return (V7_DAT_OPENFAILED); // no file, no work to do
}
if((p->miscflags&MF_v7plus)>0){
if ((dtp_fp = share_fopen (DTPName, read_binary, DENY_WRITE)) == NULL){
status_line (MSG_TXT(M_UNABLE_TO_OPEN), DTPName);
return (V7_DTP_OPENFAILED); // no file, no work to do
}
if(fread(&dtphdr,sizeof(dtphdr),1,dtp_fp)<1)
return V7_DTP_READERROR;
}
switch(p->whichindex){
case WI_ndx:
searchaddr.Zone = p->pV7Node->ZoneNumber;
searchaddr.Net = p->pV7Node->NetNumber;
searchaddr.Node = p->pV7Node->NodeNumber;
searchaddr.Point = p->pV7Node->HubNode;
compare_fn = addr_compare;
desired = &searchaddr;
desired_len = p->wLen;
break;
case WI_sdx:
c = midname; // Start of temp name buff
p2 = p->pV7Node->SysopName; // Point to start of name
m = NULL; // Init pointer to space
*c = *p2++;
while (*c) // Go entire length of name
{
if (*c == ' ') // Look for space
m = c; // Save location
c++;
*c = *p2++;
}
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
namelen = min(25,namelen);
strncpy(searchname, last_name_first, namelen);
searchname[namelen]='\0';
compare_fn = name_compare;
desired = &searchname;
desired_len = namelen;
break;
case WI_pdx:
// not implemented yet!
break;
}
find_first = 1;
return V7FindNext(p);
}
// return next match
int V7FindNext(PV7RCB p){
int ret;
PV7NODEL p1,p2;
if(find_first){
beginp = lastp = actp = NULL;
if(btree(p)!=0)
return V7_FINDNEXT_END;
}
if(find_first)
actp = beginp;
else
actp = actp->next;
if(actp==NULL){ // if this is the end, free memory
for(p1=beginp;p1;p1=p2){
p2=p1->next;
free(p1);
}
beginp=NULL;
ret = V7_FINDNEXT_END;
}else{
ret = V7_SUCCESS;
*(p->pV7Node) = actp->v7n;
}
find_first = 0;
return ret;
}
// call this after findnext returns V7_FINDNEXT_END
int V7FindClose(PV7RCB p){
PV7NODEL p1,p2;
p=p; // Make compiler happy
if(beginp){
for(p1=beginp;p1;p1=p2){
p2=p1->next;
free(p1);
}
}
beginp=NULL;
if(idx_fp){
fclose (idx_fp);
idx_fp = NULL;
}
if(dat_fp){
fclose (dat_fp);
dat_fp = NULL;
}
if((p->miscflags&MF_v7plus)>0){
if (dtp_fp){
fclose (dtp_fp);
dtp_fp = NULL;
}
}
return V7_SUCCESS;
}
// find a single match in V7
int V7Find(PV7RCB p){
int ret;
(void) V7Initialize();
ret=V7FindFirst(p);
(void) V7FindClose(p);
// (void) V7Finish(); // don't call this and avoid many malloc/free calls
return ret;
}
// conversion char -> minute of day (time is UTC!), see FSC-0062
short minute_of_day(char c)
{
char upper_c;
short hour, minutes;
upper_c=toupper(c);
if(upper_c>'X')
return -1; // invalid !
hour = upper_c - 'A'; // 00 .. 23
minutes = hour * 60;
if(islower(c)) // uppercase -> time=hh:00, lowercase -> time=hh:30
minutes += 30;
return minutes;
}
// process raw nodelist flags
static int LOCALFUNC
process_flag(V7NODE *pv7, char *rawflag)
{
static short userflag;
char *p=rawflag;
if(!p) // init call
userflag=0;
else
{
if(toupper(*p)=='U'){ // from now on: user flags!
userflag=1;
p++;
}
if(*p) // anything left (after ",U") ?
{
// ,Txy online time flag as in FSC-0062 v3 !?
if(userflag && !(pv7->NodeFlags&B_CM) && toupper(*p)=='T')
{
short start, end;
// status_line(" Online flags: %s", p+1);
if ((start=minute_of_day (*++p))<0 || (end=minute_of_day (*++p))<0)
status_line(MSG_TXT (M_V7P_INVALID_TXY), rawflag);
else{
pv7->online_start = start;
pv7->online_end = end;
}
}
}
}
return 0;
}
// parse / process raw nodelist line
static int LOCALFUNC
process_raw(V7NODE *pv7, char *raw)
{
int field=0;
char *p;
process_flag(pv7, NULL); // init flag function
if(*raw==','){
field++; // first field is empty, but counts!
raw++;
}
pv7->rawFlags[0]='\0';
for(p=strtok(raw,","); p; field++, p=strtok(NULL,","))
{
switch(field)
{
case 0: // Node, Hub, Host, Region, Zone
strcpy(pv7->rawType,p);
break;
case 1: // Zone/Net/Node/Point number
break; // nothing to do with that yet!
case 2: // System name
strcpy(pv7->rawSystemName,p);
break;
case 3: // Location / City
strcpy(pv7->rawMiscInfo,p);
break;
case 4: // Sysop
strcpy(pv7->rawSysopName,p);
break;
case 5: // Phone
case 6: // Baud
break; // nothing to do with that yet!
default: // >=7: flags: CM,XA,...
if(field>7)
strcat(pv7->rawFlags,",");
strcat(pv7->rawFlags,p);
process_flag(pv7, p);
break;
}
}
return 0;
}
// V7 dat lookup at datpos
static int LOCALFUNC
foundmatch(PV7RCB prcb, long datpos)
{
struct _vers7 vers7;
char a_line[400], a_line2[256];
char *cp,*cp2;
long dtpoffset;
int i,unpack_len;
unsigned short fieldlen;
char fieldbuf[1024];
PV7NODEL p;
if((p = (PV7NODEL) calloc(1, sizeof(V7NODEL)))==NULL)
return 1;
strcpy(lastfound_SysopName,"(unknown)");
if(beginp==NULL)
beginp=p;
else
lastp->next=p;
lastp=p;
lastp->next=NULL;
if (fseek (dat_fp, datpos, SEEK_SET)){ // point at record
status_line (MSG_TXT(M_NODELIST_SEEK_ERR), prcb->pszName, "dat");
return 1;
}
if (fread ((char *) &vers7, sizeof (struct _vers7), 1, dat_fp)!=1){
status_line (MSG_TXT(M_NODELIST_READ_ERR), prcb->pszName, "dat");
return 1;
}
p->v7n.ulOffset = datpos;
p->v7n.ZoneNumber = vers7.Zone;
p->v7n.NetNumber = vers7.Net;
p->v7n.NodeNumber = vers7.Node;
p->v7n.HubNode = vers7.HubNode;
p->v7n.BaudRate = 300*vers7.BaudRate;
p->v7n.ModemType = vers7.ModemType;
p->v7n.NodeFlags = vers7.NodeFlags;
p->v7n.RealCost = vers7.CallCost;
p->v7n.Cost = vers7.CallCost; // ?????
(void) fread (p->v7n.PhoneNumber, vers7.Phone_len, 1, dat_fp);
(void) fread (p->v7n.Password, vers7.Password_len, 1, dat_fp);
(void) memset (a_line, '\0', 400);
(void) memset (a_line2, '\0', 256);
if (fread (a_line2, vers7.pack_len, 1, dat_fp)!=1){
status_line (MSG_TXT(M_NODELIST_READ_ERR), prcb->pszName, "dat");
return 1;
}
unpack_len = unpk (a_line2, a_line, vers7.pack_len);
cp = &a_line[0];
// BBS / system name
i = vers7.Bname_len;
(void) memcpy (p->v7n.SystemName, cp, min (33, i));
cp += i;
unpack_len -= i;
// Sysop name
i = vers7.Sname_len;
(void) memcpy (p->v7n.SysopName, cp, min (25, i));
cp += i;
unpack_len -= i;
// City name
i = vers7.Cname_len;
(void) memcpy (p->v7n.MiscInfo, cp, min (29, i));
cp += i;
unpack_len -= i;
// TJW 970409 V7+ extensions
// check if there are 8 hex characters left == V7+ DTP offset
for(cp2=cp,i=0;*cp2 && i<8 && i<unpack_len;cp2++, i++)
{
if(!isxdigit(*cp2))
break;
}
if((prcb->miscflags&MF_v7plus)>0){ // v7+ enabled and
if(i==8){ // v7+ DTP offs detected
// status_line(" V7+ extension detected. Processing fields ...");
sscanf(cp, "%8lx", &dtpoffset);
// status_line(" V7+ DTP offset-value: '%lx'", dtpoffset);
if (fseek (dtp_fp, dtpoffset, SEEK_SET)){
status_line (MSG_TXT(M_NODELIST_SEEK_ERR), prcb->pszName, "dtp");
return 1;
}
// skip DTPALLLNK structure (not used yet)
// skip DTPNODELNK structure, nodes only (not used yet)
if(vers7.NodeFlags&B_point)
fseek(dtp_fp, (long) dtphdr.control.AllFixSize, SEEK_CUR);
else
fseek(dtp_fp, (long) dtphdr.control.AllFixSize
+ (long) dtphdr.control.AddFixSize, SEEK_CUR);
fieldlen=0xFFFFU;
if (fread ((char *) &fieldlen, sizeof (fieldlen), 1, dtp_fp)!=1){
status_line (MSG_TXT(M_NODELIST_READ_ERR), prcb->pszName, "dtp");
return 1;
}
if(fieldlen!=0xFFFFU){
// status_line (" V7+ Field %d, len=%d", field, (int) fieldlen);
if (fread ((char *) &fieldbuf, (size_t) fieldlen, 1, dtp_fp)!=1){
status_line (MSG_TXT(M_NODELIST_READ_ERR), prcb->pszName, "dtp");
return 1;
}
// status_line (" V7+ Field %d: %s", field, fieldbuf);
process_raw(&(p->v7n), fieldbuf);
}
}else{
status_line ("!Version7 Plus enabled, but not detected in this record");
p->v7n.rawType[0]='\0';
p->v7n.rawFlags[0]='\0';
strcpy(p->v7n.rawSystemName,p->v7n.SystemName);
strcpy(p->v7n.rawMiscInfo,p->v7n.MiscInfo);
strcpy(p->v7n.rawSysopName,p->v7n.SysopName);
}
}else{ // V7+ not enabled, use V7 stuff
p->v7n.rawType[0]='\0';
p->v7n.rawFlags[0]='\0';
strcpy(p->v7n.rawSystemName,p->v7n.SystemName);
strcpy(p->v7n.rawMiscInfo,p->v7n.MiscInfo);
strcpy(p->v7n.rawSysopName,p->v7n.SysopName);
}
return 0;
}
// compare function for name lookup
static int LOCALFUNC
name_compare (void *key, void *desired, int _len)
{
return (strnicmp ((char *) key, (char *) desired, (unsigned int) min (desired_len, _len)));
}
// compare function for address lookup
static int LOCALFUNC
addr_compare (void *key, void *desired, int _len)
{
int k, len = desired_len;
if(len>=2){
k = ((ADDRP) key)->Zone - ((ADDRP) desired)->Zone;
if (k)
return (k);
}else return 0;
if(len>=4){
k = ((ADDRP) key)->Net - ((ADDRP) desired)->Net;
if (k)
return (k);
}else return 0;
if(len>=6){
k = ((ADDRP) key)->Node - ((ADDRP) desired)->Node;
if (k)
return (k);
}else return 0;
// 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) // spezial treatment for key point
((ADDRP) key)->Point = 0;
if(len>=8){
k = ((ADDRP) key)->Point - ((ADDRP) desired)->Point;
if (k)
return (k);
}
return 0;
}
// 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!)
static int LOCALFUNC
btree (PV7RCB prcb)
{
if (!get7node(prcb, 0L, noderef)) // Get CtlRec
return 1;
return _btree(prcb, noderef->ndx.CtlBlk.CtlRoot); // start recursion
}
static int LOCALFUNC
_btree (PV7RCB prcb, long record)
{
struct _ndx nodeidx;
int j, j_done=-1, k=0, l, ret=0, count;
struct _IndxRef far *ip = NULL;
struct _LeafRef far *lp = NULL;
char far *tp;
char *np;
if (!get7node (prcb, record * noderef->ndx.CtlBlk.CtlBlkSize,&nodeidx))
return 1;
// 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.
if (nodeidx.ndx.INodeBlk.IndxFirst != -1) // INodeBlk
{
count = nodeidx.ndx.INodeBlk.IndxCnt; // count may be 0
if (count == 0){
// status_line(">Down 1");
ret=_btree(prcb, nodeidx.ndx.INodeBlk.IndxFirst);
// status_line(">Up 1");
}else{
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; // binary length in bytes
// addresses are stored as ADDR structs
// names are stored as "2ndName, 1stName"
for (np = aline; k > 0; k--)
*np++ = *tp++;
k = (*compare_fn) ((void *) aline, desired, l); // k=key-desired
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.
if(j == 0){
// status_line(">Down 2");
ret=ret+_btree(prcb, nodeidx.ndx.INodeBlk.IndxFirst);
// status_line(">Up 2");
}else if(j-1!=j_done){
// status_line(">Down 3");
ret=ret+_btree(prcb, nodeidx.ndx.INodeBlk.IndxRef[j-1].IndxPtr);
// status_line(">Up 3");
}
// foundmatch (nodeidx.ndx.INodeBlk.IndxRef[j].IndxData);
// status_line(">Down 4");
ret=ret+_btree(prcb, nodeidx.ndx.INodeBlk.IndxRef[j].IndxPtr);
// status_line(">Up 4");
j_done = j;
}
}
if (k != 0){
if(j == 0){
// status_line(">Down 5");
ret=ret+_btree(prcb, nodeidx.ndx.INodeBlk.IndxFirst);
// status_line(">Up 5");
}else if(j-1 != j_done){
// status_line(">Down 6");
ret=ret+_btree(prcb, nodeidx.ndx.INodeBlk.IndxRef[j-1].IndxPtr);
// status_line(">Up 6");
}
}
}
}else{ // LNodeBlk
count = nodeidx.ndx.LNodeBlk.IndxCnt; // count may be 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_fn) ((void *) aline, desired, l);
if (k > 0)
break;
else
if (k == 0)
ret=ret+foundmatch (prcb, nodeidx.ndx.LNodeBlk.LeafRef[j].KeyVal);
}
}
return ret;
}
// read index entry
static int LOCALFUNC
get7node (PV7RCB prcb, long position, struct _ndx far * ndx)
{
if(fseek (idx_fp, position, SEEK_SET))
{
status_line (MSG_TXT(M_NODELIST_SEEK_ERR), prcb->pszName, "?dx");
return (0);
}
if (fread (ndx, sizeof (struct _ndx), 1, idx_fp) != 1)
{
status_line (MSG_TXT(M_NODELIST_READ_ERR), prcb->pszName, "?dx");
return (0);
}
return (1);
}
// unpack a dense version of a symbol (base 40 polynomial)
static int LOCALFUNC
unpk (char *instr, char *outp, int count)
{
// This table has been modified to minimize searches
static char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";
struct chars
{
unsigned char c1;
unsigned char c2;
};
union
{
unsigned short w1;
struct chars d;
} u;
register short i, j; // MB int
char obuf[4];
int outlen;
outp[0] = '\0';
outlen = 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);
outlen += 3;
}
return outlen;
}
// these are for Binkley's use:
// address lookup
int
ver7find (ADDRP opus_addr, int have_boss_data)
{
ADDR faddr;
V7RCB v7rcb;
V7NODE v7n;
strcpy(lastfound_SysopName,"(unknown)");
have_boss_data = have_boss_data; // make compiler happy
(void) memset (&newnodedes, 0, sizeof (struct _newnode));
memset (&v7rcb, 0, sizeof(v7rcb));
memset (&v7n, 0, sizeof(v7n));
v7rcb.pV7Node = &v7n;
if (!get_nodelist_name (opus_addr))
return 0;
v7rcb.pszPath = (PSZ)net_info;
v7rcb.pszName = (PSZ)nodelist_base;
v7rcb.whichindex = WI_ndx;
v7rcb.miscflags |= (version7>1) ? 1:0;
v7rcb.miscflags |= (sysopndx) ? MF_sysopndx:0;
v7n.ZoneNumber = opus_addr->Zone;
v7n.NetNumber = opus_addr->Net;
v7n.NodeNumber = opus_addr->Node;
v7n.HubNode = opus_addr->Point;
v7rcb.wLen = 8;
if(V7Find(&v7rcb)==V7_SUCCESS){
set_vars(&v7n, &faddr);
return 1;
}else
return 0;
}
// name lookup
void
opususer (char *name, ADDRP faddr)
{
V7RCB v7rcb;
V7NODE v7n;
int namelen;
strcpy(lastfound_SysopName,"(unknown)");
faddr->Zone = faddr->Net = faddr->Node = faddr->Point = (unsigned short) -1;
faddr->Domain = NULL;
(void) memset (&newnodedes, 0, sizeof (struct _newnode));
memset (&v7rcb, 0, sizeof(v7rcb));
memset (&v7n, 0, sizeof(v7n));
v7rcb.pV7Node = &v7n;
if (nodelist_base == NULL)
get_nodelist_name (&my_addr);
v7rcb.pszPath = (PSZ)net_info;
v7rcb.pszName = (PSZ)nodelist_base;
v7rcb.whichindex = WI_sdx;
v7rcb.miscflags |= (version7>1) ? 1:0;
v7rcb.miscflags |= (sysopndx) ? MF_sysopndx:0;
namelen = min(25,strlen(name));
strncpy(v7n.SysopName, name, namelen);
v7n.SysopName[namelen]='\0';
v7rcb.wLen = namelen;
if(V7Find(&v7rcb)==V7_SUCCESS){
set_vars(&v7n, faddr);
}
}
// set BT's variables
static void LOCALFUNC
set_vars(PV7NODE p, ADDRP faddr){
newnodedes.NetNumber = p->NetNumber;
newnodedes.NodeNumber = p->NodeNumber;
newnodedes.HubNode = p->HubNode;
newnodedes.BaudRate = (byte)(p->BaudRate/300);
newnodedes.ModemType = p->ModemType;
newnodedes.NodeFlags = p->NodeFlags;
GetAltModemflag((word *)&newnodedes.ModemType,faddr);
GetAltFidoFlag ((word *)&newnodedes.NodeFlags,faddr);
newnodedes.Cost = p->RealCost;
newnodedes.RealCost = p->RealCost;
(void) strcpy (lastfound_SysopName, p->SysopName);
if (!nofancystrings)
(void) fancy_str (lastfound_SysopName);
(void) strcpy (newnodedes.SystemName, p->SystemName);
if (!nofancystrings)
(void) fancy_str (newnodedes.SystemName);
(void) strcpy (newnodedes.PhoneNumber, p->PhoneNumber);
(void) strcpy (newnodedes.MiscInfo, p->MiscInfo);
if (!nofancystrings)
(void) fancy_str (newnodedes.MiscInfo);
(void) memcpy (newnodedes.Password, p->Password, 8);
found_zone = p->ZoneNumber;
found_net = p->NetNumber;
faddr->Zone = p->ZoneNumber;
faddr->Net = p->NetNumber;
faddr->Node = p->NodeNumber;
if (p->NodeFlags & B_point)
faddr->Point = p->HubNode;
else
faddr->Point = 0;
faddr->Domain = NULL;
}