]> code.citadel.org Git - citadel.git/blobdiff - citadel/file_ops.c
Fix hangups on binary blob reads from webcit stable
[citadel.git] / citadel / file_ops.c
index 0a790832aeb931069a9929f3f8824decff45699a..413e32da1aa6f62f6fc41fc6f0d4b3916c6f0466 100644 (file)
@@ -1,8 +1,5 @@
 /* 
- * $Id$
- *
  * Server functions which handle file transfers and room directories.
- *
  */
 
 #include "sysdep.h"
@@ -15,7 +12,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/mman.h>
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -35,7 +31,6 @@
 #include "config.h"
 #include "file_ops.h"
 #include "sysdep_decls.h"
-#include "user_ops.h"
 #include "support.h"
 #include "room_ops.h"
 #include "msgbase.h"
@@ -47,6 +42,7 @@
 #endif
 
 #include "ctdl_module.h"
+#include "user_ops.h"
 
 /*
  * network_talking_to()  --  concurrency checker
@@ -237,7 +233,6 @@ 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;
 
@@ -569,6 +564,7 @@ void cmd_ucls(char *cmd)
 {
        FILE *fp;
        char upload_notice[512];
+       static int seq = 0;
 
        if (CC->upload_fp == NULL) {
                cprintf("%d You don't have an upload file open.\n", ERROR + RESOURCE_NOT_OPEN);
@@ -579,11 +575,31 @@ void cmd_ucls(char *cmd)
        CC->upload_fp = NULL;
 
        if ((!strcasecmp(cmd, "1")) && (CC->upload_type != UPL_FILE)) {
-               CC->upload_type = UPL_FILE;
                cprintf("%d Upload completed.\n", CIT_OK);
 
-               /* FIXME ... here we need to trigger a network run */
+               if (CC->upload_type == UPL_NET) {
+                       char final_filename[PATH_MAX];
+                       snprintf(final_filename, sizeof final_filename,
+                               "%s/%s.%04lx.%04x",
+                               ctdl_netin_dir,
+                               CC->net_node,
+                               (long)getpid(),
+                               ++seq
+                       );
+
+                       if (link(CC->upl_path, final_filename) == 0) {
+                               unlink(CC->upl_path);
+                       }
+                       else {
+                               CtdlLogPrintf(CTDL_ALERT, "Cannot link %d to %d: %s\n",
+                                       CC->upl_path, final_filename, strerror(errno)
+                               );
+                       }
+
+                       /* FIXME ... here we need to trigger a network run */
+               }
 
+               CC->upload_type = UPL_FILE;
                return;
        }
 
@@ -623,9 +639,9 @@ void cmd_read(char *cmdbuf)
 {
        long start_pos;
        size_t bytes;
-       size_t actual_bytes;
-       char *buf = NULL;
+       char buf[SIZ];
 
+       /* The client will transmit its requested offset and byte count */
        start_pos = extract_long(cmdbuf, 0);
        bytes = extract_int(cmdbuf, 1);
 
@@ -635,26 +651,24 @@ void cmd_read(char *cmdbuf)
                return;
        }
 
-       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(buf + start_pos, actual_bytes);
+       /* If necessary, reduce the byte count to the size of our buffer */
+       if (bytes > sizeof(buf)) {
+               bytes = sizeof(buf);
+       }
+
+       fseek(CC->download_fp, start_pos, 0);
+       bytes = fread(buf, 1, bytes, CC->download_fp);
+       if (bytes > 0) {
+               /* Tell the client the actual byte count and transmit it */
+               cprintf("%d %d\n", BINARY_FOLLOWS, (int)bytes);
+               client_write(bufbytes);
        }
        else {
                cprintf("%d %s\n", ERROR, strerror(errno));
        }
-       munmap(buf, CC->download_fp_total);
 }
 
 
-
 /*
  * write to the upload file
  */
@@ -736,7 +750,6 @@ 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);
 }