chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / remoteinfo.c
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <netinet/in.h>
4 #include <fcntl.h>
5 #include "byte.h"
6 #include "substdio.h"
7 #include "ip.h"
8 #include "fmt.h"
9 #include "timeoutconn.h"
10 #include "timeoutread.h"
11 #include "timeoutwrite.h"
12 #include "remoteinfo.h"
13
14 static char line[999];
15 static int t;
16
17 static int mywrite(fd,buf,len) int fd; char *buf; int len;
18 {
19   return timeoutwrite(t,fd,buf,len);
20 }
21 static int myread(fd,buf,len) int fd; char *buf; int len;
22 {
23   return timeoutread(t,fd,buf,len);
24 }
25
26 char *remoteinfo_get(ipr,rp,ipl,lp,timeout)
27 struct ip_address *ipr;
28 unsigned long rp;
29 struct ip_address *ipl;
30 unsigned long lp;
31 int timeout;
32 {
33   char *x;
34   int s;
35   struct sockaddr_in sin;
36   substdio ss;
37   char buf[32];
38   unsigned int len;
39   int numcolons;
40   char ch;
41
42   t = timeout;
43  
44   s = socket(AF_INET,SOCK_STREAM,0);
45   if (s == -1) return 0;
46  
47   byte_zero(&sin,sizeof(sin));
48   sin.sin_family = AF_INET;
49   byte_copy(&sin.sin_addr,4,ipl);
50   sin.sin_port = 0;
51   if (bind(s,(struct sockaddr *) &sin,sizeof(sin)) == -1) { close(s); return 0; }
52   if (timeoutconn(s,ipr,113,timeout) == -1) { close(s); return 0; }
53   fcntl(s,F_SETFL,fcntl(s,F_GETFL,0) & ~O_NDELAY);
54  
55   len = 0;
56   len += fmt_ulong(line + len,rp);
57   len += fmt_str(line + len," , ");
58   len += fmt_ulong(line + len,lp);
59   len += fmt_str(line + len,"\r\n");
60  
61   substdio_fdbuf(&ss,mywrite,s,buf,sizeof buf);
62   if (substdio_putflush(&ss,line,len) == -1) { close(s); return 0; }
63  
64   substdio_fdbuf(&ss,myread,s,buf,sizeof buf);
65   x = line;
66   numcolons = 0;
67   for (;;) {
68     if (substdio_get(&ss,&ch,1) != 1) { close(s); return 0; }
69     if ((ch == ' ') || (ch == '\t') || (ch == '\r')) continue;
70     if (ch == '\n') break;
71     if (numcolons < 3) { if (ch == ':') ++numcolons; }
72     else { *x++ = ch; if (x == line + sizeof(line) - 1) break; }
73   }
74   *x = 0;
75   close(s);
76   return line;
77 }