From ddf0e24c7f600826b88571391a8a294499a14865 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 23 Jan 2023 17:29:50 +0200 Subject: [PATCH] navigation --- src/ftp.c | 101 +++++++++++++++++++++++++++++++++++++----------------- src/ftp.h | 16 ++++++--- src/main.c | 43 +++++++++++------------ src/unix/input.c | 4 +++ 4 files changed, 108 insertions(+), 56 deletions(-) diff --git a/src/ftp.c b/src/ftp.c index ec6dbab..7cdf8ff 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -22,6 +22,8 @@ #define TIMEOUT 15 +static void free_dir(struct ftp_dirent *dir); + static int newconn(struct ftp *ftp); static int sendcmd(struct ftp *ftp, const char *fmt, ...); static int handle_control(struct ftp *ftp); @@ -44,6 +46,9 @@ struct ftp *ftp_alloc(void) return 0; } ftp->ctl = ftp->data = ftp->lis = -1; + + ftp->dirent[0] = darr_alloc(0, sizeof *ftp->dirent[0]); + ftp->dirent[1] = darr_alloc(0, sizeof *ftp->dirent[1]); return ftp; } @@ -54,6 +59,18 @@ void ftp_free(struct ftp *ftp) if(ftp->ctl >= 0) { ftp_close(ftp); } + + free_dir(ftp->dirent[0]); + free_dir(ftp->dirent[1]); +} + +static void free_dir(struct ftp_dirent *dir) +{ + int i; + for(i=0; icproc = cproc_cwd; return 0; } @@ -619,15 +644,22 @@ static int cproc_pwd(struct ftp *ftp, int code, const char *buf, void *cls) return -1; } - free(ftp->curdir_rem); - ftp->curdir_rem = strdup_nf(dirname); - ftp->modified = 1; + free(ftp->curdir[FTP_REMOTE]); + ftp->curdir[FTP_REMOTE] = strdup_nf(dirname); + ftp->modified = FTP_MOD_REMDIR; return 0; } static int cproc_cwd(struct ftp *ftp, int code, const char *buf, void *cls) { - return -1; + if(code != 250) { + warnmsg("cwd failed\n"); + return -1; + } + + ftp_queue(ftp, FTP_PWD, 0); + ftp_queue(ftp, FTP_LIST, 0); + return 0; } static int cproc_list(struct ftp *ftp, int code, const char *buf, void *cls) @@ -643,19 +675,6 @@ static int cproc_list(struct ftp *ftp, int code, const char *buf, void *cls) return 0; } -static void free_dirlist(struct ftp_dirent *list) -{ - struct ftp_dirent *tmp; - - while(list) { - tmp = list; - list = list->next; - - free(tmp->name); - free(tmp); - } -} - #define SKIP_FIELD(p) \ do { \ while(*(p) && *(p) != '\n' && !isspace(*(p))) (p)++; \ @@ -701,30 +720,32 @@ static int parse_dirent(struct ftp_dirent *ent, const char *line) return 0; } +static int direntcmp(const void *a, const void *b) +{ + const struct ftp_dirent *da = a, *db = b; + + if(da->type == db->type) { + return strcmp(da->name, db->name); + } + return da->type == FTP_DIR ? -1 : 1; +} + static void dproc_list(struct ftp *ftp, const char *buf, int sz, void *cls) { + int num; struct recvbuf *rbuf = cls; if(sz == 0) { /* EOF condition, we got the whole list, update directory entries */ char *ptr = rbuf->buf; char *end = rbuf->buf + rbuf->size; - struct ftp_dirent *tail = 0; - struct ftp_dirent *ent; + struct ftp_dirent ent; - free_dirlist(ftp->dent_rem); - ftp->dent_rem = 0; + darr_clear(ftp->dirent[FTP_REMOTE]); while(ptr < end) { - ent = malloc_nf(sizeof *ent); - if(parse_dirent(ent, ptr) != -1) { - ent->next = 0; - if(!tail) { - ftp->dent_rem = tail = ent; - } else { - tail->next = ent; - tail = ent; - } + if(parse_dirent(&ent, ptr) != -1) { + darr_push(ftp->dirent[FTP_REMOTE], &ent); } while(ptr < end && *ptr != '\n' && *ptr != '\r') ptr++; while(ptr < end && (*ptr == '\r' || *ptr == '\n')) ptr++; @@ -734,6 +755,9 @@ static void dproc_list(struct ftp *ftp, const char *buf, int sz, void *cls) free(rbuf->buf); free(rbuf); ftp->dproc = 0; + + num = darr_size(ftp->dirent[FTP_REMOTE]); + qsort(ftp->dirent[FTP_REMOTE], num, sizeof *ftp->dirent[FTP_REMOTE], direntcmp); return; } @@ -752,3 +776,18 @@ static void dproc_list(struct ftp *ftp, const char *buf, int sz, void *cls) memcpy(rbuf->buf + rbuf->size, buf, sz); rbuf->size += sz; } + +const char *ftp_curdir(struct ftp *ftp, int whichdir) +{ + return ftp->curdir[whichdir]; +} + +int ftp_num_dirent(struct ftp *ftp, int whichdir) +{ + return darr_size(ftp->dirent[whichdir]); +} + +struct ftp_dirent *ftp_dirent(struct ftp *ftp, int whichdir, int idx) +{ + return ftp->dirent[whichdir] + idx; +} diff --git a/src/ftp.h b/src/ftp.h index 13cc415..86aadab 100644 --- a/src/ftp.h +++ b/src/ftp.h @@ -6,6 +6,7 @@ enum {FTP_DIR, FTP_FILE}; /* ftp_dirent type */ enum { FTP_PWD, FTP_CHDIR, + FTP_CDUP, FTP_MKDIR, FTP_RMDIR, FTP_DEL, @@ -21,6 +22,11 @@ enum { }; enum { + FTP_REMOTE, + FTP_LOCAL +}; + +enum { FTP_MOD_REMDIR = 0x100, FTP_MOD_LOCDIR = 0x200 }; @@ -36,8 +42,6 @@ struct ftp_dirent { char *name; int type; long size; - - struct ftp_dirent *next; }; struct ftp { @@ -57,8 +61,8 @@ struct ftp { int num_crecv; char drecv[256]; - char *curdir_rem, *curdir_loc; - struct ftp_dirent *dent_rem, *dent_loc; + char *curdir[2]; + struct ftp_dirent *dirent[2]; /* dynamic array */ int last_resp; int modified; @@ -89,5 +93,9 @@ int ftp_list(struct ftp *ftp); int ftp_retrieve(struct ftp *ftp, const char *fname); int ftp_store(struct ftp *ftp, const char *fname); +const char *ftp_curdir(struct ftp *ftp, int whichdir); +int ftp_num_dirent(struct ftp *ftp, int whichdir); +struct ftp_dirent *ftp_dirent(struct ftp *ftp, int whichdir, int idx); + #endif /* FTP_H_ */ diff --git a/src/main.c b/src/main.c index fa7dbb1..358fde0 100644 --- a/src/main.c +++ b/src/main.c @@ -99,47 +99,34 @@ int main(int argc, char **argv) return 0; } -static int cmpnames(const void *a, const void *b) -{ - const char *sa = *(const char**)a; - const char *sb = *(const char**)b; - int isdir_a, isdir_b; - - isdir_a = sa[strlen(sa) - 1] == '/'; - isdir_b = sb[strlen(sb) - 1] == '/'; - - if(isdir_a == isdir_b) { - return strcmp(sa, sb); - } - return isdir_a ? -1 : 1; -} - void updateui(void) { + int i, num; struct ftp_dirent *ent; unsigned int upd = 0; char buf[128]; + const char *remdir; - if(ftp->curdir_rem && strcmp(tui_get_title(uilist), ftp->curdir_rem) != 0) { - tui_set_title(uilist, ftp->curdir_rem); + remdir = ftp_curdir(ftp, FTP_REMOTE); + if(remdir && strcmp(tui_get_title(uilist), remdir) != 0) { + tui_set_title(uilist, remdir); upd |= 1; } if(ftp->modified & FTP_MOD_REMDIR) { tui_clear_list(uilist); - ent = ftp->dent_rem; - while(ent) { + num = ftp_num_dirent(ftp, FTP_REMOTE); + for(i=0; itype == FTP_DIR) { sprintf(buf, "%s/", ent->name); tui_add_list_item(uilist, buf); } else { tui_add_list_item(uilist, ent->name); } - ent = ent->next; } - tui_sort_list(uilist, cmpnames); tui_list_select(uilist, 0); ftp->modified &= ~FTP_MOD_REMDIR; @@ -172,6 +159,9 @@ int proc_input(void) int keypress(int key) { + int sel; + const char *name; + switch(key) { case 27: case 'q': @@ -190,6 +180,17 @@ int keypress(int key) tui_list_sel_end(uilist); break; + case '\n': + sel = tui_get_list_sel(uilist); + name = ftp_dirent(ftp, FTP_REMOTE, sel)->name; + ftp_queue(ftp, FTP_CHDIR, name); + break; + + case '\b': + infomsg("CDUP\n"); + ftp_queue(ftp, FTP_CDUP, 0); + break; + default: break; } diff --git a/src/unix/input.c b/src/unix/input.c index 92c1dcc..6fba0fc 100644 --- a/src/unix/input.c +++ b/src/unix/input.c @@ -35,6 +35,10 @@ static int convkey(int key) return KB_PGUP; case KEY_NPAGE: return KB_PGDN; + case KEY_ENTER: + return '\n'; + case KEY_BACKSPACE: + return '\b'; default: break; } -- 1.7.10.4