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