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