1 #ifndef lint 2 static char sccsid[] = "@(#)htable.c 4.5 (Berkeley) 06/18/83"; 3 #endif 4 5 /* 6 * htable - convert NIC host table into a UNIX format. 7 * NIC format is described in RFC 810, 1 March 1982. 8 */ 9 #include <stdio.h> 10 #include <ctype.h> 11 #include <errno.h> 12 #include <netdb.h> 13 14 #include "htable.h" /* includes <sys/types.h> */ 15 16 #include <sys/socket.h> 17 #include <netinet/in.h> 18 19 #define INTERNET 10 /* gag */ 20 21 #define DATELINES 3 /* these lines usually contain the date */ 22 23 FILE *hf; /* hosts file */ 24 FILE *gf; /* gateways file */ 25 FILE *nf; /* networks file */ 26 27 main(argc, argv) 28 int argc; 29 char *argv[]; 30 { 31 if (argc > 2) { 32 fprintf(stderr, "usage: %s [ input-file ]\n", 33 argv[0]); 34 exit(1); 35 } 36 infile = "(stdin)"; 37 if (argc == 2) { 38 infile = argv[1]; 39 if (freopen(infile, "r", stdin) == NULL) { 40 perror(infile); 41 exit(1); 42 } 43 } 44 hf = fopen("hosts", "w"); 45 if (hf == NULL) { 46 perror("hosts"); 47 exit(1); 48 } 49 copylocal(hf, "localhosts"); 50 gf = fopen("gateways", "w"); 51 if (gf == NULL) { 52 perror("gateways"); 53 exit(1); 54 } 55 copylocal(gf, "localgateways"); 56 nf = fopen("networks", "w"); 57 if (nf == NULL) { 58 perror("networks"); 59 exit(1); 60 } 61 copylocal(nf, "localnetworks"); 62 copycomments(stdin, hf, DATELINES); 63 exit(yyparse()); 64 } 65 66 struct name * 67 newname(str) 68 char *str; 69 { 70 char *p; 71 struct name *nm; 72 73 p = malloc(strlen(str) + 1); 74 strcpy(p, str); 75 nm = (struct name *)malloc(sizeof (struct name)); 76 nm->name_val = p; 77 nm->name_link = NONAME; 78 return (nm); 79 } 80 81 char * 82 lower(str) 83 char *str; 84 { 85 register char *cp = str; 86 87 while (*cp) { 88 if (isupper(*cp)) 89 *cp = tolower(*cp); 90 cp++; 91 } 92 return (str); 93 } 94 95 do_entry(keyword, addrlist, namelist, cputype, opsys, protos) 96 int keyword; 97 struct addr *addrlist; 98 struct name *namelist, *cputype, *opsys, *protos; 99 { 100 register struct addr *al, *al2; 101 register struct name *nl; 102 struct addr *inetal; 103 int count; 104 105 switch (keyword) { 106 107 case KW_NET: 108 nl = namelist; 109 if (nl == NONAME) { 110 fprintf(stderr, "htable: net"); 111 putnet(stderr, addrlist->addr_val); 112 fprintf(stderr, " missing names.\n"); 113 break; 114 } 115 fprintf(nf, "%-16.16s", lower(nl->name_val)); 116 al2 = addrlist; 117 while (al = al2) { 118 char *cp; 119 120 putnet(nf, al->addr_val); 121 cp = "\t%s"; 122 while (nl = nl->name_link) { 123 fprintf(nf, cp, lower(nl->name_val)); 124 cp = " %s"; 125 } 126 putc('\n', nf); 127 al2 = al->addr_link; 128 free((char *)al); 129 } 130 goto alreadyfree; 131 132 case KW_GATEWAY: 133 /* 134 * Kludge here: take only gateways directly connected to 135 * the Internet. Should really calculate closure on 136 * connectivity matrix to identify gateways to all networks 137 * described in data base, but that's real work. 138 */ 139 /* locate Internet address, if one */ 140 for (al = addrlist; al; al = al->addr_link) 141 if (inet_netof(al->addr_val) == INTERNET) 142 break; 143 if (al == NULL) 144 break; 145 inetal = al; 146 for (count = 0, al = al->addr_link; al; al = al->addr_link) { 147 register int net; 148 register struct netent *np; 149 150 if (al == inetal) 151 continue; 152 /* suppress duplicates -- not optimal */ 153 net = inet_netof(al->addr_val); 154 if (checkgateway(net)) 155 break; 156 count++; 157 fprintf(gf, "net "); 158 np = getnetbyaddr(net, AF_INET); 159 if (np) 160 fprintf(gf, "%s", np->n_name); 161 else 162 putnet(gf, net); 163 /* this is a kludge */ 164 fprintf(gf, " gateway %s metric 1 passive\n", 165 lower(namelist->name_val)); 166 savegateway(net); 167 } 168 if (count > 0) { 169 putaddr(hf, inetal->addr_val); 170 fprintf(hf, "%s\t# gateway\n", 171 lower(namelist->name_val)); 172 } 173 break; 174 175 case KW_HOST: 176 al2 = addrlist; 177 while (al = al2) { 178 if (inet_netof(al->addr_val) != LOCALNET) { 179 char *cp; 180 181 putaddr(hf, al->addr_val); 182 cp = "%s"; 183 for (nl = namelist; nl; nl = nl->name_link) { 184 fprintf(hf, cp, lower(nl->name_val)); 185 cp = " %s"; 186 } 187 putc('\n', hf); 188 } 189 al2 = al->addr_link; 190 free((char *)al); 191 } 192 goto alreadyfree; 193 194 default: 195 fprintf(stderr, "Unknown keyword: %d.\n", keyword); 196 } 197 al2 = addrlist; 198 while (al = al2) 199 al2 = al->addr_link, free((char *)al); 200 alreadyfree: 201 freenames(namelist); 202 freenames(protos); 203 } 204 205 copylocal(f, filename) 206 FILE *f; 207 char *filename; 208 { 209 register FILE *lhf; 210 register cc; 211 char buf[BUFSIZ]; 212 extern int errno; 213 214 lhf = fopen(filename, "r"); 215 if (lhf == NULL) { 216 if (errno != ENOENT) { 217 perror(filename); 218 exit(1); 219 } 220 fprintf(stderr, "Warning, no %s file.\n", filename); 221 return; 222 } 223 while (cc = fread(buf, 1, sizeof(buf), lhf)) 224 fwrite(buf, 1, cc, f); 225 fclose(lhf); 226 } 227 228 copycomments(in, out, ccount) 229 FILE *in, *out; 230 int ccount; 231 { 232 char buf[BUFSIZ]; 233 int length; 234 int count; 235 char *fgets(); 236 237 for (count=0; count < ccount; count++) { 238 if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';')) 239 return; 240 buf[0] = '#'; 241 fputs(buf, out); 242 } 243 return; 244 } 245 #define UC(b) (((int)(b))&0xff) 246 247 putnet(f, v) 248 FILE *f; 249 u_long v; 250 { 251 register char *a = (char *)&v; 252 253 if (UC(a[0]&0x80) == 0) 254 fprintf(f, "%d", UC(a[0])); 255 else if ((UC(a[0])&0x40) == 0) 256 fprintf(f, "%d.%d", UC(a[0]), UC(a[1])); 257 else 258 fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2])); 259 } 260 261 putaddr(f, v) 262 FILE *f; 263 u_long v; 264 { 265 register char *a = (char *)&v; 266 char buf[32]; 267 268 sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3])); 269 fprintf(f, "%-16.16s", buf); 270 } 271 272 freenames(list) 273 struct name *list; 274 { 275 register struct name *nl, *nl2; 276 277 nl2 = list; 278 while (nl = nl2) { 279 nl2 = nl->name_link; 280 free(nl->name_val); 281 free((char *)nl); 282 } 283 } 284 struct gateway { 285 struct gateway *g_link; 286 int g_net; 287 }; 288 289 struct gateway *gateways = 0; 290 291 checkgateway(net) 292 register int net; 293 { 294 register struct gateway *gp; 295 296 for (gp = gateways; gp; gp = gp->g_link) 297 if (gp->g_net == net) 298 return (1); 299 return (0); 300 } 301 302 savegateway(net) 303 int net; 304 { 305 register struct gateway *gp; 306 307 gp = (struct gateway *)malloc(sizeof (struct gateway)); 308 if (gp == 0) { 309 fprintf(stderr, "htable: out of memory\n"); 310 exit(1); 311 } 312 gp->g_link = gateways; 313 gp->g_net = net; 314 gateways = gp; 315 } 316 317