X-Git-Url: http://git.thejh.net/?p=cwebfiles.git;a=blobdiff_plain;f=listdir.c;h=6d5843164c0e9c22507519f77ff126e0fa46eeab;hp=bfbd47cd88cb2ea4684ffdd7deb74dfb6b428a8f;hb=bb0bbf3a88932e5a32ac3055a16109fa613e575a;hpb=44ce233ab82694ae1c85d0969ec3dd89d04c4992 diff --git a/listdir.c b/listdir.c index bfbd47c..6d58431 100644 --- a/listdir.c +++ b/listdir.c @@ -10,9 +10,20 @@ #include #include #include +#include +#include + +// 64k RAM aren't really that much, and it should speed things up significantly +#define OBULEN (64*1024) +static char outbuf[OBULEN] = "Status: 200 here's your listing" + "\nX-Frame-Options: DENY" + "\nContent-Type: text/plain;charset=utf8" + "\n\n"; int main() { - FASTOUTPUT + //FASTOUTPUT + prctl(PR_SET_DUMPABLE, 1); // FIXME XXX potential security problem; disable later! + if (chdir("/")) senderr("chdir / failed", MYFAULT); char *encpath = getenv("QUERY_STRING"); login_and_setup(); // will clear the environment @@ -39,22 +50,35 @@ int main() { senderr(errstr, NOTMYFAULT); } + // ok, let's do fast output! // The directory was opened successfully - send our success header. - puts("Status: 200 here's your listing"); - puts("X-Frame-Options: DENY"); - puts("Content-Type: text/plain;charset=utf8"); - puts(""); + char *p = outbuf+strlen(outbuf); // send one line per file + #define LINE_LENGTH_LIMIT (NAME_MAX*2+1+FMT_ULONG+1+FMT_ULONG+1) struct dirent *dent; - char encfilename[NAME_MAX*2+1]; while ((dent = readdir(dir)) != NULL) { - size_t name_len = strlen(dent->d_name); - hex(encfilename, (unsigned char *)dent->d_name, name_len); - encfilename[name_len*2] = 0; + if (p+LINE_LENGTH_LIMIT >= outbuf+OBULEN) { + // Whoah, that's a big directory! + // Flush the pipe. + write(1, outbuf, p-outbuf); + // And reuse the buffer. + p = outbuf; + } struct stat st; // if we can't really see the file anyway, skip it if (lstat(dent->d_name, &st)) continue; - printf("%s %lu %u\n", encfilename, (unsigned long)st.st_size, (unsigned int)st.st_mode); + //printf("%s %lu %u\n", encfilename, (unsigned long)st.st_size, (unsigned int)st.st_mode); + size_t name_len = strlen(dent->d_name); + hex(p, (unsigned char *)dent->d_name, name_len); + p += name_len*2; + *(p++) = ' '; + p += fmt_ulong(p, (unsigned long)st.st_size); + *(p++) = ' '; + p += fmt_ulong(p, (unsigned int)st.st_mode); + *(p++) = '\n'; } + + // final pipe flush + write(1, outbuf, p-outbuf); }