/* conversations.h -- Routines for dealing with the conversations database
*
* Copyright (c) 1994-2010 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any legal
* details, please contact
* Carnegie Mellon University
* Center for Technology Transfer and Enterprise Creation
* 4615 Forbes Avenue
* Suite 302
* Pittsburgh, PA 15213
* (412) 268-7393, fax: (412) 268-7395
* innovation@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __CYRUS_CONVERSATIONS_H_
#define __CYRUS_CONVERSATIONS_H_ 1
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include "arrayu64.h"
#include "hash.h"
#include "hashu64.h"
#include "message_guid.h"
#include "strarray.h"
#include "util.h"
typedef bit64 conversation_id_t;
#define CONV_FMT "%016llx"
#define NULLCONVERSATION (0ULL)
struct index_record;
struct mailbox;
struct conversations_state {
struct db *db;
struct txn *txn;
strarray_t *counted_flags;
strarray_t *folder_names;
hash_table folderstatus;
char *path;
};
struct conversations_open {
struct conversations_state s;
struct conversations_open *next;
};
typedef struct conversation conversation_t;
typedef struct conv_folder conv_folder_t;
typedef struct conv_sender conv_sender_t;
typedef struct conv_status conv_status_t;
typedef struct conv_guidrec conv_guidrec_t;
typedef struct conv_thread conv_thread_t;
#define MAX_CONVERSATION_FLAGS 256
struct conv_thread {
conv_thread_t *next;
struct message_guid guid;
int exists;
time_t internaldate;
int32_t msgid;
int32_t inreplyto;
};
struct conv_folder {
conv_folder_t *next;
int number;
modseq_t modseq;
uint32_t num_records;
uint32_t exists;
uint32_t unseen;
uint32_t prev_exists;
};
struct conv_guidrec {
const char *mboxname;
uint32_t uid;
const char *part;
conversation_id_t cid;
};
struct conv_sender {
conv_sender_t *next;
char *name;
char *route;
char *mailbox;
char *domain;
time_t lastseen;
uint32_t exists;
};
struct conv_status {
modseq_t modseq;
uint32_t exists;
uint32_t unseen;
};
#define CONV_STATUS_INIT {0, 0, 0}
struct conversation {
modseq_t modseq;
uint32_t num_records;
uint32_t exists;
uint32_t unseen;
uint32_t prev_unseen;
uint32_t size;
uint32_t *counts;
conv_folder_t *folders;
conv_sender_t *senders;
conv_thread_t *thread;
char *subject;
int dirty;
};
#include "mailbox.h"
/* Sets the suffix used for conversations db filenames. Only needed
* when doing special weird stuff like the conversations audit mode */
extern void conversations_set_directory(const char *dir);
extern void conversations_set_suffix(const char *suff);
extern char *conversations_getmboxpath(const char *mboxname);
extern char *conversations_getuserpath(const char *username);
extern int conversations_open_path(const char *path,
struct conversations_state **statep);
extern int conversations_open_user(const char *username,
struct conversations_state **statep);
extern int conversations_open_mbox(const char *mboxname,
struct conversations_state **statep);
extern struct conversations_state *conversations_get_path(const char *path);
extern struct conversations_state *conversations_get_user(const char *username);
extern struct conversations_state *conversations_get_mbox(const char *mboxname);
/* either of these close */
extern int conversations_abort(struct conversations_state **state);
extern int conversations_commit(struct conversations_state **state);
/* functions for CONVDB_MSGID database only */
extern int conversations_add_msgid(struct conversations_state *state,
const char *msgid,
conversation_id_t cid);
extern int conversations_get_msgid(struct conversations_state *state,
const char *msgid,
arrayu64_t *cids);
extern conv_folder_t *conversation_get_folder(conversation_t *conv,
int number, int create_flag);
extern void conversation_normalise_subject(struct buf *);
/* G record */
extern const strarray_t *conversations_get_folders(struct conversations_state *state);
extern int conversations_guid_exists(struct conversations_state *state,
const char *guidrep);
extern int conversations_guid_foreach(struct conversations_state *state,
const char *guidrep,
int(*cb)(const conv_guidrec_t*,void*),
void *rock);
extern conversation_id_t conversations_guid_cid_lookup(struct conversations_state *state,
const char *guidrep);
/* F record items */
extern int conversation_getstatus(struct conversations_state *state,
const char *mboxname,
conv_status_t *status);
extern int conversation_setstatus(struct conversations_state *state,
const char *mboxname,
const conv_status_t *status);
extern int conversation_storestatus(struct conversations_state *state,
const char *key, size_t keylen,
const conv_status_t *status);
extern int conversation_parsestatus(const char *data, size_t datalen,
conv_status_t *status);
/* B record items */
extern int conversation_get_modseq(struct conversations_state *state,
conversation_id_t cid,
modseq_t *modseqp);
extern int conversation_save(struct conversations_state *state,
conversation_id_t cid,
conversation_t *conv);
extern int conversation_load(struct conversations_state *state,
conversation_id_t cid,
conversation_t **convp);
extern int conversation_parse(struct conversations_state *state,
const char *data, size_t datalen,
conversation_t **convp);
extern int conversation_store(struct conversations_state *state,
const char *key, int keylen,
conversation_t *conv);
/* Update the internal data about a conversation, enforcing
* consistency rules (e.g. the conversation's modseq is the
* maximum of all the per-folder modseqs). Sets conv->dirty
* if any data actually changed. */
extern int conversations_update_record(struct conversations_state *cstate,
struct mailbox *mailbox,
const struct index_record *old,
struct index_record *new_);
extern void conversation_update(struct conversations_state *state,
conversation_t *conv,
const char *mboxname,
int delta_num_records,
int delta_exists,
int delta_unseen,
int delta_size,
int *delta_counts,
modseq_t modseq);
extern conv_folder_t *conversation_find_folder(struct conversations_state *state,
conversation_t *,
const char *mboxname);
extern conversation_t *conversation_new(struct conversations_state *state);
extern void conversation_free(conversation_t *);
extern void conversation_update_sender(conversation_t *conv,
const char *name,
const char *route,
const char *mailbox,
const char *domain,
time_t lastseen,
int delta_exists);
extern int conversations_prune(struct conversations_state *state,
time_t thresh, unsigned int *,
unsigned int *);
extern void conversations_dump(struct conversations_state *, FILE *);
extern int conversations_undump(struct conversations_state *, FILE *);
extern int conversations_truncate(struct conversations_state *);
extern const char *conversation_id_encode(conversation_id_t cid);
extern int conversation_id_decode(conversation_id_t *cid, const char *text);
extern int conversations_zero_counts(struct conversations_state *state);
extern int conversations_cleanup_zero(struct conversations_state *state);
extern int conversations_rename_folder(struct conversations_state *state,
const char *from_name,
const char *to_name);
#endif /* __CYRUS_CONVERSATIONS_H_ */