263bcef374276fcd769fddaf071f2992db845599
[mmh] / mts / smtp / hosts.c
1
2 /*
3  * hosts.c -- find out the official name of a host
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 /*
13  * In the SendMail world, we really don't know what the valid
14  * hosts are.  We could poke around in the sendmail.cf file, but
15  * that still isn't a guarantee.  As a result, we'll say that
16  * everything is a valid host, and let SendMail worry about it.
17  */
18
19 #include <h/mh.h>
20 #include <h/mts.h>
21 #include <netdb.h>
22
23 static struct host {
24     char *h_name;
25     char **h_aliases;
26     struct host *h_next;
27 } hosts;
28
29
30 /*
31  * static prototypes
32  */
33 static int init_hs(void);
34
35
36 char *
37 OfficialName (char *name)
38 {
39     char *p, *q, site[BUFSIZ];
40     struct hostent *hp;
41
42     static char buffer[BUFSIZ];
43     char **r;
44     struct host *h;
45
46     for (p = name, q = site; *p && (q - site < sizeof(site) - 1); p++, q++)
47         *q = isupper (*p) ? tolower (*p) : *p;
48     *q = '\0';
49     q = site;
50
51     if (!strcasecmp (LocalName(), site))
52         return LocalName();
53
54 #ifdef  HAVE_SETHOSTENT
55     sethostent (1);
56 #endif
57
58     if ((hp = gethostbyname (q))) {
59         strncpy (buffer, hp->h_name, sizeof(buffer));
60         return buffer;
61     }
62     if (hosts.h_name || init_hs ()) {
63         for (h = hosts.h_next; h; h = h->h_next)
64             if (!strcasecmp (h->h_name, q)) {
65                 return h->h_name;
66             } else {
67                 for (r = h->h_aliases; *r; r++)
68                     if (!strcasecmp (*r, q))
69                         return h->h_name;
70             }
71     }
72
73     strncpy (buffer, site, sizeof(buffer));
74     return buffer;
75 }
76
77 /*
78  * Use hostable as an exception file for those hosts that aren't
79  * on the Internet (listed in /etc/hosts).  These are usually
80  * PhoneNet and UUCP sites.
81  */
82
83 #define NALIASES 50
84
85 static int
86 init_hs (void)
87 {
88     char  *cp, *dp, **q, **r;
89     char buffer[BUFSIZ], *aliases[NALIASES];
90     register struct host *h;
91     register FILE  *fp;
92
93     if ((fp = fopen (hostable, "r")) == NULL)
94         return 0;
95
96     h = &hosts;
97     while (fgets (buffer, sizeof(buffer), fp) != NULL) {
98         if ((cp = strchr(buffer, '#')))
99             *cp = 0;
100         if ((cp = strchr(buffer, '\n')))
101             *cp = 0;
102         for (cp = buffer; *cp; cp++)
103             if (isspace (*cp))
104                 *cp = ' ';
105         for (cp = buffer; isspace (*cp); cp++)
106             continue;
107         if (*cp == 0)
108             continue;
109
110         q = aliases;
111         if ((cp = strchr(dp = cp, ' '))) {
112             *cp = 0;
113             for (cp++; *cp; cp++) {
114                 while (isspace (*cp))
115                     cp++;
116                 if (*cp == 0)
117                     break;
118                 if ((cp = strchr(*q++ = cp, ' ')))
119                     *cp = 0;
120                 else
121                     break;
122                 if (q >= aliases + NALIASES)
123                     break;
124             }
125         }
126
127         *q = 0;
128
129         h->h_next = (struct host *) calloc (1, sizeof(*h));
130         h = h->h_next;
131         h->h_name = getcpy (dp);
132         r = h->h_aliases =
133                 (char **) calloc ((size_t) (q - aliases + 1), sizeof(*q));
134         for (q = aliases; *q; q++)
135             *r++ = getcpy (*q);
136         *r = 0;
137     }
138
139     fclose (fp);
140     return 1;
141 }