return ret;
}
-char *bounce_from_adr(const char *recipient, const char *listadr,
- const char *listdelim, const char *mailfilename,
- const char *listdir)
+char *bounce_from_adr(const char *recipient, const char *mailfilename,
+ struct mlmmj_list *list)
{
char *bounceaddr, *myrecipient, *mylistadr;
char *indexstr, *listdomain, *a = NULL, *mymailfilename;
if (a)
*a = '=';
- mylistadr = mystrdup(listadr);
+ mylistadr = mystrdup(list->listaddr);
if (!mylistadr) {
myfree(mymailfilename);
myfree(myrecipient);
*listdomain++ = '\0';
/* 11 = "bounces-" + "-" + "@" + NUL */
- len = strlen(mylistadr) + strlen(listdelim) + strlen(myrecipient)
+ len = strlen(mylistadr) + strlen(list->listdelim) + strlen(myrecipient)
+ strlen(indexstr) + strlen(listdomain) + 11;
- staticbounceaddr = ctrlvalue(listdir, "staticbounceaddr");
+ staticbounceaddr = ctrlvalue(list->listdir, "staticbounceaddr");
if (staticbounceaddr) {
staticbounceaddr_localpart = genlistname(staticbounceaddr);
staticbounceaddr_domain = genlistfqdn(staticbounceaddr);
if (staticbounceaddr) {
snprintf(bounceaddr, len, "%s%s%s-bounces-%s-%s@%s",
- staticbounceaddr_localpart, listdelim, mylistadr,
+ staticbounceaddr_localpart, list->listdelim, mylistadr,
indexstr, myrecipient, staticbounceaddr_domain);
myfree(staticbounceaddr);
myfree(staticbounceaddr_localpart);
myfree(staticbounceaddr_domain);
} else {
- snprintf(bounceaddr, len, "%s%sbounces-%s-%s@%s", mylistadr, listdelim,
+ snprintf(bounceaddr, len, "%s%sbounces-%s-%s@%s", mylistadr, list->listdelim,
indexstr, myrecipient, listdomain);
}
return bounceaddr;
}
-int bouncemail(const char *listdir, const char *mlmmjbounce, const char *from)
+int bouncemail(struct mlmmj_list *list, const char *mlmmjbounce, const char *from)
{
char *myfrom = mystrdup(from);
- char *listdelim = getlistdelim(listdir);
char *addr, *num, *c;
size_t len;
pid_t pid = 0;
if((c = strchr(myfrom, '@')) == NULL) {
myfree(myfrom);
- myfree(listdelim);
return 0; /* Success when malformed 'from' */
}
*c = '\0';
num = strrchr(myfrom, '-');
num++;
- c = strstr(myfrom, listdelim);
+ c = strstr(myfrom, list->listdelim);
myfrom = strchr(c, '-');
myfrom++;
len = num - myfrom - 1;
addr[len] = '\0';
strncpy(addr, myfrom, len);
- myfree(listdelim);
-
pid = fork();
if(pid < 0) {
return 0;
execlp(mlmmjbounce, mlmmjbounce,
- "-L", listdir,
+ "-L", list->listdir,
"-a", num,
"-n", addr, (char *)NULL);
int send_mail(int sockfd, const char *from, const char *to,
const char *replyto, char *mailmap, size_t mailsize,
- const char *listdir, const char *mlmmjbounce,
+ struct mlmmj_list *list, const char *mlmmjbounce,
const char *hdrs, size_t hdrslen, const char *body,
size_t bodylen)
{
if(mlmmjbounce && ((reply[0] == '4') || (reply[0] == '5'))
&& (reply[1] == '5')) {
myfree(reply);
- return bouncemail(listdir, mlmmjbounce, from);
+ return bouncemail(list, mlmmjbounce, from);
} else {
log_error(LOG_ARGS, "Error in RCPT TO. Reply = [%s]",
reply);
}
int send_mail_verp(int sockfd, struct strlist *addrs, char *mailmap,
- size_t mailsize, const char *from, const char *listdir,
+ size_t mailsize, const char *from, struct mlmmj_list *list,
const char *hdrs, size_t hdrslen, const char *body,
size_t bodylen, const char *verpextra)
{
int send_mail_many_fd(int sockfd, const char *from, const char *replyto,
char *mailmap, size_t mailsize, int subfd,
- const char *listaddr, const char *listdelim,
- const char *archivefilename, const char *listdir,
+ const char *archivefilename, struct mlmmj_list *list,
const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
const char *body, size_t bodylen)
{
res = getaddrsfromfd(&stl, subfd, maxverprecips);
if(stl.count == maxverprecips) {
ret = send_mail_many_list(sockfd, from, replyto,
- mailmap, mailsize, &stl, listaddr,
- listdelim, archivefilename, listdir,
+ mailmap, mailsize, &stl,
+ archivefilename, list,
mlmmjbounce, hdrs, hdrslen,
body, bodylen);
for(i = 0; i < stl.count; i++)
if(stl.count) {
ret = send_mail_many_list(sockfd, from, replyto, mailmap,
- mailsize, &stl, listaddr, listdelim,
- archivefilename, listdir, mlmmjbounce,
- hdrs, hdrslen, body, bodylen);
+ mailsize, &stl, archivefilename, list,
+ mlmmjbounce, hdrs, hdrslen, body, bodylen);
for(i = 0; i < stl.count; i++)
myfree(stl.strs[i]);
stl.count = 0;
int send_mail_many_list(int sockfd, const char *from, const char *replyto,
char *mailmap, size_t mailsize, struct strlist *addrs,
- const char *listaddr, const char *listdelim,
- const char *archivefilename, const char *listdir,
+ const char *archivefilename, struct mlmmj_list *list,
const char *mlmmjbounce, const char *hdrs, size_t hdrslen,
const char *body, size_t bodylen)
{
addr);
continue;
}
- if(gotsigterm && listaddr && archivefilename) {
+ if(gotsigterm && list->listaddr && archivefilename) {
/* we got SIGTERM, so save the addresses and bail */
log_error(LOG_ARGS, "TERM signal received, "
"shutting down.");
index = get_index_from_filename(archivefilename);
- status = requeuemail(listdir, index, addrs, i);
+ status = requeuemail(list->listdir, index, addrs, i);
myfree(index);
return status;
}
if(from) {
res = send_mail(sockfd, from, addr, replyto,
- mailmap, mailsize, listdir, NULL,
+ mailmap, mailsize, list, NULL,
hdrs, hdrslen, body, bodylen);
} else {
- bounceaddr = bounce_from_adr(addr, listaddr, listdelim,
- archivefilename, listdir);
+ bounceaddr = bounce_from_adr(addr, archivefilename, list);
res = send_mail(sockfd, bounceaddr, addr, replyto,
- mailmap, mailsize, listdir, mlmmjbounce,
+ mailmap, mailsize, list, mlmmjbounce,
hdrs, hdrslen, body, bodylen);
myfree(bounceaddr);
}
- if(res && listaddr && archivefilename) {
+ if(res && list->listaddr && archivefilename) {
/* we failed, so save the addresses and bail */
index = get_index_from_filename(archivefilename);
- status = requeuemail(listdir, index, addrs, i);
+ status = requeuemail(list->listdir, index, addrs, i);
myfree(index);
return status;
}
int sockfd = -1, mailfd = 0, opt, mindex = 0, subfd = 0, tmpfd, i;
int deletewhensent = 1, sendres = 0, archive = 1, digest = 0;
int ctrlarchive, res;
- char *listaddr = NULL, *listdelim = NULL;
char *mailfilename = NULL, *subfilename = NULL, *omit = NULL;
char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL;
char *relayhost = NULL, *archivefilename = NULL, *tmpstr;
- char *listctrl = NULL, *subddirname = NULL, *listdir = NULL;
+ char *listctrl = NULL, *subddirname = NULL;
char *mlmmjbounce = NULL, *bindir, *mailmap, *probefile, *a;
char *body = NULL, *hdrs = NULL, *memmailsizestr = NULL, *verp = NULL;
- char relay[16], *listname, *listfqdn, *verpfrom, *maxverprecipsstr;
+ char relay[16], *verpfrom, *maxverprecipsstr;
char strindex[32], *reply, *strport, *smtphelo, *requeuefilename;
ssize_t memmailsize = 0;
DIR *subddir;
struct hostent *relayent;
uid_t uid;
struct strlist stl;
+ struct mlmmj_list list;
unsigned short smtpport = 25;
struct sigaction sigact;
+ mlmmj_list_init(&list);
CHECKFULLPATH(argv[0]);
log_set_name(argv[0]);
listctrl = optarg;
break;
case 'L':
- listdir = optarg;
+ list.listdir = optarg;
break;
case 'm':
mailfilename = optarg;
}
}
- if(mailfilename == NULL || (listdir == NULL && listctrl == NULL)) {
+ if(mailfilename == NULL || (!mlmmj_list_open(&list) && 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);
}
/* Lets make sure no random user tries to send mail to the list */
- if(listdir) {
- if(stat(listdir, &st) == 0) {
+ if(list.listdir) {
+ if(stat(list.listdir, &st) == 0) {
uid = getuid();
if(uid && uid != st.st_uid) {
log_error(LOG_ARGS,
exit(EXIT_FAILURE);
}
} else {
- log_error(LOG_ARGS, "Could not stat %s", listdir);
+ log_error(LOG_ARGS, "Could not stat %s", list.listdir);
exit(EXIT_FAILURE);
}
}
exit(EXIT_FAILURE);
}
- if((listctrl[0] == '2' && (listdir == NULL || bounceaddr == NULL))) {
+ if((listctrl[0] == '2' && (list.listdir == NULL || bounceaddr == NULL))) {
fprintf(stderr, "With -l 2 you need -L and -F\n");
exit(EXIT_FAILURE);
}
- if((listctrl[0] == '7' && listdir == NULL)) {
+ if((listctrl[0] == '7' && list.listdir == NULL)) {
fprintf(stderr, "With -l 7 you need -L\n");
exit(EXIT_FAILURE);
}
- verp = ctrlvalue(listdir, "verp");
+ verp = ctrlvalue(list.listdir, "verp");
if(verp == NULL)
- if(statctrl(listdir, "verp") == 1)
+ if(statctrl(list.listdir, "verp") == 1)
verp = mystrdup("");
- maxverprecipsstr = ctrlvalue(listdir, "maxverprecips");
+ maxverprecipsstr = ctrlvalue(list.listdir, "maxverprecips");
if(verp && maxverprecipsstr) {
maxverprecips = atol(maxverprecipsstr);
myfree(maxverprecipsstr);
break;
}
- if(listdir && listctrl[0] != '5')
- listaddr = getlistaddr(listdir);
-
/* initialize file with mail to send */
if((mailfd = open(mailfilename, O_RDWR)) < 0) {
exit(EXIT_FAILURE);
}
- memmailsizestr = ctrlvalue(listdir, "memorymailsize");
- ctrlarchive = statctrl(listdir, "noarchive");
+ memmailsizestr = ctrlvalue(list.listdir, "memorymailsize");
+ ctrlarchive = statctrl(list.listdir, "noarchive");
if(memmailsizestr) {
memmailsize = strtol(memmailsizestr, NULL, 10);
myfree(memmailsizestr);
}
}
- if(listdir)
- listdelim = getlistdelim(listdir);
-
switch(listctrl[0]) {
case '1': /* A single mail is to be sent, do nothing */
case '5':
break;
case '2': /* Moderators */
- subfilename = concatstr(2, listdir, "/control/moderators");
+ subfilename = concatstr(2, list.listdir, "/control/moderators");
if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s':",
subfilename);
myfree(hdrs);
myfree(body);
myfree(subfilename);
- myfree(listdelim);
/* No moderators is no error. Could be the sysadmin
* likes to do it manually.
*/
}
break;
case '3':
- addtohdr = statctrl(listdir, "addtohdr");
+ addtohdr = statctrl(list.listdir, "addtohdr");
case '4': /* sending mails to subfile */
if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s':",
subfilename);
myfree(hdrs);
myfree(body);
- myfree(listdelim);
exit(EXIT_FAILURE);
}
break;
archive = 0;
deletewhensent = 0;
archivefilename = mystrdup(mailfilename);
- bounceaddr = bounce_from_adr(to_addr, listaddr, listdelim,
- archivefilename, listdir);
+ bounceaddr = bounce_from_adr(to_addr, archivefilename, &list);
break;
default: /* normal list mail -- now handled when forking */
- addtohdr = statctrl(listdir, "addtohdr");
+ addtohdr = statctrl(list.listdir, "addtohdr");
break;
}
/* initialize the archive filename */
if(archive) {
- mindex = incindexfile((const char *)listdir);
- len = strlen(listdir) + 9 + 20;
+ mindex = incindexfile(list.listdir);
+ len = strlen(list.listdir) + 9 + 20;
archivefilename = mymalloc(len);
- snprintf(archivefilename, len, "%s/archive/%d", listdir,
+ snprintf(archivefilename, len, "%s/archive/%d", list.listdir,
mindex);
}
itoa(mindex, strindex);
if(!relayhost) {
- relayhost = ctrlvalue(listdir, "relayhost");
+ relayhost = ctrlvalue(list.listdir, "relayhost");
}
if(!relayhost)
strncpy(relay, RELAYHOST, sizeof(relay));
strncpy(relay, RELAYHOST, sizeof(relay));
}
}
- strport = ctrlvalue(listdir, "smtpport");
+ strport = ctrlvalue(list.listdir, "smtpport");
if(strport)
smtpport = (unsigned short)atol(strport);
- if ((smtphelo = ctrlvalue(listdir, "smtphelo")) == NULL) {
+ if ((smtphelo = ctrlvalue(list.listdir, "smtphelo")) == NULL) {
smtphelo = hostnamestr();
}
case '6':
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(send_mail(sockfd, bounceaddr, to_addr, replyto,
- mailmap, st.st_size, listdir, NULL,
+ mailmap, st.st_size, &list, NULL,
hdrs, hdrslen, body, bodylen)) {
close(sockfd);
sockfd = -1;
case '2': /* Moderators */
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap,
- st.st_size, subfd, NULL, NULL, NULL,
- listdir, NULL, hdrs, hdrslen,
+ st.st_size, subfd, NULL,
+ &list, NULL, hdrs, hdrslen,
body, bodylen)) {
close(sockfd);
sockfd = -1;
case '3': /* resending earlier failed mails */
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(send_mail_many_fd(sockfd, NULL, NULL, mailmap, st.st_size,
- subfd, listaddr, listdelim, mailfilename,
- listdir, mlmmjbounce, hdrs, hdrslen,
+ subfd, mailfilename, &list, mlmmjbounce, hdrs, hdrslen,
body, bodylen)) {
close(sockfd);
sockfd = -1;
case '4': /* send mails to owner */
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(send_mail_many_fd(sockfd, bounceaddr, NULL, mailmap,
- st.st_size, subfd, listaddr, listdelim,
- mailfilename, listdir, mlmmjbounce,
+ st.st_size, subfd, mailfilename, &list, mlmmjbounce,
hdrs, hdrslen, body, bodylen)) {
close(sockfd);
sockfd = -1;
case '5': /* bounceprobe - handle relayhost local users bouncing*/
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(send_mail(sockfd, bounceaddr, to_addr, replyto,
- mailmap, st.st_size, listdir, NULL,
+ mailmap, st.st_size, &list, NULL,
hdrs, hdrslen, body, bodylen)) {
close(sockfd);
sockfd = -1;
a = strchr(tmpstr, '@');
MY_ASSERT(a);
*a = '=';
- probefile = concatstr(4, listdir, "/bounce/", tmpstr,
+ probefile = concatstr(4, list.listdir, "/bounce/", tmpstr,
"-probe");
unlink(probefile);
myfree(probefile);
/* fall through */
default: /* normal list mail */
if (!digest) {
- subddirname = concatstr(2, listdir, "/subscribers.d/");
+ subddirname = concatstr(2, list.listdir, "/subscribers.d/");
} else {
- subddirname = concatstr(2, listdir, "/digesters.d/");
+ subddirname = concatstr(2, list.listdir, "/digesters.d/");
}
if((subddir = opendir(subddirname)) == NULL) {
log_error(LOG_ARGS, "Could not opendir(%s)",
subddirname);
- myfree(listdelim);
myfree(subddirname);
myfree(hdrs);
myfree(body);
exit(EXIT_FAILURE);
}
- listdelim = getlistdelim(listdir);
- listname = genlistname(listaddr);
- listfqdn = genlistfqdn(listaddr);
- verpfrom = concatstr(6, listname, listdelim, "bounces-",
- strindex, "@", listfqdn);
- myfree(listname);
- myfree(listfqdn);
+ verpfrom = concatstr(6, list.listname, list.listdelim, "bounces-",
+ strindex, "@", list.listfqdn);
if(digest)
verp = NULL;
mailmap,
st.st_size,
verpfrom,
- listdir, hdrs,
+ &list, hdrs,
hdrslen, body,
bodylen, verp);
if(sendres)
- requeuemail(listdir,
+ requeuemail(list.listdir,
strindex,
&stl, 0);
} else {
NULL, mailmap,
st.st_size,
&stl,
- listaddr,
- listdelim,
archivefilename,
- listdir,
+ &list,
mlmmjbounce,
hdrs, hdrslen,
body, bodylen);
initsmtp(&sockfd, relay, smtpport, smtphelo);
if(verp) {
sendres = send_mail_verp(sockfd, &stl, mailmap,
- st.st_size, verpfrom, listdir,
+ st.st_size, verpfrom, &list,
hdrs, hdrslen, body, bodylen,
verp);
if(sendres)
- requeuemail(listdir, strindex, &stl,
+ requeuemail(list.listdir, strindex, &stl,
0);
} else {
sendres = send_mail_many_list(sockfd, NULL,
NULL, mailmap, st.st_size,
- &stl, listaddr, listdelim,
- archivefilename, listdir,
+ &stl, archivefilename, &list,
mlmmjbounce, hdrs, hdrslen,
body, bodylen);
}
break;
}
- myfree(listdelim);
myfree(hdrs);
myfree(body);
myfree(mlmmjbounce);
archivefilename);
}
} else {
- len = strlen(listdir) + 9 + 20 + 9;
+ len = strlen(list.listdir) + 9 + 20 + 9;
requeuefilename = mymalloc(len);
snprintf(requeuefilename, len, "%s/requeue/%d",
- listdir, mindex);
+ list.listdir, mindex);
if(stat(requeuefilename, &st) < 0) {
/* Nothing was requeued and we don't keep
* mail for a noarchive list. */
} else {
snprintf(requeuefilename, len,
"%s/requeue/%d/mailfile",
- listdir, mindex);
+ list.listdir, mindex);
if (rename(mailfilename, requeuefilename) < 0) {
log_error(LOG_ARGS,
"Could not rename(%s,%s);",