xref: /csrg-svn/old/gettable/gettable.c (revision 21123)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)gettable.c	5.1 (Berkeley) 05/28/85";
9 #endif not lint
10 
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 
14 #include <netinet/in.h>
15 
16 #include <stdio.h>
17 #include <netdb.h>
18 
19 #define	OUTFILE		"hosts.txt"	/* default output file */
20 #define	VERFILE		"hosts.ver"	/* default version file */
21 #define	QUERY		"ALL\r\n"	/* query to hostname server */
22 #define	VERSION		"VERSION\r\n"	/* get version number */
23 
24 #define	equaln(s1, s2, n)	(!strncmp(s1, s2, n))
25 
26 struct	sockaddr_in sin;
27 char	buf[BUFSIZ];
28 char	*outfile = OUTFILE;
29 
30 main(argc, argv)
31 	int argc;
32 	char *argv[];
33 {
34 	int s;
35 	register len;
36 	register FILE *sfi, *sfo, *hf;
37 	register char *p;
38 	char *host;
39 	register struct hostent *hp;
40 	struct servent *sp;
41 	int version = 0;
42 	int beginseen = 0;
43 	int endseen = 0;
44 
45 	argv++, argc--;
46 	if (**argv == '-') {
47 		if (argv[0][1] != 'v')
48 			fprintf(stderr, "unknown option %s ignored\n", *argv);
49 		else
50 			version++, outfile = VERFILE;
51 		argv++, argc--;
52 	}
53 	if (argc < 1 || argc > 2) {
54 		fprintf(stderr, "usage: gettable [-v] host [ file ]\n");
55 		exit(1);
56 	}
57 	sp = getservbyname("hostnames", "tcp");
58 	if (sp == NULL) {
59 		fprintf(stderr, "gettable: hostnames/tcp: unknown service\n");
60 		exit(3);
61 	}
62 	host = *argv;
63 	argv++, argc--;
64 	hp = gethostbyname(host);
65 	if (hp == NULL) {
66 		fprintf(stderr, "gettable: %s: host unknown\n", host);
67 		exit(2);
68 	}
69 	host = hp->h_name;
70 	if (argc > 0)
71 		outfile = *argv;
72 	sin.sin_family = hp->h_addrtype;
73 	s = socket(hp->h_addrtype, SOCK_STREAM, 0, 0);
74 	if (s < 0) {
75 		perror("gettable: socket");
76 		exit(4);
77 	}
78 	if (bind(s, &sin, sizeof (sin), 0) < 0) {
79 		perror("gettable: bind");
80 		exit(5);
81 	}
82 	bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
83 	sin.sin_port = sp->s_port;
84 	if (connect(s, &sin, sizeof (sin), 0) < 0) {
85 		perror("gettable: connect");
86 		exit(6);
87 	}
88 	fprintf(stderr, "Connection to %s opened.\n", host);
89 	sfi = fdopen(s, "r");
90 	sfo = fdopen(s, "w");
91 	if (sfi == NULL || sfo == NULL) {
92 		perror("gettable: fdopen");
93 		close(s);
94 		exit(1);
95 	}
96 	hf = fopen(outfile, "w");
97 	if (hf == NULL) {
98 		fprintf(stderr, "gettable: "); perror(outfile);
99 		close(s);
100 		exit(1);
101 	}
102 	fprintf(sfo, version ? VERSION : QUERY);
103 	fflush(sfo);
104 	while (fgets(buf, sizeof(buf), sfi) != NULL) {
105 		len = strlen(buf);
106 		buf[len-2] = '\0';
107 		if (!version && equaln(buf, "BEGIN", 5)) {
108 			if (beginseen || endseen) {
109 				fprintf(stderr,
110 				    "gettable: BEGIN sequence error\n");
111 				exit(90);
112 			}
113 			beginseen++;
114 			continue;
115 		}
116 		if (!version && equaln(buf, "END", 3)) {
117 			if (!beginseen || endseen) {
118 				fprintf(stderr,
119 				    "gettable: END sequence error\n");
120 				exit(91);
121 			}
122 			endseen++;
123 			continue;
124 		}
125 		if (equaln(buf, "ERR", 3)) {
126 			fprintf(stderr,
127 			    "gettable: hostname service error: %s", buf);
128 			exit(92);
129 		}
130 		fprintf(hf, "%s\n", buf);
131 	}
132 	fclose(hf);
133 	if (!version) {
134 		if (!beginseen) {
135 			fprintf(stderr, "gettable: no BEGIN seen\n");
136 			exit(93);
137 		}
138 		if (!endseen) {
139 			fprintf(stderr, "gettable: no END seen\n");
140 			exit(94);
141 		}
142 		fprintf(stderr, "Host table received.\n");
143 	} else
144 		fprintf(stderr, "Version number received.\n");
145 	close(s);
146 	fprintf(stderr, "Connection to %s closed\n", host);
147 	exit(0);
148 }
149