mbox-index.c revision b37634f5bf23ff8c72b88ef6966fd5c730017419
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "buffer.h"
#include "istream.h"
#include "mbox-index.h"
#include "mbox-lock.h"
#include "mail-index-util.h"
#include "mail-custom-flags.h"
#include "mail-cache.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
/* Don't try reading more custom flags than this. */
#define MAX_CUSTOM_FLAGS 1024
extern struct mail_index mbox_index;
{
return FALSE;
}
{
int fd;
if (fd == -1) {
return FALSE;
}
return FALSE;
}
return TRUE;
}
enum mail_lock_type lock_type)
{
switch (lock_type) {
case MAIL_LOCK_SHARED:
case MAIL_LOCK_EXCLUSIVE:
/* don't drop exclusive lock, it may be there for a reason */
return NULL;
}
break;
default:
if (!mbox_file_open(index))
return NULL;
}
break;
}
if (index->mail_read_mmaped) {
index->mbox_stream =
0, 0, FALSE);
} else {
return NULL;
}
index->mbox_stream =
FALSE);
}
}
return index->mbox_stream;
}
{
}
}
{
i_error("close(mbox) failed: %m");
}
}
struct mail_index *index,
{
}
static enum mail_flags
{
enum mail_flags flags;
size_t i;
flags = 0;
for (i = 0; i < len; i++) {
switch (value[i]) {
case 'A':
flags |= MAIL_ANSWERED;
break;
case 'F':
flags |= MAIL_FLAGGED;
break;
case 'D':
flags |= MAIL_DRAFT;
break;
case 'R':
break;
case 'T':
flags |= MAIL_DELETED;
break;
}
}
return flags;
}
{
if (index >= 0)
}
static enum mail_flags
const char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT])
{
enum mail_flags flags;
flags = 0;
return flags;
}
struct mbox_header_context *ctx)
{
char *end;
enum mail_flags flags;
unsigned int count;
int ret;
t_push();
/* <uid validity> <last uid> */
pos++;
t_pop();
return;
}
/* we're at the 3rd field now, which begins the list of custom flags */
sizeof(const char *),
MAX_CUSTOM_FLAGS * sizeof(const char *));
sizeof(flag)) == 0)
break;
}
break;
}
}
t_pop();
}
{
size_t i;
/* End of headers */
if (!ctx->set_read_limit)
return;
/* a) use Content-Length, b) search for "From "-line */
}
}
return;
}
return;
/* Pretty much copy&pasted from popa3d by Solar Designer */
case 'R':
case 'r':
/* get only the first received-header */
}
break;
case 'C':
case 'c':
if (ctx->set_read_limit &&
/* manual parsing, so we can deal with uoff_t */
ctx->content_length = 0;
/* invalid */
ctx->content_length = 0;
break;
}
}
}
break;
case 'D':
case 'd':
/* Received-header contains date too,
and more trusted one */
}
break;
case 'M':
case 'm':
/* Received-header contains unique ID too,
and more trusted one */
}
break;
case 'S':
case 's':
/* update message flags */
}
break;
case 'X':
case 'x':
/* Let the local delivery agent help generate unique
ID's but don't blindly trust this header alone as
it could just as easily come from the remote. */
break;
}
/* update message flags */
/* update custom message flags */
ctx->custom_flags);
break;
}
}
break;
}
if (fixed)
}
const char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT],
int, void *),
void *context)
{
int i;
/* the value is often empty, so check that first */
value++;
len--;
}
if (len == 0)
return;
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
strlen(custom_flags[i]) : 0;
}
for (;;) {
/* skip whitespace */
value++;
len--;
}
if (len == 0)
break;
/* find the length of the item */
break;
}
/* check if it's found */
for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
if (custom_len[i] == item_len &&
break;
}
if (i == MAIL_CUSTOM_FLAGS_COUNT)
i = -1;
}
}
{
const unsigned char *data;
pos = 0;
if (pos == 0) {
if (data[0] == '\n') {
return TRUE;
}
if (data[0] != '\r')
return FALSE;
pos++;
}
return FALSE;
return TRUE;
}
}
/* end of file */
return TRUE;
}
{
const unsigned char *data;
/* skip empty lines at beginning */
for (i = 0; i < size; i++) {
break;
}
i_stream_skip(input, i);
if (i < size)
break;
}
}
{
const unsigned char *msg;
i = startpos;
for (; i < size; i++) {
if (msg[i] == '\n') {
i -= startpos;
(time_t)-1;
}
}
}
return FALSE;
}
{
const unsigned char *msg;
/* read until "[\r]\nFrom " is found. assume '\n' at beginning of
buffer */
state = '\n';
new_state = 0;
switch (state) {
case '\n':
if (msg[i] == 'F')
new_state = 'F';
else if (header) {
if (msg[i] == '\n') {
/* \n\n, but if we have
0-byte message body the
following \n may belong
to "From "-line */
eoh = i+1;
new_state = '\n';
} else if (msg[i] == '\r') {
/* possibly \n\r\n */
new_state = '\r';
}
}
break;
case '\r':
if (msg[i] == '\n') {
/* \n\r\n */
eoh = i+1;
new_state = '\n';
}
break;
case 'F':
if (msg[i] == 'r')
new_state = 'r';
break;
case 'r':
if (msg[i] == 'o')
new_state = 'o';
break;
case 'o':
if (msg[i] == 'm')
new_state = 'm';
break;
case 'm':
if (msg[i] == ' ') {
int valid;
/* we may have trashed msg above,
get it again */
if (valid) {
/* Go back "From" */
i -= 4;
/* Go back \n, unless we're at
beginning of buffer */
if (i > 0)
i--;
/* Go back \r if it's there */
i--;
i_stream_skip(input, i);
return;
}
}
break;
}
if (new_state != 0)
else if (eoh == 0)
else {
/* end of header position confirmed */
return;
}
}
/* Leave enough space to go back "\r\nFrom" plus one for the
end-of-headers check */
i -= startpos;
if (eoh != 0) {
eoh -= i;
}
i_stream_skip(input, i);
}
if (eoh != 0) {
/* make sure we didn't end with \n\n or \n\r\n. In these
cases the last [\r]\n doesn't belong to our message. */
return;
}
}
/* end of file, leave the last [\r]\n */
startpos--;
startpos--;
}
}
{
}
{
}
{
const unsigned char *data;
/* missing data */
return FALSE;
}
/* end of file. a bit unexpected though,
since \n is missing. */
return TRUE;
}
/* read forward a bit */
return FALSE;
/* either there should be the next From-line,
or [\r]\n at end of file */
}
if (size > 0) {
if (data[0] != '\n')
return FALSE;
}
return size == 0 ||
}
struct mail_index_record *rec,
{
"Missing location field for record %u",
return FALSE;
}
}
return FALSE;
}
}
sizeof(*body_size))) {
return FALSE;
}
}
return TRUE;
}
struct mail_index *
const char *control_dir)
{
struct mail_index *index;
return index;
}
{
}
enum mail_lock_type lock_type)
{
if (lock_type == MAIL_LOCK_UNLOCK)
(void)mbox_unlock(index);
}
enum mail_lock_type lock_type)
{
if (lock_type == MAIL_LOCK_UNLOCK)
(void)mbox_unlock(index);
}
struct mail_index_record *first_rec,
struct mail_index_record *last_rec,
int external_change)
{
return FALSE;
if (first_seq == 1) {
/* Our message containing X-IMAPbase was deleted.
Get it back there. */
}
return TRUE;
}
struct mail_index_record *rec,
unsigned int seq,
enum modify_type modify_type,
enum mail_flags flags,
int external_change)
{
return FALSE;
if (!external_change) {
/* we'll just mark the message as dirty */
if ((index_flags & MAIL_INDEX_FLAG_DIRTY) == 0) {
return FALSE;
}
}
return TRUE;
}
{
/* update last_uid in X-IMAPbase */
return mail_index_append(index);
}
struct mail_index_record *rec)
{
return date;
return (time_t)-1;
}
struct mail_index mbox_index = {
};