#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <err.h>
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h>
static void subscribe_type(struct mlmmj_list *list,
char *address, char *mlmmjsend,
enum subtype typesub, enum subreason reasonsub) {
- char *subfilename = NULL;
char chstr[2], *subdir;
- char *subddirname = NULL, *sublockname;
- int groupwritable = 0, sublock, sublockfd, lock, subfilefd;
+ char *sublockname = NULL;
+ int groupwritable = 0, sublockfd, subfilefd;
struct stat st;
size_t len;
+ int subdirfd = -1;
switch(typesub) {
default:
case SUB_NORMAL:
- subdir = "/subscribers.d/";
+ subdir = "subscribers.d";
break;
case SUB_DIGEST:
- subdir = "/digesters.d/";
+ subdir = "digesters.d";
break;
case SUB_NOMAIL:
- subdir = "/nomailsubs.d/";
+ subdir = "nomailsubs.d";
break;
}
- subddirname = concatstr(2, list->dir, subdir);
- if (stat(subddirname, &st) == 0) {
+ subdirfd = openat(list->fd, subdir, O_DIRECTORY|O_CLOEXEC);
+ if (subdirfd == -1)
+ err(EXIT_FAILURE, "Unable to open %s/%s", list->dir, subdir);
+
+ if (fstat(subdirfd, &st) == 0) {
if(st.st_mode & S_IWGRP) {
groupwritable = S_IRGRP|S_IWGRP;
umask(S_IWOTH);
chstr[0] = address[0];
chstr[1] = '\0';
-
- subfilename = concatstr(3, list->dir, subdir, chstr);
- sublockname = concatstr(5, list->dir, subdir, ".", chstr, ".lock");
- sublockfd = open(sublockname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
- if(sublockfd < 0) {
- log_error(LOG_ARGS, "Error opening lock file %s",
- sublockname);
- myfree(sublockname);
- exit(EXIT_FAILURE);
+ subfilefd = openat(subdirfd, chstr, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
+ if (subfilefd == -1) {
+ log_error(LOG_ARGS, "Error opening %s/%s/%s", list->dir, subdir, chstr);
+ err(EXIT_FAILURE, "Error opening %s/%s/%s");
}
- sublock = myexcllock(sublockfd);
- if(sublock < 0) {
- log_error(LOG_ARGS, "Error locking '%s' file",
- sublockname);
+ myasprintf(&sublockname, ".%s.lock", chstr);
+ sublockfd = openat(subdirfd, sublockname, O_RDWR | O_CREAT | O_EXLOCK, S_IRUSR | S_IWUSR);
+ if(sublockfd < 0) {
+ log_error(LOG_ARGS, "Error opening lock file %s%s%s", list->dir,
+ subdir, sublockname);
myfree(sublockname);
- close(sublockfd);
exit(EXIT_FAILURE);
}
- subfilefd = open(subfilename, O_RDWR|O_CREAT,
+ subfilefd = openat(subdirfd, chstr, O_RDWR|O_CREAT|O_EXLOCK,
S_IRUSR|S_IWUSR|groupwritable);
if(subfilefd == -1) {
- log_error(LOG_ARGS, "Could not open '%s'", subfilename);
- myfree(sublockname);
- exit(EXIT_FAILURE);
- }
-
- lock = myexcllock(subfilefd);
- if(lock) {
- log_error(LOG_ARGS, "Error locking subscriber file");
- close(subfilefd);
- close(sublockfd);
+ log_error(LOG_ARGS, "Could not open '%s/%s/%s'", list->dir, chstr);
myfree(sublockname);
exit(EXIT_FAILURE);
}
address[len] = 0;
close(subfilefd);
close(sublockfd);
- unlink(sublockname);
+ unlinkat(subdirfd, sublockname, 0);
myfree(sublockname);
}