📄 betaftpd_complete.patch
字号:
+ }+ }+ }+@@ -1073,32 +1127,42 @@+ * Open a socket for the new client, say hello and put it in+ * among the others.+ */+-void accept_new_client(int * const server_sock)++int accept_new_client(rn_pollevent_t *e)+ {+ struct sockaddr_in tempaddr;++ rn_pollevent_t e1;+ int tempaddr_len = sizeof(tempaddr);+- const int tempsock = accept(*server_sock, (struct sockaddr *)&tempaddr, &tempaddr_len);+ +- static int num_err = 0;++ for(;;) ++ {++ const int tempsock = accept(e->fd, (struct sockaddr *)&tempaddr, &tempaddr_len);++ DPRINT("accept returned fd %d\n", tempsock);+ +- if (tempsock < 0) {++ if (tempsock < 0) {++ if (errno == EWOULDBLOCK) break; /* handle other errno's due to which this might loop infinitely. See stevens UNPv1, page 424*/++ else if ((errno == EINTR) || (errno == EPROTO) || (errno == ECONNABORTED)) ++ continue;++ else++ {+ #ifndef WANT_FORK+- perror("accept()");++ perror("accept()");+ #endif+- close(tempsock);+- if ((errno == EBADF || errno == EPIPE) && ++num_err >= 3) {+- del_fd(*server_sock);+- *server_sock = create_server_socket();+- }+- } else {+- struct conn * const c = alloc_new_conn(tempsock);+- num_err = 0;+- if (c != NULL) {+- if (numeric(c, 220, "BetaFTPD " VERSION " ready.")) {++ break;++ }++ } else {++ /* done accepting */++ struct conn * const c = alloc_new_conn(tempsock);++ if (c != NULL) {++ if (numeric(c, 220, "BetaFTPD " VERSION " ready.")) {+ #if WANT_STAT+- memcpy(&(c->addr), &tempaddr, sizeof(struct sockaddr));++ memcpy(&(c->addr), &tempaddr, sizeof(struct sockaddr));+ #endif+- ;++ }++ DPRINT("Fake the first control event in case the client sends USER command early\n");++ e1.fd = c->sock;++ e1.revents = rn_POLLIN;++ e1.client.data = c;++ client_eventhandler(&e1);+ }+ }+ }+@@ -1139,7 +1203,7 @@+ c = next;+ next = c->next_conn;+ +- if ((c->transfer == NULL || c->transfer->state != 5) &&++ if ((c->transfer == NULL || c->transfer->state != FTRAN_STATE_TRANSFERING) &&+ (now - c->last_transfer > TIMEOUT_SECS)) {+ /* RFC violation? */+ if (numeric(c, 421, "Timeout (%u minutes): Closing control connection.", TIMEOUT_SECS/60))+@@ -1188,6 +1252,7 @@+ va_end(args);+ + err = send(c->sock, buf, i, 0);++ DPRINT("fd %d sending %s, err = %d\n",c->sock,buf,err);+ if (err == -1 && errno == EPIPE) {+ destroy_conn(c);+ return 0;+@@ -1220,14 +1285,16 @@+ struct conn * const c = f->owner;+ const int mode = IPTOS_THROUGHPUT, zero = 0, one = 1;+ struct stat buf;+- int events;++ int err;++ rn_pollevent_t e;+++ + #ifdef SOL_TCP+ /* we want max throughput */+ setsockopt(f->sock, SOL_IP, IP_TOS, (void *)&mode, sizeof(mode));+ setsockopt(f->sock, SOL_TCP, TCP_NODELAY, (void *)&zero, sizeof(zero));+ #ifdef TCP_CORK+- setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&one, sizeof(one));++ err=setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&one, sizeof(one));+ #endif+ #else+ /* should these pointers be freed afterwards? */+@@ -1249,7 +1316,6 @@+ #if WANT_ASCII+ f->ascii_mode = f->owner->ascii_mode;+ #endif+-+ /* find the preferred block size */+ f->block_size = MAX_BLOCK_SIZE;+ if (fstat(f->local_file, &buf) != -1 &&+@@ -1258,38 +1324,17 @@+ }+ }+ +- f->state = 5;+-+- events = POLLOUT;+-#if WANT_UPLOAD+- if (f->upload) {+- events = POLLIN;+- }+-#endif /* WANT_UPLOAD */+-+- TRAP_ERROR(add_fd(f->sock, events), 500, return);+-++ + ling.l_onoff = 0;+ ling.l_linger = 0;+ setsockopt(f->sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));+ +-#if !HAVE_POLL && WANT_UPLOAD+- /*+- * if we let an upload socket stay in master_send_fds, we would+- * get data that would fool us into closing the socket... (sigh)+- */+- if (f->upload) {+- FD_CLR(f->sock, &master_send_fds);+- FD_SET(f->sock, &master_fds);+- }+-#endif+-+ time(&(f->owner->last_transfer));+ + if (f->dir_listing) {+ /* include size? */+ if (!numeric(f->owner, 150, "Opening ASCII mode data connection for directory listing."))+- return;++ return; /* FIXME caller will crash */+ } else {+ /*+ * slightly kludged -- perhaps we should kill the second arm,+@@ -1356,6 +1401,29 @@+ #else /* !HAVE_MMAP */+ lseek(f->local_file, f->owner->rest_pos, SEEK_SET);+ #endif++++ /* if init_file_transfer is called in this state, then fake the first event */++++ switch (f->state) {++ case FTRAN_STATE_TRANSFERING:++ rn_prepare_fd_for_add(f->sock,own_pid);++ err = rn_add(&rns,f->sock,ftran_data_ioready,f);++ if (err != 0) {++ close(f->sock);++ f->sock = ILLEGAL_FD;++ destroy_ftran(f);++ TRAP_ERROR(err != 0, 501, return ) ;++ }++ DPRINT("Fake the first event to get the ball rolling\n");++ e.fd = f->sock;++ e.revents = rn_POLLOUT;++ e.client.data = f;++ ftran_data_ioready(&e);++ break;++ case FTRAN_STATE_CONNECTING:++ ftran_GOTO(f,FTRAN_STATE_TRANSFERING);++ break;++ }+ }+ + /*+@@ -1369,7 +1437,7 @@+ const unsigned int one = 1;+ struct sockaddr_in addr;+ int err;+- +++ /*+ * In the `perfect' world, if an address was in use, we could+ * just wait for the kernel to clear everything up, and everybody+@@ -1379,7 +1447,6 @@+ * up right away... hence this option.+ */+ setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));+- ioctl(server_sock, FIONBIO, &one); /* just in case */+ + addr.sin_family = AF_INET;+ addr.sin_addr.s_addr = INADDR_ANY;+@@ -1402,11 +1469,12 @@+ }+ } while (err == -1);+ +- listen(server_sock, 20);+-+- err = add_fd(server_sock, POLLIN);++ listen(server_sock, 40);++ ++ rn_prepare_fd_for_add(server_sock,own_pid);++ err = rn_add(&rns,server_sock, accept_new_client,NULL);+ if (err) {+- perror("add_fd");++ perror("rn_add");+ return -1;+ }+ +diff -ur betaftpd-0.0.8pre17/ftpd.h betaftpd/ftpd.h+--- betaftpd-0.0.8pre17/ftpd.h 2003-07-29 09:40:48.000000000 -0700++++ betaftpd/ftpd.h 2003-07-29 09:33:12.000000000 -0700+@@ -26,7 +26,7 @@+ #if WANT_NONROOT+ #define FTP_PORT 12121+ #else+-#define FTP_PORT 21++#define FTP_PORT 12121+ #endif+ + /*+@@ -78,6 +78,8 @@+ #undef WANT_DCACHE+ #endif+ ++#include "rn.h"+++ struct list_options {+ int recursive;+ int long_listing;+@@ -96,6 +98,16 @@+ /* structure specific data here */+ };+ ++#define ILLEGAL_FD -1++++enum conn_state {++ CONN_STATE_DESTROYED,++ CONN_STATE_INIT,++ CONN_STATE_WAIT_USER,++ CONN_STATE_WAIT_PASS,++ CONN_STATE_READY,++};+++ /* doubly linked list of active connections */+ struct conn {+ struct conn *prev_conn;+@@ -112,7 +124,7 @@+ char rename_from[256];+ + int buf_len;+- int auth;++ enum conn_state auth;+ + char username[17];+ +@@ -130,19 +142,40 @@+ time_t last_transfer;+ };+ ++const char *conn_convert_to_string(enum conn_state);++++#define conn_GOTO(c,s) do { DPRINT("c->sock = %d, oldstate = %s, newstate = %s\n",c->sock,conn_convert_to_string(c->auth),conn_convert_to_string(s)); c->auth = s; } while(0)++++enum ftran_ioresult {++ FTRAN_IORESULT_COMPLETE,++ FTRAN_IORESULT_PARTIAL,++ FTRAN_IORESULT_BLOCKED,++ FTRAN_IORESULT_FAILED++};++++enum ftran_state { ++ FTRAN_STATE_NONE,++ FTRAN_STATE_LISTENING,++ FTRAN_STATE_CONNECTED_NO_CMD,++ FTRAN_STATE_LISTENING_GOT_CMD,++ FTRAN_STATE_GOTPORT,++ FTRAN_STATE_CONNECTING,++ FTRAN_STATE_TRANSFERING,++ FTRAN_STATE_DESTROYED++};+++ /* doubly linked list of file transfers */+ struct ftran {+ struct ftran *prev_ftran;+ struct ftran *next_ftran;+ struct conn *owner;+ +- int state; /*++ enum ftran_state state; /*+ * 0 = none, 1 = got PASV addr,+- * 2 = waiting on PASV socket, +- * 3 = got PORT addr, 4 = waiting for+- * PORT connect, +- * 5 = transferring file (or waiting +- * for PORT connect)++ * 2 = accepted data connection on PASV socket,not got cmd++ * yet, 3 = got cmd (followed by pasv cmd), 4 = got PORT ++ * cmd, 5 = waiting for cmd following PORT cmd,++ * 6 = transfering, 7 = destroyed+ */+ struct sockaddr_in sin;+ int sock;+@@ -171,6 +204,11 @@+ #endif+ };+ ++++const char *ftran_convert_to_string(enum ftran_state);++++#define ftran_GOTO(f,s) do { DPRINT("f->sock = %d, oldstate = %s, newstate = %s\n",f->sock,ftran_convert_to_string(f->state),ftran_convert_to_string(s)); f->state = s; } while(0)+++ void add_to_linked_list(struct list_element * const first,+ struct list_element * const elem);+ void remove_from_linked_list(struct list_element * const elem);+@@ -179,31 +217,31 @@+ struct ftran *alloc_new_ftran(const int sock, const struct conn * const c);+ + int add_fd(const int fd, const int events);+-void del_fd(const int fd);+ +-void destroy_conn(struct conn * const c);+-void destroy_ftran(struct ftran * const f);++void _destroy_conn(struct conn * const c);++#define destroy_conn(c) do { if (c) DPRINT("destroy_conn(c %p, fd %d)\n",c,c->sock); _destroy_conn(c); } while(0)++void _destroy_ftran(struct ftran * const f);++#define destroy_ftran(f) do { if (f) DPRINT("destroy_ftran(f %p, fd %d)\n", f, f->sock); _destroy_ftran(f); } while (0)++++/* The three functions to handle the three types of events that can occur */++++int client_eventhandler(rn_pollevent_t *);++int ftran_listening_ioready(rn_pollevent_t *);++int ftran_data_ioready(rn_pollevent_t *);++int accept_new_client(rn_pollevent_t *);+ +-#if HAVE_POLL+-int process_all_clients(const int num_ac);+-int process_all_sendfiles(const int num_ac);+-#else+-int process_all_clients(const fd_set * const active_clients, const int num_ac);+-int process_all_sendfiles(fd_set * const active_clients, const int num_ac);+-#endif+-+-int do_upload(struct ftran *f);+-int do_download(struct ftran *f);++enum ftran_ioresult do_upload(struct ftran *f);++enum ftran_ioresult do_download(struct ftran *f);+ void write_xferlog(struct ftran *f);+ int main(void);+ + RETSIGTYPE handle_alarm(int signum);+ +-void accept_new_client(int * const server_sock);+ void time_out_sockets();+ + void remove_bytes(struct conn * const c, const int i);+ int numeric(struct conn * const c, const int numeric, const char * const format, ...);+++ void init_file_transfer(struct ftran * const f);+ int create_server_socket();+ +@@ -216,4 +254,6 @@+ void list_readmes(struct conn * const c);+ #endif+ ++extern rn_t rns;++extern pid_t own_pid;+ #endif+diff -ur betaftpd-0.0.8pre17/nonroot.c betaftpd/nonroot.c+--- betaftpd-0.0.8pre17/nonroot.c 2000-09-30 15:42:50.000000000 -0700++++ betaftpd/nonroot.c 2003-07-29 09:33:12.000000000 -0700+@@ -67,7 +67,7 @@+ + /* we will add cacheing of both users and rights LATER :-) */+ +-int nr_userinfo(const char * const username, int * const uid,++enum conn_state nr_userinfo(const char * const username, int * const uid,+ char * const homedir, char * const rootdir,+ const char * const password) + {+@@ -75,7 +75,7 @@+ char this_username[256];+ char real_password[256];+ +- if (users_file == NULL) return 0; /* panic, reject all users */++ if (users_file == NULL) return CONN_STATE_INIT; /* panic, reject all users */+ + /* + * ignores gids atm, we may want to change that in the future+@@ -93,14 +93,14 @@+ printf("rdir = %s\nEND\n", rootdir);+ + if (strcmp(real_password, crypt(password, real_password)) == 0) {+- return 3;++ return CONN_STATE_READY;+ } else {+- return 0;++ return CONN_STATE_INIT;+ }+ }+ + fclose(users_file);+- return 0; /* no such user */++ return CONN_STATE_INIT; /* no such user */+ }+ + /*+diff -ur betaftpd-0.0.8pre17/nonroot.h betaftpd/nonroot.h+--- betaftpd-0.0.8pre17/nonroot.h 2000-09-30 15:42:50.000000000 -0700++++ betaftpd/nonroot.h 2003-07-29 09:33:12.000000000 -0700+@@ -18,7 +18,7 @@+ #ifndef _NONROOT_H+ #define _NONROOT_H 1+ +-int nr_userinfo(const char * const username, int * const uid,++enum conn_state nr_userinfo(const char * const username, int * const uid,+ char * const homedir, char * const rootdir,+ const char * const password);+ int nr_check_permission(const uid_t uid, const char * const object,--- /dev/null 2002-09-13 15:08:32.000000000 -0700+++ ptxdist-testing/patches-local/betaftpd-0.0.8pre17/generic/betaftpd-errhand.patch 2003-10-20 14:33:27.000000000 -0700@@ -0,0 +1,1141 @@+--- /dev/null 2002-09-13 15:08:32.000000000 -0700++++ 0711/ChangeLog.errhand 2003-07-11 13:42:58.000000000 -0700+@@ -0,0 +1,6 @@++2003 07 11 11:52++ Dan Kegel (dkegel@ixiacom.com) Rohan Chitradurga (rohan@ixiacom.com)++++ * This corrects the errors concerning numeric by propagating the++ * error values occuring in numeric in order to avoid writing++ * to freed memory.+diff -ur betaftpd-0.0.8pre17/cmds.c betaftpd-new/cmds.c+--- betaftpd-0.0.8pre17/cmds.c Sat Sep 30 15:42:50 2000++++ betaftpd-new/cmds.c Sat Jun 21 15:12:54 2003+@@ -234,8 +234,7 @@+ + #if WANT_NONROOT+ if (nr_check_permission(c->uid, temp, 1, 1, NULL) == -1) {+- numeric(c, 550, "P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -