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