tll_front(*fromemails), mlmmjsend, ctrlfd);
return -1;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for digest"
- " subscription from %s",
- tll_front(*fromemails));
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: request for digest"
+ " subscription from %s", tll_front(*fromemails));
exec_or_die(mlmmjsub, "-L", listdir, "-a",
tll_front(*fromemails), "-d", "-r", "-c",
(nosubconfirm ? NULL : "-C"), NULL);
tll_front(*fromemails), mlmmjsend, ctrlfd);
return -1;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for nomail"
- " subscription from %s",
- tll_front(*fromemails));
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: request for nomail"
+ " subscription from %s", tll_front(*fromemails));
exec_or_die(mlmmjsub, "-L", listdir, "-a",
tll_front(*fromemails), "-n", "-r", "-c",
(nosubconfirm ? NULL : "-C"), NULL);
tll_front(*fromemails), mlmmjsend, ctrlfd);
return -1;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for both"
- " subscription from %s",
- tll_front(*fromemails));
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: request for both"
+ " subscription from %s", tll_front(*fromemails));
exec_or_die(mlmmjsub, "-L", listdir, "-a",
tll_front(*fromemails), "-b", "-r", "-c",
(nosubconfirm ? NULL : "-C"), NULL);
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: request for regular"
- " subscription from %s",
- tll_front(*fromemails));
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: request for regular"
+ " subscription from %s", tll_front(*fromemails));
exec_or_die(mlmmjsub, "-L", listdir, "-a",
tll_front(*fromemails), "-r", "-c",
(nosubconfirm ? NULL : "-C"), NULL);
tmpstr = mygetline(tmpfd);
chomp(tmpstr);
close(tmpfd);
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: %s confirmed"
- " subscription to %s", tmpstr, subtypename);
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: %s confirmed"
+ " subscription to %s", tmpstr, subtypename);
exec_or_die(mlmmjsub, "-L", listdir, "-a", tmpstr, "-n",
"-R", "-c", NULL);
break;
chomp(tmpstr);
close(tmpfd);
unlink(conffilename);
- log_oper(listdir, OPLOGFNAME, "mlmmj-sub: %s confirmed"
- " subscription to regular list",
- tmpstr);
+ log_oper(listfd, OPLOGFNAME, "mlmmj-sub: %s confirmed"
+ " subscription to regular list", tmpstr);
exec_or_die(mlmmjsub, "-L", listdir, "-a", tmpstr,
"-R", "-c", NULL);
break;
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-unsub: %s requests"
- " unsubscribe",
- tll_front(*fromemails));
+ log_oper(listfd, OPLOGFNAME, "mlmmj-unsub: %s requests"
+ " unsubscribe", tll_front(*fromemails));
exec_or_die(mlmmjunsub, "-L", listdir, "-a",
tll_front(*fromemails), "-r",
(nosubconfirm ? "-c" : "-C"), NULL);
close(tmpfd);
chomp(tmpstr);
unlink(conffilename);
- log_oper(listdir, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
- " unsubscribe from digest", tmpstr);
+ log_oper(listfd, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
+ " unsubscribe from digest", tmpstr);
exec_or_die(mlmmjunsub, "-L", listdir, "-a", tmpstr, "-d",
"-R", "-c", NULL);
break;
close(tmpfd);
chomp(tmpstr);
unlink(conffilename);
- log_oper(listdir, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
- " unsubscribe from nomail", tmpstr);
+ log_oper(listfd, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
+ " unsubscribe from nomail", tmpstr);
exec_or_die(mlmmjunsub, "-L", listdir, "-a", tmpstr, "-n",
"-R", "-c", NULL);
break;
close(tmpfd);
chomp(tmpstr);
unlink(conffilename);
- log_oper(listdir, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
- " unsubscribe from regular list",
- tmpstr);
+ log_oper(listfd, OPLOGFNAME, "mlmmj-unsub: %s confirmed"
+ " unsubscribe from regular list", tmpstr);
exec_or_die(mlmmjunsub, "-L", listdir, "-a", tmpstr, "-R", "-c",
NULL);
break;
free(moderatefilename);
- log_oper(listdir, OPLOGFNAME, "%s released %s",
+ log_oper(listfd, OPLOGFNAME, "%s released %s",
tll_front(*fromemails), param);
if (omit != NULL)
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "%s rejected %s",
+ log_oper(listfd, OPLOGFNAME, "%s rejected %s",
tll_front(*fromemails), param);
free(param);
if (unlink(moderatefilename) != 0) {
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "%s permitted %s",
+ log_oper(listfd, OPLOGFNAME, "%s permitted %s",
tll_front(*fromemails), param);
exec_or_die(mlmmjsub, "-L", listdir, "-m", param, "-c", NULL);
break;
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "%s obstructed %s",
+ log_oper(listfd, OPLOGFNAME, "%s obstructed %s",
tll_front(*fromemails), param);
free(param);
if (unlink(gatekeepfilename) != 0) {
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "%s requested help",
+ log_oper(listfd, OPLOGFNAME, "%s requested help",
tll_front(*fromemails));
txt = open_text(listdir, "help", NULL, NULL, NULL, "listhelp");
MY_ASSERT(txt);
" Ignoring mail");
return -1;
}
- log_oper(listdir, OPLOGFNAME, "%s requested faq",
+ log_oper(listfd, OPLOGFNAME, "%s requested faq",
tll_front(*fromemails));
txt = open_text(listdir, "faq", NULL, NULL, NULL, "listfaq");
MY_ASSERT(txt);
log_error(LOG_ARGS, "Unable to open archive file");
exit(EXIT_FAILURE);
}
- log_oper(listdir, OPLOGFNAME, "%s got archive/%s",
+ log_oper(listfd, OPLOGFNAME, "%s got archive/%s",
tll_front(*fromemails), archivefilename);
exec_or_die(mlmmjsend, "-T", tll_front(*fromemails), "-L",
listdir, "-l", "6", "-m", archivefilename, "-a", "-D",
tll_foreach(*owners, it) {
if(strcasecmp(tll_front(*fromemails),
it->item) == 0) {
- log_oper(listdir, OPLOGFNAME,
+ log_oper(listfd, OPLOGFNAME,
"%s requested sub list",
tll_front(*fromemails));
owner = it->item;
#include <stdlib.h>
#include <stdarg.h>
+#include "xmalloc.h"
#include "mlmmj.h"
#include "log_error.h"
#include "log_oper.h"
-#include "strgen.h"
#include "wrappers.h"
#include "utils.h"
-int log_oper(const char *prefix, const char *basename, const char *fmt, ...)
+int log_oper(int listfd, const char *basename, const char *fmt, ...)
{
int fd, statres;
- char ct[26], *logfilename, *tmp, log_msg[256];
+ char ct[26], *tmp;
struct stat st;
time_t t;
va_list ap;
- size_t i;
- logfilename = concatstr(3, prefix, "/", basename);
- statres = lstat(logfilename, &st);
+ statres = fstatat(listfd, basename, &st, AT_SYMLINK_NOFOLLOW);
if(statres < 0 && errno != ENOENT) {
- log_error(LOG_ARGS, "Could not stat logfile %s", logfilename);
- free(logfilename);
+ log_error(LOG_ARGS, "Could not stat logfile %s", basename);
return -1;
}
-
+
if(statres >= 0 && st.st_size > (off_t)OPLOGSIZE) {
- tmp = concatstr(2, logfilename, ".rotated");
- if(rename(logfilename, tmp) < 0) {
+ xasprintf(&tmp, "%s.rotated", basename);
+ if(renameat(listfd, basename, listfd, tmp) < 0) {
log_error(LOG_ARGS, "Could not rename %s,%s",
- logfilename, tmp);
+ basename, tmp);
}
free(tmp);
}
-
- fd = open(logfilename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
+
+ fd = openat(listfd, basename, O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
if(fd < 0 && !lock(fd, true)) {
- log_error(LOG_ARGS, "Could not open %s", logfilename);
- free(logfilename);
+ log_error(LOG_ARGS, "Could not open %s", basename);
return -1;
}
if((time(&t) == (time_t)-1) || (ctime_r(&t, ct) == NULL))
strncpy(ct, "Unknown time", sizeof(ct));
- else
- ct[24] = '\0';
va_start(ap, fmt);
- i = vsnprintf(log_msg, sizeof(log_msg), fmt, ap);
- if(i < 0) {
- va_end(ap);
- log_error(LOG_ARGS, "Failed to format log message: %s", fmt);
- return -1;
- }
- if(i > sizeof(log_msg))
- log_error(LOG_ARGS, "Log message truncated");
-
+ if (dprintf(fd, "%s", ct) < 0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
+ if (vdprintf(fd, fmt, ap) <0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
+ if (dprintf(fd, "\n") < 0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
va_end(ap);
- if(dprintf(fd, "%s %s\n", ct, log_msg) < 0)
- log_error(LOG_ARGS, "Could not write to %s", logfilename);
-
close(fd);
- free(logfilename);
-
+
return 0;
}
static enum action do_access(strlist *rule_strs, strlist *hdrs,
- const char *from, const char *listdir)
+ const char *from, int listfd)
{
unsigned int match;
char *rule_ptr;
log_error(LOG_ARGS, "Unable to parse rule #%d \"%s\":"
" Missing action keyword. Denying post from \"%s\"",
i, it->item, from);
- log_oper(listdir, OPLOGFNAME, "Unable to parse rule #%d \"%s\":"
+ log_oper(listfd, OPLOGFNAME, "Unable to parse rule #%d \"%s\":"
" Missing action keyword. Denying post from \"%s\"",
i, it->item, from);
return DENY;
rule_ptr++;
} else if (*rule_ptr == '\0') {
/* the rule is a keyword and no regexp */
- log_oper(listdir, OPLOGFNAME, "mlmmj-process: access -"
+ log_oper(listfd, OPLOGFNAME, "mlmmj-process: access -"
" A mail from \"%s\" was %s by rule #%d \"%s\"",
from, action_strs[act], i, it->item);
return act;
log_error(LOG_ARGS, "Unable to parse rule #%d \"%s\":"
" Invalid character after action keyword."
" Denying post from \"%s\"", i, it->item, from);
- log_oper(listdir, OPLOGFNAME, "Unable to parse rule #%d \"%s\":"
+ log_oper(listfd, OPLOGFNAME, "Unable to parse rule #%d \"%s\":"
" Invalid character after action keyword."
" Denying post from \"%s\"", i, it->item, from);
return DENY;
" (message: '%s') (expression: '%s')"
" Denying post from \"%s\"",
i, it->item, errbuf, rule_ptr, from);
- log_oper(listdir, OPLOGFNAME, "regcomp() failed for rule"
+ log_oper(listfd, OPLOGFNAME, "regcomp() failed for rule"
" #%d \"%s\" (message: '%s') (expression: '%s')"
" Denying post from \"%s\"",
i, it->item, errbuf, rule_ptr, from);
if (match != not) {
if (match) {
- log_oper(listdir, OPLOGFNAME, "mlmmj-process: access -"
+ log_oper(listfd, OPLOGFNAME, "mlmmj-process: access -"
" A mail from \"%s\" with header \"%s\" was %s by"
" rule #%d \"%s\"", from, hdr, action_strs[act],
i, it->item);
} else {
- log_oper(listdir, OPLOGFNAME, "mlmmj-process: access -"
+ log_oper(listfd, OPLOGFNAME, "mlmmj-process: access -"
" A mail from \"%s\" was %s by rule #%d \"%s\""
" because no header matched.", from,
action_strs[act], i, it->item);
i++;
}
- log_oper(listdir, OPLOGFNAME, "mlmmj-process: access -"
+ log_oper(listfd, OPLOGFNAME, "mlmmj-process: access -"
" A mail from \"%s\" didn't match any rules, and"
" was denied by default.", from);
return DENY;
close(rawmailfd);
close(donemailfd);
unlink(mailfile);
- log_oper(listdir, OPLOGFNAME, "mlmmj-process: sending"
+ log_oper(listfd, OPLOGFNAME, "mlmmj-process: sending"
" mail from %s to owner",
efrom);
exec_or_die(mlmmjsend, "-l", "4", "-L", listdir, "-F",
/* Don't send a mail about denial to the list, but silently
* discard and exit. Also do this in case it's turned off */
accret = do_access(access_rules, &allheaders,
- posteraddr, listdir);
+ posteraddr, listfd);
if (accret == DENY) {
if ((strcasecmp(listaddr, posteraddr) == 0) ||
statctrl(ctrlfd, "noaccessdenymails")) {