⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 list.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1985 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */#ifndef lintstatic char sccsid[] = "@(#)list.c 1.1 92/07/30 SMI from UCB 5.10 2/17/88";#endif /* not lint *//* ******************************************************************************* * *  list.c -- * *	Routines to obtain info from name and finger servers. * *	Adapted from 4.3BSD BIND ns_init.c and from /usr/src/ucb/finger.c * ******************************************************************************* */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <stdio.h>#include <strings.h>#include <ctype.h>#include <arpa/nameser.h>#include <resolv.h>#include "res.h"/* *  Imported from res_debug.c */extern char *_res_resultcodes[];typedef union {    HEADER qb1;    char qb2[PACKETSZ];} querybuf;extern u_long 		inet_addr();extern HostInfo 	*defaultPtr;extern HostInfo 	curHostInfo;extern int 		curHostValid;/* *  During a listing to a file, hash marks are printed  *  every HASH_SIZE records. */#define HASH_SIZE 50/* ******************************************************************************* * *  ListHosts -- * *	Requests the name server to do a zone transfer so we *	find out what hosts it knows about. * *	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) *	 *	To see all three types of information in sorted order,  *	do the following: *	  ls domain.edu > file *	  ls -a domain.edu >> file *	  ls -h domain.edu >> file *	  ls -s 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. * ******************************************************************************* */intListHosts(string, putToFile)    char *string;    int  putToFile;{	querybuf 		buf;	struct sockaddr_in 	sin;	HEADER 			*headerPtr;	int 			queryType;	int 			msglen;	int 			amtToRead;	int 			numRead;	int 			i;	int 			numAnswers = 0;	int 			result;	int 			soacnt = 0;	u_short 		len;	char 			*cp, *nmp;	char 			name[NAME_LEN];	char 			dname[2][NAME_LEN];	char 			option[NAME_LEN];	char 			file[NAME_LEN];	char			*namePtr;	enum {	    NO_ERRORS, 	    ERR_READING_LEN, 	    ERR_READING_MSG,	    ERR_PRINTING,	} error = NO_ERRORS;	/*	 *    /*     *  Parse the command line. It maybe of the form "ls domain",     *  "ls -a domain" or "ls -h domain".     */ 	i = sscanf(string, " ls %s %s", option, name);	if (putToFile && i == 2 && name[0] == '>') {	    i--;	}	if (i == 2) {	    if (strcmp("-a", option) == 0) {		queryType = T_CNAME;	    } else if (strcmp("-h", option) == 0) {		queryType = T_HINFO;	    } else if (strcmp("-m", option) == 0) {		queryType = T_MX;	    } else if (strcmp("-s", option) == 0) {		queryType = T_WKS;	    } else if (strcmp("-d", option) == 0) {		queryType = T_ANY;	    } else {		queryType = T_A;	    }	    namePtr = name;	} else if (i == 1) {	    namePtr = option;	    queryType = T_A;	} else {	    fprintf(stderr, "ListHosts: invalid request %s\n",string);	    return(ERROR);	}	/*	 *  Create a query packet for the requested domain name.	 *	 */	msglen = res_mkquery(QUERY, namePtr, C_IN, T_AXFR,				(char *)0, 0, (char *)0, 				(char *) &buf, sizeof(buf));	if (msglen < 0) {	    if (_res.options & RES_DEBUG) {		fprintf(stderr, "ListHosts: Res_mkquery failed\n");	    }	    return (ERROR);	}	bzero((char *)&sin, sizeof(sin));	sin.sin_family	= AF_INET;	sin.sin_port	=  htons(NAMESERVER_PORT);	/*	 *  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("ListHosts");	    return(ERROR);	}		if (connect(sockFD, &sin, sizeof(sin)) < 0) {	    perror("ListHosts");	    (void) close(sockFD);	    sockFD = -1;	    return(ERROR);	}		/*	 * 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("ListHosts");		(void) close(sockFD);		sockFD = -1;		return(ERROR);	}	fprintf(stdout,"[%s]\n",		(defaultPtr->addrList != NULL) ? defaultPtr->name : 		 defaultPtr->servers[0]->name);	if (!putToFile) {	    filePtr = stdout;	} else {	    filePtr = OpenFile(string, 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", string);	    fprintf(filePtr,"[%s]\n",		(defaultPtr->addrList != NULL) ? defaultPtr->name : 		 defaultPtr->servers[0]->name);	}	fprintf(filePtr, "%-30s", "Host or domain name");	switch(queryType) {	    case T_ANY:		    fprintf(filePtr, " %-30s\n", "Resource record info");		    break;	    case T_A:		    fprintf(filePtr, " %-30s\n", "Internet address");		    break;	    case T_HINFO:		    fprintf(filePtr, " %-10s %s\n", "CPU", "OS");		    break;	    case T_CNAME:		    fprintf(filePtr, " %-30s\n", "Alias");		    break;	    case T_MX:		    fprintf(filePtr, " %3s %s\n", "Metric", "Host");		    break;	    case T_WKS:		    fprintf(filePtr, " %-4s %s\n", "Protocol", "Services");	}	while (1) {	    /*	     * Read the length of the response.	     */	    cp = (char *) &buf;	    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(*(u_short *)&buf)) == 0) {		break;	/* nothing left to read */	    }	    /*	     * Read the response.	     */	    amtToRead = len;	    cp = (char *) &buf;	    while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){		cp += numRead;		amtToRead -= numRead;	    }	    if (numRead <= 0) {		error = ERR_READING_MSG;		break;	    }	    result = PrintListInfo(filePtr, (char *) &buf, cp, queryType);	    if (result != SUCCESS) {		error = ERR_PRINTING;		break;	    }	    numAnswers++;	    if (putToFile && ((numAnswers % HASH_SIZE) == 0)) {		fprintf(stdout, "#");		fflush(stdout);	    }	    cp = buf.qb2 + sizeof(HEADER);	    if (ntohs(buf.qb1.qdcount) > 0)		cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ;	    nmp = cp;	    cp += dn_skipname(cp, (u_char *)&buf + len);	    if ((_getshort(cp) == T_SOA)) {		dn_expand(buf.qb2, buf.qb2 + len, nmp, dname[soacnt],			sizeof(dname[0]));	        if (soacnt) {		    if (strcmp(dname[0], dname[1]) == 0)			break;		} else		    soacnt++;	    }	}	if (putToFile) {	    fprintf(stdout, "%sReceived %d record%s.\n", 		(numAnswers >= HASH_SIZE) ? "\n" : "",		numAnswers,		(numAnswers > 1) ? "s" : "");	}	(void) close(sockFD);	sockFD = -1;	if (putToFile) {	    fclose(filePtr);	    filePtr = NULL;	}	switch (error) {	    case NO_ERRORS:		return (SUCCESS);	    case ERR_READING_LEN:		return(ERROR);	    case ERR_PRINTING:		fprintf(stderr,"*** Error during listing of %s: %s\n", 				namePtr, DecodeError(result));		return(result);	    case ERR_READING_MSG:		headerPtr = (HEADER *) &buf;		fprintf(stderr,"ListHosts: error receiving zone transfer:\n");		fprintf(stderr,	       "  result: %s, answers = %d, authority = %d, additional = %d\n", 		    	_res_resultcodes[headerPtr->rcode], 		    	ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), 			ntohs(headerPtr->arcount));		return(ERROR);	    default:		return(ERROR);	}}/* ******************************************************************************* * *  PrintListInfo -- * * 	Used by the ListInfo routine to print the answer  *	received from the name server. Only the desired  *	information is printed. * *  Results: *	SUCCESS		the answer was printed without a problem. *	NO_INFO		the answer packet did not contain an answer. *	ERROR		the answer was malformed. *      Misc. errors	returned in the packet header. * ******************************************************************************* */#define NAME_FORMAT " %-30s"#define STRIP_DOMAIN(string) if((dot = index(string, '.')) != NULL) *dot = '\0'PrintListInfo(file, msg, eom, queryType)    FILE 	*file;    char 	*msg, *eom;    int 	queryType;{    register char 	*cp;    HEADER 		*headerPtr;    int 		type, class, dlen, nameLen;    u_long		ttl;    int 		n;    struct in_addr 	inaddr;    char 		name[NAME_LEN];    char 		name2[NAME_LEN];    char 		*dot;    /*     * Read the header fields.     */    headerPtr = (HEADER *)msg;    cp = msg + sizeof(HEADER);    if (headerPtr->rcode != NOERROR) {	return(headerPtr->rcode);    }    /*     *  We are looking for info from answer resource records.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -