maildir.c
author Sunil Nimmagadda <sunil@nimmagadda.net>
Sun, 31 Aug 2014 16:18:35 +0500
changeset 37 e3dccf824f91
parent 26 b20d78c55e91
permissions -rw-r--r--
Disengaging imsgev is tricky. First imsgev_clear as we know there isn't anything left to be written. Signal imsgev termination by setting iev->terminate = 1(Mind that we are setting it from with the callback). As imsgev would again callback dispatch with IMSGEV_DONE, we cannot free imsgev yet. So iev_maildrop need to exist beyond lifetime of session until IMSGEV_DONE. Allocating it seperately from session. imsgev_close is avoided as it schedules another EV_WRITE which is not needed in our case. This fixes a crash observed consistently with a little perl script to simulate concurrent sessions. Thanks MALLOC_OPTIONS='SFG<<'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     1
/*
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     2
 * Copyright (c) 2014 Sunil Nimmagadda <sunil@nimmagadda.net>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     3
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     4
 * Permission to use, copy, modify, and distribute this software for any
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     5
 * purpose with or without fee is hereby granted, provided that the above
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     6
 * copyright notice and this permission notice appear in all copies.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     7
 *
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    15
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    16
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    17
#include <sys/param.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    18
#include <sys/types.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    19
#include <sys/tree.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    20
#include <sys/stat.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    21
#include <sys/socket.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    22
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    23
#include <fcntl.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    24
#include <dirent.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    25
#include <stdio.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    26
#include <string.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    27
#include <syslog.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    28
#include <unistd.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    29
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    30
#include "pop3d.h"
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    31
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    32
static int init(struct mdrop *, size_t *, size_t *);
10
d1fb040b60d9 Fix clang warnings. offset is always long.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 9
diff changeset
    33
static int retr(struct mdrop *, unsigned int, size_t *, long *);
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    34
static int update(struct mdrop *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    35
static int new_to_cur(struct mdrop *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    36
static int msgcmp(struct msg *, struct msg *);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
RB_PROTOTYPE(msgtree, msg, e.t_entry, msgcmp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    38
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    39
struct m_backend m_backend_maildir = {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    40
	init,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    41
	retr,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    42
	update
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    43
};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    44
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
/*
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
 * No resource management on error path as the process is
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    47
 * killed if an error occurs.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
static int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    50
init(struct mdrop *m, size_t *nmsgs, size_t *sz)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
	SHA1_CTX	ctx;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
	struct stat	sb;
10
d1fb040b60d9 Fix clang warnings. offset is always long.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 9
diff changeset
    54
	u_char		buf[MAXBSIZE];
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    55
	DIR		*dirp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    56
	struct dirent	*dp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    57
	struct msg	*msg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    58
	u_char		*C;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    59
	size_t		i;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    60
	ssize_t		len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    61
	int		cur_fd, msg_fd;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    62
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    63
	*nmsgs = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    64
	*sz = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    65
	if (new_to_cur(m) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    66
		logit(LOG_WARNING, "maildir: move msgs from new to cur failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    67
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    68
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    69
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    70
	if ((cur_fd = openat(m->fd, "cur", O_RDONLY)) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    71
		logit(LOG_CRIT, "maildir: unable to open \"cur\" dir");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    72
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    73
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    74
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    75
	if ((dirp = fdopendir(cur_fd)) == NULL)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    76
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    77
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    78
	while ((dp = readdir(dirp))) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    79
		if (dp->d_type != DT_REG)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    80
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    81
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    82
		if (strcmp(dp->d_name, ".") == 0 ||
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    83
		    strcmp(dp->d_name, "..") == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    84
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    85
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    86
		msg = xcalloc(1, sizeof(*msg), "init");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    87
		if ((msg->u.fname = strdup(dp->d_name)) == NULL)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    88
			fatalx("init: strdup");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    89
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    90
		if (fstatat(cur_fd, dp->d_name, &sb, 0) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    91
			logit(LOG_CRIT, "%s fstatat failed", dp->d_name);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    92
			return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    93
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    94
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    95
		msg->sz = sb.st_size;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    96
		if ((msg_fd = openat(cur_fd, dp->d_name, O_RDONLY)) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    97
			logit(LOG_CRIT, "%s openat failed", dp->d_name);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    98
			return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    99
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   100
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   101
		SHA1Init(&ctx);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   102
		while (( len = read(msg_fd, buf, sizeof(buf))) > 0) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   103
			SHA1Update(&ctx, (u_int8_t *)buf, len);
9
52527e90ed80 Return correct nlines for RETR in maildir handling.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   104
			for (C = buf; len--; ++C)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   105
				if (*C == '\n')
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   106
					msg->nlines += 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   107
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   108
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   109
		SHA1End(&ctx, msg->hash);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   110
		close(msg_fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   111
		RB_INSERT(msgtree, &m->e.t_msgs, msg);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   112
		m->nmsgs += 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   113
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   114
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   115
	/* allocate space for nmsgs of struct msg pointers */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   116
	m->msgs_index = xcalloc(m->nmsgs, sizeof(msg), "init");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   117
	*nmsgs = m->nmsgs;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   118
	i = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   119
	*sz = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   120
	RB_FOREACH(msg, msgtree, &m->e.t_msgs) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   121
		m->msgs_index[i++] = msg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   122
		/* calculate maildir size by counting newline as 2 (CRLF) */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   123
		*sz += msg->sz + msg->nlines;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   124
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   125
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   126
	closedir(dirp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   127
	close(cur_fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   128
	return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   129
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   130
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
static int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   132
new_to_cur(struct mdrop *m)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   133
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   134
	DIR		*dirp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   135
	struct dirent	*dp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   136
	int		cur_fd, new_fd;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   137
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   138
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   139
	if ((cur_fd = openat(m->fd, "cur", O_RDONLY)) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   140
		logit(LOG_CRIT, "maildir: unable to open \"cur\" dir");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   141
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   142
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   143
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   144
	if ((new_fd = openat(m->fd, "new", O_RDONLY)) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   145
		logit(LOG_CRIT, "maildir: unable to open \"new\" dir");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   146
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   147
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   148
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   149
	if ((dirp = fdopendir(new_fd)) == NULL)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   150
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   151
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   152
	while ((dp = readdir(dirp))) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   153
		if (dp->d_type != DT_REG)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   154
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   155
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   156
		if (strcmp(dp->d_name, ".") == 0 ||
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   157
		    strcmp(dp->d_name, "..") == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   158
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   159
26
b20d78c55e91 knf and whitespace fixes.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 10
diff changeset
   160
		if (renameat(new_fd, dp->d_name, cur_fd, dp->d_name) == -1) {
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   161
			logit(LOG_CRIT, "maildir: renameat failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   162
			return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   163
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   164
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   165
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   166
	closedir(dirp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   167
	close(cur_fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   168
	close(new_fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   169
	return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   170
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   171
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   172
static int
10
d1fb040b60d9 Fix clang warnings. offset is always long.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 9
diff changeset
   173
retr(struct mdrop *m, unsigned int idx, size_t *nlines, long *offset)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   174
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   175
	char	buf[MAXPATHLEN];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   176
	int	fd, r;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   177
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   178
	*offset = 0;
9
52527e90ed80 Return correct nlines for RETR in maildir handling.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   179
	*nlines = m->msgs_index[idx]->nlines;
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
	r = snprintf(buf, sizeof(buf), "cur/%s", m->msgs_index[idx]->u.fname);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
	if ((u_int)r >= sizeof(buf)) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
		logit(LOG_WARNING, "path too long");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
	fd = openat(m->fd, buf, O_RDONLY);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
	return (fd);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   188
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   189
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   190
static int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
update(struct mdrop *m)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
	char	buf[MAXPATHLEN];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
	size_t	i, j = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
	int	r;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
	for (i = 0; i < m->nmsgs; i++)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
		if (m->msgs_index[i]->flags & F_DELE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
			j += 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
	if (j == 0) /* nothing to update */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
		return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
	for (i = 0; i < m->nmsgs; i++) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
		if (!(m->msgs_index[i]->flags & F_DELE))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   207
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   208
		r = snprintf(buf, sizeof(buf), "cur/%s",
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   209
		    m->msgs_index[i]->u.fname);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   210
		if ((u_int)r >= sizeof(buf)) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   211
			logit(LOG_WARNING, "path too long");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   212
			return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   213
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   214
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   215
		if (unlinkat(m->fd, buf, 0) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   216
			logit(LOG_CRIT, "%s unlink failed", buf);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   217
			return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   218
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   219
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   220
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   221
	return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   222
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   223
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   224
static int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   225
msgcmp(struct msg *m1, struct msg *m2)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   226
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   227
	return strcmp(m1->u.fname, m2->u.fname);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   228
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   229
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   230
RB_GENERATE(msgtree, msg, e.t_entry, msgcmp);