// --------------------------------------------------------------------
// F i d o a d d r . c p p
//
// class of fido address
// --------------------------------------------------------------------
// Copyright (c) 1998-2001 by Fyodor Ustinov
// FIDONet 2:5020/79
//
// All rights reserved.
// --------------------------------------------------------------------
#include <string.h>
// #include "vars.hpp"
// #include "constant.hpp"
#include "fidoaddr.h"
#include "ustr.hpp"
#include <stdlib.h>
#include <ctype.h>
#undef _DEBUG
/*--------------------------------------------------------------------------*/
FA::FA(const FA &r) {
zone_v = r.zone_v;
net_v = r.net_v;
node_v = r.node_v;
point_v = r.point_v;
}
FA::FA(void){
Clean();
}
/*--------------------------------------------------------------------------*/
int FACmp(unsigned int r1, unsigned int r2) {
if (r1 & FA_ANYMASK) return TRUE;
if (r2 & FA_ANYMASK) return TRUE;
return ((r1 & 0xffff) == (r2 & 0xffff));
}
int FA::operator == (const FA &r) const {
int rc,rc2;
rc = TRUE;
if (zone_v & FA_NOTMASK) rc = !rc;
if (r.zone_v & FA_NOTMASK) rc = !rc;
rc2 = (FACmp(zone_v,r.zone_v) && FACmp(net_v,r.net_v) &&
FACmp(node_v,r.node_v) && FACmp(point_v,r.point_v));
return (rc == rc2);
}
int FA::operator != (const FA &r) const {
int rc,rc2;
rc = TRUE;
if (zone_v & FA_NOTMASK) rc = !rc;
if (r.zone_v & FA_NOTMASK) rc = !rc;
rc2 = (FACmp(zone_v,r.zone_v) && FACmp(net_v,r.net_v) &&
FACmp(node_v,r.node_v) && FACmp(point_v,r.point_v));
return (rc != rc2);
}
/*--------------------------------------------------------------------------*/
FA & FA::operator = (const FA &r){
zone_v = r.zone_v;
net_v = r.net_v;
node_v = r.node_v;
point_v = r.point_v;
return *this;
}
/*--------------------------------------------------------------------------*
*
* General Zone/Net/Node/Point parser
*
**/
unsigned int _ParseOneDigit(char *&p) {
unsigned int tmp;
if (*p == ANYMASK_CHAR[0]) { p++; return FA_ANYMASK; }
if (*p == LSTMASK_CHAR[0]) { p++; return FA_LSTMASK; }
if (*p == TOMASK_CHAR[0]) { p++; return FA_TOMASK; }
if (*p == FROMMASK_CHAR[0]) { p++; return FA_FROMMASK; }
if (*p == OURMASK_CHAR[0]) { p++; return FA_OURMASK; }
if (*p == SUBMASK_CHAR[0]) { p++; return FA_SUBMASK; }
if (*p == NHOLDMASK_CHAR[0]) { p++; return FA_HOLDMASK; }
if (*p == NHUBMASK_CHAR[0]) { p++; return FA_HUBMASK; }
if (*p == NPVTMASK_CHAR[0]) { p++; return FA_PVTMASK; }
if (*p == NDOWNMASK_CHAR[0]) { p++; return FA_DOWNMASK; }
if (!isdigit((uchar)*p)) return FA_NOTDEF;
tmp = atoi(p);
while (isdigit((uchar)*p)) p++;
if (tmp > 65535U) return FA_NOTDEF;
return tmp;
}
unsigned int _ParseZone (char *&p) {
char *t;
unsigned int tmp;
// Parsing zone 'XX:'
t = p;
tmp = _ParseOneDigit(t);
if (tmp == FA_NOTDEF) {
return FA_NOTDEF;
}
if (tmp == FA_SUBMASK) {
return FA_NOTDEF;
}
if (*t != ':') {
return FA_NOTDEF;
}
p = t + 1;
return tmp;
}
unsigned int _ParseNet (char *&p) {
char *t;
unsigned int tmp;
t = p;
tmp = _ParseOneDigit(t);
if (tmp == FA_NOTDEF) {
return FA_NOTDEF;
}
if (tmp == FA_SUBMASK) {
return FA_NOTDEF;
}
if (*t != '/') {
return FA_NOTDEF;
}
p = t + 1;
return tmp;
}
unsigned int _ParseNode (char *&p) {
char *t;
unsigned int tmp;
if (*p == '.') { // catch '.XX'
p++;
return FA_NOTDEF;
}
t = p;
tmp = _ParseOneDigit(t);
if (tmp == FA_SUBMASK) {
return FA_NOTDEF;
}
if (tmp != FA_NOTDEF) {
if (*t != '.' && *t != '\0' && *t != ' ' && *t != '@') {
p = t;
return FA_NOTDEF;
}
}
p = t;
return tmp;
}
int FA::Parse(char *&p) {
int NotFlag;
if (strlen(p) == 0) {
zone_v = net_v = node_v = point_v = FA_NOTDEF;
return FALSE;
}
while( *p == ' ') p++;
NotFlag = FALSE;
if (*p == NOTMASK_CHAR[0]) { // Found NOT flag. This flag set _only_ on ZONE
NotFlag = TRUE;
p++;
}
zone_v = _ParseZone(p);
net_v = _ParseNet(p);
node_v = _ParseNode(p);
if (*p == '.') {
p++;
point_v = _ParseOneDigit(p);
} else {
point_v = FA_NOTDEF;
}
if (node_v & FA_MASK) {
if ((zone_v & FA_NOTDEF) && (net_v & FA_NOTDEF) && (point_v & FA_NOTDEF)) {
zone_v = node_v;
net_v = node_v;
point_v = node_v;
}
}
// Now, check errors.
if (point_v & FA_SUBMASK) { // set point submask
// i'm not understud, who need doing...
}
if (!(zone_v & FA_NOTDEF) && (net_v & FA_NOTDEF)) { // zone exist but not net.
zone_v = FA_NOTDEF;
node_v = FA_NOTDEF;
point_v = FA_NOTDEF;
while(*p > ' ') p++;
}
if (!(net_v & FA_NOTDEF) && (node_v & FA_NOTDEF)) { // net exist but not node.
zone_v = FA_NOTDEF;
net_v = FA_NOTDEF;
point_v = FA_NOTDEF;
while(*p > ' ') p++;
}
if (*p == '@') { // skip domain.
while(*p > ' ') p++;
}
if (*p > ' ') { // exist some not parsed...
zone_v = FA_NOTDEF;
net_v = FA_NOTDEF;
node_v = FA_NOTDEF;
point_v = FA_NOTDEF;
while(*p > ' ') p++;
}
if ((node_v & FA_TOMASK) && !(point_v & FA_TOMASK)) {
zone_v = FA_TOMASK;
net_v = FA_TOMASK;
}
if (point_v == FA_NOTDEF && (zone_v != FA_NOTDEF && net_v != FA_NOTDEF &&
node_v != FA_NOTDEF)) point_v = 0;
if (NotFlag) {
zone_v |= FA_NOTMASK;
}
return TRUE;
}
/*--------------------------------------------------------------------------*/
Str fatoa(unsigned int i) {
Str tmp;
if (i & FA_NOTMASK) {
tmp = NOTMASK_CHAR;
}
if (i & FA_ANYMASK) { tmp += ANYMASK_CHAR; return tmp; }
if (i & FA_NOTDEF) { tmp += "?"; return tmp; }
if (i & FA_LSTMASK) { tmp += LSTMASK_CHAR; return tmp; }
if (i & FA_FROMMASK) { tmp += FROMMASK_CHAR; return tmp; }
if (i & FA_TOMASK) { tmp += TOMASK_CHAR; return tmp; }
if (i & FA_OURMASK) { tmp += OURMASK_CHAR; return tmp; }
if (i & FA_SUBMASK) { tmp += SUBMASK_CHAR; return tmp; }
if (i & FA_HOLDMASK) { tmp += NHOLDMASK_CHAR; return tmp; }
if (i & FA_PVTMASK) { tmp += NPVTMASK_CHAR; return tmp; }
if (i & FA_DOWNMASK) { tmp += NDOWNMASK_CHAR; return tmp; }
if (i & FA_HUBMASK) { tmp += NHUBMASK_CHAR; return tmp; }
tmp += (unsigned long)(i & 0xffff);
return tmp;
}
FA::operator Str() const {
Str s;
s = fatoa(zone_v);
s += ':';
s += fatoa(net_v);
s += '/';
s += fatoa(node_v);
if (point_v != 0 && (point_v & FA_NOTDEF) == 0) {
s += '.';
s += fatoa(point_v);
}
return s;
}
/*--------------------------------------------------------------------------*/
// LogStream &operator <<(LogStream &os,FA const &f) {
// os << f;
// return (os);
//}
/*--------------------------------------------------------------------------*/
int FA::Valid(void) const {
if ((zone_v & FA_NOTDEF) && (net_v & FA_NOTDEF)
&& (node_v & FA_NOTDEF) && (point_v & FA_NOTDEF)) {
return FALSE;
} else {
return TRUE;
}
}
void Parse_NetNode(char *netnode,word *zone,word *net,word *node,word *point) {
FA f;
f.Parse(netnode);
*zone = f.Zone() & 0xffff;
*net = f.Net() & 0xffff;
*node = f.Node() & 0xffff;
*point = f.Point() & 0xffff;
}
#if 0
void main(void) {
FA f1;
FA f2;
char *p;
p = "2:5020/79.* 2:5020/*.2";
f1.Parse(p);
f2.Parse(p);
fprintf(stderr,"'%s'\n",f1.ToStr());
fprintf(stderr,"'%s'\n",f2.ToStr());
(f1 == f2) ? fprintf(stderr,"equal\n") : fprintf(stderr,"not equal\n");
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1