* remember the total size a downloadable file has
authorWilfried Göesgens <willi@citadel.org>
Sat, 6 Feb 2010 10:12:48 +0000 (10:12 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sat, 6 Feb 2010 10:12:48 +0000 (10:12 +0000)
* use mmap to read the download file for output; this way we don't need to copy it into memory first and can let the kernel do this job
* remove the 10k transfer limit

citadel/context.h
citadel/file_ops.c

index b8e48c42ab90c58a141f79dae37d59b454af6463..ff62295e708cfaf411e5f2c9033ebfdc94eb6004 100644 (file)
@@ -64,6 +64,7 @@ struct CitContext {
        char cs_inet_fn[128];                   /* Friendly-name of outbound Internet mail */
 
        FILE *download_fp;      /* Fields relating to file transfer */
+       size_t download_fp_total;
        char download_desired_section[128];
        FILE *upload_fp;
        char upl_file[256];
index ced5a31d568c3fef6f83466c7e51313abfdd4fbc..6f0669093bc08d705aad4ad141101f18b341ad85 100644 (file)
@@ -15,6 +15,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/mman.h>
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -236,6 +237,7 @@ void OpenCmdResult(char *filename, const char *mime_type)
        long filesize;
 
        fstat(fileno(CC->download_fp), &statbuf);
+       CC->download_fp_total = statbuf.st_size;
        filesize = (long) statbuf.st_size;
        modtime = (time_t) statbuf.st_mtime;
 
@@ -633,20 +635,22 @@ void cmd_read(char *cmdbuf)
                return;
        }
 
-       if (bytes > 100000) bytes = 100000;
-       buf = malloc(bytes + 1);
-
-       fseek(CC->download_fp, start_pos, 0);
-
-       actual_bytes = fread(buf, 1, bytes, CC->download_fp);
-       if (actual_bytes > 0) {
+       buf = mmap(NULL, 
+                  CC->download_fp_total, 
+                  PROT_READ, 
+                  MAP_PRIVATE,
+                  fileno(CC->download_fp), 
+                  0);
+       
+       actual_bytes = CC->download_fp_total - start_pos;
+       if ((actual_bytes > 0) && (buf != NULL)) {
                cprintf("%d %d\n", BINARY_FOLLOWS, (int)actual_bytes);
-               client_write(bufbytes);
+               client_write(buf + start_pos, actual_bytes);
        }
        else {
                cprintf("%d %s\n", ERROR, strerror(errno));
        }
-       free(buf);
+       munmap(buf, CC->download_fp_total);
 }
 
 
@@ -732,6 +736,7 @@ void cmd_ndop(char *cmdbuf)
        CC->dl_is_net = 1;
 
        stat(pathname, &statbuf);
+       CC->download_fp_total = statbuf.st_size;
        cprintf("%d %ld\n", CIT_OK, (long)statbuf.st_size);
 }