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 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