From: John Tsiombikas Date: Sat, 21 Jan 2023 05:56:50 +0000 (+0200) Subject: foo X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=c65c4562a19c45eda17d7d672afe15f5c8ce5fec;p=oftp foo --- diff --git a/src/ftp.c b/src/ftp.c index 59bc284..961eea3 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -17,10 +19,15 @@ #define fcntlsocket fcntl #endif +static int sendcmd(struct ftp *ftp, const char *fmt, ...); static int handle_control(struct ftp *ftp); static int handle_data(struct ftp *ftp, int s); static void proc_control(struct ftp *ftp, const char *buf); +static void cproc_pwd(struct ftp *ftp, int code, const char *buf, void *cls); +static void cproc_cwd(struct ftp *ftp, int code, const char *buf, void *cls); + + struct ftp *ftp_alloc(void) { struct ftp *ftp; @@ -129,6 +136,23 @@ int ftp_handle(struct ftp *ftp, int s) return -1; } +static int sendcmd(struct ftp *ftp, const char *fmt, ...) +{ + char buf[256]; + va_list ap; + + if(ftp->ctl < 0) { + return -1; + } + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + strcat(buf, "\r\n"); + + return send(ftp->ctl, buf, strlen(buf), 0); +} + static int handle_control(struct ftp *ftp) { int i, sz, rd; @@ -168,8 +192,59 @@ static int handle_data(struct ftp *ftp, int s) return -1; } +static int respcode(const char *resp) +{ + if(!isdigit(resp[0]) || !isdigit(resp[1]) || !isdigit(resp[2])) { + return 0; + } + + if(isspace(resp[3])) { + return atoi(resp); + } + if(resp[3] == '-') { + return -atoi(resp); + } + return 0; +} + static void proc_control(struct ftp *ftp, const char *buf) { + int code; + + while(*buf && isspace(*buf)) buf++; + + if((code = respcode(buf)) == 0) { + warnmsg("ignoring invalid response: %s\n", buf); + return; + } + if(code < 0) { + return; /* ignore continuations for now */ + } + + if(ftp->cproc) { + ftp->cproc(ftp, code, buf, ftp->cproc_cls); + ftp->cproc = 0; + return; + } + + switch(code) { + case 220: + sendcmd(ftp, "user %s", ftp->user ? ftp->user : "anonymous"); + break; + case 331: + sendcmd(ftp, "pass %s", ftp->pass ? ftp->pass : "foobar"); + break; + case 230: + ftp->status = 1; + infomsg("login successful\n"); + ftp_pwd(ftp); + ftp->modified = 1; + break; + case 530: + ftp->status = 0; + errmsg("login failed\n"); + break; + } } int ftp_update(struct ftp *ftp) @@ -177,7 +252,60 @@ int ftp_update(struct ftp *ftp) return -1; } +int ftp_pwd(struct ftp *ftp) +{ + sendcmd(ftp, "pwd"); + ftp->cproc = cproc_pwd; + return 0; +} + int ftp_chdir(struct ftp *ftp, const char *dirname) { - return -1; + // TODO queue + sendcmd(ftp, "cwd %s", dirname); + ftp->cproc = cproc_cwd; + return 0; +} + +static int get_quoted_text(const char *str, char *buf) +{ + int len; + const char *src, *end; + + if(!(src = strchr(str, '"'))) { + return -1; + } + src++; + end = src; + while(*end && *end != '"') end++; + if(!*end) return -1; + + len = end - src; + memcpy(buf, src, len); + buf[len] = 0; + return 0; +} + +static void cproc_pwd(struct ftp *ftp, int code, const char *buf, void *cls) +{ + char *dirname; + + if(code != 257) { + warnmsg("pwd failed\n"); + return; + } + + dirname = alloca(strlen(buf) + 1); + if(get_quoted_text(buf, dirname) == -1) { + warnmsg("pwd: invalid response: %s\n", buf); + return; + } + + free(ftp->curdir_rem); + ftp->curdir_rem = strdup_nf(dirname); + ftp->modified = 1; +} + +static void cproc_cwd(struct ftp *ftp, int code, const char *buf, void *cls) +{ } diff --git a/src/ftp.h b/src/ftp.h index 2d69ce7..c9ebbe2 100644 --- a/src/ftp.h +++ b/src/ftp.h @@ -3,6 +3,22 @@ enum {FTP_DIR, FTP_FILE}; /* ftp_dirent type */ +enum { + FTP_PWD, + FTP_CHDIR, + FTP_MKDIR, + FTP_RMDIR, + FTP_DEL, + FTP_LIST, + FTP_RETR, + FTP_STORE +}; + +struct ftp_op { + int op; + char *arg; +}; + struct ftp_dirent { char *name; int type; @@ -11,19 +27,30 @@ struct ftp_dirent { struct ftp { int ctl, data; /* sockets */ + int status; + char *user, *pass; + + void (*cproc)(struct ftp *ftp, int code, const char *buf, void *cls); + void (*dproc)(struct ftp *ftp, const char *buf, int sz, void *cls); + void *cproc_cls, *dproc_cls; + char crecv[256]; int num_crecv; char drecv[256]; int num_drecv; - char *cwd; + char *curdir_rem, *curdir_loc; struct ftp_dirent *dent; int num_dent; + + int modified; }; struct ftp *ftp_alloc(void); void ftp_free(struct ftp *ftp); +void ftp_auth(const char *user, const char *pass); + int ftp_connect(struct ftp *ftp, const char *host, int port); void ftp_close(struct ftp *ftp); @@ -33,6 +60,7 @@ int ftp_pending(struct ftp *ftp); int ftp_handle(struct ftp *ftp, int s); int ftp_update(struct ftp *ftp); +int ftp_pwd(struct ftp *ftp); int ftp_chdir(struct ftp *ftp, const char *dirname); diff --git a/src/main.c b/src/main.c index 611508d..c2820ba 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -6,6 +8,7 @@ #include "tui.h" #include "ftp.h" +void updateui(void); int proc_input(void); int keypress(int key); @@ -79,6 +82,11 @@ int main(void) ftp_handle(ftp, ftpsock[i]); } } + + if(ftp->modified) { + updateui(); + ftp->modified = 0; + } } tg_cleanup(); @@ -88,6 +96,20 @@ int main(void) return 0; } +void updateui(void) +{ + unsigned int upd = 0; + + if(ftp->curdir_rem && strcmp(tui_get_title(uilist), ftp->curdir_rem) != 0) { + tui_set_title(uilist, ftp->curdir_rem); + upd |= 1; + } + + if(upd & 1) { + tui_draw(uilist); + } +} + int proc_input(void) { union event ev; diff --git a/src/tui.c b/src/tui.c index 106b28f..2a4d431 100644 --- a/src/tui.c +++ b/src/tui.c @@ -6,6 +6,7 @@ #include "tuipriv.h" #include "tgfx.h" #include "darray.h" +#include "util.h" int tui_init(void) @@ -101,6 +102,18 @@ void tui_set_callback(struct tui_widget *w, int type, tui_callback func, void *c w->cbcls[type] = cls; } +int tui_set_title(struct tui_widget *w, const char *s) +{ + free(w->title); + w->title = strdup_nf(s); + return 0; +} + +const char *tui_get_title(struct tui_widget *w) +{ + return w->title; +} + struct tui_widget *tui_window(const char *title, int x, int y, int width, int height) { struct tui_widget *w; diff --git a/src/tui.h b/src/tui.h index 5e3012e..78ec8bd 100644 --- a/src/tui.h +++ b/src/tui.h @@ -31,6 +31,9 @@ void tui_draw(struct tui_widget *w); void tui_set_callback(struct tui_widget *w, int type, tui_callback func, void *cls); +int tui_set_title(struct tui_widget *w, const char *s); +const char *tui_get_title(struct tui_widget *w); + struct tui_widget *tui_window(const char *title, int x, int y, int w, int h); struct tui_widget *tui_button(const char *title, int x, int y, tui_callback cbfunc, void *cbdata); struct tui_widget *tui_list(const char *title, int x, int y, int w, int h, tui_callback cbfunc, void *cbdata); diff --git a/src/unix/tgfx.c b/src/unix/tgfx.c index b7f9f82..c807aed 100644 --- a/src/unix/tgfx.c +++ b/src/unix/tgfx.c @@ -10,7 +10,7 @@ static int curses_color(int col); void tg_init(void) { initscr(); - raw(); + cbreak(); keypad(stdscr, TRUE); noecho(); start_color();