]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/ctdlproto/serv_file.c
Merge branch 'configdb' of ssh://git.citadel.org/appl/gitroot/citadel
[citadel.git] / citadel / modules / ctdlproto / serv_file.c
index 2970f1ccd60522cb3e96ca59d5ad4df2d6b7b1a5..50661c7c75d64187e97edcdbef00a4d88fcc4bce 100644 (file)
@@ -1,47 +1,28 @@
 /* 
  * Server functions which handle file transfers and room directories.
+ *
+ * Copyright (c) 1987-2015 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
-#include "sysdep.h"
-#include <stdlib.h>
-#include <unistd.h>
 #include <stdio.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <ctype.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#include <limits.h>
 #include <libcitadel.h>
-#include "citadel.h"
-#include "server.h"
-#include "config.h"
-#include "files.h"
-#include "sysdep_decls.h"
-#include "support.h"
-#include "room_ops.h"
-#include "msgbase.h"
-#include "citserver.h"
-#include "threads.h"
+#include <dirent.h>
+
 #include "ctdl_module.h"
+#include "citserver.h"
+#include "support.h"
+#include "config.h"
 #include "user_ops.h"
 
 
-
 /*
  * Server command to delete a file from a room's directory
  */
@@ -799,6 +780,172 @@ void files_logout_hook(void)
 
 }
 
+/* 
+ * help_subst()  -  support routine for help file viewer
+ */
+void help_subst(char *strbuf, char *source, char *dest)
+{
+       char workbuf[SIZ];
+       int p;
+
+       while (p = pattern2(strbuf, source), (p >= 0)) {
+               strcpy(workbuf, &strbuf[p + strlen(source)]);
+               strcpy(&strbuf[p], dest);
+               strcat(strbuf, workbuf);
+       }
+}
+
+void do_help_subst(char *buffer)
+{
+       char buf2[16];
+
+       help_subst(buffer, "^nodename", CtdlGetConfigStr("c_nodename"));
+       help_subst(buffer, "^humannode", CtdlGetConfigStr("c_humannode"));
+       help_subst(buffer, "^fqdn", CtdlGetConfigStr("c_fqdn"));
+       help_subst(buffer, "^username", CC->user.fullname);
+       snprintf(buf2, sizeof buf2, "%ld", CC->user.usernum);
+       help_subst(buffer, "^usernum", buf2);
+       help_subst(buffer, "^sysadm", CtdlGetConfigStr("c_sysadm"));
+       help_subst(buffer, "^variantname", CITADEL);
+       help_subst(buffer, "^maxsessions", CtdlGetConfigStr("c_maxsessions"));          // yes it's numeric but str is ok here
+       help_subst(buffer, "^bbsdir", ctdl_message_dir);
+}
+
+
+typedef const char *ccharp;
+/*
+ * display system messages or help
+ */
+void cmd_mesg(char *mname)
+{
+       FILE *mfp;
+       char targ[256];
+       char buf[256];
+       char buf2[256];
+       char *dirs[2];
+       DIR *dp;
+       struct dirent *d;
+
+       extract_token(buf, mname, 0, '|', sizeof buf);
+
+       dirs[0] = strdup(ctdl_message_dir);
+       dirs[1] = strdup(ctdl_hlp_dir);
+
+       snprintf(buf2, sizeof buf2, "%s.%d.%d",
+               buf, CC->cs_clientdev, CC->cs_clienttyp);
+
+       /* If the client requested "?" then produce a listing */
+       if (!strcmp(buf, "?")) {
+               cprintf("%d %s\n", LISTING_FOLLOWS, buf);
+               dp = opendir(dirs[1]);
+               if (dp != NULL) {
+                       while (d = readdir(dp), d != NULL) {
+                               if (d->d_name[0] != '.') {
+                                       cprintf(" %s\n", d->d_name);
+                               }
+                       }
+                       closedir(dp);
+               }
+               cprintf("000\n");
+               free(dirs[0]);
+               free(dirs[1]);
+               return;
+       }
+
+       /* Otherwise, look for the requested file by name. */
+       else {
+               mesg_locate(targ, sizeof targ, buf2, 2, (const ccharp*)dirs);
+               if (IsEmptyStr(targ)) {
+                       snprintf(buf2, sizeof buf2, "%s.%d",
+                                                       buf, CC->cs_clientdev);
+                       mesg_locate(targ, sizeof targ, buf2, 2,
+                                   (const ccharp*)dirs);
+                       if (IsEmptyStr(targ)) {
+                               mesg_locate(targ, sizeof targ, buf, 2,
+                                           (const ccharp*)dirs);
+                       }       
+               }
+       }
+
+       free(dirs[0]);
+       free(dirs[1]);
+
+       if (IsEmptyStr(targ)) {
+               cprintf("%d '%s' not found.  (Searching in %s and %s)\n",
+                       ERROR + FILE_NOT_FOUND,
+                       mname,
+                       ctdl_message_dir,
+                       ctdl_hlp_dir
+               );
+               return;
+       }
+
+       mfp = fopen(targ, "r");
+       if (mfp==NULL) {
+               cprintf("%d Cannot open '%s': %s\n",
+                       ERROR + INTERNAL_ERROR, targ, strerror(errno));
+               return;
+       }
+       cprintf("%d %s\n", LISTING_FOLLOWS,buf);
+
+       while (fgets(buf, (sizeof buf - 1), mfp) != NULL) {
+               buf[strlen(buf)-1] = 0;
+               do_help_subst(buf);
+               cprintf("%s\n",buf);
+       }
+
+       fclose(mfp);
+       cprintf("000\n");
+}
+
+
+/*
+ * enter system messages or help
+ */
+void cmd_emsg(char *mname)
+{
+       FILE *mfp;
+       char targ[256];
+       char buf[256];
+       char *dirs[2];
+       int a;
+
+       unbuffer_output();
+
+       if (CtdlAccessCheck(ac_aide)) return;
+
+       extract_token(buf, mname, 0, '|', sizeof buf);
+       for (a=0; !IsEmptyStr(&buf[a]); ++a) {          /* security measure */
+               if (buf[a] == '/') buf[a] = '.';
+       }
+
+       dirs[0] = strdup(ctdl_message_dir);
+       dirs[1] = strdup(ctdl_hlp_dir);
+
+       mesg_locate(targ, sizeof targ, buf, 2, (const ccharp*)dirs);
+       free(dirs[0]);
+       free(dirs[1]);
+
+       if (IsEmptyStr(targ)) {
+               snprintf(targ, sizeof targ, 
+                                "%s/%s",
+                                ctdl_hlp_dir, buf);
+       }
+
+       mfp = fopen(targ,"w");
+       if (mfp==NULL) {
+               cprintf("%d Cannot open '%s': %s\n",
+                       ERROR + INTERNAL_ERROR, targ, strerror(errno));
+               return;
+       }
+       cprintf("%d %s\n", SEND_LISTING, targ);
+
+       while (client_getln(buf, sizeof buf) >=0 && strcmp(buf, "000")) {
+               fprintf(mfp, "%s\n", buf);
+       }
+
+       fclose(mfp);
+}
 
 /*****************************************************************************/
 /*                      MODULE INITIALIZATION STUFF                          */
@@ -821,6 +968,9 @@ CTDL_MODULE_INIT(file_ops)
                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");
+
+               CtdlRegisterProtoHook(cmd_mesg, "MESG", "fetch system banners");
+               CtdlRegisterProtoHook(cmd_emsg, "EMSG", "submit system banners");
        }
         /* return our Subversion id for the Log */
        return "file_ops";