1 /*
2 ** Copyright 1998 - 2001 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5
6 #if HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9 #include "tcpremoteinfo.h"
10 #include "soxwrap/sconnect.h"
11
12 #if HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15 #if HAVE_FCNTL_H
16 #include <fcntl.h>
17 #endif
18 #include <stdio.h>
19 #include <errno.h>
20 #include <string.h>
21
22 #include "soxwrap/soxwrap.h"
23
24
tcpremoteinfo(const RFC1035_ADDR * laddr,int lport,const RFC1035_ADDR * raddr,int rport,const char ** ostype)25 const char *tcpremoteinfo(const RFC1035_ADDR *laddr, int lport,
26 const RFC1035_ADDR *raddr, int rport, const char **ostype)
27 {
28 int fd;
29 time_t current_time, max_time;
30 fd_set fds;
31 struct timeval tv;
32 static char buf[512];
33 char *bufptr;
34 int bufleft, n;
35 char *p;
36 char *q;
37 RFC1035_NETADDR sin;
38 const struct sockaddr *addr;
39 int addrlen;
40
41 fd=rfc1035_mksocket(SOCK_STREAM, 0, &n);
42 if (fd < 0) return (0);
43
44 if (rfc1035_mkaddress(n, &sin, laddr, 0, &addr, &addrlen) < 0)
45 {
46 close(fd);
47 return (0);
48 }
49
50 if (sox_bind(fd, addr, addrlen) < 0)
51 {
52 sox_close(fd);
53 return (0);
54 }
55
56 time (¤t_time);
57 max_time=current_time+30;
58
59 if (rfc1035_mkaddress(n, &sin, raddr, htons(113), &addr, &addrlen) < 0)
60 {
61 sox_close(fd);
62 return (0);
63 }
64
65 if (s_connect(fd, addr, addrlen, max_time - current_time) < 0)
66 {
67 sox_close(fd);
68 return (0);
69 }
70
71 sprintf(buf, "%d,%d\r\n", ntohs(rport), ntohs(lport));
72 bufptr=buf;
73 bufleft=strlen(buf);
74 while (bufleft)
75 {
76 time(¤t_time);
77 if (current_time >= max_time)
78 {
79 sox_close(fd);
80 return (0);
81 }
82
83 FD_ZERO(&fds);
84 FD_SET(fd, &fds);
85 tv.tv_sec=max_time-current_time;
86 tv.tv_usec=0;
87 if (sox_select(fd+1, 0, &fds, 0, &tv) != 1 ||
88 !FD_ISSET(fd, &fds))
89 {
90 sox_close(fd);
91 return (0);
92 }
93 n=sox_write(fd, bufptr, bufleft);
94 if (n <= 0)
95 {
96 sox_close(fd);
97 return (0);
98 }
99 bufptr += n;
100 bufleft -= n;
101 }
102
103 bufptr=buf;
104 bufleft=sizeof(buf);
105 do
106 {
107 if (bufleft == 0)
108 {
109 sox_close(fd);
110 return (0);
111 }
112
113 time(¤t_time);
114 if (current_time >= max_time)
115 {
116 sox_close(fd);
117 return (0);
118 }
119
120 FD_ZERO(&fds);
121 FD_SET(fd, &fds);
122 tv.tv_sec=max_time-current_time;
123 tv.tv_usec=0;
124 if (sox_select(fd+1, &fds, 0, 0, &tv) != 1 ||
125 !FD_ISSET(fd, &fds))
126 {
127 sox_close(fd);
128 return (0);
129 }
130
131 n=sox_read(fd, bufptr, bufleft);
132 if (n <= 0)
133 {
134 sox_close(fd);
135 return (0);
136 }
137 bufptr += n;
138 bufleft -= n;
139 } while (bufptr[-1] != '\n');
140 sox_close(fd);
141 bufptr[-1]=0;
142 --bufptr;
143 if (bufptr > buf && bufptr[-1] == '\r')
144 bufptr[-1]=0;
145
146 if ((p=strchr(buf, ':')) == 0)
147 return (0);
148
149 q=++p;
150 if ((p=strchr(p, ':')) == 0)
151 return (0);
152
153 *p++=0;
154 q=strtok(q, " \t");
155 if (!q || strcmp(q, "USERID")) return (0);
156 if (ostype) *ostype=p;
157 if ((p=strchr(p, ':')) == 0)
158 return (0);
159 *p++=0;
160 while (*p && (*p == ' ' || *p == '\t')) p++;
161 return (p);
162 }
163
164