+0.4.0
+ o Add moderation functionality
0.3.4
o Fix handling of lines which start with a dot
0.3.3
#ifndef GETLISTADDR_H
#define GETLISTADDR_H
-char *getlistaddr(char *listaddrdeststr, const char *listdir);
+char *getlistaddr(const char *listdir);
#endif /* GETLISTADDR_H */
There exists the following options:
- To unsubscribe send a mail to
+To unsubscribe send a mail to
- *UNSUBADDR*
+*UNSUBADDR*
- To subscribe send a mail to
+To subscribe send a mail to
- *SUBADDR*
+*SUBADDR*
- For this help send a mail to
+For this help send a mail to
+
+*HLPADDR*
- *HLPADDR*
Mails can have any subject and any body.
--- /dev/null
+Hello,
+
+Someone send a mail for moderation to:
+
+*LISTADDR*
+
+
+To accept it send a mail to
+
+*MODERATEADDR*
+
+
+Your mailer probably automatically replies to this address, when you hit
+the reply button. If you don't want it sent to the list, simply ignore this
+mail.
+
+The following moderators have recieved this mail:
+
+*MODERATORS*
+
+
+--- below this line the first 100 lines of the mail up for moderation --->
mlmmj_send_SOURCES = mlmmj-send.c writen.c mail-functions.c itoa.c chomp.c \
incindexfile.c checkwait_smtpreply.c getlistaddr.c \
mylocking.c init_sockfd.c strgen.c random-int.c \
- print-version.c log_error.c
+ print-version.c log_error.c mygetline.c
mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c header_token.c \
getlistaddr.c chomp.c strgen.c print-version.c \
incindexfile.$(OBJEXT) checkwait_smtpreply.$(OBJEXT) \
getlistaddr.$(OBJEXT) mylocking.$(OBJEXT) \
init_sockfd.$(OBJEXT) strgen.$(OBJEXT) random-int.$(OBJEXT) \
- print-version.$(OBJEXT) log_error.$(OBJEXT)
+ print-version.$(OBJEXT) log_error.$(OBJEXT) \
+ mygetline.$(OBJEXT)
mlmmj_send_OBJECTS = $(am_mlmmj_send_OBJECTS)
mlmmj_send_LDADD = $(LDADD)
am_mlmmj_sub_OBJECTS = mlmmj-sub.$(OBJEXT) writen.$(OBJEXT) \
mlmmj_send_SOURCES = mlmmj-send.c writen.c mail-functions.c itoa.c chomp.c \
incindexfile.c checkwait_smtpreply.c getlistaddr.c \
mylocking.c init_sockfd.c strgen.c random-int.c \
- print-version.c log_error.c
+ print-version.c log_error.c mygetline.c
mlmmj_recieve_SOURCES = mlmmj-recieve.c writen.c random-int.c header_token.c \
getlistaddr.c chomp.c strgen.c print-version.c \
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+
#include "getlistaddr.h"
#include "chomp.h"
#include "log_error.h"
+#include "mygetline.h"
+#include "strgen.h"
-#define MAXLISTNAMELEN 1024
-
-char *getlistaddr(char *listaddrdeststr, const char *listdir)
+char *getlistaddr(const char *listdir)
{
- size_t len;
char *tmpstr;
FILE *listnamefile;
- len = strlen(listdir) + strlen("/listaddress") + 1;
- tmpstr = malloc(len);
-
- snprintf(tmpstr, len, "%s/listaddress", listdir);
+ tmpstr = concatstr(2, listdir, "/listaddress");;
if((listnamefile = fopen(tmpstr, "r")) == NULL) {
log_error(LOG_ARGS, "Could not open '%s'", tmpstr);
exit(EXIT_FAILURE);
}
+ free(tmpstr);
- fgets(listaddrdeststr, MAXLISTNAMELEN, listnamefile);
- chomp(listaddrdeststr);
+ tmpstr = myfgetline(listnamefile);
+ if(!tmpstr){
+ log_error(LOG_ARGS, "FATAL. Could not get listaddress");
+ exit(EXIT_FAILURE);
+ }
+
+ chomp(tmpstr);
fclose(listnamefile);
- free(tmpstr);
- return listaddrdeststr;
+
+ return tmpstr;
}
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <string.h>
#include "init_sockfd.h"
#include "log_error.h"
{
char tmpstr[READ_BUFSIZE];
char *atsign, *recipdelimsign, *tokenvalue, *confstr, *bouncenr;
- char *controlstr, *conffilename;
+ char *controlstr, *conffilename, *moderatefilename;
FILE *mailfile, *tempfile;
struct email_container fromemails;
struct stat stbuf;
"-L", listdir,
"-a", tmpstr,
"-c", 0);
- log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjunsub);
+ log_error(LOG_ARGS, "execlp() of '%s' failed",
+ mlmmjunsub);
exit(EXIT_FAILURE);
} else {
exit(EXIT_SUCCESS);
} else if(strncasecmp(controlstr, "bounces-", 8) == 0) {
controlstr += 8;
bouncenr = strrchr(controlstr, '-');
- if (!bouncenr) exit(EXIT_SUCCESS); /* malformed bounce, ignore */
+ if (!bouncenr) exit(EXIT_SUCCESS); /* malformed bounce, ignore */
*bouncenr++ = '\0';
#if 0
log_error(LOG_ARGS, "bounce, bounce, bounce email=[%s] nr=[%s]", controlstr, bouncenr);
"-a", controlstr,
"-n", bouncenr, 0);
log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjbounce);
+ exit(EXIT_FAILURE);
+ } else if(strncasecmp(controlstr, "moderate-", 9) == 0) {
+ controlstr += 9;
+ moderatefilename = concatstr(3, listdir, "/moderation/queue/",
+ controlstr);
+ controlstr -= 9;
+ free(controlstr);
+ if(stat(moderatefilename, &stbuf) < 0) {
+ free(moderatefilename);
+ exit(EXIT_SUCCESS); /* just exit, no mail to moderate */
+ } else {
+ execlp(mlmmjsend, mlmmjsend,
+ "-L", listdir,
+ "-m", moderatefilename, 0);
+ log_error(LOG_ARGS, "execlp() of %s failed", mlmmjsend);
+ exit(EXIT_FAILURE);
+ }
} else if(strncasecmp(controlstr, "help", 4) == 0) {
printf("Help wanted!\n");
free(controlstr);
FQDN=`domainname`
fi
+echo -n "The path to the directory with the texts for the list? [] : "
+read TEXTPATH
+if [ -z "$TEXTPATH" -o ! -d "$TEXTPATH" ]; then
+ echo "**NOTE** Could not copy the texts for the list"
+ echo "Please manually copy the files from the listtexts/ directory"
+ echo "in the source distribution of mlmmj."
+fi
+cp "$TEXTPATH"/* "$LISTDIR"/"text"
+
LISTADDRESS="$LISTNAME@$FQDN"
echo "$LISTADDRESS" > "$LISTDIR"/"listaddress"
echo "$ALIAS"
fi
-echo "Hi, this is the mlmmj program managing the mailinglist
-
-*LSTADDR*
-
-
-To confirm you want the address
-
-*SUBADDR*
-
-
-added to this list, please send a reply to
-
-*CNFADDR*
-
-
-Your mailer probably automatically replies to this address, when you hit
-the reply button.
-
-This confirmation serves two purposes. It tests that mail can be sent to your
-address. Second, it makes sure someone else did not try and subscribe your
-emailaddress." > $SPOOLDIR/$LISTNAME/text/sub-confirm
-
-echo "WELCOME! You have been subscribed to the
-
-*LSTADDR*
-
-
-mailinglist." > $SPOOLDIR/$LISTNAME/text/sub-ok
-
-echo "Hi, this is the mlmmj program managing the mailinglist
-
-*LSTADDR*
-
-
-To confirm you want the address
-
-*SUBADDR*
-
-
-removed from this list, please send a reply to
-
-*CNFADDR*
-
-
-Your mailer probably automatically replies to this address, when you hit
-the reply button.
-
-If you're not subscribed with this list, you will recieve no reply. You can
-see in the From header of a mail to the mailinglist which mail you're sub-
-scribed with." > $SPOOLDIR/$LISTNAME/text/unsub-confirm
-
-
-echo "GOODBYE! You have been removed from the
-
-*LSTADDR*
-
-
-mailinglist." > $SPOOLDIR/$LISTNAME/text/unsub-ok
-
-echo "Hello,
-
-There exists the following options:
-
- To unsubscribe send a mail to
-
- *UNSUBADDR*
-
-
- To subscribe send a mail to
-
- *SUBADDR*
-
-
- For this help send a mail to
-
- *HLPADDR*
-
-Mails can have any subject and any body." > $SPOOLDIR/$LISTNAME/text/listhelp
-
echo " ** DON'T FORGET **
1) The mailinglist directory have to be owned by the user running the
mailserver (i.e. starting the binaries to work the list)
#include "strgen.h"
#include "do_all_the_voodo_here.h"
#include "log_error.h"
+#include "mygetline.h"
+#include "statctrl.h"
+
+void newmoderated(const char *listdir, const char *mailfilename,
+ const char *mlmmjsend)
+{
+ char *to, *from, *subject, *fqdn, *listname, *replyto;
+ char *buf, *moderatorfilename, *listaddr = getlistaddr(listdir);
+ char *queuefilename, *moderatorsfilename, *randomstr = random_str();
+ char *mailbasename = basename(strdup(mailfilename));
+ FILE *moderatorfile, *queuefile, *moderatorsfile, *mailfile;
+ size_t count = 0;
+
+ printf("mailfilename = [%s], mailbasename = [%s]\n", mailfilename,
+ mailbasename);
+
+ fqdn = genlistfqdn(listaddr);
+ listname = genlistname(listaddr);
+ moderatorfilename = concatstr(2, listdir, "/text/moderation");
+ if((moderatorfile = fopen(moderatorfilename, "r")) == NULL) {
+ log_error(LOG_ARGS, "Could not open text/moderation");
+ free(moderatorfilename);
+ exit(EXIT_FAILURE);
+ }
+ queuefilename = concatstr(3, listdir, "/queue/", randomstr);
+ printf("%s\n", queuefilename);
+
+ if((queuefile = fopen(queuefilename, "w")) == NULL) {
+ log_error(LOG_ARGS, "Could not open '%s'", queuefilename);
+ free(queuefilename);
+ free(randomstr);
+ exit(EXIT_FAILURE);
+ }
+ free(randomstr);
+
+ moderatorsfilename = concatstr(2, listdir, "/moderators");
+ if((moderatorsfile = fopen(moderatorsfilename, "r")) == NULL) {
+ log_error(LOG_ARGS, "Could not open '%s'", moderatorsfilename);
+ free(queuefilename);
+ free(moderatorsfilename);
+ fclose(queuefile);
+ exit(EXIT_FAILURE);
+ }
+ free(moderatorfilename);
+
+ if((mailfile = fopen(mailfilename, "r")) == NULL) {
+ log_error(LOG_ARGS, "Could not open '%s'", mailfilename);
+ free(queuefilename);
+ free(moderatorsfilename);
+ fclose(queuefile);
+ exit(EXIT_FAILURE);
+ }
+
+ fputs("From: ", queuefile);
+ from = concatstr(3, listname, "+owner@", fqdn);
+ fputs(from, queuefile);
+ fputc('\n', queuefile);
+ to = concatstr(5, "To: ", listname, "-moderators@", fqdn, "\n");
+ fputs(to, queuefile);
+ free(to);
+ replyto = concatstr(7, "Reply-To: ", listname, "+moderate-",
+ mailbasename, "@", fqdn, "\n");
+ fputs(replyto, queuefile);
+ free(replyto);
+ subject = concatstr(3, "Subject: Moderation needed for ", listaddr,
+ "\n\n");
+ fputs(subject, queuefile);
+ free(subject);
+
+ while((buf = myfgetline(moderatorfile))) {
+ if(strncmp(buf, "*LISTADDR*", 10) == 0) {
+ fputs(listaddr, queuefile);
+ } else if(strncmp(buf, "*MODERATEADDR*", 14) == 0) {
+ fputs(listname, queuefile);
+ fputs("+moderate-", queuefile);
+ fputs(mailbasename, queuefile);
+ fputc('@', queuefile);
+ fputs(fqdn, queuefile);
+ } else if(strncmp(buf, "*MODERATORS*", 12) == 0) {
+ free(buf);
+ while((buf = myfgetline(moderatorsfile))) {
+ fputs(buf, queuefile);
+ free(buf);
+ buf = NULL;
+ }
+ } else
+ fputs(buf, queuefile);
+ free(buf);
+ }
+ fclose(moderatorfile);
+ while((buf = myfgetline(mailfile)) && count < 100) {
+ fputc(' ', queuefile);
+ fputs(buf, queuefile);
+ free(buf);
+ count++;
+ }
+ fclose(queuefile);
+
+ execlp(mlmmjsend, mlmmjsend,
+ "-l", "2",
+ "-L", listdir,
+ "-F", from,
+ "-m", queuefilename, 0);
+
+ log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend);
+
+ exit(EXIT_FAILURE);
+}
static void print_help(const char *prg)
{
int main(int argc, char **argv)
{
- int fd, opt, i, noprocess = 0;
+ int fd, opt, noprocess = 0, moderated = 0;
char *listdir = NULL, *mailfile = NULL, *headerfilename = NULL;
char *footerfilename = NULL, *donemailname = NULL;
- char *randomstr = random_str();
+ char *randomstr = random_str(), *basename, *mqueuename;
char *mlmmjsend, *mlmmjsub, *mlmmjunsub, *mlmmjbounce;
char *argv0 = strdup(argv[0]);
FILE *headerfile, *footerfile, *rawmailfile, *donemailfile;
struct mailhdr readhdrs[] = {
{ "To:", NULL },
{ "Cc:", NULL },
+ { "From:", NULL },
{ NULL, NULL }
};
break;
case 'V':
print_version(argv[0]);
- exit(0);
+ exit(EXIT_SUCCESS);
}
}
if(listdir == NULL || mailfile == NULL) {
exit(EXIT_FAILURE);
}
- donemailname = concatstr(3, listdir, "/queue/", randomstr);
+ basename = strdup(randomstr);
free(randomstr);
+ donemailname = concatstr(3, listdir, "/queue/", basename);
fd = open(donemailname, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
while(fd == -1 && errno == EEXIST) {
free(donemailname);
#endif
}
+
if(strchr(toemails.emaillist[0], RECIPDELIM)) {
#if 0
log_error(LOG_ARGS, "listcontrol(%s, %s, %s, %s, %s, %s, %s)\n", donemailname, listdir, toemails.emaillist[0], mlmmjsub, mlmmjunsub, mlmmjsend, mlmmjbounce);
return EXIT_SUCCESS;
}
+ moderated = statctrl(listdir, "moderated");
+
+ if(moderated) {
+ mqueuename = concatstr(3, listdir, "/moderation/queue/",
+ basename);
+ printf("Going into moderatemode, mqueuename = [%s]\n",
+ mqueuename);
+ free(basename);
+ if(rename(donemailname, mqueuename) < 0) {
+ printf("could not rename(%s,%s)\n",
+ donemailname, mqueuename);
+ perror("rename");
+ log_error(LOG_ARGS, "could not rename(%s,%s)",
+ donemailname, mqueuename);
+ free(donemailname);
+ free(mqueuename);
+ exit(EXIT_FAILURE);
+ }
+ free(donemailname);
+ newmoderated(listdir, mqueuename, mlmmjsend);
+ return EXIT_SUCCESS;
+ }
+
+
if(noprocess) {
free(donemailname);
/* XXX: toemails and ccemails etc. have to be free() */
size_t len = 0;
int sockfd = 0, opt, mindex, retval = 0;
FILE *subfile = NULL, *mailfile = NULL;
- char listadr[READ_BUFSIZE], buf[READ_BUFSIZE];
+ char *listadr, buf[READ_BUFSIZE];
char *mailfilename = NULL, *subfilename = NULL, *listdir = NULL;
char *replyto = NULL, *bounce_adr = NULL, *to_addr = NULL;
char *bufres, *relayhost = NULL, *archivefilename = NULL;
+ char *listctrl = NULL;
int deletewhensent = 1;
log_set_name(argv[0]);
- while ((opt = getopt(argc, argv, "VDhm:L:R:F:T:r:")) != -1){
+ while ((opt = getopt(argc, argv, "VDhm:l:L:R:F:T:r:")) != -1){
switch(opt) {
case 'D':
deletewhensent = 0;
case 'h':
print_help(argv[0]);
break;
+ case 'l':
+ listctrl = optarg;
+ break;
case 'L':
listdir = optarg;
break;
break;
case 'V':
print_version(argv[0]);
- exit(0);
+ exit(EXIT_SUCCESS);
}
}
- if(mailfilename == 0 || listdir == 0) {
- fprintf(stderr, "You have to specify -L and -m\n");
+ if(mailfilename == NULL || (listdir == NULL && listctrl == NULL)) {
+ fprintf(stderr, "You have to specify -m and -L or -l\n");
fprintf(stderr, "%s -h for help\n", argv[0]);
exit(EXIT_FAILURE);
}
+
+ if(!listctrl && listdir && listdir[0] == '1')
+ listctrl = strdup("1");
+
+ if(!listctrl)
+ listctrl = strdup("0");
+
+
/* get the list address */
- if(listdir[0] == '1' && (bounce_adr == 0 || to_addr == 0))
- fprintf(stderr, "With -L 1 you need -F and -T\n");
+ if(listctrl[0] == '1' && (bounce_adr == NULL || to_addr == NULL)) {
+ fprintf(stderr, "With -l 1 you need -F and -T\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if((listctrl[0] == '2' && listdir == NULL)) {
+ fprintf(stderr, "With -l 2 you need -L\n");
+ exit(EXIT_FAILURE);
+ }
- if(listdir[0] != '1')
- getlistaddr(listadr, listdir);
+ if(listctrl[0] != '1' && listctrl[0] != '2')
+ listadr = getlistaddr(listdir);
/* initialize file with mail to send */
else
init_sockfd(&sockfd, RELAYHOST);
- /* XXX: Here is the subscribers unrolled and mails are sent.
- * A more intelligent generic solution will be implemented
- * later, so we can get LDAP, SQL etc. support for the
- * subscribers list. Choeger?
- */
- if(listdir[0] != '1') {
+ switch(listctrl[0]) {
+ case '1': /* A single mail is to be sent, do nothing */
+ break;
+ case '2': /* Moderators */
+ subfilename = concatstr(2, listdir, "/moderators");
+ if((subfile = fopen(subfilename, "r")) == NULL) {
+ log_error(LOG_ARGS, "Could not open '%s':",
+ subfilename);
+ free(subfilename);
+ /* No moderators is no error. Could be the sysadmin
+ * likes to do it manually.
+ */
+ exit(EXIT_SUCCESS);
+ }
+ break;
+ default: /* normal list mail */
subfilename = concatstr(2, listdir, "/subscribers");
if((subfile = fopen(subfilename, "r")) == NULL) {
- log_error(LOG_ARGS, "Could not open subscriberfile:");
+ log_error(LOG_ARGS, "Could not open '%s':",
+ subfilename);
+ free(subfilename);
exit(EXIT_FAILURE);
}
+ break;
}
/* initialize the archive filename */
- if(listdir[0] != '1') {
+ if(listctrl[0] != '1' && listctrl[0] != '2') {
mindex = incindexfile((const char *)listdir, 1);
len = strlen(listdir) + 9 + 20;
archivefilename = malloc(len);
/* FIXME: quit and tell admin to configure correctly */
}
- if(listdir[0] != '1') {
+ /* FIXME: use myfgetline instead! */
+ switch(listctrl[0]) {
+ case '1': /* A single mail is to be sent */
+ send_mail(sockfd, bounce_adr, to_addr, replyto, mailfile);
+ break;
+ case '2': /* Moderators */
+ while((bufres = fgets(buf, READ_BUFSIZE, subfile))) {
+ chomp(buf);
+ send_mail(sockfd, bounce_adr, buf, 0, mailfile);
+ }
+ break;
+ default: /* normal list mail */
while((bufres = fgets(buf, READ_BUFSIZE, subfile))) {
chomp(buf);
bounce_adr = bounce_from_adr(buf, listadr,
archivefilename);
-
send_mail(sockfd, bounce_adr, buf, 0, mailfile);
free(bounce_adr);
}
- } else
- send_mail(sockfd, bounce_adr, to_addr, replyto, mailfile);
+ break;
+ }
write_quit(sockfd);
if((checkwait_smtpreply(sockfd, MLMMJ_QUIT)) != 0) {
"We close the socket anyway though\n");
}
- if(listdir[0] != '1') {
+ if(listctrl[0] != '1' && listctrl[0] != '2') {
/* The mail now goes to the archive */
rename(mailfilename, archivefilename);
char *bufres, *subtextfilename, *randomstr, *queuefilename;
char *fromstr, *tostr, *subjectstr, *fromaddr, *helpaddr;
char *listname, *listfqdn;
- size_t len;
subtextfilename = concatstr(2, listdir, "/text/sub-ok");
}
free(randomstr);
- len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
- helpaddr = malloc(len);
- snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+ helpaddr = concatstr(3, listname, "+help@", listfqdn);
- len += strlen("-bounces");
- fromaddr = malloc(len);
- snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+ fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
fromstr = headerstr("From: ", helpaddr);
fputs(fromstr, queuefile);
char *confirmaddr, *bufres, *listname, *listfqdn, *confirmfilename;
char *subtextfilename, *queuefilename, *fromaddr, *randomstr;
char *tostr, *fromstr, *helpaddr, *subjectstr;
- size_t len;
listname = genlistname(listaddr);
listfqdn = genlistfqdn(listaddr);
fclose(subconffile);
free(confirmfilename);
- len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
- helpaddr = malloc(len);
- snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+ helpaddr = concatstr(3, listname, "+help@", listfqdn);
- len = strlen(listname) + strlen(listfqdn) + strlen("+confsub")
- + strlen(subaddr) + 20;
- confirmaddr = malloc(len);
- snprintf(confirmaddr, len, "%s+confsub-%s@%s", listname, randomstr,
- listfqdn);
+ confirmaddr = concatstr(5, listname, "+confsub-", randomstr, "@",
+ listfqdn);
- len += strlen("-bounces");
- fromaddr = malloc(len);
- snprintf(fromaddr, len, "%s-bounces+confsub-%s@%s", listname,
- randomstr, listfqdn);
+ fromaddr = concatstr(5, listname, "+bounces-confsub-", randomstr,
+ "@", listfqdn);
subtextfilename = concatstr(2, listdir, "/text/sub-confirm");
fclose(queuefile);
execlp(mlmmjsend, mlmmjsend,
- "-L", "1",
+ "-l", "1",
"-T", subaddr,
"-F", fromaddr,
"-R", confirmaddr,
int main(int argc, char **argv)
{
- char listaddr[READ_BUFSIZE];
- char *listdir = NULL, *address = NULL, *subfilename = NULL;
+ char *listaddr, *listdir = NULL, *address = NULL, *subfilename = NULL;
char *mlmmjsend, *argv0 = strdup(argv[0]);
int subconfirm = 0, confirmsub = 0, opt, subfilefd, lock;
size_t len;
}
/* get the list address */
- getlistaddr(listaddr, listdir);
+ listaddr = getlistaddr(listdir);
if(strncasecmp(listaddr, address, strlen(listaddr)) == 0) {
printf("Cannot subscribe the list address to the list\n");
exit(EXIT_SUCCESS); /* XXX is this success? */
char *bufres, *subtextfilename, *randomstr, *queuefilename;
char *fromstr, *tostr, *subjectstr, *fromaddr, *helpaddr;
char *listname, *listfqdn;
- size_t len;
subtextfilename = concatstr(2, listdir, "/text/unsub-ok");
}
free(randomstr);
- len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
- helpaddr = malloc(len);
- snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+ helpaddr = concatstr(3, listname, "+help@", listfqdn);
- len += strlen("-bounces");
- fromaddr = malloc(len);
- snprintf(fromaddr, len, "%s-bounces+help@%s", listname, listfqdn);
+ fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
fromstr = headerstr("From: ", helpaddr);
fputs(fromstr, queuefile);
void generate_unsubconfirm(const char *listdir, const char *listaddr,
const char *subaddr, const char *mlmmjsend)
{
- size_t len;
char buf[READ_BUFSIZE];
char *confirmaddr, *bufres, *listname, *listfqdn, *confirmfilename;
char *subtextfilename, *queuefilename, *fromaddr, *randomstr;
fputs(subaddr, subconffile);
fclose(subconffile);
free(confirmfilename);
+ helpaddr = concatstr(3, listname, "+help@", listfqdn);
- len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
- helpaddr = malloc(len);
- snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+ confirmaddr = concatstr(5, listname, "+confunsub-", randomstr, "@",
+ listfqdn);
- len = strlen(listname) + strlen(listfqdn) + strlen("+confunsub")
- + strlen(subaddr) + 20;
- confirmaddr = malloc(len);
- snprintf(confirmaddr, len, "%s+confunsub-%s@%s", listname, randomstr,
- listfqdn);
-
- len += strlen("-bounces");
- fromaddr = malloc(len);
- snprintf(fromaddr, len, "%s-bounces+confunsub-%s@%s", listname,
- randomstr, listfqdn);
+ fromaddr = concatstr(5, listname, "+bounces-confunsub-", randomstr,
+ "@", listfqdn);
subtextfilename = concatstr(2, listdir, "/text/unsub-confirm");
fclose(queuefile);
execlp(mlmmjsend, mlmmjsend,
- "-L", "1",
+ "-l", "1",
"-T", subaddr,
"-F", fromaddr,
"-R", confirmaddr,
size_t len = strlen(address) + 1; /* + 1 for the '\n' */
if(suboff == -1)
- return 0; /* Did not find subscriber */
+ return 1; /* Did not find subscriber */
if(fstat(subreadfd, &st) < 0) {
log_error(LOG_ARGS, "Could not stat fd");
static void print_help(const char *prg)
{
printf("Usage: %s -L /path/to/chat-list\n"
- " -a someguy@somewhere.ltd\n"
+ " -a someguy@somewhere.tld\n"
" -C request mail confirmation\n"
" -c send goodbye mail\n"
" -h this help\n"
int main(int argc, char **argv)
{
- int subread, subwrite, rlock, wlock, opt;
+ int subread, subwrite, rlock, wlock, opt, unsubres;
int confirmunsub = 0, unsubconfirm = 0;
- char listaddr[READ_BUFSIZE];
- char *listdir = NULL, *address = NULL, *subreadname = NULL;
+ char *listaddr, *listdir = NULL, *address = NULL, *subreadname = NULL;
char *subwritename, *mlmmjsend, *argv0 = strdup(argv[0]);
off_t suboff;
}
/* get the list address */
- getlistaddr(listaddr, listdir);
+ listaddr = getlistaddr(listdir);
subreadname = concatstr(2, listdir, "/subscribers");
subwritename = concatstr(2, listdir, "/subscribers.new");
if(unsubconfirm)
generate_unsubconfirm(listdir, listaddr, address, mlmmjsend);
else
- unsubscribe(subread, subwrite, address);
+ unsubres = unsubscribe(subread, subwrite, address);
+
+ if(unsubres == 0)
+ unlink(subreadname);
if(rename(subwritename, subreadname) < 0) {
log_error(LOG_ARGS, "Could not rename '%s' to '%s'",
const char *mlmmjsend)
{
FILE *helpfile, *queuefile;
- char buf[READ_BUFSIZE], listaddr[READ_BUFSIZE];
- char *bufres, *helpaddr, *fromaddr, *fromstr, *tostr;
+ char buf[READ_BUFSIZE];
+ char *listaddr, *bufres, *helpaddr, *fromaddr, *fromstr, *tostr;
char *subjectstr, *helpfilename, *queuefilename, *listname;
char *randomstr, *listfqdn;
size_t len;
- getlistaddr(listaddr, listdir);
+ listaddr = getlistaddr(listdir);
helpfilename = concatstr(2, listdir, "/text/listhelp");
#include <sys/types.h>
#include <sys/stat.h>
+#include <stdlib.h>
#include "strgen.h"
#include "statctrl.h"