diff src/mlmmj-receive.c @ 748:dfc9ab125fd4

Fix spelling of 'receive' and 'voodoo'; make mlmmj-recieve a symlink
author Chris Webb
date Sun, 03 Oct 2010 21:40:42 +1100
parents src/mlmmj-recieve.c@94429995a6a8
children f8f3f4525a2b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mlmmj-receive.c	Sun Oct 03 21:40:42 2010 +1100
@@ -0,0 +1,185 @@
+/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ *
+ * $Id$
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+#include "mlmmj.h"
+#include "wrappers.h"
+#include "mygetline.h"
+#include "strgen.h"
+#include "log_error.h"
+#include "memory.h"
+
+extern char *optarg;
+
+static void print_help(const char *prg)
+{
+        printf("Usage: %s -L /path/to/listdir [-s sender@example.org] [-e extension] [-h] [-V] [-P] [-F]\n"
+	       " -h: This help\n"
+	       " -F: Don't fork in the background\n"
+	       " -L: Full path to list directory\n"
+	       " -s: Specify sender address\n"
+	       " -e: The foo part of user+foo@example.org\n"
+	       " -P: Don't execute mlmmj-process\n"
+	       " -V: Print version\n", prg);
+	exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+	char *infilename = NULL, *listdir = NULL;
+	char *randomstr = random_str();
+	char *mlmmjprocess, *bindir;
+	int fd, opt, noprocess = 0, nofork = 0;
+	struct stat st;
+	uid_t uid;
+	pid_t childpid;
+
+	CHECKFULLPATH(argv[0]);
+	
+	log_set_name(argv[0]);
+
+	bindir = mydirname(argv[0]);
+	mlmmjprocess = concatstr(2, bindir, "/mlmmj-process");
+	myfree(bindir);
+	
+	while ((opt = getopt(argc, argv, "hPVL:s:e:F")) != -1) {
+		switch(opt) {
+		case 'h':
+			print_help(argv[0]);
+			break;
+		case 'L':
+			listdir = optarg;
+			break;
+		case 's':
+			setenv("SENDER", optarg, 1);
+			break;
+		case 'e':
+			setenv("EXTENSION", optarg, 1);
+			break;
+		case 'P':
+			noprocess = 1;
+			break;
+		case 'F':
+			nofork = 1;
+			break;
+		case 'V':
+			print_version(argv[0]);
+			exit(0);
+		}
+	}
+
+	if(listdir == NULL) {
+		fprintf(stderr, "You have to specify -L\n");
+		fprintf(stderr, "%s -h for help\n", argv[0]);
+		exit(EXIT_FAILURE);
+	}
+
+	/* Lets make sure no random user tries to send mail to the list */
+	if(listdir) {
+		if(stat(listdir, &st) == 0) {
+			uid = getuid();
+			if(uid && uid != st.st_uid) {
+				log_error(LOG_ARGS,
+					"Have to invoke either as root "
+					"or as the user owning listdir "
+					"Invoked with uid = [%d]", (int)uid);
+				writen(STDERR_FILENO,
+					"Have to invoke either as root "
+					"or as the user owning listdir\n", 60);
+				exit(EXIT_FAILURE);
+			}
+		} else {
+			log_error(LOG_ARGS, "Could not stat %s", listdir);
+			exit(EXIT_FAILURE);
+		}
+	}
+	
+	infilename = concatstr(3, listdir, "/incoming/", randomstr);
+	myfree(randomstr);
+	fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+	while(fd < 0 && errno == EEXIST) {
+		myfree(infilename);
+		randomstr = random_str();
+		infilename = concatstr(3, listdir, "/incoming/", randomstr);
+		myfree(randomstr);
+		fd = open(infilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+	}
+
+	if(fd < 0) {
+		log_error(LOG_ARGS, "could not create mail file in "
+				    "%s/incoming directory", listdir);
+		myfree(infilename);
+		exit(EXIT_FAILURE);
+	}
+	
+	if(dumpfd2fd(fileno(stdin), fd) != 0) {
+		log_error(LOG_ARGS, "Could not receive mail");
+		exit(EXIT_FAILURE);
+	}
+
+#if 0
+	log_oper(listdir, OPLOGFNAME, "mlmmj-receive got %s", infilename);
+#endif
+	fsync(fd);
+	close(fd);
+
+	if(noprocess) {
+		myfree(infilename);
+		exit(EXIT_SUCCESS);
+	}
+
+	/*
+	 * Now we fork so we can exit with success since it could potentially
+	 * take a long time for mlmmj-send to finish delivering the mails and
+	 * returning, making it susceptible to getting a SIGKILL from the
+	 * mailserver invoking mlmmj-receive.
+	 */
+	if (!nofork) {
+		childpid = fork();
+		if(childpid < 0)
+			log_error(LOG_ARGS, "fork() failed! Proceeding anyway");
+	
+		if(childpid)
+			exit(EXIT_SUCCESS); /* Parent says: "bye bye kids!"*/
+
+		close(0);
+		close(1);
+		close(2);
+	}
+
+	execlp(mlmmjprocess, mlmmjprocess,
+				"-L", listdir,
+				"-m", infilename, (char *)NULL);
+	log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjprocess);
+
+	exit(EXIT_FAILURE);
+}