retrieve directory listing in active mode
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 21 Jan 2023 14:37:44 +0000 (16:37 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 21 Jan 2023 14:37:44 +0000 (16:37 +0200)
.gitignore
src/ftp.c
src/main.c
src/util.c

index 1ec8f24..30c0671 100644 (file)
@@ -6,3 +6,4 @@ oftp
 *.obj
 *.lnk
 *.map
+*.log
index 6a29a77..04a8ae4 100644 (file)
--- 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);
index c2820ba..89ab3e2 100644 (file)
@@ -2,30 +2,40 @@
 #include <string.h>
 #include <signal.h>
 #include <errno.h>
+#include <assert.h>
 #include <sys/select.h>
 #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<argc; i++) {
+               if(argv[i][0] == '-') {
+                       if(argv[i][2] != 0) {
+                               goto inval;
+                       }
+                       switch(argv[i][1]) {
+                       case 'h':
+                               printf(usage, argv[0]);
+                               exit(0);
+
+                       default:
+                               goto inval;
+                       }
+
+               } else {
+                       switch(argidx++) {
+                       case 0:
+                               host = argv[i];
+                               break;
+
+                       case 1:
+                               if((port = atoi(argv[i])) <= 0) {
+                                       fprintf(stderr, "invalid port number: %s\n", argv[i]);
+                                       return -1;
+                               }
+                               break;
+
+                       default:
+                               goto inval;
+                       }
+               }
+       }
+
+       return 0;
+inval:
+       fprintf(stderr, "invalid argument: %s\n", argv[i]);
+       fprintf(stderr, usage, argv[0]);
+       return -1;
+}
index 241cade..b4b96b7 100644 (file)
@@ -54,6 +54,26 @@ int match_prefix(const char *str, const char *prefix)
        return *prefix ? 0 : 1;
 }
 
+static FILE *logfile;
+
+static void closelog(void)
+{
+       fclose(logfile);
+}
+
+static void logmsg(const char *tag, const char *fmt, va_list ap)
+{
+       if(!logfile) {
+               if(!(logfile = fopen("oftp.log", "w"))) {
+                       return;
+               }
+               setvbuf(logfile, 0, _IOLBF, 0);
+               atexit(closelog);
+       }
+       fprintf(logfile, "%s: ", tag);
+       vfprintf(logfile, fmt, ap);
+}
+
 void errmsg(const char *fmt, ...)
 {
        va_list ap;
@@ -61,6 +81,10 @@ void errmsg(const char *fmt, ...)
        va_start(ap, fmt);
        tui_vmsgbox(TUI_ERROR, "error", fmt, ap);
        va_end(ap);
+
+       va_start(ap, fmt);
+       logmsg("error", fmt, ap);
+       va_end(ap);
 }
 
 void warnmsg(const char *fmt, ...)
@@ -70,6 +94,10 @@ void warnmsg(const char *fmt, ...)
        va_start(ap, fmt);
        tui_status(TUI_WARN, fmt, ap);
        va_end(ap);
+
+       va_start(ap, fmt);
+       logmsg("warning", fmt, ap);
+       va_end(ap);
 }
 
 void infomsg(const char *fmt, ...)
@@ -79,4 +107,8 @@ void infomsg(const char *fmt, ...)
        va_start(ap, fmt);
        tui_status(TUI_INFO, fmt, ap);
        va_end(ap);
+
+       va_start(ap, fmt);
+       logmsg("info", fmt, ap);
+       va_end(ap);
 }