X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmain.c;h=0334910f19bbf51d462cb699b8f54fa20f988be0;hb=7690b174f121007c511f40d69c70d72e6953b5a9;hp=89ab3e205894d23576cd708895c22d8e58207d02;hpb=cd17f98f32857e5cb547984387239bd86749044e;p=oftp diff --git a/src/main.c b/src/main.c index 89ab3e2..0334910 100644 --- a/src/main.c +++ b/src/main.c @@ -3,24 +3,46 @@ #include #include #include +#ifdef __DOS__ +#include +#else +#include +#include +#endif +#include #include #include "tgfx.h" #include "input.h" #include "util.h" #include "tui.h" #include "ftp.h" +#include "darray.h" + +#ifdef __DOS__ +#define select select_s +#endif void updateui(void); +int update_localdir(void); int proc_input(void); int keypress(int key); +static void fixname(char *dest, const char *src); +static void xfer_done(struct ftp *ftp, struct ftp_transfer *xfer); int parse_args(int argc, char **argv); static struct ftp *ftp; -static struct tui_widget *uilist; +static struct tui_widget *uilist[2]; + +static int focus; static char *host = "localhost"; static int port = 21; +static char curdir[PATH_MAX + 1]; +static struct ftp_dirent *localdir; +static int local_modified; + + int main(int argc, char **argv) { int i, numsock, maxfd; @@ -32,6 +54,10 @@ int main(int argc, char **argv) return 1; } + localdir = darr_alloc(0, sizeof *localdir); + getcwd(curdir, sizeof curdir); + update_localdir(); + if(!(ftp = ftp_alloc())) { return 1; } @@ -47,15 +73,15 @@ int main(int argc, char **argv) tg_bgchar(' '); tg_clear(); - uilist = tui_list("Remote", 0, 0, 40, 23, 0, 0); - tui_add_list_item(uilist, "first item"); - tui_add_list_item(uilist, "second item"); - tui_add_list_item(uilist, "another item"); - tui_add_list_item(uilist, "foo"); + uilist[0] = tui_list("Remote", 0, 0, 40, 23, 0, 0); + uilist[1] = tui_list("Local", 40, 0, 40, 23, 0, 0); + focus = 0; + tui_focus(uilist[focus], 1); tg_setcursor(0, 23); - tui_draw(uilist); + tui_draw(uilist[0]); + tui_draw(uilist[1]); for(;;) { FD_ZERO(&rdset); @@ -85,6 +111,10 @@ int main(int argc, char **argv) break; } } +#else + if(proc_input() == -1) { + break; + } #endif for(i=0; imodified) { - updateui(); - ftp->modified = 0; - } + updateui(); } tg_cleanup(); @@ -108,18 +135,103 @@ int main(int argc, char **argv) void updateui(void) { + int i, num; + struct ftp_dirent *ent; unsigned int upd = 0; + char buf[128]; + const char *remdir; + + remdir = ftp_curdir(ftp); + if(remdir && strcmp(tui_get_title(uilist[0]), remdir) != 0) { + tui_set_title(uilist[0], remdir); + upd |= 1; + } + + if(ftp->modified & FTP_MOD_DIR) { + tui_clear_list(uilist[0]); + + num = ftp_num_dirent(ftp); + for(i=0; itype == FTP_DIR) { + sprintf(buf, "%s/", ent->name); + tui_add_list_item(uilist[0], buf); + } else { + tui_add_list_item(uilist[0], ent->name); + } + } + + tui_list_select(uilist[0], 0); - if(ftp->curdir_rem && strcmp(tui_get_title(uilist), ftp->curdir_rem) != 0) { - tui_set_title(uilist, ftp->curdir_rem); + ftp->modified &= ~FTP_MOD_DIR; upd |= 1; } - if(upd & 1) { - tui_draw(uilist); + if(local_modified || strcmp(tui_get_title(uilist[1]), curdir) != 0) { + tui_clear_list(uilist[1]); + num = darr_size(localdir); + for(i=0; itype == FTP_DIR) { + sprintf(buf, "%s/", ent->name); + tui_add_list_item(uilist[1], buf); + } else { + tui_add_list_item(uilist[1], ent->name); + } + } + tui_list_select(uilist[1], 0); + tui_set_title(uilist[1], curdir); + + local_modified = 0; + upd |= 2; + } + + if(tui_isdirty(uilist[0]) || upd & 1) { + tui_draw(uilist[0]); + } + if(tui_isdirty(uilist[1]) || upd & 2) { + tui_draw(uilist[1]); } } +int update_localdir(void) +{ + DIR *dir; + struct dirent *dent; + struct stat st; + struct ftp_dirent ent; + + if(!(dir = opendir(curdir))) { + errmsg("failed to open directory: %s\n", curdir); + return -1; + } + + darr_clear(localdir); + while((dent = readdir(dir))) { + ent.name = strdup_nf(dent->d_name); + if(strcmp(dent->d_name, ".") == 0) continue; + + if(stat(dent->d_name, &st) == 0) { + if(S_ISDIR(st.st_mode)) { + ent.type = FTP_DIR; + } else { + ent.type = FTP_FILE; + } + ent.size = st.st_size; + } else { + ent.type = FTP_FILE; + ent.size = 0; + } + + darr_push(localdir, &ent); + } + closedir(dir); + + qsort(localdir, darr_size(localdir), sizeof *localdir, ftp_direntcmp); + local_modified = 1; + return 0; +} + int proc_input(void) { union event ev; @@ -141,17 +253,136 @@ int proc_input(void) int keypress(int key) { + int sel; + switch(key) { case 27: case 'q': + case KB_F10: return -1; + case '\t': + tui_focus(uilist[focus], 0); + focus ^= 1; + tui_focus(uilist[focus], 1); + break; + + case KB_UP: + tui_list_sel_prev(uilist[focus]); + break; + case KB_DOWN: + tui_list_sel_next(uilist[focus]); + break; + case KB_LEFT: + tui_list_sel_start(uilist[focus]); + break; + case KB_RIGHT: + tui_list_sel_end(uilist[focus]); + break; + + case '\n': + sel = tui_get_list_sel(uilist[focus]); + if(focus == 0) { + struct ftp_dirent *ent = ftp_dirent(ftp, sel); + if(ent->type == FTP_DIR) { + ftp_queue(ftp, FTP_CHDIR, ent->name); + } else { + /* TODO */ + } + } else { + if(localdir[sel].type == FTP_DIR) { + if(chdir(localdir[sel].name) == -1) { + errmsg("failed to change directory: %s\n", localdir[sel].name); + } else { + getcwd(curdir, sizeof curdir); + update_localdir(); + } + } else { + /* TODO */ + } + } + break; + + case '\b': + if(focus == 0) { + ftp_queue(ftp, FTP_CDUP, 0); + } else { + if(chdir("..") == 0) { + getcwd(curdir, sizeof curdir); + update_localdir(); + } + } + break; + + case KB_F5: + sel = tui_get_list_sel(uilist[focus]); + if(focus == 0) { + struct ftp_transfer *xfer; + struct ftp_dirent *ent = ftp_dirent(ftp, sel); + char *lname = alloca(strlen(ent->name) + 1); + + fixname(lname, ent->name); + + xfer = malloc_nf(sizeof *xfer); + if(!(xfer->fp = fopen(lname, "wb"))) { + errmsg("failed to open %s: %s\n", lname, strerror(errno)); + free(xfer); + break; + } + + xfer->op = FTP_RETR; + xfer->rname = strdup_nf(ent->name); + xfer->total = ent->size; + xfer->done = xfer_done; + + ftp_queue_transfer(ftp, xfer); + local_modified = 1; + } else { + /* TODO */ + } + break; + default: break; } return 0; } +static void fixname(char *dest, const char *src) +{ + strcpy(dest, src); + +#ifdef __DOS__ + { + char *suffix; + if((suffix = strrchr(dest, '.'))) { + *suffix++ = 0; + if(strlen(suffix) > 3) { + suffix[3] = 0; + } + } + if(strlen(dest) > 8) { + dest[8] = 0; + } + + if(suffix) { + strcat(dest, "."); + strcat(dest, suffix); + } + } +#endif +} + +static void xfer_done(struct ftp *ftp, struct ftp_transfer *xfer) +{ + if(xfer->fp) { + fclose(xfer->fp); + } + free(xfer->rname); + free(xfer); + update_localdir(); +} + static const char *usage = "Usage: %s [options] [hostname] [port]\n" "Options:\n" " -h: print usage information and exit\n";