X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/1a63734f7ddbd2d487c9c69705997efddcde94f9..14dfb9912037c6e7f0ddb9ef1cd77d5e14246639:/libexec/dma/spool.c diff --git a/libexec/dma/spool.c b/libexec/dma/spool.c index f5a9d790ee..416b5fa8f0 100644 --- a/libexec/dma/spool.c +++ b/libexec/dma/spool.c @@ -32,6 +32,9 @@ * SUCH DAMAGE. */ +#include "dfcompat.h" + +#include #include #include @@ -120,9 +123,11 @@ writequeuef(struct qitem *it) int error; int queuefd; - queuefd = open_locked(it->queuefn, O_CREAT|O_EXCL|O_RDWR, 0600); + queuefd = open_locked(it->queuefn, O_CREAT|O_EXCL|O_RDWR, 0660); if (queuefd == -1) return (-1); + if (fchmod(queuefd, 0660) < 0) + return (-1); it->queuef = fdopen(queuefd, "w+"); if (it->queuef == NULL) return (-1); @@ -279,7 +284,7 @@ load_queue(struct queue *queue) char *queuefn; char *mailfn; - bzero(queue, sizeof(queue)); + bzero(queue, sizeof(*queue)); LIST_INIT(&queue->queue); spooldir = opendir(config.spooldir); @@ -290,9 +295,7 @@ load_queue(struct queue *queue) queuefn = NULL; mailfn = NULL; - /* ignore temp files */ - if (strncmp(de->d_name, "tmp_", 4) == 0 || de->d_type != DT_REG) - continue; + /* ignore non-queue files */ if (de->d_name[0] != 'Q') continue; if (asprintf(&queuefn, "%s/Q%s", config.spooldir, de->d_name + 1) < 0) @@ -300,6 +303,18 @@ load_queue(struct queue *queue) if (asprintf(&mailfn, "%s/M%s", config.spooldir, de->d_name + 1) < 0) goto fail; + /* + * Some file systems don't provide a de->d_type, so we have to + * do an explicit stat on the queue file. + * Move on if it turns out to be something else than a file. + */ + if (stat(queuefn, &sb) != 0) + goto skip_item; + if (!S_ISREG(sb.st_mode)) { + errno = EINVAL; + goto skip_item; + } + if (stat(mailfn, &sb) != 0) goto skip_item; @@ -359,6 +374,8 @@ acquirespool(struct qitem *it) return (0); fail: + if (errno == EWOULDBLOCK) + return (1); syslog(LOG_INFO, "could not acquire queue file: %m"); return (-1); } @@ -378,3 +395,46 @@ dropspool(struct queue *queue, struct qitem *keep) fclose(it->mailf); } } + +int +flushqueue_since(unsigned int period) +{ + struct stat st; + struct timeval now; + char *flushfn = NULL; + + if (asprintf(&flushfn, "%s/%s", config.spooldir, SPOOL_FLUSHFILE) < 0) + return (0); + if (stat(flushfn, &st) < 0) { + free(flushfn); + return (0); + } + free(flushfn); + flushfn = NULL; + if (gettimeofday(&now, 0) != 0) + return (0); + + /* Did the flush file get touched within the last period seconds? */ + if (st.st_mtim.tv_sec + period >= now.tv_sec) + return (1); + else + return (0); +} + +int +flushqueue_signal(void) +{ + char *flushfn = NULL; + int fd; + + if (asprintf(&flushfn, "%s/%s", config.spooldir, SPOOL_FLUSHFILE) < 0) + return (-1); + fd = open(flushfn, O_CREAT|O_WRONLY|O_TRUNC, 0660); + free(flushfn); + if (fd < 0) { + syslog(LOG_ERR, "could not open flush file: %m"); + return (-1); + } + close(fd); + return (0); +}