|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 17578 (0x44aa) Types: TextFile Names: »isoaddrs.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/compat/isoaddrs.c«
/* isoaddrs.c - simple parsing of ISODE addresses */ #ifndef lint static char *rcsid = "$Header: /f/osi/compat/RCS/isoaddrs.c,v 6.0 89/03/18 23:25:12 mrose Rel $"; #endif /* * $Header: /f/osi/compat/RCS/isoaddrs.c,v 6.0 89/03/18 23:25:12 mrose Rel $ * * * $Log: isoaddrs.c,v $ * Revision 6.0 89/03/18 23:25:12 mrose * Release 5.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ #include <ctype.h> #include <stdio.h> #include "general.h" #include "manifest.h" #include "isoaddrs.h" #include "internet.h" #include "tailor.h" /* \f DATA */ static char *isomacros = "isomacros"; #define MBUCKETS 128 #define MHASH(nm) \ (((nm)[1]) ? (((((nm)[0]) - ((nm)[1])) & 0x1f) + (((nm)[2]) & 0x5f)) \ : ((nm)[0]) & 0x7f) struct macro { char *m_name; char *m_value; struct macro *m_chain; }; static int inited = 0; static struct macro *Mbuckets[MBUCKETS]; /* \f MACROS */ static struct macro *name2macro (name) char *name; { register struct macro *m; read_macros (); for (m = Mbuckets[MHASH (name)]; m && strcmp (m -> m_name, name); m = m -> m_chain) continue; return m; } /* \f */ static struct macro *value2macro (value) char *value; { register int i, j, k; register struct macro *m, *p, **np, **pp; read_macros (); p = NULL, i = 0; k = strlen (value); for (pp = (np = Mbuckets) + MBUCKETS; np < pp; np++) for (m = *np; m; m = m -> m_chain) if ((j = strlen (m -> m_value)) <= k && j > i && strncmp (value, m -> m_value, j) == 0) p = m, i = j; return p; } /* \f */ static int read_macros () { register char *hp; char buffer[BUFSIZ]; if (inited) return; inited = 1; bzero ((char *) Mbuckets, sizeof Mbuckets); read_file (isodefile (isomacros)); if ((hp = getenv ("HOME")) == NULL) hp = "."; (void) sprintf (buffer, "%s/.isode_macros", hp); read_file (buffer); } /* \f */ static int read_file (file) char *file; { register char *cp; char buffer[BUFSIZ + 1], *vec[NVEC + NSLACK + 1]; register FILE *fp; if ((fp = fopen (file, "r")) == NULL) return; while (fgets (buffer, sizeof buffer, fp)) { if (*buffer == '#') continue; if (cp = index (buffer, '\n')) *cp = NULL; if (str2vec (buffer, vec) < 2) continue; if (add_macro (vec[0], vec[1]) == NOTOK) break; } (void) fclose (fp); } /* \f */ static int add_macro (name, value) char *name, *value; { int i; register char *cp; char buffer[BUFSIZ]; register struct macro *m, *p; if (cp = index (value, '=')) { *cp++ = NULL; if ((p = name2macro (value)) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("macro \"%s\" references non-existant macro \"%s\"", name, value)); return OK; } (void) sprintf (value = buffer, "%s%s", p -> m_value, cp); } if ((m = (struct macro *) calloc (1, sizeof *m)) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("calloc of macro structure failed")); return NOTOK; } if ((m -> m_name = malloc ((unsigned) (strlen (name) + 1))) == NULL || (m -> m_value = malloc ((unsigned) (strlen (value) + 1))) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("malloc of alias structure failed")); if (m -> m_name) free (m -> m_name); free ((char *) m); return NOTOK; } (void) strcpy (m -> m_name, name); (void) strcpy (m -> m_value, value); m -> m_chain = Mbuckets[i = MHASH (m -> m_name)]; Mbuckets[i] = m; return OK; } /* \f STR2PADDR */ #define PS_INIT 0 /* <selector> or <network-address> */ #define PS_SEL1 1 /* .. got one selector already */ #define PS_SEL2 2 /* .. got two selectors already */ #define PS_SEL3 3 /* <network-address> */ static struct pair { char *p_name; char *p_value; } afi_entries[] = { "X121", "36", "DCC", "38", "TELEX", "54", "PSTN", "56", "ISDN", "58", "ICD", "46", "LOCAL", "48", NULL }; static char sel1[TSSIZE]; static char sel2[TSSIZE]; static char sel3[TSSIZE]; static char *sels[3] = { sel1, sel2, sel3 }; #define IMPLODE(intres,octres,octval,intval) \ { \ register int z = (intval); \ register char *y = (octval); \ register char *zp = y + z; \ \ while (zp-- > y) \ if (!isxdigit (*zp)) { \ SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, \ ("invalid hexstring: \"%*.*s\"", \ z, z, y)); \ } \ (intres) = implode ((u_char *) (octres), y, z); \ } /* \f */ struct PSAPaddr *str2paddr (str) char *str; { register int state, *lp; int j, lens[3]; register char *cp, *dp, *ep, *np, **sp; char buf1[BUFSIZ], buf2[BUFSIZ], nsap[NASIZE * 2 + 1]; register struct macro *m; register struct pair *pp; static int i = 0; static struct PSAPaddr pas[2]; register struct PSAPaddr *pa = &pas[i++]; register struct SSAPaddr *sa = &pa -> pa_addr; register struct TSAPaddr *ta = &sa -> sa_addr; register struct NSAPaddr *na = ta -> ta_addrs; i = i % 2; bzero ((char *) pa, sizeof *pa); (void) strcpy (buf1, str); state = PS_INIT; sp = sels, lp = lens; for (cp = buf1; *cp; ) switch (state) { case PS_INIT: case PS_SEL1: case PS_SEL2: switch (*cp) { case '"': /* '"' <otherstring> '"' */ if ((cp = index (dp = cp + 1, '"')) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("missing double-quote in selector: %s", str)); return NULLPA; } *cp++ = NULL; (void) strcpy (*sp, dp); *lp = strlen (dp); break; case '#': /* '#' <digitstring> */ j = 0; for (cp++; isdigit (*cp); cp++) j = j * 10 + *cp - '0'; if (j > 0xffff) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("invalid #-style selector: %s", str)); return NULLPA; } (*sp)[0] = (j >> 8) & 0xff; (*sp)[1] = j & 0xff; *lp = 2; break; case '\'': /* "'" <hexstring> "'H" */ if ((cp = index (dp = cp + 1, '\'')) == NULL) { missing_quoteH: ; SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("missing 'H in selector: %s",str)); return NULLPA; } *cp++ = NULL; if (*cp++ != 'H') goto missing_quoteH; IMPLODE (*lp, *sp, dp, strlen (dp)); break; case '/': /* empty selector */ *lp = 0; break; default: goto stuff_selectors; } sp++, lp++; if (*cp++ != '/') { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("missing selector seperator at position %d: %s", cp - buf1, str)); return NULLPA; } state++; break; stuff_selectors: ; state = PS_SEL3; /* and fall */ case PS_SEL3: if ((cp = index (ep = cp, '|')) == NULL) cp = ep + strlen (ep); else *cp++ = NULL; if (dp = index (ep, '=')) { *dp++ = NULL; if ((m = name2macro (ep)) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("non-existant macro \"%s\"", ep)); return NULLPA; } (void) sprintf (ep = buf2, "%s%s", m -> m_value, dp); } if ((ep = index (dp = ep, '+')) == NULL) { missing_seperator: ; SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("missing network-address seperator: %s", str)); return NULLPA; } *ep++ = NULL; if (ta -> ta_naddr >= NTADDR) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("too many network addresses starting at position %d: %s", dp - buf1 + 1, str)); return pa; } na -> na_type = NA_NSAP; if (strcmp (dp, "NS") == 0) { IMPLODE (na -> na_addrlen, na -> na_address, ep, strlen (ep)); } else { for (pp = afi_entries; pp -> p_name; pp++) if (strcmp (pp -> p_name, dp) == 0) break; if (!pp -> p_name) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("unknown AFI \"%s\": %s", dp, str)); return NULLPA; } if ((ep = index (dp = ep, '+')) == NULL) ep = dp + strlen (dp); else *ep++ = NULL; if (strcmp (pp -> p_name, "X121") == 0) { /* X121 form -- should be more general */ (void) strcpy (nsap, dp); if ((na -> na_dtelen = strlen (nsap)) > NSAP_DTELEN) { dp = nsap; goto invalid_dte; } (void) strcpy (na -> na_dte, nsap); na -> na_subnet = SUBNET_INTL_X25; #ifdef BRIDGE_X25 na -> na_type = bridgediscrim (na) ? NA_BRG : NA_X25; #else na -> na_type = NA_X25; #endif if (*ep != NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("bad X121 form \"%s\"", ep)); return NULLPA; } goto next; } else (void) sprintf (nsap, "%s%s", pp -> p_value, dp); switch (*ep) { case 'd': (void) strcpy (nsap + strlen (nsap), ep + 1); /* and fall */ case 'x': case 'l': case NULL: np = nsap, dp = na -> na_address; while (*np) { *dp = (*np++ - '0') << 4; if (*np) *dp++ |= (*np++ - '0') & 0x0f; else *dp++ |= 0x0f; } na -> na_addrlen = dp - na -> na_address; if (*ep == 'x') { IMPLODE (j, dp, ep + 1, strlen (ep + 1)); na -> na_addrlen += j; } else if (*ep == 'l') { (void) strcpy (dp, ep + 1); na -> na_addrlen += strlen (ep + 1); } break; default: if (strncmp ("RFC-1006+", ep, sizeof "RFC-1006+" - 1) == 0) { register struct hostent *hp; na -> na_type = NA_TCP; if (strcmp (nsap, INTERIM_IDP)) { wrong_idp: ; SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("wrong IDP \"%s\" for DSP \"%s\"", nsap, ep)); return NULLPA; } ep += sizeof "RFC-1006+" - 1; if ((ep = index (dp = ep, '+')) == NULL) goto missing_seperator; *ep++ = NULL; na -> na_subnet = atoi (dp); if ((ep = index (dp = ep, '+')) == NULL) ep = dp + strlen (dp); else *ep++ = NULL; if ((hp = gethostbystring (dp)) == NULL) { SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", dp)); return NULLPA; } #define s2a(b) (((int) (b)) & 0xff) (void) sprintf (na -> na_domain, "%d.%d.%d.%d", s2a (hp -> h_addr[0]), s2a (hp -> h_addr[1]), s2a (hp -> h_addr[2]), s2a (hp -> h_addr[3])); #undef s2a if (*ep) { if ((ep = index (dp = ep, '+')) == NULL) ep = dp + strlen (dp); else *ep++ = NULL; na -> na_port = htons ((u_short) atoi(dp)); if (*ep) na -> na_tset = atoi (ep); } break; } if (strncmp ("X.25(80)+", ep, sizeof "X.25(80)+" - 1) == 0) { na -> na_type = NA_X25; if (strcmp (nsap, INTERIM_IDP)) goto wrong_idp; ep += sizeof "X.25(80)+" - 1; if ((ep = index (dp = ep, '+')) == NULL) goto missing_seperator; *ep++ = NULL; na -> na_subnet = atoi (dp); if ((ep = index (dp = ep, '+')) == NULL) ep = dp + strlen (dp); else *ep++ = NULL; for (np = dp; *np; np++) if (!isdigit (*np)) { invalid_dte: ; SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("invalid DTE \"%s\": %s", dp, str)); return NULLPA; } if (np - dp > NSAP_DTELEN + 1) goto invalid_dte; (void) strcpy (na -> na_dte, dp); na -> na_dtelen = strlen (na -> na_dte); if (*ep) { char *cudf, *clen; if ((ep = index (dp = ep, '+')) == NULL) goto missing_seperator; *ep++ = NULL; if (strcmp (dp, "CUDF") == 0) { cudf = na -> na_cudf; clen = &na -> na_cudflen; j = sizeof na -> na_cudf; } else if (strcmp (dp, "PID") == 0) { cudf = na -> na_pid; clen = &na -> na_pidlen; j = sizeof na -> na_pid; } else { invalid_field: ; SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("invalid field \"%s\": %s", dp, str)); return NULLPA; } if (j * 2 < strlen (ep)) goto invalid_field; IMPLODE (j, cudf, ep, strlen (ep)); *clen = j & 0xff; } #ifdef BRIDGE_X25 na -> na_type = bridgediscrim (na) ? NA_BRG : NA_X25; #endif break; } #ifdef notdef if (strcmp ("ECMA-117-Binary", ep) == 0) { /* some day support this... */ break; } if (strcmp ("ECMA-117-Decimal", ep) == 0) { /* some day support this... */ break; } #endif SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("unknown DSP \"%s\": %s", ep, str)); return NULLPA; } } next: ; ta -> ta_naddr++, na++; break; } switch (sp - sels) { case 3: /* PSEL+SSEL+TSEL */ bcopy (*--sp, ta -> ta_selector, ta -> ta_selectlen = *--lp); bcopy (*--sp, sa -> sa_selector, sa -> sa_selectlen = *--lp); bcopy (*--sp, pa -> pa_selector, pa -> pa_selectlen = *--lp); break; case 2: /* SSEL+TSEL */ bcopy (*--sp, ta -> ta_selector, ta -> ta_selectlen = *--lp); bcopy (*--sp, sa -> sa_selector, sa -> sa_selectlen = *--lp); break; case 1: /* TSEL */ bcopy (*--sp, ta -> ta_selector, ta -> ta_selectlen = *--lp); break; default: break; } return pa; } /* \f PADDR2STR */ static char *SEL2STR (sel, len) char *sel; int len; { register char *cp, *dp, *ep; static char buffer[BUFSIZ]; if (len == 0) return ""; cp = buffer; for (ep = (dp = sel) + len; dp < ep; dp++) switch (*dp) { case '+': case '-': case '.': break; default: if (!isdigit (*dp) && !isalpha (*dp)) { *cp++ = '\''; cp += explode (cp, (u_char *) sel, len); (void) strcpy (cp, "'H"); return buffer; } break; } (void) sprintf (buffer, "\"%*.*s\"", len, len, sel); return buffer; } /* \f */ char *_paddr2str (pa, na, compact) register struct PSAPaddr *pa; register struct NSAPaddr *na; int compact; { register int n; int first; register char *bp, *cp, *dp; register struct macro *m; register struct SSAPaddr *sa; register struct TSAPaddr *ta; register struct NSAPaddr *ca; static int i = 0; static char buf1[BUFSIZ], buf2[BUFSIZ]; static char *bufs[] = { buf1, buf2 }; bp = cp = bufs[i++]; i = i % 2; if (pa == NULLPA) { bad_pa: ; (void) strcpy (bp, "NULLPA"); return bp; } sa = &pa -> pa_addr; ta = &sa -> sa_addr; if (na) n = 1; else if ((n = ta -> ta_naddr) > 0) na = ta -> ta_addrs; if (pa -> pa_selectlen > 0) { (void) sprintf (cp, "%s/", SEL2STR (pa -> pa_selector, pa -> pa_selectlen)); cp += strlen (cp); } if (sa -> sa_selectlen > 0 || bp != cp) { (void) sprintf (cp, "%s/", SEL2STR (sa -> sa_selector, sa -> sa_selectlen)); cp += strlen (cp); } if (ta -> ta_selectlen > 0 || bp != cp) { (void) sprintf (cp, "%s/", SEL2STR (ta -> ta_selector, ta -> ta_selectlen)); cp += strlen (cp); } for (first = 1; n > 0; na++, n--) { if (first) first = 0; else *cp++ = '|'; if (compact > 0) { if ((ca = na2norm (na)) == NULLNA) goto bad_pa; (void) strcpy (cp, "NS+"); cp += strlen (cp); cp += explode (cp, (u_char *) ca -> na_address, ca -> na_addrlen); *cp = NULL; continue; } dp = cp; switch (na -> na_type) { case NA_NSAP: (void) strcpy (cp, "NS+"); cp += strlen (cp); cp += explode (cp, (u_char *) na -> na_address, na -> na_addrlen); *cp = NULL; break; case NA_TCP: (void) sprintf (cp, "TELEX+%s+RFC-1006+%02d+%s", INTERIM_IDP + 2, na -> na_subnet ? na -> na_subnet : SUBNET_INTERNET, na -> na_domain); cp += strlen (cp); if (na -> na_port) { (void) sprintf (cp, "+%d", (int) ntohs (na -> na_port)); cp += strlen (cp); if (na -> na_tset) { (void) sprintf (cp, "+%d", (int) na -> na_tset); cp += strlen (cp); } } break; case NA_X25: case NA_BRG: if (na -> na_cudflen == 0 && na -> na_pidlen == 0 && na -> na_dte[0] != '0') { (void) sprintf (cp, "X121+%s", na -> na_dte); cp += strlen (cp); } else { (void) sprintf (cp, "TELEX+%s+X.25(80)+%02d+%s", INTERIM_IDP + 2, na -> na_subnet ? na -> na_subnet : SUBNET_INTL_X25, na -> na_dte); cp += strlen (cp); if (na -> na_pidlen > 0) { (void) strcpy (cp, "+PID+"); cp += strlen (cp); cp += explode (cp, (u_char *) na -> na_pid, (int) na -> na_pidlen); } else if (na -> na_cudflen > 0) { (void) strcpy (cp, "+CUDF+"); cp += strlen (cp); cp += explode (cp, (u_char *) na -> na_cudf, (int) na -> na_cudflen); cp += strlen (cp); } } break; default: SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("unknown address type 0x%x", na -> na_type)); goto bad_pa; } LLOG (addr_log, LLOG_DEBUG, ("dp = %s",dp)); if (!compact && (m = value2macro (dp))) { char buffer[BUFSIZ]; (void) sprintf (buffer, "%s=%s", m -> m_name, dp + strlen (m -> m_value)); (void) strcpy (dp, buffer); cp = dp + strlen (dp); } } return bp; }