summaryrefslogtreecommitdiffstats
path: root/libexec/ftpd/ftpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ftpd/ftpd.c')
-rw-r--r--libexec/ftpd/ftpd.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 1f5ce00..d59edd6 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -1772,7 +1772,7 @@ dataconn(char *name, off_t size, char *mode)
{
char sizebuf[32];
FILE *file;
- int retry = 0, tos;
+ int retry = 0, tos, conerrno;
file_size = size;
byte_count = 0;
@@ -1840,28 +1840,35 @@ pdata_err:
if (usedefault)
data_dest = his_addr;
usedefault = 1;
- file = getdatasock(mode);
- if (file == NULL) {
- char hostbuf[BUFSIZ], portbuf[BUFSIZ];
- getnameinfo((struct sockaddr *)&data_source,
- data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
- portbuf, sizeof(portbuf),
- NI_NUMERICHOST|NI_NUMERICSERV);
- reply(425, "Can't create data socket (%s,%s): %s.",
- hostbuf, portbuf, strerror(errno));
- return (NULL);
- }
- data = fileno(file);
- while (connect(data, (struct sockaddr *)&data_dest,
- data_dest.su_len) < 0) {
- if (errno == EADDRINUSE && retry < swaitmax) {
+ do {
+ file = getdatasock(mode);
+ if (file == NULL) {
+ char hostbuf[BUFSIZ], portbuf[BUFSIZ];
+ getnameinfo((struct sockaddr *)&data_source,
+ data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
+ portbuf, sizeof(portbuf),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ reply(425, "Can't create data socket (%s,%s): %s.",
+ hostbuf, portbuf, strerror(errno));
+ return (NULL);
+ }
+ data = fileno(file);
+ conerrno = 0;
+ if (connect(data, (struct sockaddr *)&data_dest,
+ data_dest.su_len) == 0)
+ break;
+ conerrno = errno;
+ (void) fclose(file);
+ data = -1;
+ if (conerrno == EADDRINUSE) {
sleep((unsigned) swaitint);
retry += swaitint;
- continue;
+ } else {
+ break;
}
+ } while (retry <= swaitmax);
+ if (conerrno != 0) {
perror_reply(425, "Can't build data connection");
- (void) fclose(file);
- data = -1;
return (NULL);
}
reply(150, "Opening %s mode data connection for '%s'%s.",
OpenPOWER on IntegriCloud