X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fftp.c;fp=src%2Fftp.c;h=7cdf8ff703e5e93a803d3f378b8b8b57cf1e6edb;hb=ddf0e24c7f600826b88571391a8a294499a14865;hp=ec6dbab649d613891dbc8c92782547be983f69f4;hpb=85b4b3f42fd47fbc9baff6f0aa988037f1b73bc1;p=oftp 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; +}