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 (&current_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(&current_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(&current_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