121123Sdist /*
235612Sbostic * Copyright (c) 1983 The Regents of the University of California.
335612Sbostic * All rights reserved.
435612Sbostic *
542798Sbostic * %sccs.include.redist.c%
621123Sdist */
721123Sdist
810038Ssam #ifndef lint
935612Sbostic char copyright[] =
1035612Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
1135612Sbostic All rights reserved.\n";
1235612Sbostic #endif /* not lint */
1310038Ssam
1435612Sbostic #ifndef lint
15*46905Sbostic static char sccsid[] = "@(#)gettable.c 5.6 (Berkeley) 03/02/91";
1635612Sbostic #endif /* not lint */
1735612Sbostic
1810038Ssam #include <sys/types.h>
1910038Ssam #include <sys/socket.h>
2010038Ssam
2110038Ssam #include <netinet/in.h>
2210038Ssam
2310038Ssam #include <stdio.h>
2410038Ssam #include <netdb.h>
2510038Ssam
2610038Ssam #define OUTFILE "hosts.txt" /* default output file */
2716078Sralph #define VERFILE "hosts.ver" /* default version file */
2810038Ssam #define QUERY "ALL\r\n" /* query to hostname server */
2916078Sralph #define VERSION "VERSION\r\n" /* get version number */
3010038Ssam
3110038Ssam #define equaln(s1, s2, n) (!strncmp(s1, s2, n))
3210038Ssam
3310038Ssam struct sockaddr_in sin;
3410038Ssam char buf[BUFSIZ];
3510038Ssam char *outfile = OUTFILE;
3610038Ssam
main(argc,argv)3710038Ssam main(argc, argv)
3810038Ssam int argc;
3910038Ssam char *argv[];
4010038Ssam {
4110038Ssam int s;
4210038Ssam register len;
4310038Ssam register FILE *sfi, *sfo, *hf;
4410038Ssam char *host;
4510038Ssam register struct hostent *hp;
4610038Ssam struct servent *sp;
4716078Sralph int version = 0;
4817581Ssam int beginseen = 0;
4917581Ssam int endseen = 0;
5010038Ssam
5110038Ssam argv++, argc--;
5216078Sralph if (**argv == '-') {
5316078Sralph if (argv[0][1] != 'v')
5416078Sralph fprintf(stderr, "unknown option %s ignored\n", *argv);
5516078Sralph else
5616078Sralph version++, outfile = VERFILE;
5716078Sralph argv++, argc--;
5816078Sralph }
5910038Ssam if (argc < 1 || argc > 2) {
6016078Sralph fprintf(stderr, "usage: gettable [-v] host [ file ]\n");
6110038Ssam exit(1);
6210038Ssam }
6315167Skarels sp = getservbyname("hostnames", "tcp");
6410038Ssam if (sp == NULL) {
6515167Skarels fprintf(stderr, "gettable: hostnames/tcp: unknown service\n");
6610038Ssam exit(3);
6710038Ssam }
6810038Ssam host = *argv;
6910038Ssam argv++, argc--;
7010038Ssam hp = gethostbyname(host);
7110038Ssam if (hp == NULL) {
7235785Sbostic fprintf(stderr, "gettable: %s: ", host);
7335785Sbostic herror((char *)NULL);
7410038Ssam exit(2);
7510038Ssam }
7610038Ssam host = hp->h_name;
7710038Ssam if (argc > 0)
7810038Ssam outfile = *argv;
7910038Ssam sin.sin_family = hp->h_addrtype;
8027646Slepreau s = socket(hp->h_addrtype, SOCK_STREAM, 0);
8110038Ssam if (s < 0) {
8210038Ssam perror("gettable: socket");
8310038Ssam exit(4);
8410038Ssam }
85*46905Sbostic if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
8610038Ssam perror("gettable: bind");
8710038Ssam exit(5);
8810038Ssam }
89*46905Sbostic bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
9010038Ssam sin.sin_port = sp->s_port;
91*46905Sbostic if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
9210038Ssam perror("gettable: connect");
9310038Ssam exit(6);
9410038Ssam }
9510038Ssam fprintf(stderr, "Connection to %s opened.\n", host);
9610038Ssam sfi = fdopen(s, "r");
9710038Ssam sfo = fdopen(s, "w");
9810038Ssam if (sfi == NULL || sfo == NULL) {
9910038Ssam perror("gettable: fdopen");
10010038Ssam close(s);
10110038Ssam exit(1);
10210038Ssam }
10310038Ssam hf = fopen(outfile, "w");
10410038Ssam if (hf == NULL) {
10510038Ssam fprintf(stderr, "gettable: "); perror(outfile);
10610038Ssam close(s);
10710038Ssam exit(1);
10810038Ssam }
10916078Sralph fprintf(sfo, version ? VERSION : QUERY);
11010038Ssam fflush(sfo);
11110038Ssam while (fgets(buf, sizeof(buf), sfi) != NULL) {
11210038Ssam len = strlen(buf);
11310038Ssam buf[len-2] = '\0';
11417581Ssam if (!version && equaln(buf, "BEGIN", 5)) {
11517581Ssam if (beginseen || endseen) {
11617581Ssam fprintf(stderr,
11717581Ssam "gettable: BEGIN sequence error\n");
11817581Ssam exit(90);
11917581Ssam }
12017581Ssam beginseen++;
12110038Ssam continue;
12210038Ssam }
12317581Ssam if (!version && equaln(buf, "END", 3)) {
12417581Ssam if (!beginseen || endseen) {
12517581Ssam fprintf(stderr,
12617581Ssam "gettable: END sequence error\n");
12717581Ssam exit(91);
12817581Ssam }
12917581Ssam endseen++;
13010038Ssam continue;
13110038Ssam }
13217581Ssam if (equaln(buf, "ERR", 3)) {
13317581Ssam fprintf(stderr,
13417581Ssam "gettable: hostname service error: %s", buf);
13517581Ssam exit(92);
13617581Ssam }
13710038Ssam fprintf(hf, "%s\n", buf);
13810038Ssam }
13910038Ssam fclose(hf);
14017581Ssam if (!version) {
14117581Ssam if (!beginseen) {
14217581Ssam fprintf(stderr, "gettable: no BEGIN seen\n");
14317581Ssam exit(93);
14417581Ssam }
14517581Ssam if (!endseen) {
14617581Ssam fprintf(stderr, "gettable: no END seen\n");
14717581Ssam exit(94);
14817581Ssam }
14917581Ssam fprintf(stderr, "Host table received.\n");
15017581Ssam } else
15116078Sralph fprintf(stderr, "Version number received.\n");
15210038Ssam close(s);
15310038Ssam fprintf(stderr, "Connection to %s closed\n", host);
15416078Sralph exit(0);
15510038Ssam }
156