Commit | Line | Data |
---|---|---|
d185cb11 | 1 | /* |
dc45ba8c | 2 | * Copyright (c) 1983 Eric P. Allman |
31de980b KB |
3 | * Copyright (c) 1988, 1993 |
4 | * The Regents of the University of California. All rights reserved. | |
710322bb | 5 | * |
417f7a11 | 6 | * %sccs.include.redist.c% |
710322bb | 7 | */ |
d185cb11 | 8 | |
d0432129 | 9 | #include <errno.h> |
97543758 | 10 | #include "sendmail.h" |
6b6d57eb | 11 | # include <sys/mx.h> |
ef34cbda | 12 | |
710322bb KB |
13 | #ifndef lint |
14 | #ifdef DAEMON | |
832e8a27 | 15 | static char sccsid[] = "@(#)daemon.c 8.74 (Berkeley) %G% (with daemon mode)"; |
710322bb | 16 | #else |
832e8a27 | 17 | static char sccsid[] = "@(#)daemon.c 8.74 (Berkeley) %G% (without daemon mode)"; |
710322bb KB |
18 | #endif |
19 | #endif /* not lint */ | |
20 | ||
21 | #ifdef DAEMON | |
17a67c62 | 22 | |
17a67c62 | 23 | # include <netdb.h> |
377054c1 | 24 | # include <arpa/inet.h> |
17a67c62 | 25 | |
efe7f723 | 26 | #if NAMED_BIND |
ab6ca5e5 EA |
27 | # include <resolv.h> |
28 | #endif | |
29 | ||
ef34cbda EA |
30 | /* |
31 | ** DAEMON.C -- routines to use when running as a daemon. | |
2a16bae3 EA |
32 | ** |
33 | ** This entire file is highly dependent on the 4.2 BSD | |
34 | ** interprocess communication primitives. No attempt has | |
35 | ** been made to make this file portable to Version 7, | |
36 | ** Version 6, MPX files, etc. If you should try such a | |
37 | ** thing yourself, I recommend chucking the entire file | |
38 | ** and starting from scratch. Basic semantics are: | |
39 | ** | |
40 | ** getrequests() | |
41 | ** Opens a port and initiates a connection. | |
42 | ** Returns in a child. Must set InChannel and | |
43 | ** OutChannel appropriately. | |
eb8af3ce EA |
44 | ** clrdaemon() |
45 | ** Close any open files associated with getting | |
46 | ** the connection; this is used when running the queue, | |
47 | ** etc., to avoid having extra file descriptors during | |
48 | ** the queue run and to avoid confusing the network | |
49 | ** code (if it cares). | |
8657d05f | 50 | ** makeconnection(host, port, outfile, infile, usesecureport) |
2a16bae3 EA |
51 | ** Make a connection to the named host on the given |
52 | ** port. Set *outfile and *infile to the files | |
53 | ** appropriate for communication. Returns zero on | |
54 | ** success, else an exit status describing the | |
55 | ** error. | |
713c523f | 56 | ** host_map_lookup(map, hbuf, avp, pstat) |
5a4c03c6 | 57 | ** Convert the entry in hbuf into a canonical form. |
ef34cbda | 58 | */ |
6b6d57eb EA |
59 | |
60 | static FILE *MailPort; /* port that mail comes in on */ | |
ef34cbda EA |
61 | \f/* |
62 | ** GETREQUESTS -- open mail IPC port and get requests. | |
63 | ** | |
64 | ** Parameters: | |
65 | ** none. | |
66 | ** | |
67 | ** Returns: | |
68 | ** none. | |
69 | ** | |
70 | ** Side Effects: | |
71 | ** Waits until some interesting activity occurs. When | |
72 | ** it does, a child is created to process it, and the | |
73 | ** parent waits for completion. Return from this | |
40d27fed EA |
74 | ** routine is always in the child. The file pointers |
75 | ** "InChannel" and "OutChannel" should be set to point | |
76 | ** to the communication channel. | |
ef34cbda EA |
77 | */ |
78 | ||
8829f52e EA |
79 | int DaemonSocket = -1; /* fd describing socket */ |
80 | SOCKADDR DaemonAddr; /* socket for incoming */ | |
278c561a | 81 | int ListenQueueSize = 10; /* size of listen queue */ |
118dcfcf EA |
82 | int TcpRcvBufferSize = 0; /* size of TCP receive buffer */ |
83 | int TcpSndBufferSize = 0; /* size of TCP send buffer */ | |
14a39063 | 84 | |
ea07b2d2 | 85 | void |
7f108496 | 86 | getrequests() |
14a39063 | 87 | { |
7e3417e6 | 88 | int t; |
a90a7c55 | 89 | bool refusingconnections = TRUE; |
654398d7 | 90 | FILE *pidf; |
54c90151 | 91 | int socksize; |
6e48b8f0 EA |
92 | #ifdef XDEBUG |
93 | bool j_has_dot; | |
94 | #endif | |
0df908a9 | 95 | extern void reapchild(); |
14a39063 EA |
96 | |
97 | /* | |
98 | ** Set up the address for the mailer. | |
99 | */ | |
100 | ||
8829f52e EA |
101 | if (DaemonAddr.sin.sin_family == 0) |
102 | DaemonAddr.sin.sin_family = AF_INET; | |
103 | if (DaemonAddr.sin.sin_addr.s_addr == 0) | |
104 | DaemonAddr.sin.sin_addr.s_addr = INADDR_ANY; | |
105 | if (DaemonAddr.sin.sin_port == 0) | |
7f108496 | 106 | { |
c075e44e EA |
107 | register struct servent *sp; |
108 | ||
8829f52e EA |
109 | sp = getservbyname("smtp", "tcp"); |
110 | if (sp == NULL) | |
111 | { | |
9964213c | 112 | syserr("554 service \"smtp\" unknown"); |
c075e44e | 113 | DaemonAddr.sin.sin_port = htons(25); |
8829f52e | 114 | } |
c075e44e EA |
115 | else |
116 | DaemonAddr.sin.sin_port = sp->s_port; | |
7f108496 | 117 | } |
14a39063 EA |
118 | |
119 | /* | |
120 | ** Try to actually open the connection. | |
121 | */ | |
122 | ||
9678c96d | 123 | if (tTd(15, 1)) |
8829f52e | 124 | printf("getrequests: port 0x%x\n", DaemonAddr.sin.sin_port); |
14a39063 | 125 | |
7f108496 | 126 | /* get a socket for the SMTP connection */ |
15b0addc | 127 | socksize = opendaemonsocket(TRUE); |
14a39063 | 128 | |
39270cfd | 129 | (void) setsignal(SIGCHLD, reapchild); |
199d34eb | 130 | |
654398d7 EA |
131 | /* write the pid to the log file for posterity */ |
132 | pidf = fopen(PidFile, "w"); | |
133 | if (pidf != NULL) | |
134 | { | |
353ccd78 EA |
135 | extern char *CommandLineArgs; |
136 | ||
137 | /* write the process id on line 1 */ | |
654398d7 | 138 | fprintf(pidf, "%d\n", getpid()); |
353ccd78 EA |
139 | |
140 | /* line 2 contains all command line flags */ | |
141 | fprintf(pidf, "%s\n", CommandLineArgs); | |
142 | ||
143 | /* flush and close */ | |
654398d7 EA |
144 | fclose(pidf); |
145 | } | |
146 | ||
6e48b8f0 EA |
147 | #ifdef XDEBUG |
148 | { | |
15c7b837 | 149 | char jbuf[MAXHOSTNAMELEN]; |
6e48b8f0 | 150 | |
832e8a27 | 151 | expand("\201j", jbuf, sizeof jbuf, CurEnv); |
15c7b837 | 152 | j_has_dot = strchr(jbuf, '.') != NULL; |
6e48b8f0 EA |
153 | } |
154 | #endif | |
654398d7 | 155 | |
7f108496 | 156 | if (tTd(15, 1)) |
eb8af3ce | 157 | printf("getrequests: %d\n", DaemonSocket); |
2a16bae3 | 158 | |
7f108496 EA |
159 | struct wh wbuf; |
160 | ||
161 | wbuf.index = index; | |
162 | wbuf.count = 0; | |
163 | wbuf.ccount = cnt; | |
164 | wbuf.data = buf; | |
165 | write(MailPort, &wbuf, sizeof wbuf); | |
14a39063 | 166 | } |
1ab402f2 EA |
167 | \f/* |
168 | ** MAKECONNECTION -- make a connection to an SMTP socket on another machine. | |
169 | ** | |
170 | ** Parameters: | |
171 | ** host -- the name of the host. | |
e2d7c32a | 172 | ** port -- the port number to connect to. |
2ae0e0ed EA |
173 | ** mci -- a pointer to the mail connection information |
174 | ** structure to be filled in. | |
8657d05f EA |
175 | ** usesecureport -- if set, use a low numbered (reserved) |
176 | ** port to provide some rudimentary authentication. | |
1ab402f2 EA |
177 | ** |
178 | ** Returns: | |
179 | ** An exit code telling whether the connection could be | |
180 | ** made and if not why not. | |
181 | ** | |
182 | ** Side Effects: | |
183 | ** none. | |
184 | */ | |
185 | ||
3341995c | 186 | SOCKADDR CurHostAddr; /* address of current host */ |
9b95d94a | 187 | |
f2e44ded | 188 | int |
2ae0e0ed | 189 | makeconnection(host, port, mci, usesecureport) |
1ab402f2 | 190 | char *host; |
f7eb07a3 | 191 | u_short port; |
f2e44ded | 192 | register MCI *mci; |
8657d05f | 193 | bool usesecureport; |
1ab402f2 | 194 | { |
ea07b2d2 EA |
195 | register int i = 0; |
196 | register int s; | |
9e881165 | 197 | register struct hostent *hp = (struct hostent *)NULL; |
3341995c | 198 | SOCKADDR addr; |
fa163d3c | 199 | int sav_errno; |
3341995c | 200 | int addrlen; |
8d7cd263 | 201 | bool firstconnect; |
efe7f723 | 202 | #if NAMED_BIND |
35af2f06 EA |
203 | extern int h_errno; |
204 | #endif | |
1ab402f2 EA |
205 | |
206 | /* | |
207 | ** Set up the address for the mailer. | |
b3e29341 | 208 | ** Accept "[a.b.c.d]" syntax for host name. |
1ab402f2 EA |
209 | */ |
210 | ||
efe7f723 | 211 | #if NAMED_BIND |
459e21be | 212 | h_errno = 0; |
35af2f06 | 213 | #endif |
459e21be | 214 | errno = 0; |
f66cc88e | 215 | bzero(&CurHostAddr, sizeof CurHostAddr); |
649a3283 | 216 | SmtpPhase = mci->mci_phase = "initial connection"; |
f53bb556 | 217 | CurHostName = host; |
459e21be | 218 | |
b3e29341 EA |
219 | if (host[0] == '[') |
220 | { | |
e56baaff | 221 | long hid; |
f3d8f6d6 | 222 | register char *p = strchr(host, ']'); |
b3e29341 | 223 | |
e56baaff | 224 | if (p != NULL) |
b3e29341 | 225 | { |
e56baaff | 226 | *p = '\0'; |
69d3adf7 | 227 | #ifdef NETINET |
e56baaff | 228 | hid = inet_addr(&host[1]); |
b120ff69 | 229 | if (hid == -1) |
69d3adf7 | 230 | #endif |
b120ff69 EA |
231 | { |
232 | /* try it as a host name (avoid MX lookup) */ | |
233 | hp = gethostbyname(&host[1]); | |
53d4f262 EA |
234 | if (hp == NULL && p[-1] == '.') |
235 | { | |
fe188caa | 236 | #if NAMED_BIND |
e65a357f EA |
237 | int oldopts = _res.options; |
238 | ||
239 | _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); | |
240 | #endif | |
53d4f262 EA |
241 | p[-1] = '\0'; |
242 | hp = gethostbyname(&host[1]); | |
243 | p[-1] = '.'; | |
fe188caa | 244 | #if NAMED_BIND |
e65a357f EA |
245 | _res.options = oldopts; |
246 | #endif | |
53d4f262 | 247 | } |
b120ff69 EA |
248 | *p = ']'; |
249 | goto gothostent; | |
250 | } | |
e56baaff | 251 | *p = ']'; |
b3e29341 | 252 | } |
b120ff69 | 253 | if (p == NULL) |
b3e29341 | 254 | { |
b6edea3d | 255 | usrerr("553 Invalid numeric domain spec \"%s\"", host); |
b3e29341 EA |
256 | return (EX_NOHOST); |
257 | } | |
69d3adf7 EA |
258 | #ifdef NETINET |
259 | addr.sin.sin_family = AF_INET; /*XXX*/ | |
3356c77c | 260 | addr.sin.sin_addr.s_addr = hid; |
69d3adf7 | 261 | #endif |
b3e29341 | 262 | } |
7f108496 EA |
263 | else |
264 | { | |
53d4f262 EA |
265 | register char *p = &host[strlen(host) - 1]; |
266 | ||
9e881165 | 267 | hp = gethostbyname(host); |
53d4f262 EA |
268 | if (hp == NULL && *p == '.') |
269 | { | |
fe188caa | 270 | #if NAMED_BIND |
e65a357f EA |
271 | int oldopts = _res.options; |
272 | ||
273 | _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); | |
274 | #endif | |
53d4f262 EA |
275 | *p = '\0'; |
276 | hp = gethostbyname(host); | |
277 | *p = '.'; | |
fe188caa | 278 | #if NAMED_BIND |
e65a357f EA |
279 | _res.options = oldopts; |
280 | #endif | |
53d4f262 | 281 | } |
b120ff69 | 282 | gothostent: |
e56baaff | 283 | if (hp == NULL) |
459e21be | 284 | { |
efe7f723 | 285 | #if NAMED_BIND |
a542cc51 EA |
286 | /* check for name server timeouts */ |
287 | if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || | |
288 | (errno == ECONNREFUSED && UseNameServer)) | |
289 | { | |
b5e36a3d | 290 | mci->mci_status = "4.4.3"; |
35af2f06 | 291 | return (EX_TEMPFAIL); |
a542cc51 | 292 | } |
35af2f06 | 293 | #endif |
7f108496 | 294 | return (EX_NOHOST); |
459e21be | 295 | } |
3356c77c EA |
296 | addr.sa.sa_family = hp->h_addrtype; |
297 | switch (hp->h_addrtype) | |
298 | { | |
299 | #ifdef NETINET | |
300 | case AF_INET: | |
3341995c | 301 | bcopy(hp->h_addr, |
3356c77c | 302 | &addr.sin.sin_addr, |
648eb46e | 303 | INADDRSZ); |
3356c77c EA |
304 | break; |
305 | #endif | |
306 | ||
307 | default: | |
3341995c | 308 | bcopy(hp->h_addr, |
3356c77c | 309 | addr.sa.sa_data, |
3341995c | 310 | hp->h_length); |
3356c77c EA |
311 | break; |
312 | } | |
9e881165 | 313 | i = 1; |
7f108496 EA |
314 | } |
315 | ||
316 | /* | |
317 | ** Determine the port number. | |
318 | */ | |
319 | ||
372c9e7f | 320 | if (port != 0) |
3341995c | 321 | port = htons(port); |
372c9e7f | 322 | else |
7f108496 EA |
323 | { |
324 | register struct servent *sp = getservbyname("smtp", "tcp"); | |
325 | ||
326 | if (sp == NULL) | |
327 | { | |
9964213c | 328 | syserr("554 makeconnection: service \"smtp\" unknown"); |
c075e44e | 329 | port = htons(25); |
7f108496 | 330 | } |
c075e44e EA |
331 | else |
332 | port = sp->s_port; | |
3341995c EA |
333 | } |
334 | ||
3356c77c | 335 | switch (addr.sa.sa_family) |
3341995c | 336 | { |
69d3adf7 | 337 | #ifdef NETINET |
3341995c | 338 | case AF_INET: |
3356c77c | 339 | addr.sin.sin_port = port; |
3341995c EA |
340 | addrlen = sizeof (struct sockaddr_in); |
341 | break; | |
69d3adf7 | 342 | #endif |
3341995c EA |
343 | |
344 | #ifdef NETISO | |
345 | case AF_ISO: | |
346 | /* assume two byte transport selector */ | |
347 | bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2); | |
348 | addrlen = sizeof (struct sockaddr_iso); | |
349 | break; | |
350 | #endif | |
351 | ||
352 | default: | |
3356c77c | 353 | syserr("Can't connect to address family %d", addr.sa.sa_family); |
3341995c | 354 | return (EX_NOHOST); |
7f108496 | 355 | } |
1ab402f2 EA |
356 | |
357 | /* | |
358 | ** Try to actually open the connection. | |
359 | */ | |
360 | ||
b4f81c5d EA |
361 | #ifdef XLA |
362 | /* if too many connections, don't bother trying */ | |
363 | if (!xla_noqueue_ok(host)) | |
364 | return EX_TEMPFAIL; | |
365 | #endif | |
366 | ||
8d7cd263 | 367 | firstconnect = TRUE; |
6feb509e | 368 | for (;;) |
8657d05f | 369 | { |
6feb509e | 370 | if (tTd(16, 1)) |
3341995c EA |
371 | printf("makeconnection (%s [%s])\n", |
372 | host, anynet_ntoa(&addr)); | |
8657d05f | 373 | |
83c07d72 EA |
374 | /* save for logging */ |
375 | CurHostAddr = addr; | |
376 | ||
6feb509e EA |
377 | if (usesecureport) |
378 | { | |
379 | int rport = IPPORT_RESERVED - 1; | |
380 | ||
381 | s = rresvport(&rport); | |
382 | } | |
383 | else | |
384 | { | |
385 | s = socket(AF_INET, SOCK_STREAM, 0); | |
386 | } | |
387 | if (s < 0) | |
388 | { | |
389 | sav_errno = errno; | |
390 | syserr("makeconnection: no socket"); | |
391 | goto failure; | |
392 | } | |
1ab402f2 | 393 | |
118dcfcf EA |
394 | #ifdef SO_SNDBUF |
395 | if (TcpSndBufferSize > 0) | |
396 | { | |
397 | if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, | |
53335960 | 398 | (char *) &TcpSndBufferSize, |
118dcfcf EA |
399 | sizeof(TcpSndBufferSize)) < 0) |
400 | syserr("makeconnection: setsockopt(SO_SNDBUF)"); | |
401 | } | |
402 | #endif | |
403 | ||
6feb509e EA |
404 | if (tTd(16, 1)) |
405 | printf("makeconnection: fd=%d\n", s); | |
78c9dc29 | 406 | |
6feb509e EA |
407 | /* turn on network debugging? */ |
408 | if (tTd(16, 101)) | |
409 | { | |
410 | int on = 1; | |
2e7d8e3e | 411 | (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, |
6feb509e EA |
412 | (char *)&on, sizeof on); |
413 | } | |
414 | if (CurEnv->e_xfp != NULL) | |
415 | (void) fflush(CurEnv->e_xfp); /* for debugging */ | |
416 | errno = 0; /* for debugging */ | |
3341995c | 417 | if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0) |
6feb509e EA |
418 | break; |
419 | ||
8d7cd263 EA |
420 | /* if running demand-dialed connection, try again */ |
421 | if (DialDelay > 0 && firstconnect) | |
422 | { | |
423 | if (tTd(16, 1)) | |
424 | printf("Connect failed (%s); trying again...\n", | |
425 | errstring(sav_errno)); | |
426 | firstconnect = FALSE; | |
427 | sleep(DialDelay); | |
428 | continue; | |
429 | } | |
430 | ||
6feb509e | 431 | /* couldn't connect.... figure out why */ |
fa163d3c JB |
432 | sav_errno = errno; |
433 | (void) close(s); | |
ea07b2d2 | 434 | if (hp != NULL && hp->h_addr_list[i]) |
9e881165 | 435 | { |
6feb509e | 436 | if (tTd(16, 1)) |
3341995c EA |
437 | printf("Connect failed (%s); trying new address....\n", |
438 | errstring(sav_errno)); | |
3356c77c EA |
439 | switch (addr.sa.sa_family) |
440 | { | |
441 | #ifdef NETINET | |
442 | case AF_INET: | |
3341995c | 443 | bcopy(hp->h_addr_list[i++], |
3356c77c | 444 | &addr.sin.sin_addr, |
648eb46e | 445 | INADDRSZ); |
3356c77c EA |
446 | break; |
447 | #endif | |
448 | ||
449 | default: | |
3341995c | 450 | bcopy(hp->h_addr_list[i++], |
3356c77c | 451 | addr.sa.sa_data, |
8657d05f | 452 | hp->h_length); |
3356c77c EA |
453 | break; |
454 | } | |
6feb509e | 455 | continue; |
9e881165 JB |
456 | } |
457 | ||
1ab402f2 EA |
458 | /* failure, decide if temporary or not */ |
459 | failure: | |
46500bf5 EA |
460 | #ifdef XLA |
461 | xla_host_end(host); | |
462 | #endif | |
1eaa5615 EA |
463 | if (transienterror(sav_errno)) |
464 | return EX_TEMPFAIL; | |
1eaa5615 EA |
465 | else |
466 | { | |
1eaa5615 EA |
467 | message("%s", errstring(sav_errno)); |
468 | return (EX_UNAVAILABLE); | |
1ab402f2 EA |
469 | } |
470 | } | |
471 | ||
472 | /* connection ok, put it into canonical form */ | |
e9d81da2 EA |
473 | if ((mci->mci_out = fdopen(s, "w")) == NULL || |
474 | (s = dup(s)) < 0 || | |
35f14050 | 475 | (mci->mci_in = fdopen(s, "r")) == NULL) |
e9d81da2 EA |
476 | { |
477 | syserr("cannot open SMTP client channel, fd=%d", s); | |
478 | return EX_TEMPFAIL; | |
479 | } | |
1ab402f2 | 480 | |
1aaa7dec | 481 | return (EX_OK); |
1ab402f2 | 482 | } |
2ec2faaa EA |
483 | \f/* |
484 | ** MYHOSTNAME -- return the name of this host. | |
485 | ** | |
486 | ** Parameters: | |
487 | ** hostbuf -- a place to return the name of this host. | |
05894fc6 | 488 | ** size -- the size of hostbuf. |
2ec2faaa EA |
489 | ** |
490 | ** Returns: | |
491 | ** A list of aliases for this host. | |
492 | ** | |
493 | ** Side Effects: | |
377054c1 | 494 | ** Adds numeric codes to $=w. |
2ec2faaa EA |
495 | */ |
496 | ||
a8ec2376 | 497 | struct hostent * |
05894fc6 | 498 | myhostname(hostbuf, size) |
2ec2faaa | 499 | char hostbuf[]; |
05894fc6 | 500 | int size; |
2ec2faaa | 501 | { |
740d17b3 | 502 | register struct hostent *hp; |
2ec2faaa | 503 | extern struct hostent *gethostbyname(); |
a94b65bf EA |
504 | extern bool getcanonname(); |
505 | extern int h_errno; | |
2ec2faaa | 506 | |
17a67c62 EA |
507 | if (gethostname(hostbuf, size) < 0) |
508 | { | |
509 | (void) strcpy(hostbuf, "localhost"); | |
510 | } | |
e56baaff | 511 | hp = gethostbyname(hostbuf); |
7309c0a5 | 512 | if (hp == NULL) |
056f9f43 | 513 | return NULL; |
a94b65bf EA |
514 | if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) |
515 | { | |
516 | (void) strncpy(hostbuf, hp->h_name, size - 1); | |
517 | hostbuf[size - 1] = '\0'; | |
518 | } | |
e9870a62 | 519 | |
7309c0a5 | 520 | #if NAMED_BIND |
a94b65bf EA |
521 | /* |
522 | ** If still no dot, try DNS directly (i.e., avoid NIS problems). | |
523 | ** This ought to be driven from the configuration file, but | |
524 | ** we are called before the configuration is read. We could | |
525 | ** check for an /etc/resolv.conf file, but that isn't required. | |
526 | ** All in all, a bit of a mess. | |
527 | */ | |
528 | ||
529 | if (strchr(hostbuf, '.') == NULL && | |
530 | !getcanonname(hostbuf, size, TRUE) && | |
531 | h_errno == TRY_AGAIN) | |
7309c0a5 | 532 | { |
7309c0a5 | 533 | /* try twice in case name server not yet started up */ |
a94b65bf EA |
534 | message("My unqualifed host name (%s) unknown to DNS; sleeping for retry", |
535 | hostbuf); | |
536 | sleep(60); | |
537 | if (!getcanonname(hostbuf, size, TRUE)) | |
7309c0a5 | 538 | errno = h_errno + E_DNSBASE; |
7309c0a5 | 539 | } |
e9870a62 | 540 | #endif |
a8ec2376 | 541 | return (hp); |
2ec2faaa | 542 | } |
bbfde42f | 543 | \f/* |
3f03d7a7 EA |
544 | ** GETAUTHINFO -- get the real host name asociated with a file descriptor |
545 | ** | |
546 | ** Uses RFC1413 protocol to try to get info from the other end. | |
5973222c EA |
547 | ** |
548 | ** Parameters: | |
549 | ** fd -- the descriptor | |
550 | ** | |
551 | ** Returns: | |
3f03d7a7 | 552 | ** The user@host information associated with this descriptor. |
5973222c EA |
553 | */ |
554 | ||
3f03d7a7 EA |
555 | static jmp_buf CtxAuthTimeout; |
556 | ||
ea07b2d2 | 557 | static void |
3f03d7a7 EA |
558 | authtimeout() |
559 | { | |
560 | longjmp(CtxAuthTimeout, 1); | |
561 | } | |
562 | ||
5973222c | 563 | char * |
3f03d7a7 | 564 | getauthinfo(fd) |
5973222c EA |
565 | int fd; |
566 | { | |
3f03d7a7 | 567 | int falen; |
72bc63d1 | 568 | register char *p; |
3f03d7a7 EA |
569 | SOCKADDR la; |
570 | int lalen; | |
571 | register struct servent *sp; | |
572 | int s; | |
573 | int i; | |
3f03d7a7 | 574 | EVENT *ev; |
569e2784 | 575 | int nleft; |
6f74842a | 576 | char ibuf[MAXNAME + 1]; |
8b2f7f25 | 577 | char ibuf[MAXNAME + 1]; |
3f03d7a7 EA |
578 | static char hbuf[MAXNAME * 2 + 2]; |
579 | extern char *hostnamebyanyaddr(); | |
580 | extern char RealUserName[]; /* main.c */ | |
581 | ||
07385570 | 582 | falen = sizeof RealHostAddr; |
703f8e63 EA |
583 | if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 || |
584 | falen <= 0 || RealHostAddr.sa.sa_family == 0) | |
3f03d7a7 | 585 | { |
3f03d7a7 | 586 | (void) sprintf(hbuf, "%s@localhost", RealUserName); |
a9bac7a9 | 587 | if (tTd(9, 1)) |
3f03d7a7 EA |
588 | printf("getauthinfo: %s\n", hbuf); |
589 | return hbuf; | |
590 | } | |
591 | ||
07385570 EA |
592 | if (RealHostName == NULL) |
593 | { | |
594 | /* translate that to a host name */ | |
595 | RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); | |
596 | } | |
597 | ||
423d92e1 EA |
598 | if (TimeOuts.to_ident == 0) |
599 | goto noident; | |
600 | ||
3f03d7a7 | 601 | lalen = sizeof la; |
07385570 | 602 | if (RealHostAddr.sa.sa_family != AF_INET || |
3f03d7a7 EA |
603 | getsockname(fd, &la.sa, &lalen) < 0 || lalen <= 0 || |
604 | la.sa.sa_family != AF_INET) | |
605 | { | |
606 | /* no ident info */ | |
607 | goto noident; | |
608 | } | |
609 | ||
610 | /* create ident query */ | |
968f1a79 | 611 | (void) sprintf(ibuf, "%d,%d\r\n", |
07385570 | 612 | ntohs(RealHostAddr.sin.sin_port), ntohs(la.sin.sin_port)); |
3f03d7a7 EA |
613 | |
614 | /* create local address */ | |
c32e1955 | 615 | la.sin.sin_port = 0; |
3f03d7a7 EA |
616 | |
617 | /* create foreign address */ | |
618 | sp = getservbyname("auth", "tcp"); | |
619 | if (sp != NULL) | |
07385570 | 620 | RealHostAddr.sin.sin_port = sp->s_port; |
5973222c | 621 | else |
07385570 | 622 | RealHostAddr.sin.sin_port = htons(113); |
3f03d7a7 EA |
623 | |
624 | s = -1; | |
625 | if (setjmp(CtxAuthTimeout) != 0) | |
626 | { | |
627 | if (s >= 0) | |
628 | (void) close(s); | |
629 | goto noident; | |
630 | } | |
631 | ||
632 | /* put a timeout around the whole thing */ | |
cf7a936d | 633 | ev = setevent(TimeOuts.to_ident, authtimeout, 0); |
3f03d7a7 | 634 | |
c32e1955 | 635 | /* connect to foreign IDENT server using same address as SMTP socket */ |
3f03d7a7 EA |
636 | s = socket(AF_INET, SOCK_STREAM, 0); |
637 | if (s < 0) | |
638 | { | |
639 | clrevent(ev); | |
640 | goto noident; | |
641 | } | |
c32e1955 | 642 | if (bind(s, &la.sa, sizeof la.sin) < 0 || |
07385570 | 643 | connect(s, &RealHostAddr.sa, sizeof RealHostAddr.sin) < 0) |
3f03d7a7 | 644 | { |
57c59cf7 | 645 | goto closeident; |
3f03d7a7 EA |
646 | } |
647 | ||
a9bac7a9 | 648 | if (tTd(9, 10)) |
968f1a79 | 649 | printf("getauthinfo: sent %s", ibuf); |
3f03d7a7 EA |
650 | |
651 | /* send query */ | |
968f1a79 | 652 | if (write(s, ibuf, strlen(ibuf)) < 0) |
3f03d7a7 EA |
653 | goto closeident; |
654 | ||
655 | /* get result */ | |
968f1a79 EA |
656 | p = &ibuf[0]; |
657 | nleft = sizeof(ibuf - 1); | |
569e2784 EA |
658 | while ((i = read(s, p, nleft)) > 0) |
659 | { | |
660 | p += i; | |
661 | nleft -= i; | |
662 | } | |
3f03d7a7 EA |
663 | (void) close(s); |
664 | clrevent(ev); | |
968f1a79 | 665 | if (i < 0 || p == &ibuf[0]) |
3f03d7a7 | 666 | goto noident; |
569e2784 EA |
667 | |
668 | if (*--p == '\n' && *--p == '\r') | |
669 | p--; | |
670 | *++p = '\0'; | |
3f03d7a7 | 671 | |
a9bac7a9 | 672 | if (tTd(9, 3)) |
968f1a79 | 673 | printf("getauthinfo: got %s\n", ibuf); |
3f03d7a7 EA |
674 | |
675 | /* parse result */ | |
968f1a79 | 676 | p = strchr(ibuf, ':'); |
3f03d7a7 EA |
677 | if (p == NULL) |
678 | { | |
679 | /* malformed response */ | |
680 | goto noident; | |
681 | } | |
682 | while (isascii(*++p) && isspace(*p)) | |
683 | continue; | |
684 | if (strncasecmp(p, "userid", 6) != 0) | |
685 | { | |
686 | /* presumably an error string */ | |
687 | goto noident; | |
688 | } | |
689 | p += 6; | |
690 | while (isascii(*p) && isspace(*p)) | |
691 | p++; | |
692 | if (*p++ != ':') | |
693 | { | |
694 | /* either useridxx or malformed response */ | |
695 | goto noident; | |
696 | } | |
697 | ||
698 | /* p now points to the OSTYPE field */ | |
699 | p = strchr(p, ':'); | |
700 | if (p == NULL) | |
701 | { | |
702 | /* malformed response */ | |
703 | goto noident; | |
704 | } | |
a9bac7a9 EA |
705 | |
706 | /* 1413 says don't do this -- but it's broken otherwise */ | |
707 | while (isascii(*++p) && isspace(*p)) | |
708 | continue; | |
3f03d7a7 | 709 | |
3fd289f3 | 710 | /* p now points to the authenticated name -- copy carefully */ |
68359be4 EA |
711 | cleanstrcpy(hbuf, p, MAXNAME); |
712 | i = strlen(hbuf); | |
3fd289f3 EA |
713 | hbuf[i++] = '@'; |
714 | strcpy(&hbuf[i], RealHostName == NULL ? "localhost" : RealHostName); | |
a9bac7a9 EA |
715 | goto finish; |
716 | ||
57c59cf7 EA |
717 | closeident: |
718 | (void) close(s); | |
719 | clrevent(ev); | |
720 | ||
a9bac7a9 | 721 | noident: |
389c0d5e EA |
722 | if (RealHostName == NULL) |
723 | { | |
724 | if (tTd(9, 1)) | |
725 | printf("getauthinfo: NULL\n"); | |
726 | return NULL; | |
727 | } | |
a9bac7a9 EA |
728 | (void) strcpy(hbuf, RealHostName); |
729 | ||
730 | finish: | |
389c0d5e | 731 | if (RealHostName != NULL && RealHostName[0] != '[') |
3f03d7a7 EA |
732 | { |
733 | p = &hbuf[strlen(hbuf)]; | |
734 | (void) sprintf(p, " [%s]", anynet_ntoa(&RealHostAddr)); | |
735 | } | |
a9bac7a9 | 736 | if (tTd(9, 1)) |
3f03d7a7 | 737 | printf("getauthinfo: %s\n", hbuf); |
5973222c EA |
738 | return hbuf; |
739 | } | |
740 | \f/* | |
713c523f | 741 | ** HOST_MAP_LOOKUP -- turn a hostname into canonical form |
42fa5d67 EA |
742 | ** |
743 | ** Parameters: | |
5a4c03c6 | 744 | ** map -- a pointer to this map (unused). |
713c523f | 745 | ** name -- the (presumably unqualified) hostname. |
3ff91010 | 746 | ** av -- unused -- for compatibility with other mapping |
0cf5a7ba | 747 | ** functions. |
d1db7a89 EA |
748 | ** statp -- an exit status (out parameter) -- set to |
749 | ** EX_TEMPFAIL if the name server is unavailable. | |
42fa5d67 EA |
750 | ** |
751 | ** Returns: | |
752 | ** The mapping, if found. | |
753 | ** NULL if no mapping found. | |
754 | ** | |
755 | ** Side Effects: | |
756 | ** Looks up the host specified in hbuf. If it is not | |
757 | ** the canonical name for that host, return the canonical | |
758 | ** name. | |
759 | */ | |
bbfde42f | 760 | |
42fa5d67 | 761 | char * |
3ff91010 | 762 | host_map_lookup(map, name, av, statp) |
5a4c03c6 | 763 | MAP *map; |
713c523f | 764 | char *name; |
3ff91010 | 765 | char **av; |
d1db7a89 | 766 | int *statp; |
217a0102 EA |
767 | { |
768 | register struct hostent *hp; | |
d2dc4dd0 | 769 | struct in_addr in_addr; |
5a4c03c6 | 770 | char *cp; |
b97dd58b | 771 | register STAB *s; |
8446c922 | 772 | char hbuf[MAXNAME + 1]; |
b97dd58b | 773 | extern struct hostent *gethostbyaddr(); |
efe7f723 | 774 | #if NAMED_BIND |
b97dd58b | 775 | extern int h_errno; |
68d8d275 | 776 | #endif |
217a0102 | 777 | |
33e4da31 | 778 | /* |
b97dd58b EA |
779 | ** See if we have already looked up this name. If so, just |
780 | ** return it. | |
781 | */ | |
782 | ||
713c523f | 783 | s = stab(name, ST_NAMECANON, ST_ENTER); |
b97dd58b EA |
784 | if (bitset(NCF_VALID, s->s_namecanon.nc_flags)) |
785 | { | |
d3b6a883 | 786 | if (tTd(9, 1)) |
713c523f EA |
787 | printf("host_map_lookup(%s) => CACHE %s\n", |
788 | name, s->s_namecanon.nc_cname); | |
b97dd58b | 789 | errno = s->s_namecanon.nc_errno; |
efe7f723 | 790 | #if NAMED_BIND |
b97dd58b | 791 | h_errno = s->s_namecanon.nc_herrno; |
68d8d275 | 792 | #endif |
b97dd58b | 793 | *statp = s->s_namecanon.nc_stat; |
3b2f690b | 794 | if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL) |
e1a4f0fb EA |
795 | { |
796 | sprintf(hbuf, "%s: Name server timeout", | |
797 | shortenstring(name, 33)); | |
798 | CurEnv->e_message = newstr(hbuf); | |
799 | } | |
b97dd58b EA |
800 | return s->s_namecanon.nc_cname; |
801 | } | |
802 | ||
803 | /* | |
804 | ** If first character is a bracket, then it is an address | |
805 | ** lookup. Address is copied into a temporary buffer to | |
713c523f | 806 | ** strip the brackets and to preserve name if address is |
b97dd58b EA |
807 | ** unknown. |
808 | */ | |
42fa5d67 | 809 | |
713c523f | 810 | if (*name != '[') |
42fa5d67 | 811 | { |
0cf5a7ba EA |
812 | extern bool getcanonname(); |
813 | ||
a97feb13 | 814 | if (tTd(9, 1)) |
713c523f | 815 | printf("host_map_lookup(%s) => ", name); |
b97dd58b | 816 | s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ |
8446c922 EA |
817 | if (strlen(name) < sizeof hbuf) |
818 | (void) strcpy(hbuf, name); | |
819 | else | |
820 | { | |
821 | bcopy(name, hbuf, sizeof hbuf - 1); | |
822 | hbuf[sizeof hbuf - 1] = '\0'; | |
823 | } | |
4fed4c18 | 824 | if (getcanonname(hbuf, sizeof hbuf - 1, TRUE)) |
1d136a1f EA |
825 | { |
826 | if (tTd(9, 1)) | |
827 | printf("%s\n", hbuf); | |
3ff91010 EA |
828 | cp = map_rewrite(map, hbuf, strlen(hbuf), av); |
829 | s->s_namecanon.nc_cname = newstr(cp); | |
830 | return cp; | |
1d136a1f | 831 | } |
42fa5d67 | 832 | else |
1d136a1f | 833 | { |
d1db7a89 | 834 | register struct hostent *hp; |
d1db7a89 | 835 | |
b97dd58b | 836 | s->s_namecanon.nc_errno = errno; |
efe7f723 | 837 | #if NAMED_BIND |
b97dd58b | 838 | s->s_namecanon.nc_herrno = h_errno; |
68d8d275 EA |
839 | if (tTd(9, 1)) |
840 | printf("FAIL (%d)\n", h_errno); | |
d1db7a89 EA |
841 | switch (h_errno) |
842 | { | |
843 | case TRY_AGAIN: | |
c281eee3 | 844 | if (UseNameServer) |
7ffb494c | 845 | { |
36456ed1 | 846 | sprintf(hbuf, "%s: Name server timeout", |
e1a4f0fb | 847 | shortenstring(name, 33)); |
36456ed1 | 848 | message("%s", hbuf); |
7ffb494c | 849 | if (CurEnv->e_message == NULL) |
36456ed1 | 850 | CurEnv->e_message = newstr(hbuf); |
7ffb494c | 851 | } |
d1db7a89 EA |
852 | *statp = EX_TEMPFAIL; |
853 | break; | |
854 | ||
855 | case HOST_NOT_FOUND: | |
856 | *statp = EX_NOHOST; | |
857 | break; | |
858 | ||
859 | case NO_RECOVERY: | |
860 | *statp = EX_SOFTWARE; | |
861 | break; | |
862 | ||
863 | default: | |
864 | *statp = EX_UNAVAILABLE; | |
865 | break; | |
866 | } | |
68d8d275 EA |
867 | #else |
868 | if (tTd(9, 1)) | |
869 | printf("FAIL\n"); | |
870 | *statp = EX_NOHOST; | |
871 | #endif | |
b97dd58b | 872 | s->s_namecanon.nc_stat = *statp; |
365c0831 EA |
873 | if ((*statp != EX_TEMPFAIL && *statp != EX_NOHOST) || |
874 | UseNameServer) | |
d1db7a89 EA |
875 | return NULL; |
876 | ||
877 | /* | |
878 | ** Try to look it up in /etc/hosts | |
879 | */ | |
880 | ||
713c523f | 881 | hp = gethostbyname(name); |
d1db7a89 EA |
882 | if (hp == NULL) |
883 | { | |
884 | /* no dice there either */ | |
b97dd58b | 885 | s->s_namecanon.nc_stat = *statp = EX_NOHOST; |
d1db7a89 EA |
886 | return NULL; |
887 | } | |
888 | ||
b97dd58b | 889 | s->s_namecanon.nc_stat = *statp = EX_OK; |
3ff91010 EA |
890 | cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av); |
891 | s->s_namecanon.nc_cname = newstr(cp); | |
892 | return cp; | |
1d136a1f | 893 | } |
42fa5d67 | 894 | } |
713c523f | 895 | if ((cp = strchr(name, ']')) == NULL) |
42fa5d67 | 896 | return (NULL); |
bd974b31 | 897 | *cp = '\0'; |
d2dc4dd0 | 898 | in_addr.s_addr = inet_addr(&name[1]); |
740d17b3 | 899 | |
740d17b3 | 900 | /* nope -- ask the name server */ |
648eb46e | 901 | hp = gethostbyaddr((char *)&in_addr, INADDRSZ, AF_INET); |
b97dd58b | 902 | s->s_namecanon.nc_errno = errno; |
efe7f723 | 903 | #if NAMED_BIND |
b97dd58b | 904 | s->s_namecanon.nc_herrno = h_errno; |
68d8d275 | 905 | #endif |
b97dd58b | 906 | s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ |
d0432129 | 907 | if (hp == NULL) |
b97dd58b EA |
908 | { |
909 | s->s_namecanon.nc_stat = *statp = EX_NOHOST; | |
42fa5d67 | 910 | return (NULL); |
b97dd58b | 911 | } |
42fa5d67 | 912 | |
740d17b3 | 913 | /* found a match -- copy out */ |
3ff91010 | 914 | cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av); |
b97dd58b | 915 | s->s_namecanon.nc_stat = *statp = EX_OK; |
3ff91010 EA |
916 | s->s_namecanon.nc_cname = newstr(cp); |
917 | return cp; | |
217a0102 | 918 | } |
3341995c EA |
919 | \f/* |
920 | ** ANYNET_NTOA -- convert a network address to printable form. | |
921 | ** | |
922 | ** Parameters: | |
923 | ** sap -- a pointer to a sockaddr structure. | |
924 | ** | |
925 | ** Returns: | |
926 | ** A printable version of that sockaddr. | |
927 | */ | |
928 | ||
929 | char * | |
930 | anynet_ntoa(sap) | |
931 | register SOCKADDR *sap; | |
932 | { | |
933 | register char *bp; | |
934 | register char *ap; | |
935 | int l; | |
13cdecbc | 936 | static char buf[100]; |
3341995c | 937 | |
a97feb13 EA |
938 | /* check for null/zero family */ |
939 | if (sap == NULL) | |
940 | return "NULLADDR"; | |
941 | if (sap->sa.sa_family == 0) | |
942 | return "0"; | |
943 | ||
13cdecbc EA |
944 | switch (sap->sa.sa_family) |
945 | { | |
2f10abc1 | 946 | #ifdef NETUNIX |
13cdecbc | 947 | case AF_UNIX: |
2122a474 EA |
948 | if (sap->sunix.sun_path[0] != '\0') |
949 | sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path); | |
13cdecbc EA |
950 | else |
951 | sprintf(buf, "[UNIX: localhost]"); | |
952 | return buf; | |
953 | #endif | |
954 | ||
3356c77c | 955 | #ifdef NETINET |
13cdecbc | 956 | case AF_INET: |
3341995c | 957 | return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr); |
3356c77c | 958 | #endif |
3341995c | 959 | |
13cdecbc EA |
960 | default: |
961 | /* this case is only to ensure syntactic correctness */ | |
962 | break; | |
963 | } | |
964 | ||
3341995c | 965 | /* unknown family -- just dump bytes */ |
3356c77c | 966 | (void) sprintf(buf, "Family %d: ", sap->sa.sa_family); |
3341995c | 967 | bp = &buf[strlen(buf)]; |
3356c77c EA |
968 | ap = sap->sa.sa_data; |
969 | for (l = sizeof sap->sa.sa_data; --l >= 0; ) | |
3341995c EA |
970 | { |
971 | (void) sprintf(bp, "%02x:", *ap++ & 0377); | |
972 | bp += 3; | |
973 | } | |
974 | *--bp = '\0'; | |
975 | return buf; | |
976 | } | |
3f03d7a7 EA |
977 | \f/* |
978 | ** HOSTNAMEBYANYADDR -- return name of host based on address | |
979 | ** | |
980 | ** Parameters: | |
981 | ** sap -- SOCKADDR pointer | |
982 | ** | |
983 | ** Returns: | |
984 | ** text representation of host name. | |
985 | ** | |
986 | ** Side Effects: | |
987 | ** none. | |
988 | */ | |
989 | ||
990 | char * | |
991 | hostnamebyanyaddr(sap) | |
992 | register SOCKADDR *sap; | |
993 | { | |
994 | register struct hostent *hp; | |
ab6ca5e5 EA |
995 | int saveretry; |
996 | ||
efe7f723 | 997 | #if NAMED_BIND |
ab6ca5e5 EA |
998 | /* shorten name server timeout to avoid higher level timeouts */ |
999 | saveretry = _res.retry; | |
1000 | _res.retry = 3; | |
1001 | #endif /* NAMED_BIND */ | |
1002 | ||
3f03d7a7 EA |
1003 | switch (sap->sa.sa_family) |
1004 | { | |
1005 | #ifdef NETINET | |
1006 | case AF_INET: | |
1007 | hp = gethostbyaddr((char *) &sap->sin.sin_addr, | |
648eb46e | 1008 | INADDRSZ, |
3f03d7a7 EA |
1009 | AF_INET); |
1010 | break; | |
1011 | #endif | |
1012 | ||
1013 | #ifdef NETISO | |
1014 | case AF_ISO: | |
1015 | hp = gethostbyaddr((char *) &sap->siso.siso_addr, | |
1016 | sizeof sap->siso.siso_addr, | |
1017 | AF_ISO); | |
1018 | break; | |
1019 | #endif | |
1020 | ||
13cdecbc EA |
1021 | case AF_UNIX: |
1022 | hp = NULL; | |
1023 | break; | |
13cdecbc | 1024 | |
3f03d7a7 EA |
1025 | default: |
1026 | hp = gethostbyaddr(sap->sa.sa_data, | |
1027 | sizeof sap->sa.sa_data, | |
1028 | sap->sa.sa_family); | |
1029 | break; | |
1030 | } | |
1031 | ||
efe7f723 | 1032 | #if NAMED_BIND |
ab6ca5e5 EA |
1033 | _res.retry = saveretry; |
1034 | #endif /* NAMED_BIND */ | |
1035 | ||
3f03d7a7 EA |
1036 | if (hp != NULL) |
1037 | return hp->h_name; | |
1038 | else | |
1039 | { | |
1040 | /* produce a dotted quad */ | |
1041 | static char buf[512]; | |
1042 | ||
1043 | (void) sprintf(buf, "[%s]", anynet_ntoa(sap)); | |
1044 | return buf; | |
1045 | } | |
1046 | } | |
d0432129 | 1047 | |
f3d8f6d6 | 1048 | # else /* DAEMON */ |
217a0102 | 1049 | /* code for systems without sophisticated networking */ |
2ec2faaa EA |
1050 | |
1051 | /* | |
1052 | ** MYHOSTNAME -- stub version for case of no daemon code. | |
69f904e0 EA |
1053 | ** |
1054 | ** Can't convert to upper case here because might be a UUCP name. | |
05894fc6 EA |
1055 | ** |
1056 | ** Mark, you can change this to be anything you want...... | |
2ec2faaa EA |
1057 | */ |
1058 | ||
1059 | char ** | |
05894fc6 | 1060 | myhostname(hostbuf, size) |
2ec2faaa | 1061 | char hostbuf[]; |
05894fc6 | 1062 | int size; |
2ec2faaa EA |
1063 | { |
1064 | register FILE *f; | |
1065 | ||
1066 | hostbuf[0] = '\0'; | |
1067 | f = fopen("/usr/include/whoami", "r"); | |
1068 | if (f != NULL) | |
1069 | { | |
05894fc6 | 1070 | (void) fgets(hostbuf, size, f); |
2ec2faaa EA |
1071 | fixcrlf(hostbuf, TRUE); |
1072 | (void) fclose(f); | |
1073 | } | |
1074 | return (NULL); | |
1075 | } | |
217a0102 | 1076 | \f/* |
3f03d7a7 | 1077 | ** GETAUTHINFO -- get the real host name asociated with a file descriptor |
5973222c EA |
1078 | ** |
1079 | ** Parameters: | |
1080 | ** fd -- the descriptor | |
1081 | ** | |
1082 | ** Returns: | |
1083 | ** The host name associated with this descriptor, if it can | |
1084 | ** be determined. | |
1085 | ** NULL otherwise. | |
1086 | ** | |
1087 | ** Side Effects: | |
1088 | ** none | |
1089 | */ | |
1090 | ||
1091 | char * | |
3f03d7a7 | 1092 | getauthinfo(fd) |
5973222c EA |
1093 | int fd; |
1094 | { | |
1095 | return NULL; | |
1096 | } | |
1097 | \f/* | |
217a0102 EA |
1098 | ** MAPHOSTNAME -- turn a hostname into canonical form |
1099 | ** | |
1100 | ** Parameters: | |
5a4c03c6 | 1101 | ** map -- a pointer to the database map. |
713c523f | 1102 | ** name -- a buffer containing a hostname. |
42fa5d67 | 1103 | ** avp -- a pointer to a (cf file defined) argument vector. |
d1db7a89 | 1104 | ** statp -- an exit status (out parameter). |
217a0102 EA |
1105 | ** |
1106 | ** Returns: | |
42fa5d67 | 1107 | ** mapped host name |
bbfde42f | 1108 | ** FALSE otherwise. |
217a0102 EA |
1109 | ** |
1110 | ** Side Effects: | |
713c523f | 1111 | ** Looks up the host specified in name. If it is not |
217a0102 EA |
1112 | ** the canonical name for that host, replace it with |
1113 | ** the canonical name. If the name is unknown, or it | |
1114 | ** is already the canonical name, leave it unchanged. | |
1115 | */ | |
1116 | ||
1117 | /*ARGSUSED*/ | |
42fa5d67 | 1118 | char * |
713c523f | 1119 | host_map_lookup(map, name, avp, statp) |
5a4c03c6 | 1120 | MAP *map; |
713c523f | 1121 | char *name; |
42fa5d67 | 1122 | char **avp; |
d1db7a89 | 1123 | char *statp; |
217a0102 | 1124 | { |
d1db7a89 EA |
1125 | register struct hostent *hp; |
1126 | ||
713c523f | 1127 | hp = gethostbyname(name); |
d1db7a89 EA |
1128 | if (hp != NULL) |
1129 | return hp->h_name; | |
1130 | *statp = EX_NOHOST; | |
42fa5d67 | 1131 | return NULL; |
217a0102 EA |
1132 | } |
1133 | ||
f3d8f6d6 | 1134 | #endif /* DAEMON */ |