DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T i

⟦ebf007af9⟧ TextFile

    Length: 17578 (0x44aa)
    Types: TextFile
    Names: »isoaddrs.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/compat/isoaddrs.c« 

TextFile

/* 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;
}