1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 40 #include <netinet/in.h> 41 42 #include <stdio.h> 43 #include <netdb.h> 44 45 #define OUTFILE "hosts.txt" /* default output file */ 46 #define VERFILE "hosts.ver" /* default version file */ 47 #define QUERY "ALL\r\n" /* query to hostname server */ 48 #define VERSION "VERSION\r\n" /* get version number */ 49 50 #define equaln(s1, s2, n) (!strncmp(s1, s2, n)) 51 52 #ifdef SYSV 53 #define bcopy(a,b,c) memcpy(b,a,c) 54 #endif 55 56 struct sockaddr_in sin; 57 struct sockaddr_in sintmp; 58 char buf[BUFSIZ]; 59 char *outfile = OUTFILE; 60 61 int 62 main(argc, argv) 63 int argc; 64 char *argv[]; 65 { 66 int s; 67 register int len; 68 register FILE *sfi, *sfo, *hf; 69 char *host; 70 register struct hostent *hp; 71 struct servent *sp; 72 int version = 0; 73 int beginseen = 0; 74 int endseen = 0; 75 76 argv++, argc--; 77 if (argc > 0 && **argv == '-') { 78 if (argv[0][1] != 'v') 79 fprintf(stderr, "unknown option %s ignored\n", *argv); 80 else 81 version++, outfile = VERFILE; 82 argv++, argc--; 83 } 84 if (argc < 1 || argc > 2) { 85 fprintf(stderr, "usage: gettable [-v] host [ file ]\n"); 86 exit(1); 87 } 88 sp = getservbyname("hostnames", "tcp"); 89 if (sp == NULL) { 90 fprintf(stderr, "gettable: hostnames/tcp: unknown service\n"); 91 exit(3); 92 } 93 host = *argv; 94 argv++, argc--; 95 sintmp.sin_addr.s_addr = inet_addr(host); 96 if (sintmp.sin_addr.s_addr != -1 && sintmp.sin_addr.s_addr != 0) { 97 sin.sin_family = AF_INET; 98 } else { 99 hp = gethostbyname(host); 100 if (hp == NULL) { 101 fprintf(stderr, "gettable: %s: host unknown\n", host); 102 exit(2); 103 } else { 104 sin.sin_family = hp->h_addrtype; 105 host = hp->h_name; 106 } 107 } 108 if (argc > 0) 109 outfile = *argv; 110 s = socket(sin.sin_family, SOCK_STREAM, 0); 111 if (s < 0) { 112 perror("gettable: socket"); 113 exit(4); 114 } 115 if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 116 perror("gettable: bind"); 117 exit(5); 118 } 119 if (sintmp.sin_addr.s_addr != -1 && sintmp.sin_addr.s_addr != 0) 120 bcopy((char *)&sintmp.sin_addr, (char *)&sin.sin_addr, 121 sizeof(sintmp.sin_addr)); 122 else 123 bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length); 124 sin.sin_port = sp->s_port; 125 if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 126 perror("gettable: connect"); 127 exit(6); 128 } 129 fprintf(stderr, "Connection to %s opened.\n", host); 130 sfi = fdopen(s, "r"); 131 sfo = fdopen(s, "w"); 132 if (sfi == NULL || sfo == NULL) { 133 perror("gettable: fdopen"); 134 close(s); 135 exit(1); 136 } 137 hf = fopen(outfile, "w"); 138 if (hf == NULL) { 139 fprintf(stderr, "gettable: "); perror(outfile); 140 close(s); 141 exit(1); 142 } 143 fprintf(sfo, version ? VERSION : QUERY); 144 fflush(sfo); 145 while (fgets(buf, sizeof(buf), sfi) != NULL) { 146 len = strlen(buf); 147 buf[len-2] = '\0'; 148 if (!version && equaln(buf, "BEGIN", 5)) { 149 if (beginseen || endseen) { 150 fprintf(stderr, 151 "gettable: BEGIN sequence error\n"); 152 exit(90); 153 } 154 beginseen++; 155 continue; 156 } 157 if (!version && equaln(buf, "END", 3)) { 158 if (!beginseen || endseen) { 159 fprintf(stderr, 160 "gettable: END sequence error\n"); 161 exit(91); 162 } 163 endseen++; 164 continue; 165 } 166 if (equaln(buf, "ERR", 3)) { 167 fprintf(stderr, 168 "gettable: hostname service error: %s", buf); 169 exit(92); 170 } 171 fprintf(hf, "%s\n", buf); 172 } 173 fclose(hf); 174 if (!version) { 175 if (!beginseen) { 176 fprintf(stderr, "gettable: no BEGIN seen\n"); 177 exit(93); 178 } 179 if (!endseen) { 180 fprintf(stderr, "gettable: no END seen\n"); 181 exit(94); 182 } 183 fprintf(stderr, "Host table received.\n"); 184 } else 185 fprintf(stderr, "Version number received.\n"); 186 close(s); 187 fprintf(stderr, "Connection to %s closed\n", host); 188 return (0); 189 } 190