1 |
|
|
2 |
/* Copyright (C) 1999 Beau Kuiper |
/* Copyright (C) 1999 Beau Kuiper |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
26 |
char *getipstr(unsigned int server) |
char *getipstr(unsigned int server) |
27 |
{ |
{ |
28 |
static char ipstr[20]; |
static char ipstr[20]; |
29 |
snprintf(ipstr, 20, "%d.%d.%d.%d", server >> 24, |
|
30 |
(server >> 16) & 0xFF, |
snprintf(ipstr, 20, "%d.%d.%d.%d", server >> 24, |
31 |
(server >> 8) & 0xFF, |
(server >> 16) & 0xFF, (server >> 8) & 0xFF, server & 0xFF); |
32 |
server & 0xFF); |
return (ipstr); |
|
return(ipstr); |
|
33 |
} |
} |
34 |
|
|
35 |
void takentoolong(int sig) |
void takentoolong(int sig) |
36 |
{ |
{ |
37 |
siglongjmp(sigbuf, 1); |
siglongjmp(sigbuf, 1); |
43 |
struct hostent *hostentry; |
struct hostent *hostentry; |
44 |
unsigned int myserve = htonl(server); |
unsigned int myserve = htonl(server); |
45 |
int a; |
int a; |
46 |
|
|
47 |
a = sigsetjmp(sigbuf, 1); |
a = sigsetjmp(sigbuf, 1); |
48 |
signal(SIGALRM, takentoolong); |
signal(SIGALRM, takentoolong); |
49 |
|
|
50 |
if ((a == 0) && (config->dnstimeout != -1)) |
if ((a == 0) && (config->dnstimeout != -1)) |
51 |
{ |
{ |
52 |
alarm(config->dnstimeout); |
alarm(config->dnstimeout); |
53 |
hostentry = gethostbyaddr((char *)&myserve, sizeof(unsigned int), AF_INET); |
hostentry = |
54 |
|
gethostbyaddr((char *) &myserve, sizeof(unsigned int), AF_INET); |
55 |
} |
} |
56 |
else |
else |
57 |
hostentry = NULL; |
hostentry = NULL; |
59 |
alarm(0); |
alarm(0); |
60 |
|
|
61 |
if (hostentry) |
if (hostentry) |
62 |
return(strdupwrapper(hostentry->h_name)); |
return (strdupwrapper(hostentry->h_name)); |
63 |
else |
else |
64 |
return(strdupwrapper((char *)getipstr(server))); |
return (strdupwrapper((char *) getipstr(server))); |
65 |
} |
} |
66 |
|
|
67 |
/* This procedure gets the internet ip address for a hostname or IP string. |
/* This procedure gets the internet ip address for a hostname or IP string. |
69 |
a host name |
a host name |
70 |
*/ |
*/ |
71 |
|
|
72 |
int getnetworkint(char *server, unsigned int *out) |
int getnetworkint(char *server, |
73 |
|
unsigned int *out) |
74 |
{ |
{ |
75 |
int pos, trigger; |
int pos, trigger; |
76 |
struct hostent *hostentry; |
struct hostent *hostentry; |
78 |
char *buffertmp; |
char *buffertmp; |
79 |
unsigned int a1, a2, a3, a4; |
unsigned int a1, a2, a3, a4; |
80 |
unsigned int l; |
unsigned int l; |
81 |
|
|
82 |
pos = 0; trigger = 0; |
pos = 0; |
83 |
|
trigger = 0; |
84 |
while ((server[pos] != 0) && (trigger != 1)) |
while ((server[pos] != 0) && (trigger != 1)) |
85 |
{ |
{ |
86 |
if (((server[pos] < '0') || (server[pos] > '9')) && (server[pos] != 46)) |
if (((server[pos] < '0') || (server[pos] > '9')) |
87 |
|
&& (server[pos] != 46)) |
88 |
trigger = 1; |
trigger = 1; |
89 |
pos = pos + 1; |
pos = pos + 1; |
90 |
} |
} |
92 |
{ |
{ |
93 |
hostentry = gethostbyname(server); |
hostentry = gethostbyname(server); |
94 |
if (hostentry == NULL) |
if (hostentry == NULL) |
95 |
return(-1); /* DNS failure */ |
return (-1); /* DNS failure */ |
96 |
ipaddrstr = hostentry->h_addr_list; |
ipaddrstr = hostentry->h_addr_list; |
97 |
memcpy(&l, *ipaddrstr, 4); |
memcpy(&l, *ipaddrstr, 4); |
98 |
l = ntohl(l); |
l = ntohl(l); |
99 |
} |
} |
100 |
else |
else |
101 |
{ |
{ |
102 |
|
|
103 |
buffertmp = mallocwrapper(sizeof(char) * (strlen(server) + 1)); |
buffertmp = mallocwrapper(sizeof(char) * (strlen(server) + 1)); |
104 |
pos = 0; |
pos = 0; |
105 |
while (server[pos] != 0) |
while (server[pos] != 0) |
111 |
pos = pos + 1; |
pos = pos + 1; |
112 |
} |
} |
113 |
buffertmp[pos] = 0; |
buffertmp[pos] = 0; |
114 |
sscanf(buffertmp, "%uA%uA%uA%u", &a1, &a2, &a3,&a4); |
sscanf(buffertmp, "%uA%uA%uA%u", &a1, &a2, &a3, &a4); |
115 |
l = ((a1 * 256 * 256 * 256) + (a2 * 256 * 256) + (a3 * 256) + a4); |
l = ((a1 * 256 * 256 * 256) + (a2 * 256 * 256) + (a3 * 256) + a4); |
116 |
freewrapper(buffertmp); |
freewrapper(buffertmp); |
117 |
} |
} |
118 |
*out = l; |
*out = l; |
119 |
return(0); |
return (0); |
120 |
} |
} |
121 |
|
|
122 |
int conn_server(unsigned int ip, int port) |
int conn_server(unsigned int ip, |
123 |
|
int port) |
124 |
{ |
{ |
125 |
int socknum, pos; |
int socknum, pos; |
126 |
|
|
129 |
dest.sin_addr.s_addr = htonl(ip); |
dest.sin_addr.s_addr = htonl(ip); |
130 |
dest.sin_port = htons(port); |
dest.sin_port = htons(port); |
131 |
dest.sin_family = AF_INET; |
dest.sin_family = AF_INET; |
132 |
socknum = socket( AF_INET, SOCK_STREAM, 6); |
socknum = socket(AF_INET, SOCK_STREAM, 6); |
133 |
if (socknum == -1) |
if (socknum == -1) |
134 |
return(-1); |
return (-1); |
135 |
|
|
136 |
pos = connect(socknum, (struct sockaddr *)&dest, sizeof(dest)); |
pos = connect(socknum, (struct sockaddr *) &dest, sizeof(dest)); |
137 |
if (pos == -1) |
if (pos == -1) |
138 |
return(-1); /* Connection failure */ |
return (-1); /* Connection failure */ |
139 |
|
|
140 |
return (socknum); |
return (socknum); |
141 |
} |
} |
142 |
|
|
143 |
int conn_server_nonblocking(unsigned int ip, int port, int localport, int fd) |
int conn_server_nonblocking(unsigned int ip, |
144 |
|
int port, |
145 |
|
int localport, |
146 |
|
int fd) |
147 |
{ |
{ |
148 |
int socknum, pos; |
int socknum, pos; |
149 |
struct sockaddr_in dest; |
struct sockaddr_in dest; |
150 |
int on = 1; |
int on = 1; |
151 |
int tmp; |
int tmp; |
152 |
|
|
153 |
socknum = socket(AF_INET, SOCK_STREAM, 6); |
socknum = socket(AF_INET, SOCK_STREAM, 6); |
154 |
if (socknum == -1) |
if (socknum == -1) |
155 |
return(-1); |
return (-1); |
156 |
|
|
157 |
/* See if we can get the local port we want to bind to */ |
/* |
158 |
/* If we can't, just let the computer choose a port for us */ |
* See if we can get the local port we want to bind to |
159 |
|
*/ |
160 |
|
/* |
161 |
|
* If we can't, just let the computer choose a port for us |
162 |
|
*/ |
163 |
|
|
164 |
dest.sin_family = AF_INET; |
dest.sin_family = AF_INET; |
165 |
|
|
166 |
tmp = sizeof(dest); |
tmp = sizeof(dest); |
167 |
getsockname(fd, (struct sockaddr *)&dest, &tmp); |
getsockname(fd, (struct sockaddr *) &dest, &tmp); |
168 |
|
|
169 |
dest.sin_port = htons(localport); |
dest.sin_port = htons(localport); |
170 |
|
|
171 |
setsockopt(socknum, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
setsockopt(socknum, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
172 |
|
|
173 |
/* attempt to bind the socket, if it doesn't work, it isn't a problem */ |
/* |
174 |
bind(socknum, (struct sockaddr *)&dest, sizeof(dest)); |
* attempt to bind the socket, if it doesn't work, it isn't a problem |
175 |
|
*/ |
176 |
|
bind(socknum, (struct sockaddr *) &dest, sizeof(dest)); |
177 |
|
|
178 |
dest.sin_port = htons(port); |
dest.sin_port = htons(port); |
179 |
dest.sin_addr.s_addr = htonl(ip); |
dest.sin_addr.s_addr = htonl(ip); |
180 |
fcntl(socknum, F_SETFL, O_NONBLOCK); |
fcntl(socknum, F_SETFL, O_NONBLOCK); |
181 |
|
|
182 |
pos = connect(socknum, (struct sockaddr *)&dest, sizeof(dest)); |
pos = connect(socknum, (struct sockaddr *) &dest, sizeof(dest)); |
183 |
if ((pos == -1) && (errno != EINPROGRESS)) |
if ((pos == -1) && (errno != EINPROGRESS)) |
184 |
return(-1); /* Connection failure */ |
return (-1); /* Connection failure */ |
185 |
|
|
186 |
return (socknum); |
return (socknum); |
187 |
} |
} |
188 |
|
|
195 |
-1 - Binding the socket failed, probably because the port is already used |
-1 - Binding the socket failed, probably because the port is already used |
196 |
-2 - Socket creation failed for some, probably serious reason |
-2 - Socket creation failed for some, probably serious reason |
197 |
*/ |
*/ |
198 |
|
|
199 |
int listenport(int port, unsigned int ip, int maxconnect) |
int listenport(int port, |
200 |
|
unsigned int ip, |
201 |
|
int maxconnect) |
202 |
{ |
{ |
203 |
int newport; |
int newport; |
204 |
struct sockaddr_in dest; |
struct sockaddr_in dest; |
205 |
int on = 1; |
int on = 1; |
206 |
|
|
207 |
newport = socket(AF_INET, SOCK_STREAM, 6); |
newport = socket(AF_INET, SOCK_STREAM, 6); |
208 |
if (newport == -1) |
if (newport == -1) |
209 |
return(-1); |
return (-1); |
210 |
|
|
211 |
dest.sin_family = AF_INET; |
dest.sin_family = AF_INET; |
212 |
dest.sin_port = htons(port); |
dest.sin_port = htons(port); |
213 |
dest.sin_addr.s_addr = htonl(ip); /* clear the address so it works */ |
dest.sin_addr.s_addr = htonl(ip); /* clear the address so it works */ |
214 |
|
|
215 |
setsockopt(newport, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
setsockopt(newport, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); |
216 |
|
|
217 |
if (bind(newport, (struct sockaddr *)&dest, sizeof(dest)) == -1) |
if (bind(newport, (struct sockaddr *) &dest, sizeof(dest)) == -1) |
218 |
return(-1); |
return (-1); |
219 |
|
|
220 |
listen(newport, maxconnect); |
listen(newport, maxconnect); |
221 |
|
|
222 |
return(newport); |
return (newport); |
223 |
} |
} |
224 |
|
|
225 |
/* This procedure accepts a connection on a socket defined with the above |
/* This procedure accepts a connection on a socket defined with the above |
226 |
procedure. It requires the socket number. |
procedure. It requires the socket number. |
227 |
|
|
230 |
>0 - the file descriptor of the open connection |
>0 - the file descriptor of the open connection |
231 |
-1 - failure (something went wrong) |
-1 - failure (something went wrong) |
232 |
*/ |
*/ |
233 |
|
|
234 |
int get_conn(int socketin, unsigned int *addr) |
int get_conn(int socketin, |
235 |
|
unsigned int *addr) |
236 |
{ |
{ |
237 |
struct sockaddr_in dest; |
struct sockaddr_in dest; |
238 |
int inport, n; |
int inport, n; |
239 |
|
|
240 |
n = sizeof(dest); |
n = sizeof(dest); |
241 |
|
|
242 |
|
inport = accept(socketin, (struct sockaddr *) &dest, &n); |
243 |
|
|
|
inport = accept(socketin, (struct sockaddr *)&dest, &n); |
|
|
|
|
244 |
if (inport == -1) |
if (inport == -1) |
245 |
{ |
{ |
246 |
return(-1); |
return (-1); |
247 |
} |
} |
248 |
|
|
249 |
*addr = ntohl(dest.sin_addr.s_addr); |
*addr = ntohl(dest.sin_addr.s_addr); |
250 |
return(inport); |
return (inport); |
251 |
} |
} |
252 |
|
|
253 |
/* this sets up a connection parralel to a current connection. It is used |
/* this sets up a connection parralel to a current connection. It is used |
254 |
for the data connection in the FTP server */ |
for the data connection in the FTP server */ |
255 |
|
|
256 |
int listenparrelelport(int fd, int *port, unsigned int *ip, int maxconnect) |
int listenparrelelport(int fd, |
257 |
|
int *port, |
258 |
|
unsigned int *ip, |
259 |
|
int maxconnect) |
260 |
{ |
{ |
261 |
int newport; |
int newport; |
262 |
struct sockaddr_in dest; |
struct sockaddr_in dest; |
263 |
int tmp; |
int tmp; |
264 |
|
|
265 |
newport = socket(AF_INET, SOCK_STREAM, 6); |
newport = socket(AF_INET, SOCK_STREAM, 6); |
266 |
if (newport == -1) |
if (newport == -1) |
267 |
return(-1); |
return (-1); |
|
|
|
|
tmp = sizeof(dest); |
|
|
getsockname(fd, (struct sockaddr *)&dest, &tmp); |
|
268 |
|
|
269 |
tmp = 1; |
tmp = sizeof(dest); |
270 |
|
getsockname(fd, (struct sockaddr *) &dest, &tmp); |
271 |
|
|
272 |
|
tmp = 1; |
273 |
setsockopt(newport, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); |
setsockopt(newport, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); |
274 |
|
|
275 |
dest.sin_port = htons(*port); |
dest.sin_port = htons(*port); |
276 |
if (bind(newport, (struct sockaddr *)&dest, sizeof(dest)) == -1) |
if (bind(newport, (struct sockaddr *) &dest, sizeof(dest)) == -1) |
277 |
return(-1); |
return (-1); |
278 |
|
|
279 |
tmp = sizeof(dest); |
tmp = sizeof(dest); |
280 |
getsockname(newport, (struct sockaddr *)&dest, &tmp); |
getsockname(newport, (struct sockaddr *) &dest, &tmp); |
281 |
|
|
282 |
*port = ntohs(dest.sin_port); |
*port = ntohs(dest.sin_port); |
283 |
*ip = ntohl(dest.sin_addr.s_addr); |
*ip = ntohl(dest.sin_addr.s_addr); |
|
|
|
|
listen(newport, maxconnect); |
|
284 |
|
|
285 |
return(newport); |
listen(newport, maxconnect); |
286 |
|
|
287 |
|
return (newport); |
288 |
} |
} |
289 |
|
|
290 |
void getsockinfo(int fd, unsigned int *ip, int *port) |
void getsockinfo(int fd, |
291 |
|
unsigned int *ip, |
292 |
|
int *port) |
293 |
{ |
{ |
294 |
struct sockaddr_in dest; |
struct sockaddr_in dest; |
295 |
int tmp; |
int tmp; |
296 |
|
|
297 |
tmp = sizeof(dest); |
tmp = sizeof(dest); |
298 |
getsockname(fd, (struct sockaddr *)&dest, &tmp); |
getsockname(fd, (struct sockaddr *) &dest, &tmp); |
299 |
*ip = ntohl(dest.sin_addr.s_addr); |
*ip = ntohl(dest.sin_addr.s_addr); |
300 |
*port = ntohs(dest.sin_port); |
*port = ntohs(dest.sin_port); |
301 |
} |
} |
304 |
{ |
{ |
305 |
struct sockaddr_in name; |
struct sockaddr_in name; |
306 |
int len = sizeof(name); |
int len = sizeof(name); |
307 |
|
|
308 |
if (!getpeername(fd, (struct sockaddr *)&name, &len)) |
if (!getpeername(fd, (struct sockaddr *) &name, &len)) |
309 |
return(ntohl(name.sin_addr.s_addr)); |
return (ntohl(name.sin_addr.s_addr)); |
310 |
else |
else |
311 |
return(1); |
return (1); |
312 |
} |
} |
313 |
|
|
314 |
void socket_flush_wait(int fd, int timeout) |
void socket_flush_wait(int fd, |
315 |
|
int timeout) |
316 |
{ |
{ |
317 |
char c; |
char c; |
318 |
|
|
319 |
signal(SIGALRM, SIG_IGN); |
signal(SIGALRM, SIG_IGN); |
320 |
alarm(timeout); |
alarm(timeout); |
321 |
|
|
322 |
shutdown(fd, 1); |
shutdown(fd, 1); |
323 |
read(fd, &c, 1); |
read(fd, &c, 1); |
324 |
alarm(0); |
alarm(0); |