From cd17f98f32857e5cb547984387239bd86749044e Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 21 Jan 2023 16:37:44 +0200 Subject: [PATCH] retrieve directory listing in active mode --- .gitignore | 1 + src/ftp.c | 17 ++++++++++++---- src/main.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/util.c | 32 +++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 1ec8f24..30c0671 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ oftp *.obj *.lnk *.map +*.log diff --git a/src/ftp.c b/src/ftp.c index 6a29a77..04a8ae4 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -268,9 +268,11 @@ static int ftp_active(struct ftp *ftp) return -1; } + len = sizeof sa; + getsockname(ftp->ctl, (struct sockaddr*)&sa, &len); + sa.sin_family = AF_INET; sa.sin_port = 0; - sa.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(ftp->lis, (struct sockaddr*)&sa, sizeof sa) == -1) { errmsg("ftp_active: failed to bind listening socket\n"); @@ -281,7 +283,7 @@ static int ftp_active(struct ftp *ftp) listen(ftp->lis, 1); len = sizeof sa; - if(getsockname(ftp->ctl, (struct sockaddr*)&sa, &len) == -1) { + if(getsockname(ftp->lis, (struct sockaddr*)&sa, &len) == -1) { errmsg("ftp_active: failed to retrieve listening socket address\n"); closesocket(ftp->lis); ftp->lis = -1; @@ -290,6 +292,7 @@ static int ftp_active(struct ftp *ftp) addr = ntohl(sa.sin_addr.s_addr); port = ntohs(sa.sin_port); + infomsg("listening on %s port %d\n", inet_ntoa(sa.sin_addr), port); sendcmd(ftp, "PORT %d,%d,%d,%d,%d,%d", addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff, port >> 8, port & 0xff); @@ -330,8 +333,8 @@ static int sendcmd(struct ftp *ftp, const char *fmt, ...) va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); + infomsg("send: %s\n", buf); strcat(buf, "\r\n"); - return send(ftp->ctl, buf, strlen(buf), 0); } @@ -418,8 +421,14 @@ static int respcode(const char *resp) static void proc_control(struct ftp *ftp, const char *buf) { int code; + char *end; while(*buf && isspace(*buf)) buf++; + if((end = strchr(buf, '\r'))) { + *end = 0; + } + + infomsg("recv: %s\n", buf); if((code = respcode(buf)) == 0) { warnmsg("ignoring invalid response: %s\n", buf); @@ -620,7 +629,7 @@ static void dproc_list(struct ftp *ftp, const char *buf, int sz, void *cls) /* EOF condition, we got the whole list, update directory entries */ /* TODO */ rbuf->buf[rbuf->size] = 0; - fprintf(stderr, "%s\n", rbuf->buf); + infomsg("%s\n", rbuf->buf); free(rbuf->buf); free(rbuf); diff --git a/src/main.c b/src/main.c index c2820ba..89ab3e2 100644 --- a/src/main.c +++ b/src/main.c @@ -2,30 +2,40 @@ #include #include #include +#include #include #include "tgfx.h" #include "input.h" +#include "util.h" #include "tui.h" #include "ftp.h" void updateui(void); int proc_input(void); int keypress(int key); +int parse_args(int argc, char **argv); -struct ftp *ftp; -struct tui_widget *uilist; +static struct ftp *ftp; +static struct tui_widget *uilist; -int main(void) +static char *host = "localhost"; +static int port = 21; + +int main(int argc, char **argv) { int i, numsock, maxfd; int ftpsock[16]; fd_set rdset; struct timeval tv; + if(parse_args(argc, argv) == -1) { + return 1; + } + if(!(ftp = ftp_alloc())) { return 1; } - if(ftp_connect(ftp, "192.168.0.4", 21) == -1) { + if(ftp_connect(ftp, host, port) == -1) { ftp_free(ftp); return 1; } @@ -141,3 +151,51 @@ int keypress(int key) } return 0; } + +static const char *usage = "Usage: %s [options] [hostname] [port]\n" + "Options:\n" + " -h: print usage information and exit\n"; + +int parse_args(int argc, char **argv) +{ + int i, argidx = 0; + + for(i=1; i