diff -Nu publicfile-0.52.old/fetch.c publicfile-0.52/fetch.c --- publicfile-0.52.old/fetch.c 1999-11-09 01:23:46.000000000 -0600 +++ publicfile-0.52/fetch.c 2009-11-23 14:26:23.758117127 -0600 @@ -8,6 +8,7 @@ #include "direntry.h" #include "fmt.h" #include "fetch.h" +#include "strsort.h" int fetch_ascii = 1; unsigned long fetch_rest = 0; @@ -88,6 +89,9 @@ direntry *d; int r; int i; + struct strsort_tree sorttree; + struct strsort_iter sortiter; + const char *str; substdio_fdbuf(&ss,datawrite,fddata,ssbuf,sizeof ssbuf); @@ -110,12 +114,23 @@ return; } + strsort_init(&sorttree); + dir = opendir("."); if (!dir) _exit(23); /* XXX: could be out of memory */ while (d = readdir(dir)) /* XXX: temporary errors */ - list(d->d_name,how == FETCH_LIST); + if (strsort_add(&sorttree, d->d_name) == -1) + _exit(23); closedir(dir); + sortiter = strsort_start(&sorttree); + while ((str = strsort_get(&sortiter))) { + list((char *)str, how == FETCH_LIST); + strsort_incr(&sortiter); + } + + strsort_destroy(&sorttree); + break; default: diff -Nu publicfile-0.52.old/Makefile publicfile-0.52/Makefile --- publicfile-0.52.old/Makefile 1999-11-09 01:23:46.000000000 -0600 +++ publicfile-0.52/Makefile 2009-11-23 12:20:36.105533296 -0600 @@ -181,11 +181,13 @@ fmt_xlong.o scan_ulong.o ftpd: \ +strsort.o \ load ftpd.o main.o prot.o pathdecode.o file.o fetch.o ip.o \ timeoutread.o timeoutwrite.o timeoutconn.o timeoutaccept.o ndelay.a \ env.a sig.a substdio.a stralloc.a alloc.a error.a open.a case.a str.a \ fs.a socket.lib ./load ftpd main.o prot.o pathdecode.o file.o fetch.o ip.o \ + strsort.o \ timeoutread.o timeoutwrite.o timeoutconn.o timeoutaccept.o \ ndelay.a env.a sig.a substdio.a stralloc.a alloc.a error.a \ open.a case.a str.a fs.a `cat socket.lib` @@ -506,6 +508,10 @@ compile strerr_sys.c error.h strerr.h ./compile strerr_sys.c +strsort.o: \ +compile strsort.c strsort.h + ./compile strsort.c + subfderr.o: \ compile subfderr.c readwrite.h substdio.h subfd.h substdio.h ./compile subfderr.c diff -Nu publicfile-0.52.old/strsort.c publicfile-0.52/strsort.c --- publicfile-0.52.old/strsort.c 1969-12-31 18:00:00.000000000 -0600 +++ publicfile-0.52/strsort.c 2009-11-23 14:21:53.148144784 -0600 @@ -0,0 +1,132 @@ +#include +#include +#include + +#include "strsort.h" + +void +strsort_init(struct strsort_tree *t) +{ + t->l = t->r = t->p = 0; + t->data = 0; +} + +/* destroys the tree, freeing the original node as well */ +static void +destroy_and_free(struct strsort_tree *t) +{ + struct strsort_tree *next; + + /* iterate through right nodes, making half as many recursive + * function calls */ + while (t) { + /* destroy left tree recursively and free string */ + destroy_and_free(t->l); + if (t->data) free(t->data); + + /* free this tree and continue to the next */ + next = t->r; + free(t); + t = next; + } +} + +void +strsort_destroy(struct strsort_tree *t) +{ + destroy_and_free(t->l); + destroy_and_free(t->r); + if (t->data) free(t->data); + + strsort_init(t); +} + +int +strsort_add(struct strsort_tree *t, const char *s) +{ + struct strsort_tree *node; + int diff; + size_t len; + + node = malloc(sizeof(struct strsort_tree)); + if (!node) + return -1; + strsort_init(node); + + /* copy the string */ + len = strlen(s); + node->data = malloc(len + 1); + if (!node->data) { + free(node); + return -1; + } + memcpy(node->data, s, len + 1); + + /* find correct spot */ + while (t) { + if (!t->data) { + /* tree is empty */ + t->data = node->data; + free(node); + return 0; + } + + diff = strcmp(s, t->data); + if (diff >= 0) { + if (!t->r) { + t->r = node; + node->p = t; + return 0; + } + t = t->r; + } else { + if (!t->l) { + t->l = node; + node->p = t; + return 0; + } + t = t->l; + } + } + + return -1; +} + +struct strsort_iter +strsort_start(const struct strsort_tree *t) +{ + struct strsort_iter iter; + if (t->data) + while (t->l) t = t->l; + else + /* empty tree */ + t = 0; + iter.cur = (struct strsort_tree *)t; + return iter; +} + +void +strsort_incr(struct strsort_iter *i) +{ + struct strsort_tree *x = i->cur; + struct strsort_tree *y; + if (!x); + else if (x->r) { + x = x->r; + while (x->l) x = x->l; + i->cur = x; + } else { + y = x->p; + while (y && y->r == x) { + x = y; + y = y->p; + } + i->cur = y; + } +} + +const char * +strsort_get(struct strsort_iter *i) +{ + return i->cur ? i->cur->data : 0; +} diff -Nu publicfile-0.52.old/strsort.h publicfile-0.52/strsort.h --- publicfile-0.52.old/strsort.h 1969-12-31 18:00:00.000000000 -0600 +++ publicfile-0.52/strsort.h 2009-11-23 12:58:25.235305208 -0600 @@ -0,0 +1,31 @@ +#ifndef STRSORT_H +#define STRSORT_H + +struct strsort_tree +{ + /* private members */ + struct strsort_tree *l; + struct strsort_tree *r; + struct strsort_tree *p; + char *data; +}; + +struct strsort_iter +{ + /* private member */ + struct strsort_tree *cur; +}; + +void strsort_init(struct strsort_tree *); +void strsort_destroy(struct strsort_tree *); + +/* returns -1 if out of memory, 0 otherwise */ +int strsort_add(struct strsort_tree *, const char *); + +struct strsort_iter + strsort_start(const struct strsort_tree *); +/* returns the next string, else NULL if no more strings */ +void strsort_incr(struct strsort_iter *); +const char *strsort_get(struct strsort_iter *); + +#endif