📄 list.c
字号:
/* * ++Copyright++ 1985, 1989 * - * Copyright (c) 1985, 1989 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */#ifndef lintstatic char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91";static char rcsid[] = "$Id: list.c,v 4.9.1.5 1993/12/06 00:43:17 vixie Exp $";#endif /* not lint *//* ******************************************************************************* * * list.c -- * * Routines to obtain info from name and finger servers. * * Adapted from 4.3BSD BIND ns_init.c and from finger.c. * ******************************************************************************* */#include <sys/param.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.h>#include <resolv.h>#include <netdb.h>#include <stdio.h>#include <limits.h>#include <ctype.h>#include <errno.h>#include "res.h"#include "../../conf/portability.h"extern char *_res_resultcodes[]; /* res_debug.c */extern char *pager;typedef union { HEADER qb1; char qb2[PACKETSZ];} querybuf;extern HostInfo *defaultPtr;extern HostInfo curHostInfo;extern int curHostValid;extern int queryType;extern int queryClass;static int sockFD = -1;int ListSubr();/* * During a listing to a file, hash marks are printed * every HASH_SIZE records. */#define HASH_SIZE 50/* ******************************************************************************* * * ListHosts -- * ListHostsByType -- * * Requests the name server to do a zone transfer so we * find out what hosts it knows about. * * For ListHosts, there are five types of output: * - Internet addresses (default) * - cpu type and operating system (-h option) * - canonical and alias names (-a option) * - well-known service names (-s option) * - ALL records (-d option) * ListHostsByType prints records of the default type or of a speicific * type. * * To see all types of information sorted by name, do the following: * ls -d domain.edu > file * view file * * Results: * SUCCESS the listing was successful. * ERROR the server could not be contacted because * a socket could not be obtained or an error * occured while receiving, or the output file * could not be opened. * ******************************************************************************* */voidListHostsByType(string, putToFile) char *string; int putToFile;{ int i, qtype, result; char *namePtr; char name[NAME_LEN]; char option[NAME_LEN]; /* * Parse the command line. It maybe of the form "ls -t domain" * or "ls -t type domain". */ i = sscanf(string, " ls -t %s %s", option, name); if (putToFile && i == 2 && name[0] == '>') { i--; } if (i == 2) { qtype = StringToType(option, -1, stderr); if (qtype == -1) return; namePtr = name; } else if (i == 1) { namePtr = option; qtype = queryType; } else { fprintf(stderr, "*** ls: invalid request %s\n",string); return; } result = ListSubr(qtype, namePtr, putToFile ? string : NULL); if (result != SUCCESS) fprintf(stderr, "*** Can't list domain %s: %s\n", namePtr, DecodeError(result));}voidListHosts(string, putToFile) char *string; int putToFile;{ int i, qtype, result; char *namePtr; char name[NAME_LEN]; char option[NAME_LEN]; /* * Parse the command line. It maybe of the form "ls domain", * "ls -X domain". */ i = sscanf(string, " ls %s %s", option, name); if (putToFile && i == 2 && name[0] == '>') { i--; } if (i == 2) { if (strcmp("-a", option) == 0) { qtype = T_CNAME; } else if (strcmp("-h", option) == 0) { qtype = T_HINFO; } else if (strcmp("-m", option) == 0) { qtype = T_MX; } else if (strcmp("-s", option) == 0) { qtype = T_WKS; } else if (strcmp("-d", option) == 0) { qtype = T_ANY; } else { qtype = T_A; } namePtr = name; } else if (i == 1) { namePtr = option; qtype = T_A; } else { fprintf(stderr, "*** ls: invalid request %s\n",string); return; } result = ListSubr(qtype, namePtr, putToFile ? string : NULL); if (result != SUCCESS) fprintf(stderr, "*** Can't list domain %s: %s\n", namePtr, DecodeError(result));}intListSubr(qtype, domain, cmd) int qtype; char *domain; char *cmd;{ querybuf buf; struct sockaddr_in sin; HEADER *headerPtr; int msglen; int amtToRead; int numRead; int numAnswers = 0; int result; int soacnt = 0; u_short len; char *cp, *nmp; char dname[2][NAME_LEN]; char file[NAME_LEN]; static char *answer = NULL; static int answerLen = 0; enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING } error = NO_ERRORS; /* * Create a query packet for the requested domain name. */ msglen = res_mkquery(QUERY, domain, queryClass, T_AXFR, (char *)0, 0, 0, (char *) &buf, sizeof(buf)); if (msglen < 0) { if (_res.options & RES_DEBUG) { fprintf(stderr, "*** ls: res_mkquery failed\n"); } return (ERROR); } bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(nsport); /* * Check to see if we have the address of the server or the * address of a server who knows about this domain. * * For now, just use the first address in the list. */ if (defaultPtr->addrList != NULL) { sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0]; } else { sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0]; } /* * Set up a virtual circuit to the server. */ if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("ls: socket"); return(ERROR); } if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) < 0) { int e; if (errno == ECONNREFUSED) { e = NO_RESPONSE; } else { perror("ls: connect"); e = ERROR; } (void) close(sockFD); sockFD = -1; return e; } /* * Send length & message for zone transfer */ len = htons(msglen); if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) || write(sockFD, (char *) &buf, msglen) != msglen) { perror("ls: write"); (void) close(sockFD); sockFD = -1; return(ERROR); } fprintf(stdout,"[%s]\n", (defaultPtr->addrList != NULL) ? defaultPtr->name : defaultPtr->servers[0]->name); if (cmd == NULL) { filePtr = stdout; } else { filePtr = OpenFile(cmd, file); if (filePtr == NULL) { fprintf(stderr, "*** Can't open %s for writing\n", file); (void) close(sockFD); sockFD = -1; return(ERROR); } fprintf(filePtr, "> %s\n", cmd); fprintf(filePtr,"[%s]\n", (defaultPtr->addrList != NULL) ? defaultPtr->name : defaultPtr->servers[0]->name); }#if 0 if (qtype == T_CNAME) { fprintf(filePtr, "%-30s", "Alias"); } else if (qtype == T_TXT) { fprintf(filePtr, "%-30s", "Key"); } else { fprintf(filePtr, "%-30s", "Host or domain name"); } switch (qtype) { case T_A: fprintf(filePtr, " %-30s\n", "Internet Address"); break; case T_HINFO: fprintf(filePtr, " %-30s\n", "CPU & OS"); break; case T_CNAME: fprintf(filePtr, " %-30s\n", "Canonical Name"); break; case T_MX: fprintf(filePtr, " %-30s\n", "Metric & Host"); break; case T_AFSDB: fprintf(filePtr, " %-30s\n", "Subtype & Host"); break; case T_WKS: fprintf(filePtr, " %-4s %s\n", "Protocol", "Services"); break; case T_MB: fprintf(filePtr, " %-30s\n", "Mailbox"); break; case T_MG: fprintf(filePtr, " %-30s\n", "Mail Group"); break; case T_MR: fprintf(filePtr, " %-30s\n", "Mail Rename"); break; case T_MINFO: fprintf(filePtr, " %-30s\n", "Mail List Requests & Errors"); break; case T_UINFO: fprintf(filePtr, " %-30s\n", "User Information"); break; case T_UID: fprintf(filePtr, " %-30s\n", "User ID"); break; case T_GID: fprintf(filePtr, " %-30s\n", "Group ID"); break; case T_TXT: fprintf(filePtr, " %-30s\n", "Text"); break; case T_RP: fprintf(filePtr, " %-30s\n", "Responsible Person"); break; case T_NS: fprintf(filePtr, " %-30s\n", "Name Servers"); break; case T_PTR: fprintf(filePtr, " %-30s\n", "Pointers"); break; case T_SOA: fprintf(filePtr, " %-30s\n", "Start of Authority"); break; case T_ANY: fprintf(filePtr, " %-30s\n", "Resource Record Info."); break; }#endif dname[0][0] = '\0'; while (1) { unsigned short tmp; /* * Read the length of the response. */ cp = (char *) &tmp; amtToRead = sizeof(u_short); while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) { cp += numRead; amtToRead -= numRead; } if (numRead <= 0) { error = ERR_READING_LEN; break; } if ((len = htons(tmp)) == 0) { break; /* nothing left to read */ } /* * The server sent too much data to fit the existing buffer -- * allocate a new one. */ if (len > answerLen) { if (answerLen != 0) { free(answer); } answerLen = len; answer = Malloc(answerLen); } /* * Read the response. */ amtToRead = len; cp = answer; while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) { cp += numRead; amtToRead -= numRead; } if (numRead <= 0) { error = ERR_READING_MSG; break; } result = PrintListInfo(filePtr, answer, cp, qtype, dname[0]); if (result != SUCCESS) { error = ERR_PRINTING; break; } numAnswers++; if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) { fprintf(stdout, "#"); fflush(stdout); } cp = answer + sizeof(HEADER); if (ntohs(((HEADER* )answer)->qdcount) > 0) cp += dn_skipname((u_char *)cp, (u_char *)answer + len) + QFIXEDSZ; nmp = cp; cp += dn_skipname((u_char *)cp, (u_char *)answer + len); if ((_getshort(cp) == T_SOA)) { dn_expand((u_char *)answer, (u_char *)answer + len, (u_char *)nmp, (u_char *)dname[soacnt], sizeof(dname[0])); if (soacnt) { if (strcmp(dname[0], dname[1]) == 0) break; } else soacnt++; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -