X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ftpd.c;h=7d52ba3d234da84a6f699aecc1aced981faf1d56;hb=387002b6259cb7f9284e786a35763a2aeaff5dbd;hp=23a7134e51665e384d598839ef28770e3faa95b1;hpb=8c87c5d1792e7dd55f8b07f717d329f612e263dc;p=betaftpd diff --git a/ftpd.c b/ftpd.c index 23a7134..7d52ba3 100644 --- a/ftpd.c +++ b/ftpd.c @@ -446,6 +446,9 @@ struct ftran *alloc_new_ftran(const int sock, const struct conn * const c) #endif f->dir_listing = 0; +#if WANT_UPLOAD + f->upload = 0; +#endif return f; } @@ -583,7 +586,7 @@ int process_all_clients(const fd_set * const active_clients, const int num_ac) c->buf_len += bytes_avail; parse_command(c); - if (fds[c->sock].revents & (POLLERR|POLLHUP|POLLNVAL)) { + if (c->free_me || (fds[c->sock].revents & (POLLERR|POLLHUP|POLLNVAL))) { destroy_conn(c); } } @@ -599,7 +602,7 @@ int process_all_clients(const fd_set * const active_clients, const int num_ac) void finish_transfer(struct ftran * const f) { char finished[] = "226 Transfer complete.\r\n"; - if (send(f->owner->sock, finished, sizeof(finished), 0) == -1 && errno == EPIPE) { + if (send(f->owner->sock, finished, strlen(finished), 0) == -1 && errno == EPIPE) { destroy_conn(f->owner); return; } @@ -683,12 +686,25 @@ int process_all_sendfiles(fd_set * const active_clients, const int num_ac) f->sock = tempsock; ioctl(f->sock, FIONBIO, &one); init_file_transfer(f); + + flush_numeric(f->owner); + if (f->owner->free_me) { + destroy_conn(f->owner); + continue; + } + #if WANT_UPLOAD if (f->upload) continue; #endif } if (f->state < 5) { init_file_transfer(f); + + flush_numeric(f->owner); + if (f->owner->free_me) { + destroy_conn(f->owner); + continue; + } #if WANT_UPLOAD if (f->upload) continue; #endif @@ -746,7 +762,7 @@ int do_upload(struct ftran *f) #endif if (size > 0 && (write(f->local_file, upload_buf, size) == size)) { return 1; - } else if (size == -1) { + } else if (size == -1 && errno != EAGAIN) { /* don't write xferlog... or? */ numeric(f->owner, 426, strerror(errno)); destroy_ftran(f); @@ -1130,7 +1146,7 @@ void accept_new_client(int * const server_sock) memcpy(&(c->addr), &tempaddr, sizeof(struct sockaddr)); #endif - if (send(tempsock, hello, sizeof(hello), 0) == -1 && errno == EPIPE) + if (send(tempsock, hello, strlen(hello), 0) == -1 && errno == EPIPE) destroy_conn(c); } } @@ -1215,7 +1231,7 @@ void numeric(struct conn * const c, const int numeric, const char * const format { char fmt[256]; va_list args; - int i, err; + int i; int in_buf = strlen(message_buf); snprintf(fmt, 256, "%03u %s\r\n", numeric, format); @@ -1225,6 +1241,16 @@ void numeric(struct conn * const c, const int numeric, const char * const format va_end(args); } +/* flush_numeric(): + * Actually flushes the buffer written by numeric() -- but does + * NOT erase it. If an error, sets the "free_me" flag in the socket. + */ +void flush_numeric(struct conn * const c) +{ + if (send(c->sock, message_buf, strlen(message_buf), 0) == -1 && errno == EPIPE) + c->free_me = 1; +} + /* * init_file_transfer(): * Initiate a data connection for sending. This does not open