Change all chars being passed to the ctype macros (isalph(), etc.) to
[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     unsigned char *p;
40     char *q, site[BUFSIZ];
41     struct hostent *hp;
42
43     static char buffer[BUFSIZ];
44     char **r;
45     struct host *h;
46
47     for (p = name, q = site; *p && (q - site < sizeof(site) - 1); p++, q++)
48         *q = isupper (*p) ? tolower (*p) : *p;
49     *q = '\0';
50     q = site;
51
52     if (!mh_strcasecmp (LocalName(), site))
53         return LocalName();
54
55 #ifdef  HAVE_SETHOSTENT
56     sethostent (1);
57 #endif
58
59     if ((hp = gethostbyname (q))) {
60         strncpy (buffer, hp->h_name, sizeof(buffer));
61         return buffer;
62     }
63     if (hosts.h_name || init_hs ()) {
64         for (h = hosts.h_next; h; h = h->h_next)
65             if (!mh_strcasecmp (h->h_name, q)) {
66                 return h->h_name;
67             } else {
68                 for (r = h->h_aliases; *r; r++)
69                     if (!mh_strcasecmp (*r, q))
70                         return h->h_name;
71             }
72     }
73
74     strncpy (buffer, site, sizeof(buffer));
75     return buffer;
76 }
77
78 /*
79  * Use hostable as an exception file for those hosts that aren't
80  * on the Internet (listed in /etc/hosts).  These are usually
81  * PhoneNet and UUCP sites.
82  */
83
84 #define NALIASES 50
85
86 static int
87 init_hs (void)
88 {
89     unsigned char  *cp;
90     char *dp, **q, **r;
91     char buffer[BUFSIZ], *aliases[NALIASES];
92     register struct host *h;
93     register FILE  *fp;
94
95     if ((fp = fopen (hostable, "r")) == NULL)
96         return 0;
97
98     h = &hosts;
99     while (fgets (buffer, sizeof(buffer), fp) != NULL) {
100         if ((cp = strchr(buffer, '#')))
101             *cp = 0;
102         if ((cp = strchr(buffer, '\n')))
103             *cp = 0;
104         for (cp = buffer; *cp; cp++)
105             if (isspace (*cp))
106                 *cp = ' ';
107         for (cp = buffer; isspace (*cp); cp++)
108             continue;
109         if (*cp == 0)
110             continue;
111
112         q = aliases;
113         if ((cp = strchr(dp = cp, ' '))) {
114             *cp = 0;
115             for (cp++; *cp; cp++) {
116                 while (isspace (*cp))
117                     cp++;
118                 if (*cp == 0)
119                     break;
120                 if ((cp = strchr(*q++ = cp, ' ')))
121                     *cp = 0;
122                 else
123                     break;
124                 if (q >= aliases + NALIASES)
125                     break;
126             }
127         }
128
129         *q = 0;
130
131         h->h_next = (struct host *) calloc (1, sizeof(*h));
132         h = h->h_next;
133         h->h_name = getcpy (dp);
134         r = h->h_aliases =
135                 (char **) calloc ((size_t) (q - aliases + 1), sizeof(*q));
136         for (q = aliases; *q; q++)
137             *r++ = getcpy (*q);
138         *r = 0;
139     }
140
141     fclose (fp);
142     return 1;
143 }