]> code.citadel.org Git - citadel.git/blobdiff - citadel/file_ops.c
* INLINE doesn't work across several objects as of C99; we just survive it the way...
[citadel.git] / citadel / file_ops.c
index 1424e33e18aec2b64572befe4cf276502d6b9dcf..f303ac28c857904b9060e2a8e9aeff80173b8978 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>
@@ -34,7 +35,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"
@@ -45,6 +45,9 @@
 #include "snprintf.h"
 #endif
 
+#include "ctdl_module.h"
+#include "user_ops.h"
+
 /*
  * network_talking_to()  --  concurrency checker
  */
@@ -161,6 +164,7 @@ void cmd_movf(char *cmdbuf)
        char buf[PATH_MAX];
        int a;
        struct ctdlroom qrbuf;
+       int rv = 0;
 
        extract_token(filename, cmdbuf, 0, '|', sizeof filename);
        extract_token(newroom, cmdbuf, 1, '|', sizeof newroom);
@@ -192,7 +196,7 @@ void cmd_movf(char *cmdbuf)
                return;
        }
 
-       if (getroom(&qrbuf, newroom) != 0) {
+       if (CtdlGetRoom(&qrbuf, newroom) != 0) {
                cprintf("%d '%s' does not exist.\n", ERROR + ROOM_NOT_FOUND, newroom);
                return;
        }
@@ -214,7 +218,7 @@ void cmd_movf(char *cmdbuf)
        snprintf(buf, sizeof buf,
                 "cat ./files/%s/filedir |grep \"%s\" >>./files/%s/filedir",
                 CC->room.QRdirname, filename, qrbuf.QRdirname);
-       system(buf);
+       rv = system(buf);
        cprintf("%d File '%s' has been moved.\n", CIT_OK, filename);
 }
 
@@ -233,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;
 
@@ -305,6 +310,7 @@ void cmd_oimg(char *cmdbuf)
        char which_user[USERNAME_SIZE];
        int which_floor;
        int a;
+       int rv;
 
        extract_token(filename, cmdbuf, 0, '|', sizeof filename);
 
@@ -322,7 +328,7 @@ void cmd_oimg(char *cmdbuf)
 
        if (!strcasecmp(filename, "_userpic_")) {
                extract_token(which_user, cmdbuf, 1, '|', sizeof which_user);
-               if (getuser(&usbuf, which_user) != 0) {
+               if (CtdlGetUser(&usbuf, which_user) != 0) {
                        cprintf("%d No such user.\n",
                                ERROR + NO_SUCH_USER);
                        return;
@@ -361,7 +367,7 @@ void cmd_oimg(char *cmdbuf)
                        ERROR + FILE_NOT_FOUND, pathname, strerror(errno));
                return;
        }
-       fread(&MimeTestBuf[0], 1, 32, CC->download_fp);
+       rv = fread(&MimeTestBuf[0], 1, 32, CC->download_fp);
        rewind (CC->download_fp);
        OpenCmdResult(pathname, GuessMimeType(&MimeTestBuf[0], 32));
 }
@@ -464,7 +470,7 @@ void cmd_uimg(char *cmdbuf)
                }
        }
 
-       if (CC->user.axlevel >= 6) {
+       if (CC->user.axlevel >= AxAideU) {
                snprintf(CC->upl_path, sizeof CC->upl_path, 
                                 "%s/%s",
                                 ctdl_image_dir,
@@ -479,7 +485,7 @@ void cmd_uimg(char *cmdbuf)
        }
 
        if ((!strcasecmp(basenm, "_floorpic_"))
-           && (CC->user.axlevel >= 6)) {
+           && (CC->user.axlevel >= AxAideU)) {
                which_floor = extract_int(cmdbuf, 2);
                snprintf(CC->upl_path, sizeof CC->upl_path,
                                 "%s/floor.%d.gif",
@@ -516,7 +522,7 @@ void cmd_uimg(char *cmdbuf)
 /*
  * close the download file
  */
-void cmd_clos(void)
+void cmd_clos(char *cmdbuf)
 {
        char buf[256];
 
@@ -545,7 +551,7 @@ void cmd_clos(void)
 /*
  * abort an upload
  */
-void abort_upl(struct CitContext *who)
+void abort_upl(CitContext *who)
 {
        if (who->upload_fp != NULL) {
                fclose(who->upload_fp);
@@ -563,6 +569,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);
@@ -576,7 +583,27 @@ void cmd_ucls(char *cmd)
                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 */
+               }
 
                return;
        }
@@ -629,14 +656,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);
-       cprintf("%d %d\n", BINARY_FOLLOWS, (int)actual_bytes);
-       client_write(buf, actual_bytes);
-       free(buf);
+       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);
+       }
+       else {
+               cprintf("%d %s\n", ERROR, strerror(errno));
+       }
+       munmap(buf, CC->download_fp_total);
 }
 
 
@@ -648,6 +683,7 @@ void cmd_writ(char *cmdbuf)
 {
        int bytes;
        char *buf;
+       int rv;
 
        unbuffer_output();
 
@@ -667,7 +703,7 @@ void cmd_writ(char *cmdbuf)
        cprintf("%d %d\n", SEND_BINARY, bytes);
        buf = malloc(bytes + 1);
        client_read(buf, bytes);
-       fwrite(buf, bytes, 1, CC->upload_fp);
+       rv = fwrite(buf, bytes, 1, CC->upload_fp);
        free(buf);
 }
 
@@ -721,6 +757,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);
 }
 
@@ -745,7 +782,7 @@ void cmd_nuop(char *cmdbuf)
 
        snprintf(CC->upl_path, sizeof CC->upl_path,
                         "%s/%s.%04lx.%04x",
-                        ctdl_netin_dir,
+                        ctdl_nettmp_dir,
                         CC->net_node, 
                         (long)getpid(), 
                         ++seq);
@@ -769,3 +806,28 @@ void cmd_nuop(char *cmdbuf)
        CC->upload_type = UPL_NET;
        cprintf("%d Ok\n", CIT_OK);
 }
+
+
+/*****************************************************************************/
+/*                      MODULE INITIALIZATION STUFF                          */
+/*****************************************************************************/
+
+CTDL_MODULE_INIT(file_ops)
+{
+       if (!threading) {
+               CtdlRegisterProtoHook(cmd_delf, "DELF", "Delete a file");
+               CtdlRegisterProtoHook(cmd_movf, "MOVF", "Move a file");
+               CtdlRegisterProtoHook(cmd_open, "OPEN", "Open a download file transfer");
+               CtdlRegisterProtoHook(cmd_clos, "CLOS", "Close a download file transfer");
+               CtdlRegisterProtoHook(cmd_uopn, "UOPN", "Open an upload file transfer");
+               CtdlRegisterProtoHook(cmd_ucls, "UCLS", "Close an upload file transfer");
+               CtdlRegisterProtoHook(cmd_read, "READ", "File transfer read operation");
+               CtdlRegisterProtoHook(cmd_writ, "WRIT", "File transfer write operation");
+               CtdlRegisterProtoHook(cmd_ndop, "NDOP", "Open a network spool file for download");
+               CtdlRegisterProtoHook(cmd_nuop, "NUOP", "Open a network spool file for upload");
+               CtdlRegisterProtoHook(cmd_oimg, "OIMG", "Open an image file for download");
+               CtdlRegisterProtoHook(cmd_uimg, "UIMG", "Upload an image file");
+       }
+        /* return our Subversion id for the Log */
+       return "$Id$";
+}