📄 gethostent.c
字号:
#ifdef DEBUG fprintf(stderr, "gethostbyname_yp(%s)\n", name);#endif DEBUG sethostent_yp(0); if ((domain = yellowup(0)) == NULL) return (gethostbyname_local(name)); if (reason = yp_match(domain, "hosts.byname", name, strlen(name), &val, &vallen)) {#ifdef DEBUG fprintf(stderr, "reason yp_first failed is %d\n", reason);#endif p = NULL; } else { p = interpret(val, vallen, SVC_YP); free(val); } endhostent_yp(); return (p);}staticsethostent_local(f) int f;{ if (hostf == NULL) hostf = fopen(HOSTDB, "r"); else rewind(hostf); stayopen |= f;}/* * setent_bind(stayopen) in getcommon.c */sethostent_yp(f) int f;{ if ((domain = yellowup(1)) == NULL) return (sethostent_local (f)); if (current) free(current); current = NULL; stayopen |= f;}static endhostent_local(){ if (hostf && !stayopen) { fclose(hostf); hostf = NULL; }}/* * endent_bind(stayopen) in getcommon.c */endhostent_yp(){ if ((domain = yellowup(0)) == NULL) return (endhostent_local ()); if (current && !stayopen) { free(current); current = NULL; }}static struct hostent *gethostent_local(){ static char line1[BUFSIZ+1];#ifdef DEBUG fprintf(stderr,"gethostent_local\n");#endif DEBUG if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL) return (NULL); if (fgets(line1, BUFSIZ, hostf) == NULL) return (NULL); return interpret(line1, strlen(line1), SVC_LOCAL);}struct hostent *gethostent_bind(){ char bindbuf[64]; struct hostent *hp = NULL; sprintf(bindbuf, "hosts-%d", svc_gethostbind);#ifdef DEBUG fprintf(stderr, "gethostent_bind(%s)\n", bindbuf);#endif DEBUG if ((hp = gethostbyname_bind(bindbuf)) == NULL) return(NULL); svc_gethostbind++; return(hp);}struct hostent *gethostent_yp(){ struct hostent *hp; int reason; char *key = NULL; char *val = NULL; int keylen = 0; int vallen = 0;#ifdef DEBUG fprintf(stderr,"gethostent_yp\n");#endif DEBUG if ((domain = yellowup(0)) == NULL) return (gethostent_local ()); if (current == NULL) { if (reason = yp_first(domain, "hosts.byaddr", &key, &keylen, &val, &vallen)) {#ifdef DEBUG fprintf(stderr, "reason yp_first failed is %d\n", reason);#endif return NULL; } } else { if (reason = yp_next(domain, "hosts.byaddr", current, currentlen, &key, &keylen, &val, &vallen)) {#ifdef DEBUG fprintf(stderr, "reason yp_next failed is %d\n", reason);#endif return NULL; } } if (current) free(current); current = key; currentlen = keylen; hp = interpret(val, vallen, SVC_YP); free(val); return (hp);}static struct hostent *interpret(val, len, svc) char *val; int len, svc;{ char *p; register char *cp, **q; strncpy(line, val, len); p = line; line[len] = '\n'; if (*p == '#') switch (svc) { case SVC_LOCAL: return (gethostent_local()); case SVC_YP: return (gethostent_yp()); } cp = getcommon_any(p, "#\n"); if (cp == NULL) switch (svc) { case SVC_LOCAL: return (gethostent_local()); case SVC_YP: return (gethostent_yp()); } *cp = '\0'; cp = getcommon_any(p, " \t"); if (cp == NULL) switch (svc) { case SVC_LOCAL: return (gethostent_local()); case SVC_YP: return (gethostent_yp()); } *cp++ = '\0'; /* THIS STUFF IS INTERNET SPECIFIC */ /* * The hostent structure was modified in 4.3BSD to return * a list of host addresses, with the last address in the list * NULL. Some 4.3 utilities expect the list, so set it up, * but provide backward compatibility for local /etc/hosts * and YP by defining host.h_addr as the first address in * the list. */ host.h_addr_list = host_addrs; /* point to the list */ host.h_addr_list[0] = hostaddr; /* point to the host addrs */ host.h_addr_list[1] = (char *)0; /* and null terminate */ *((u_long *)host.h_addr) = inet_addr(p); host.h_length = sizeof (u_long); host.h_addrtype = AF_INET; while (*cp == ' ' || *cp == '\t') cp++; host.h_name = cp; q = host.h_aliases = host_aliases; cp = getcommon_any(cp, " \t"); if (cp != NULL) *cp++ = '\0'; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q < &host_aliases[MAXALIASES - 1]) *q++ = cp; cp = getcommon_any(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } *q = NULL; return (&host);}char *hostalias(name) register char *name;{ register char *C1, *C2; FILE *fp; char *file, *getenv(); char buf[BUFSIZ]; static char abuf[MAXDNAME]; file = getenv("HOSTALIASES"); if (file == NULL || (fp = fopen(file, "r")) == NULL) return (NULL); buf[sizeof(buf) - 1] = '\0'; while (fgets(buf, sizeof(buf), fp)) { for (C1 = buf; *C1 && !isspace(*C1); ++C1); if (!*C1) break; *C1 = '\0'; if (!strcasecmp(buf, name)) { while (isspace(*++C1)); if (!*C1) break; for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2); abuf[sizeof(abuf) - 1] = *C2 = '\0'; (void)strncpy(abuf, C1, sizeof(abuf) - 1); fclose(fp); return (abuf); } } fclose(fp); return (NULL);}static struct hostent *gethostdomain(name, domain) char *name, *domain;{ querybuf buf; char nbuf[2*MAXDNAME+2]; char *longname = nbuf; int n; if (domain == NULL || strfind(name,domain)) { /* * Check for trailing '.'; * copy without '.' if present. */ n = strlen(name) - 1; if (name[n] == '.' && n < sizeof(nbuf) - 1) { bcopy(name, nbuf, n); nbuf[n] = '\0'; } else longname = name; } else (void)sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); n = res_mkquery(QUERY, longname, C_IN, T_A, (char *)NULL, 0, NULL, (char *)&buf, sizeof(buf)); if (n < 0) {#ifdef DEBUG if (_res.options & RES_DEBUG) fprintf(stderr,"res_mkquery failed\n");#endif return ((struct hostent *)NULL); } return (getanswer((char *)&buf, n, 0));}static struct hostent *getanswer(msg, msglen, iquery) char *msg; int msglen, iquery;{ register HEADER *hp; register char *cp; register int n; querybuf answer; char *eom, *bp, **ap; int type, class, buflen, ancount, qdcount; int haveanswer, getclass = C_ANY; char **hap; n = res_send(msg, msglen, (char *)&answer, sizeof(answer)); if (n < 0) {#ifdef DEBUG int terrno; terrno = errno; if (_res.options & RES_DEBUG) fprintf(stderr,"res_send failed\n"); errno = terrno;#endif h_errno = TRY_AGAIN; return ((struct hostent *)NULL); } eom = (char *)&answer + n; /* * find first satisfactory answer */ hp = (HEADER *) &answer; ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); if (hp->rcode != NOERROR || ancount == 0) {#ifdef DEBUG if (_res.options & RES_DEBUG) fprintf(stderr,"rcode = %d, ancount=%d\n", hp->rcode, ancount);#endif switch (hp->rcode) { case NXDOMAIN: /* Check if it's an authoritive answer */ if (hp->aa) h_errno = HOST_NOT_FOUND; else h_errno = TRY_AGAIN; break; case SERVFAIL: h_errno = TRY_AGAIN; break; case NOERROR: if (hp->aa) h_errno = NO_ADDRESS; else h_errno = TRY_AGAIN; break; case FORMERR: case NOTIMP: case REFUSED: h_errno = NO_RECOVERY; } return ((struct hostent *)NULL); } bp = hostbuf; buflen = sizeof(hostbuf); cp = (char *)&answer + sizeof(HEADER); if (qdcount) { if (iquery) { if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) { h_errno = NO_RECOVERY; return ((struct hostent *)NULL); } cp += n + QFIXEDSZ; host.h_name = bp; n = strlen(bp) + 1; bp += n; buflen -= n; } else cp += dn_skipname(cp, eom) + QFIXEDSZ; while (--qdcount > 0) cp += dn_skipname(cp, eom) + QFIXEDSZ; } else if (iquery) { if (hp->aa) h_errno = HOST_NOT_FOUND; else h_errno = TRY_AGAIN; return ((struct hostent *)NULL); } ap = host_aliases; host.h_aliases = host_aliases; hap = h_addr_ptrs;#ifdef h_addr host.h_addr_list = h_addr_ptrs;#endif haveanswer = 0; while (--ancount >= 0 && cp < eom) { if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) break; cp += n; type = _getshort(cp); cp += sizeof(u_short); class = _getshort(cp); cp += sizeof(u_short) + sizeof(u_long); n = _getshort(cp); cp += sizeof(u_short); if (type == T_CNAME) { cp += n; if (ap >= &host_aliases[MAXALIASES-1]) continue; *ap++ = bp; n = strlen(bp) + 1; bp += n; buflen -= n; continue; } if (type == T_PTR) { if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) { cp += n; continue; } cp += n; host.h_name = bp; return(&host); } if (type != T_A) {#ifdef DEBUG if (_res.options & RES_DEBUG) fprintf(stderr,"unexpected answer type %d, size %d\n", type, n);#endif cp += n; continue; } if (haveanswer) { if (n != host.h_length) { cp += n; continue; } if (class != getclass) { cp += n; continue; } } else { host.h_length = n; getclass = class; host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; if (!iquery) { host.h_name = bp; bp += strlen(bp) + 1; } } bp += sizeof(align) - ((u_long)bp % sizeof(align)); if (bp + n >= &hostbuf[sizeof(hostbuf)]) {#ifdef DEBUG if (_res.options & RES_DEBUG) fprintf(stderr,"size (%d) too big\n", n);#endif break; } bcopy(cp, *hap++ = bp, n); bp +=n; cp += n; haveanswer++; } if (haveanswer) { *ap = NULL;#ifdef h_addr *hap = NULL;#else host.h_addr = h_addr_ptrs[0];#endif return (&host); } else { h_errno = TRY_AGAIN; return ((struct hostent *)NULL); }}/* * If * 1. There is a dot in hname, and * 2. the resolver is inited, and * 3. the default domain name is not null, and * 4. the end of hname contains the local domain name * return the length of the local host name of hname. */local_hostname_length(hname) char *hname;{ char *cp; int i,j = 0; if (hname == NULL) return(NULL); i = strlen(hname); for (cp = hname; cp && *cp != NULL && *cp != '.'; cp++, j++) ; if ((j < i) && (res_init() != -1) && (_res.defdname[0] != '\0') && ((strcasecmp(cp+1, _res.defdname)) == NULL)) return(j); return(NULL);}/* Function: * * strfind * * Function Description: * * Searches for substr at the END of text. ie. * See if one string is terminated by the occurance of another string. * * Arguments: * * char *text Text to search * char *substr String to locate * * Return values: * * Pointer to substr starting position in text if found. * NULL if not found. * * Side Effects: * * */char *strfind(text,substr) char *text, *substr;{ int substrlen; int textlen;textlen = strlen(text);substrlen = strlen(substr);if (textlen > substrlen) text = (text + textlen) - substrlen;else return(NULL);/* Search end of text for match. */if (strncasecmp(text, substr, substrlen) == NULL) return(text);else return(NULL);}/*E strfind() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -