# /* resolve_name.c */ /* EMACS_MODES: c !fill */ /* Resolve a host name into an internet address. Three name formats are * accepted: * 1) A character string host name * 2) An octal host number, in the form: * ,,, * Any of the , , and may be left blank or left out * entirely; they default to the local net/subnet. * 3) A thirty-two bit hex number, preceeded by a '#', which is used * without interpretation as the host number. * If a character string name is supplied, it is first looked up in a * local host table. If it is not found there, the routine goes off to * internet name servers to try to resolve the name. * * The following routines are included in this file: * resolve_name Resolve a name as specified above * gethmch Parse a hex machine address specification * getomch Parse an octal machine address specification * The routines which use the internet name server are in the file * name_user.c. */ #include #define INSZ 4 /* Format of host tables */ extern struct mach { char *m_name; int m_id; } mach[]; extern struct mchid { char m_addr[INSZ]; int m_type; } mchid[]; extern int nmach; extern in_name gethmch(); extern in_name getomch(); extern in_name udpname(); #define MYNET 022 #define MYSNET 012 #define MYRSD 0 #define MYHOST 010 in_name resolve_name (name) /* Resolve foreign host internet address * Scan table of host names and nicknames. * For each name, see if our string is a prefix. If so, keep checking - * could be ambiguous. * If ambiguous, return 0. * When find no matches, try internet name servers. * * Arguments: */ char *name; /* name to resolve */ { register int i; register struct mach *pm, *pn; int pre, ans; union { char bytes[INSZ]; in_name name; } addr; in_name udpname(); if ((*name >= '0') && (*name <= '7')) return (getomch(name)); if (*name == '#') return (gethmch(name)); ans = FALSE; for (pm = &mach[0]; pm < &mach[nmach]; pm++) if ((pre = prefix (name, pm->m_name)) == 0) { /* exact match */ ans = TRUE; pn = pm; break; } else if (pre > 0) { /* leading substring */ if (ans) return (0L); else { ans = TRUE; pn = pm; } } if (ans) { for (i = 0; i < INSZ; i++) addr.bytes[i] = mchid[pn->m_id].m_addr[i]; return (addr.name); } return (udpname (name)); } /* Parse foreign host number input as hex string */ in_name gethmch(name) register char *name; { register char *tmp; register int i; union { char bytes[INSZ]; in_name name; } addr; tmp = &name[1]; for (i = 0; i < 8; i++) { if ((*tmp >= '0') && (*tmp <= '9')) *tmp++ -= '0'; else if ((*tmp >= 'A') && (*tmp <= 'Z')) *tmp++ -= ('A' - 10); else if ((*tmp >= 'a') && (*tmp <= 'z')) *tmp++ -= ('a' - 10); else return (0); } if (*tmp != 0) return (0); tmp = &name[1]; for (i = 0; i < INSZ; i++) addr.bytes[i] = ((*tmp++ << 4) + *tmp++); return (addr.name); } /* Parse foreign host number input as octal string */ in_name getomch(name) char *name; { char tmp[INSZ]; register char *p; register int i, j; register int n; union { char bytes[INSZ]; in_name name; } addr; addr.bytes[0] = MYNET; addr.bytes[1] = MYSNET; addr.bytes[2] = MYRSD; addr.bytes[3] = MYHOST; p = name; for (i = 0; i < INSZ; i++) { n = 0; while((*p >= '0') && (*p <= '7')) { n = ((n << 3) + (*p++ - '0')); if (n > 0377) return (0); } tmp[i] = n; if (*p == 0) break; if (*p == ',') p++; else return (0); } if (i == INSZ) return (0); for (j = 3; j >= 0; j--) { addr.bytes[j] = tmp[i]; if (--i < 0) break; } return (addr.name); } #define tolower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c)) prefix (s1, s2) /* Returns > 0 iff string s1 is a prefix of string s2; ie if * strlen(s1) <= strlen(s2) and s1 == the first strlen(s1) characters * of s2. Returns == 0 iff s1 == s2. Otherwise returns < 0. * This routine has been modified to ignore the case of the first string, * given that the second string is all-lower-case. */ register char *s1, *s2; { while (*s1 != '\0') if (tolower (*s1) != *s2 || *s2++ == '\0') return (-1); else s1++; return (*s2 == 0 ? 0 : 1); }