source: trunk/athena/bin/hostinfo/hostinfo.c @ 5279

Revision 5279, 6.2 KB checked in by epeisach, 33 years ago (diff)
[tom] mx queries and fixes to allow multiple host lookups\
Line 
1/* This program looks up a given hostname on the nameserver and prints
2 * its Internet address, official name, etc.
3 *
4 * Win Treese
5 * MIT Project Athena
6 *
7 * Copyright (c) 1986 by the Massachusetts Institute of Technology.
8 *
9 * Created:     08/29/86
10 *
11 * Modified:    02/03/87        Doug Alan
12 *              Let input also be in form of an internet address.
13 *
14 * Modified:    02/04/87        Doug Alan
15 *              Take flags to control output.
16 *
17 * Modified:    08/20/90        Tom Coppeto
18 *              Added HINFO and MX queries.
19 *              List all returned addresses
20 *              Allow for multiple hostnames.
21 *                     
22 */
23
24#ifndef lint
25static char rcsid[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/hostinfo/hostinfo.c,v 1.6 1991-07-08 10:05:40 epeisach Exp $";
26#endif
27
28#include <stdio.h>                      /* Standard IO */
29#include <sys/types.h>                  /* System type defs. */
30#include <netdb.h>                      /* Networking defs. */
31#include <sys/socket.h>                 /* More network defs. */
32#include <strings.h>                    /* String fct. declarations. */
33#include <ctype.h>                      /* Character type macros. */
34#include <netinet/in.h>                 /* Internet defs. */
35
36typedef int bool;
37
38#define TRUE            1
39#define FALSE           0
40#define LINE_LENGTH     128
41#define ERROR           -1
42#define CPNULL          ((char *) NULL)
43
44static char *usage[] = {
45  "Usage: %s <options> <host-names-or-addresses>",
46  "   -h: output only hostname",
47  "   -a: output only internet address",
48  "   -i: output only host info record",
49  "   -m: output only mx record",
50  "   -q: disable additional query for hinfo & mx",
51  "   -ns <server>: ask specified name server",
52  CPNULL,
53};
54
55char *myname;                           /* How program was invoked. */
56char *hostname = NULL;                  /* desired host */
57
58struct in_addr server_addr;
59int server_specified;
60
61bool h_flag = FALSE;
62bool a_flag = FALSE;
63bool n_flag = FALSE;
64bool m_flag = FALSE;
65bool i_flag = FALSE;
66bool q_flag = FALSE;
67
68static void usage_error();
69static void clear_flags();
70
71main(argc, argv)
72     int argc;
73     char **argv;
74     
75{
76  extern int h_errno;
77  struct hostent *host_entry = NULL;   
78  unsigned long host_address;
79  char *server = NULL;
80  char *hinfo = NULL;
81  char *mx = NULL;
82  int status = 0;
83  int set_server = 0;
84
85  myname = (myname = rindex(argv[0], '/')) ? myname + 1 : argv[0];
86  if(argc == 1)
87    usage_error();
88  if(strcmp(argv[1], "-help") == 0)
89    usage_error();
90
91  while(*++argv)
92    {
93      if(hostname && !(a_flag || m_flag || i_flag || h_flag))
94        putchar('\n');
95
96      set_server = 0;
97      if(**argv == '-')
98        switch((*argv)[1])
99          {
100          case 'h':
101            clear_flags();
102            h_flag = TRUE;
103            continue;
104          case 'a':
105            clear_flags();
106            a_flag = TRUE;
107            continue;
108          case 'm':
109            clear_flags();
110            m_flag = TRUE;
111            continue;
112          case 'i':
113            clear_flags();
114            i_flag = TRUE;
115            continue;
116          case 'q':
117            clear_flags();
118            q_flag = TRUE;
119            continue;
120          case 'n':
121            if(!*++argv)
122              usage_error();
123            server = *argv;
124            set_server = 1;
125            break;
126          case '?':
127          default:
128            usage_error();
129            break;
130          }
131     
132      hinfo = NULL;
133      mx = NULL;
134      host_address = 0;
135      host_entry = NULL;
136      hostname = *argv;
137     
138      if (*hostname >= '0' && *hostname <= '9')
139        {
140          host_address = inet_addr(hostname);
141          if (host_address)
142            {
143              host_entry = gethostbyaddr((char *) &host_address, 4, AF_INET);
144              if(host_entry)
145                if(set_server)           
146                  bcopy(host_entry->h_addr, &server_addr, sizeof(server_addr));
147                else             
148                  print_host(host_entry);
149            }
150        }
151
152      if(host_entry <= 0)
153        {
154          host_entry = gethostbyname(hostname);
155          if(host_entry)
156            {
157              if(set_server)
158                bcopy(host_entry->h_addr, &server_addr, sizeof(server_addr));
159              else
160                {
161                  print_host(host_entry);
162                  if(!q_flag)
163                    {
164                      hinfo = (char *) gethinfobyname(hostname);
165                      if(hinfo)
166                        {
167                          if(!h_flag && !a_flag && !m_flag)
168                            {
169                              int i = (int) hinfo[0];
170                              hinfo[i+1] = '/';
171                              if(i_flag)
172                                printf("%s\n", hinfo+1);
173                              else
174                                printf("Host info:\t%s\n", hinfo+1);
175                            }
176                        }
177                      if(!h_flag && !a_flag && !i_flag)
178                        if(mx = (char *) getmxbyname(hostname))
179                          if(m_flag)
180                            printf("%s\n", mx);
181                          else
182                            printf("MX address:\t%s\n", mx);             
183                    }
184                }
185            }
186        }
187 
188      if(host_entry && set_server)
189        {
190          struct in_addr internet_address;
191
192          server_specified = 1;
193          bcopy(host_entry->h_addr_list[0], &internet_address,
194                host_entry->h_length);
195          printf("Using domain server:\nHost name:\t%s\nHost Address\t%s\n",
196                 host_entry->h_name, inet_ntoa(internet_address));
197          continue;
198        }
199
200      if (!host_entry)
201        {
202          switch (h_errno)
203            {
204#ifdef ultrix
205              /* it can return NULL, h_errno == 0 in some cases when
206                 there is no name */
207            case 0:
208#endif
209            case HOST_NOT_FOUND:
210              printf("No such host '%s'.\n",hostname);
211              status = ERROR;
212              continue;
213              break;
214            default:
215            case TRY_AGAIN:
216            case NO_RECOVERY:
217              printf("Cannot resolve name '%s' due to network difficulties.\n",
218                     hostname);
219              status = ERROR;
220              continue;
221              break;
222            case NO_ADDRESS:
223            /* should look up MX record? */
224              /* this error return appears if there is some entry for the
225                 requested name, but no A record (e.g. only an NS record) */
226              printf("No address for '%s'.\n", hostname);
227              status = ERROR;
228              continue;
229              break;
230            }
231        }
232    }
233 
234  exit(status);
235} /* main */
236
237
238print_host(h)
239     struct hostent *h;
240{
241  struct in_addr internet_address;
242  char **alias;                           
243  char **addr;
244
245  if(m_flag || i_flag)
246    return;
247
248  if (h_flag)
249    printf("%s\n", h->h_name);
250  else 
251    {
252      if(!a_flag)
253        {
254          printf("Desired host:\t%s\n", hostname);
255          printf("Official name:\t%s\n", h->h_name);
256          for (alias = h->h_aliases; *alias; alias++)
257            printf("Alias:\t\t%s\n", *alias);
258        }
259         
260      for (addr = h->h_addr_list; *addr; addr++)
261        {
262          bcopy(*addr, &internet_address, h->h_length);
263          if(a_flag)
264            printf("%s\n", inet_ntoa(internet_address));
265          else
266            printf("Host address:\t%s\n", inet_ntoa(internet_address));
267        }
268    }
269}
270
271
272static void
273usage_error()
274{
275  int line = 0;                         /* current line */
276  while (usage[line] != CPNULL)
277    {
278      fprintf (stderr, usage[line++], myname);
279      putc('\n', stderr);
280    }
281  exit(ERROR);
282} /* usage_error */
283
284
285static void
286clear_flags()
287{
288  i_flag = m_flag = h_flag = a_flag = 0;
289}
Note: See TracBrowser for help on using the repository browser.