summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctm/ctm_dequeue
diff options
context:
space:
mode:
authorgpalmer <gpalmer@FreeBSD.org>1996-07-01 20:54:11 +0000
committergpalmer <gpalmer@FreeBSD.org>1996-07-01 20:54:11 +0000
commit638960af56480e9c96c107cc882824f784b6bb9a (patch)
tree6ea142dfb1d1d56db293e286f233b14dc2766f08 /usr.sbin/ctm/ctm_dequeue
parent017c920ce33090135e3f56c9ebdb7021e7f6714f (diff)
downloadFreeBSD-src-638960af56480e9c96c107cc882824f784b6bb9a.zip
FreeBSD-src-638960af56480e9c96c107cc882824f784b6bb9a.tar.gz
Add a facility for a ``slow'' CTM delta queue, allowing `x' number
of delta's to be mailed out every hour (or however often you schedule the cron job). ctm_dequeue is the cron job which takes the stuff from the queue directory and punts it into sendmail. The chunks of the deltas (and the complete deltas if they are that small) are sorted into order before being dispatched, so the people subscribing should still get the bits in the right order. The changes to ctm_smail should be fairly safe as they won't be activated unless you go for the new queue directory option.
Diffstat (limited to 'usr.sbin/ctm/ctm_dequeue')
-rw-r--r--usr.sbin/ctm/ctm_dequeue/Makefile8
-rw-r--r--usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c224
2 files changed, 232 insertions, 0 deletions
diff --git a/usr.sbin/ctm/ctm_dequeue/Makefile b/usr.sbin/ctm/ctm_dequeue/Makefile
new file mode 100644
index 0000000..543e77e
--- /dev/null
+++ b/usr.sbin/ctm/ctm_dequeue/Makefile
@@ -0,0 +1,8 @@
+PROG= ctm_dequeue
+SRCS= ctm_dequeue.c error.c
+NOMAN= yes
+CFLAGS+= -Wall -I${.CURDIR}/../ctm_rmail
+
+.PATH: ${.CURDIR}/../ctm_rmail
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c b/usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c
new file mode 100644
index 0000000..9d10fc5
--- /dev/null
+++ b/usr.sbin/ctm/ctm_dequeue/ctm_dequeue.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1996, Gary J. Palmer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * Change this if you want to alter how many files it sends out by
+ * default
+ */
+
+#define DEFAULT_NUM 2
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fts.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <paths.h>
+#include "error.h"
+#include "options.h"
+
+int fts_sort(const FTSENT **, const FTSENT **);
+FILE *open_sendmail(void);
+int close_sendmail(FILE *fp);
+
+int
+main(int argc, char **argv)
+{
+ char *log_file = NULL;
+ char *queue_dir = NULL;
+ char *list[2];
+ char *buffer, *filename;
+ int num_to_send = DEFAULT_NUM, piece, fp, len;
+ FTS *fts;
+ FTSENT *ftsent;
+ FILE *sfp;
+
+ err_prog_name(argv[0]);
+
+ OPTIONS("[-l log] [-n num] queuedir")
+ NUMBER('n', num_to_send)
+ STRING('l', log_file)
+ ENDOPTS;
+
+ if (argc != 2)
+ usage();
+
+ queue_dir = argv[1];
+ list[0] = queue_dir;
+ list[1] = NULL;
+
+ fts = fts_open(list, FTS_PHYSICAL, fts_sort);
+ if (fts == NULL)
+ {
+ err("fts failed on `%s'", queue_dir);
+ exit(1);
+ }
+
+ (void) fts_read(fts);
+
+ ftsent = fts_children(fts, 0);
+ if (ftsent == NULL)
+ {
+ err("ftschildren failed");
+ exit(1);
+ }
+
+ /* assumption :-( */
+ len = strlen(queue_dir) + 40;
+ filename = malloc(len);
+ if (filename == NULL)
+ {
+ err("malloc failed");
+ exit(1);
+ }
+
+ for (piece = 0; piece < num_to_send ; piece++)
+ {
+ /* Skip non-files and files we should ignore (ones starting with `.') */
+
+#define ISFILE ((ftsent->fts_info & FTS_F) == FTS_F)
+#define IGNORE (ftsent->fts_name[0] == '.')
+#define HASNEXT (ftsent->fts_link != NULL)
+
+ while(((!ISFILE) || (IGNORE)) && (HASNEXT))
+ ftsent = ftsent->fts_link;
+
+ if ((!ISFILE) || (IGNORE) || (!HASNEXT))
+ {
+ err("No more chunks to mail");
+ exit(0);
+ }
+
+#undef ISFILE
+#undef IGNORE
+#undef HASNEXT
+
+ if (snprintf(filename, len, "%s/%s", queue_dir, ftsent->fts_name) > len)
+ err("snprintf(filename) longer than buffer");
+
+ fp = open(filename, O_RDONLY, 0);
+ if (fp < 0)
+ {
+ err("open(`%s') failed, errno = %d", filename, errno);
+ exit(1);
+ }
+
+ buffer = mmap(0, ftsent->fts_statp->st_size, PROT_READ, MAP_PRIVATE, fp, 0);
+ if (((int) buffer) <= 0)
+ {
+ err("mmap failed, errno = %d", errno);
+ exit(1);
+ }
+
+ sfp = open_sendmail();
+ if (sfp == NULL)
+ exit(1);
+
+ if (fwrite(buffer, ftsent->fts_statp->st_size, 1, sfp) < 1)
+ {
+ err("fwrite failed: errno = %d", errno);
+ close_sendmail(sfp);
+ exit(1);
+ }
+
+ if (!close_sendmail(sfp))
+ exit(1);
+
+ munmap(buffer, ftsent->fts_statp->st_size);
+ close(fp);
+
+ err("sent file `%s'", ftsent->fts_name);
+
+ if (ftsent->fts_link != NULL)
+ ftsent = ftsent->fts_link;
+ }
+ err("exiting normally");
+ return(0);
+}
+
+int
+fts_sort(const FTSENT ** a, const FTSENT ** b)
+{
+ int a_info, b_info;
+
+ a_info = (*a)->fts_info;
+ if (a_info == FTS_ERR)
+ return (0);
+ b_info = (*b)->fts_info;
+ if (b_info == FTS_ERR)
+ return (0);
+
+ return (strcmp((*a)->fts_name, (*b)->fts_name));
+}
+
+/*
+ * Start a pipe to sendmail. Sendmail will decode the destination
+ * from the message contents.
+ */
+FILE *
+open_sendmail()
+{
+ FILE *fp;
+ char buf[100];
+
+ sprintf(buf, "%s -t", _PATH_SENDMAIL);
+ if ((fp = popen(buf, "w")) == NULL)
+ err("cannot start sendmail");
+ return fp;
+}
+
+
+/*
+ * Close a pipe to sendmail. Sendmail will then do its bit.
+ * Return 1 on success, 0 on failure.
+ */
+int
+close_sendmail(FILE *fp)
+{
+ int status;
+
+ fflush(fp);
+ if (ferror(fp))
+ {
+ err("error writing to sendmail");
+ return 0;
+ }
+
+ if ((status = pclose(fp)) != 0)
+ err("sendmail failed with status %d", status);
+
+ return (status == 0);
+}
OpenPOWER on IntegriCloud