// -------------------------------------------------------------------- // 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 // #include "vars.hpp" // #include "constant.hpp" #include "fidoaddr.h" #include "ustr.hpp" #include #include #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