mbox.c
author Sunil Nimmagadda <sunil@nimmagadda.net>
Fri, 05 Sep 2014 08:13:18 +0500
changeset 40 a0c73de318ed
parent 10 d1fb040b60d9
permissions -rw-r--r--
Stop leaking sock descriptors in error path.
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/queue.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    20
#include <sys/socket.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    21
#include <sys/stat.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 <errno.h>
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    24
#include <fcntl.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: 0
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
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    36
struct m_backend m_backend_mbox = {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
	init,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    38
	retr,
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    39
	update
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    40
};
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    41
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    42
/* 
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    43
 * Parse mbox calculating each message's offset, size and hash.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    44
 * A message is identified by "From " at the start of a line.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
 * Returns 0 on success with nmsgs and sz populated.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    47
int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
init(struct mdrop *m, size_t *nmsgs, size_t *sz)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    50
	SHA1_CTX	ctx;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
	FILE		*fp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
	struct msg	*msg = NULL;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
	size_t		i, len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    54
	long		offset;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    55
	char		*line;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    56
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    57
	*nmsgs = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    58
	*sz = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    59
	if (flock(m->fd, LOCK_EX|LOCK_NB) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    60
		switch (errno) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    61
		case EWOULDBLOCK:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    62
			logit(LOG_INFO, "mbox: locked by other process");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    63
			return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    64
		default:
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    65
			fatal("flock(LOCK_EX)");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    66
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    67
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    68
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    69
	if ((fp = fdopen(dup(m->fd), "r+")) == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    70
		logit(LOG_INFO, "mbox: fdopen failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    71
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    72
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    73
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    74
	SIMPLEQ_INIT(&m->e.q_msgs);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    75
	offset = ftell(fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    76
	while ((line = fgetln(fp, &len))) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    77
		if ((len > 5) && strncmp("From ", line, 5) == 0) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    78
			if (msg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    79
				SHA1End(&ctx, msg->hash);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    80
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    81
			msg = xcalloc(1, sizeof(*msg), "init");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    82
			SHA1Init(&ctx);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    83
			msg->u.offset = offset;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    84
			m->nmsgs += 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    85
			SIMPLEQ_INSERT_TAIL(&m->e.q_msgs, msg, e.q_entry);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    86
		} else {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    87
			if (msg == NULL)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    88
				fatalx("mbox corrupted: no \"From \" line");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    89
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    90
			msg->sz += len;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    91
			msg->nlines += 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    92
			SHA1Update(&ctx, (u_int8_t *)line, len);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    93
			offset = ftell(fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    94
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    95
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    96
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    97
	if (msg)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    98
		SHA1End(&ctx, msg->hash);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    99
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   100
	/* allocate space for nmsgs of struct msg pointers */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   101
	m->msgs_index = xcalloc(m->nmsgs, sizeof(msg), "make_index");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   102
	i = 0;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   103
	SIMPLEQ_FOREACH(msg, &m->e.q_msgs, e.q_entry) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   104
		m->msgs_index[i++] = msg;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   105
		/* calculate mbox size by counting newline as 2 (CRLF) */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   106
		m->sz += msg->sz + msg->nlines;
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
	*nmsgs = m->nmsgs;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   110
	*sz = m->sz;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   111
	fclose(fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   112
	return (0);
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
static int
10
d1fb040b60d9 Fix clang warnings. offset is always long.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents: 0
diff changeset
   116
retr(struct mdrop *m, unsigned int idx, size_t *nlines, long *offset)
0
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   117
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   118
	if (m->msgs_index[idx]->flags & F_DELE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   119
		return (-1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   120
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   121
	*offset = m->msgs_index[idx]->u.offset;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   122
	*nlines = m->msgs_index[idx]->nlines;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   123
	return (dup(m->fd)); /* imsg closes sender's fd */
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
/* 
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   127
 * No resource management as this process is blown away
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   128
 * upon success or error.
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   129
 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   130
static int
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
update(struct mdrop *m)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   132
{
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   133
	struct msg	*cur;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   134
	size_t		i, j = 0, len, nlines;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   135
	char		buf[MAXBSIZE], fn[22], *line;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   136
	FILE		*tmp_fp, *m_fp;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   137
	mode_t		old_mask;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   138
	int		tmp_fd;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   139
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   140
	for (i = 0; i < m->nmsgs; i++)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   141
		if (m->msgs_index[i]->flags & F_DELE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   142
			j += 1;
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 ((m_fp = fdopen(dup(m->fd), "r+")) == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   145
		logit(LOG_INFO, "mbox: fdopen failed");
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 (j == 0)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   150
		return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   151
	else if (j == m->nmsgs) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   152
		if (ftruncate(fileno(m_fp), 0) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   153
			logit(LOG_CRIT, "update: ftruncate failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   154
			return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   155
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   156
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   157
		return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   158
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   159
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   160
	strlcpy(fn, "/tmp/pop3d.XXXXXXXXXX", sizeof(fn));
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   161
	old_mask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   162
	if ((tmp_fd = mkstemp(fn)) == -1 ||
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   163
	    (tmp_fp = fdopen(tmp_fd, "r+")) == NULL) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   164
		logit(LOG_CRIT, "mbox: mkstemp failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   165
		return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   166
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   167
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   168
	umask(old_mask);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   169
	for (i = 0; i < m->nmsgs; i++) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   170
		cur = m->msgs_index[i];
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   171
		if (cur->flags & F_DELE)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   172
			continue;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   173
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   174
		if (fseek(m_fp, cur->u.offset, SEEK_SET) == -1) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   175
			logit(LOG_CRIT, "update: fseek failed");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   176
			return (1);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   177
		}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   178
		/*
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   179
		 * "From " line isn't counted in nlines but offset starts
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
		 * there, adjust nlines here 
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
		 */
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
		nlines = m->msgs_index[i]->nlines + 1;
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
		while (nlines--) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
			if ((line = fgetln(m_fp, &len)))
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
				if (fwrite(line, len, 1, tmp_fp) != 1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
					fatalx("update: short write");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
		}
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
	fflush(tmp_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
	rewind(m_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
	rewind(tmp_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
	while (!feof(tmp_fp)) {
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
		fread(buf, sizeof(buf), 1, tmp_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
		if (fwrite(buf, sizeof(buf), 1, m_fp) != 1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
			fatalx("update: short write");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
	}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
	fflush(m_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
	if (ftruncate(fileno(m_fp), ftello(tmp_fp)) == -1)
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
		fatal("update: failed to truncate");
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
	fclose(m_fp);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
	return (0);
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
}
9e2cb1ed20b1 Import pop3d.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206