Upstream qmail 1.01
[qmail] / tcp-env.c
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <sys/param.h>
4 #include <netinet/in.h>
5 #include "sig.h"
6 #include "stralloc.h"
7 #include "str.h"
8 #include "env.h"
9 #include "fmt.h"
10 #include "scan.h"
11 #include "subgetopt.h"
12 #include "ip.h"
13 #include "dns.h"
14 #include "byte.h"
15 #include "remoteinfo.h"
16 #include "exit.h"
17 #include "case.h"
18
19 void die() { _exit(111); }
20
21 struct sockaddr_in salocal;
22 unsigned long localport;
23 struct ip_address iplocal;
24 stralloc localname = {0};
25
26 struct sockaddr_in saremote;
27 unsigned long remoteport;
28 struct ip_address ipremote;
29 stralloc remotename = {0};
30
31 char temp[IPFMT + FMT_ULONG];
32
33 void main(argc,argv)
34 int argc;
35 char *argv[];
36 {
37 int dummy;
38 char *proto;
39 int opt;
40 int flagremoteinfo;
41 unsigned long timeout;
42
43 sig_pipeignore();
44
45 flagremoteinfo = 1;
46 timeout = 30;
47 while ((opt = sgopt(argc,argv,"rRt:")) != sgoptdone)
48 switch(opt)
49 {
50 case 'r': flagremoteinfo = 1; break;
51 case 'R': flagremoteinfo = 0; break;
52 case 't': scan_ulong(sgoptarg,&timeout); break;
53 }
54
55 argv += sgoptind;
56 argc -= sgoptind;
57
58 if (argc < 1) die();
59 if (!env_init()) die();
60
61 proto = env_get("PROTO");
62 if (!proto || str_diff(proto,"TCP"))
63 {
64 if (!env_put("PROTO=TCP")) die();
65
66 dummy = sizeof(salocal);
67 if (getsockname(0,(struct sockaddr *) &salocal,&dummy) == -1) die();
68
69 localport = ntohs(salocal.sin_port);
70 temp[fmt_ulong(temp,localport)] = 0;
71 if (!env_put2("TCPLOCALPORT",temp)) die();
72
73 byte_copy(&iplocal,4,&salocal.sin_addr);
74 temp[ip_fmt(temp,&iplocal)] = 0;
75 if (!env_put2("TCPLOCALIP",temp)) die();
76
77 switch(dns_ptr(&localname,&iplocal))
78 {
79 case DNS_MEM: die();
80 case DNS_SOFT:
81 if (!stralloc_copys(&localname,"softdnserror")) die();
82 case 0:
83 if (!stralloc_0(&localname)) die();
84 case_lowers(localname.s);
85 if (!env_put2("TCPLOCALHOST",localname.s)) die();
86 break;
87 default:
88 if (!env_unset("TCPLOCALHOST")) die();
89 }
90
91 dummy = sizeof(saremote);
92 if (getpeername(0,(struct sockaddr *) &saremote,&dummy) == -1) die();
93
94 remoteport = ntohs(saremote.sin_port);
95 temp[fmt_ulong(temp,remoteport)] = 0;
96 if (!env_put2("TCPREMOTEPORT",temp)) die();
97
98 byte_copy(&ipremote,4,&saremote.sin_addr);
99 temp[ip_fmt(temp,&ipremote)] = 0;
100 if (!env_put2("TCPREMOTEIP",temp)) die();
101
102 switch(dns_ptr(&remotename,&ipremote))
103 {
104 case DNS_MEM: die();
105 case DNS_SOFT:
106 if (!stralloc_copys(&remotename,"softdnserror")) die();
107 case 0:
108 if (!stralloc_0(&remotename)) die();
109 case_lowers(remotename.s);
110 if (!env_put2("TCPREMOTEHOST",remotename.s)) die();
111 break;
112 default:
113 if (!env_unset("TCPREMOTEHOST")) die();
114 }
115
116 if (!env_unset("TCPREMOTEINFO")) die();
117 if (flagremoteinfo)
118 {
119 char *rinfo;
120 rinfo = remoteinfo_get(&ipremote,remoteport,&iplocal,localport,(int) timeout);
121 if (rinfo)
122 if (!env_put2("TCPREMOTEINFO",rinfo)) die();
123 }
124 }
125
126 sig_pipedefault();
127 execvp(*argv,argv);
128 die();
129 }