/*--------------------------------------------------------------------------*/ /* */ /* */ /* ------------ Bit-Bucket Software, Co. */ /* \ 10001101 / Writers and Distributors of */ /* \ 011110 / Freely Available 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 #include #include #include #include #include #include #include #include #include #ifdef OS_2 #define INCL_DOS #include #define _dos_read DosRead #endif #ifdef __TURBOC__ #include #define _fmalloc(n) farmalloc (n) #define _ffree(n) farfree (n) #else #include #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); static int opus_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; static void get_nodelist_name (ADDR *); static void get_nodelist_name (opus_addr) ADDR *opus_addr; { int i; 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 (n) 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 () { 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]); _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 (nodeaddr) 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) (void) set_baud (max_baud.rate_value, 1); /* Set to our highest baud rate */ else (void) 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 (bink_addr, prtflag) ADDR *bink_addr; /* zone, net and node */ int prtflag; { int i, j, k; int have_boss_data = 0; int need_boss_data = 0; (void) 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) { (void) strncpy (newnodedes.PhoneNumber, BOSSphone, 40); newnodedes.PhoneNumber[39] = '\0'; } if (BOSSpwd && strlen (BOSSpwd) > 2) { (void) memset (newnodedes.Password, 0, sizeof (newnodedes.Password)); (void) 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 */ (void) strcpy (newnodedes.SystemName, "Binkley's Boss"); /* System Name defaults */ (void) 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 Quick_Next_Zone () { 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 (Quick_addr, have_boss_data) ADDR *Quick_addr; /* zone, net and node */ int have_boss_data; /* BOSS data flag */ { 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" */ (void) strcpy (index_filename, net_info); /* take nodelist path */ (void) 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 */ } (void) 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]); (void) close (stream); return (0); } if (_dos_read (stream, node_index, i, &got) != 0) { status_line (msgtxt[M_NODELIST_READ_ERR]); (void) close (stream); return (0); } (void) 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 */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) 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); (void) fclose (stream1); return (0); } if (!fread (&nodedes, sizeof (nodedes), 1, stream1)) { status_line (msgtxt[M_NODELIST_REC_ERR], temp); (void) fclose (stream1); return (0); } (void) 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); (void) strncpy (&newnodedes.SystemName[0], &nodedes.QL_Name[1], i); newnodedes.SystemName[i] = '\0'; /* System Name */ i = min (nodedes.QL_Phone[0], 39); (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.QL_Phone[1], i); newnodedes.PhoneNumber[i] = '\0'; /* Phone Number */ i = min (nodedes.QL_City[0], 29); (void) 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); (void) 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); } static int opus_next_zone () { 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); } int opusfind (opus_addr, have_boss_data) ADDR *opus_addr; /* zone, net and node */ int have_boss_data; /* BOSS data flag */ { 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 (nodelist_base == NULL) nodelist_base = nodelist_name; if ((node_index == NULL) || ((curr_domain != opus_addr->Domain) && ((opus_addr->Domain != NULL) || (curr_domain != my_addr.Domain)))) { if (node_index != NULL) { _ffree (node_index); } get_nodelist_name (opus_addr); index_filesize == (off_t) 0L; /* Cover ourselves for error */ 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, ".IDX"); /* add in the file ext */ if ((stream = open(index_filename, O_RDONLY|O_BINARY)) == -1) { i = 0; /* Need this later */ if (have_boss_data != 2) status_line (msgtxt[M_UNABLE_TO_OPEN], index_filename); return (0); /* no file, no work to do */ } (void) 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]); (void) close (stream); return (0); } if (_dos_read (stream, node_index, i, &got) != 0) { status_line (msgtxt[M_NODELIST_READ_ERR]); (void) close (stream); return (0); } (void) close (stream); 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) { temp[0] = '\0'; /* "null-terminated string" */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) strcat (temp, nodelist_base); /* add in the file name */ (void) strcat (temp, ".DAT"); /* add in the file name */ if (!stat (temp, &f)) { extra_bytes = ((int) (f.st_size / idx_size)) - sizeof (newnodedes); } } } nodeidx = (struct _ndi far *) node_index; /* If using the old nodelist, bypass zone stuff - it isn't there */ if (opus_addr->Zone == (unsigned int) -1) { return (opus_next_zone ()); } else if ((!newnodelist) || (alias[0].Zone == 0) || (no_zones)) { opus_addr->Zone = 0; } for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++) { if (nodeidx->node == -2) current_zone = nodeidx->net; if (opus_addr->Zone > 0 && current_zone != opus_addr->Zone) continue; if (nodeidx->net == opus_addr->Net) /* if a match on net, */ { /* foundnet = 1; */ /* say we found the net */ if (((opus_addr->Node == 0) && (nodeidx->node <= 0)) || (nodeidx->node == opus_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 */ /* else*/ /* if (foundnet)*//* already past the net? */ /* break;*//* Yes, we failed... */ } if (!found) return (0); found_zone = current_zone; /* Keep track of found zone */ found_net = nodeidx->net; /* Keep track of found net */ if (newnodelist) i = (get_new_info (nodeoff)); else i = (get_old_info (nodeoff)); return (i); } static int get_old_info (recno) 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 */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) strcat (temp, nodelist_base); /* add in the file name */ (void) 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); (void) fclose (stream); return (0); } if (!fread (&nodedes, sizeof (nodedes), 1, stream)) { status_line (msgtxt[M_NODELIST_REC_ERR], temp); (void) fclose (stream); return (0); } (void) 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 */ (void) strncpy (&newnodedes.SystemName[0], &nodedes.name[0], 20); newnodedes.SystemName[19] = '\0'; /* System Name */ (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.phone[0], 40); newnodedes.PhoneNumber[39] = '\0'; /* Phone Number */ (void) 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) { (void) 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 (recno) 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) + extra_bytes)); (void) strcpy (temp, net_info); /* take nodelist path */ (void) strcat (temp, nodelist_base); /* add in the file name */ (void) 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); (void) fclose (stream); return (0); } if (!fread (&newnodedes, sizeof (newnodedes), 1, stream)) { status_line (msgtxt[M_NODELIST_REC_ERR], temp); (void) fclose (stream); return (0); } (void) fclose (stream); return (1); } static int get_TBBS_info (recno, TBBS_addr) 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 */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) 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); (void) fclose (stream); return (0); } if (!fread (&nodedes, sizeof (nodedes), 1, stream)) { status_line (msgtxt[M_NODELIST_REC_ERR], temp); (void) fclose (stream); return (0); } (void) 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 */ (void) strncpy (&newnodedes.SystemName[0], &nodedes.nodename[0], 14); newnodedes.SystemName[19] = '\0'; /* System Name */ (void) strncpy (&newnodedes.PhoneNumber[0], &nodedes.nodephone[0], 40); newnodedes.PhoneNumber[39] = '\0'; /* Phone Number */ (void) 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 */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) 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 */ { (void) fclose (stream); return (1); } if (!fread (&ext, sizeof (ext), 1, stream)) { (void) fclose (stream); return (1); } (void) fclose (stream); /* * Copy data from ext into newnodedes. */ (void) 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 (TBBS_addr, have_boss_data) ADDR *TBBS_addr; /* zone, net and node */ int have_boss_data; /* BOSS data flag */ { 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" */ (void) strcpy (temp, net_info); /* take nodelist path */ (void) 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 */ } (void) 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]); (void) close (stream); return (0); } if (_dos_read (stream, node_index, i, &got) != 0) { status_line (msgtxt[M_NODELIST_READ_ERR]); (void) close (stream); return (0); } (void) close (stream); } nodeidx = (struct _ndi far *) node_index; if (TBBS_addr->Zone == (unsigned int) -1) { return (opus_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 */ /* else*/ /* if (foundnet)*//* already past the net? */ /* break;*//* Yes, we failed... */ } 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); }