/*
* mailbox and message representations
*
* these structures are allocated with emalloc and must be explicitly freed
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <auth.h>
#include <avl.h>
#include <bin.h>
typedef struct Box Box;
typedef struct Header Header;
typedef struct Maddr Maddr;
typedef struct Mblock Mblock;
typedef struct Mimehdr Mimehdr;
typedef struct Msg Msg;
typedef struct Namedint Namedint;
typedef struct Pair Pair;
typedef struct Uidplus Uidplus;
enum
{
Stralloc = 32, /* characters allocated at a time */
Bufsize = 8*1024, /* size of transfer block */
Ndigest = 40, /* length of digest string */
Nuid = 10, /* length of .imp uid string */
Nflags = 8, /* length of .imp flag string */
Locksecs = 5 * 60, /* seconds to wait for acquiring a locked file */
Pathlen = 256, /* max. length of upas/fs mbox name */
Filelen = 32, /* max. length of a file in a upas/fs mbox */
Userlen = 64, /* max. length of user's name */
Mutf7max = 6, /* max bytes for a mutf7 character: &bbbb- */
/*
* message flags
*/
Fseen = 1 << 0,
Fanswered = 1 << 1,
Fflagged = 1 << 2,
Fdeleted = 1 << 3,
Fdraft = 1 << 4,
Frecent = 1 << 5,
};
typedef struct Fstree Fstree;
struct Fstree {
Avl;
Msg *m;
};
struct Box
{
char *name; /* path name of mailbox */
char *fs; /* fs name of mailbox */
char *fsdir; /* /mail/fs/box->fs */
char *imp; /* path name of .imp file */
uchar writable; /* can write back messages? */
uchar dirtyimp; /* .imp file needs to be written? */
uchar sendflags; /* need flags update */
Qid qid; /* qid of fs mailbox */
Qid impqid; /* qid of .imp when last synched */
long mtime; /* file mtime when last read */
uint max; /* maximum msgs->seq, same as number of messages */
uint toldmax; /* last value sent to client */
uint recent; /* number of recently received messaged */
uint toldrecent; /* last value sent to client */
uint uidnext; /* next uid value assigned to a message */
uint uidvalidity; /* uid of mailbox */
Msg *msgs; /* msgs in uid order */
Avltree *fstree; /* msgs in upas/fs order */
};
/*
* fields of Msg->info
*/
enum
{
/*
* read from upasfs
*/
Ifrom,
Ito,
Icc,
Ireplyto,
Iunixdate,
Isubject,
Itype,
Idisposition,
Ifilename,
Idigest,
Ibcc,
Iinreplyto,
Idate,
Isender,
Imessageid,
Ilines, /* number of lines of raw body */
Isize,
// Iflags,
// Idatesec
Imax
};
struct Header
{
char *buf; /* header, including terminating \r\n */
uint size; /* strlen(buf) */
uint lines; /* number of \n characters in buf */
/*
* pre-parsed mime headers
*/
Mimehdr *type; /* content-type */
Mimehdr *id; /* content-id */
Mimehdr *description; /* content-description */
Mimehdr *encoding; /* content-transfer-encoding */
// Mimehdr *md5; /* content-md5 */
Mimehdr *disposition; /* content-disposition */
Mimehdr *language; /* content-language */
};
struct Msg
{
Msg *next;
Msg *kids;
Msg *parent;
char *fsdir; /* box->fsdir of enclosing message */
Header head; /* message header */
Header mime; /* mime header from enclosing multipart spec */
int flags;
uchar sendflags; /* flags value needs to be sent to client */
uchar expunged; /* message actually expunged, but not yet reported to client */
uchar matched; /* search succeeded? */
uint uid; /* imap unique identifier */
uint seq; /* position in box; 1 is oldest */
uint id; /* number of message directory in upas/fs */
char *fs; /* name of message directory */
char *efs; /* pointer after / in fs; enough space for file name */
uint size; /* size of fs/rawbody, in bytes, with \r added before \n */
uint lines; /* number of lines in rawbody */
char *ibuf;
char *info[Imax]; /* all info about message */
char *unixdate;
Maddr *unixfrom;
Maddr *to; /* parsed out address lines */
Maddr *from;
Maddr *replyto;
Maddr *sender;
Maddr *cc;
Maddr *bcc;
};
/*
* pre-parsed header lines
*/
struct Maddr
{
char *personal;
char *box;
char *host;
Maddr *next;
};
struct Mimehdr
{
char *s;
char *t;
Mimehdr *next;
};
/*
* mapping of integer & names
*/
struct Namedint
{
char *name;
int v;
};
/*
* lock for all mail file operations
*/
struct Mblock
{
int fd;
};
/*
* parse nodes for imap4rev1 protocol
*
* important: all of these items are allocated
* in one can, so they can be tossed out at the same time.
* this allows leakless parse error recovery by simply tossing the can away.
* however, it means these structures cannot be mixed with the mailbox structures
*/
typedef struct Fetch Fetch;
typedef struct Nlist Nlist;
typedef struct Slist Slist;
typedef struct Msgset Msgset;
typedef struct Store Store;
typedef struct Search Search;
/*
* parse tree for fetch command
*/
enum
{
Fenvelope,
Fflags,
Finternaldate,
Frfc822,
Frfc822head,
Frfc822size,
Frfc822text,
Fbodystruct,
Fuid,
Fbody, /* BODY */
Fbodysect, /* BODY [...] */
Fbodypeek,
Fmax
};
enum
{
FPall,
FPhead,
FPheadfields,
FPheadfieldsnot,
FPmime,
FPtext,
FPmax
};
struct Fetch
{
uchar op; /* F.* operator */
uchar part; /* FP.* subpart for body[] & body.peek[]*/
uchar partial; /* partial fetch? */
long start; /* partial fetch amounts */
long size;
Nlist *sect;
Slist *hdrs;
Fetch *next;
};
/*
* status items
*/
enum{
Smessages = 1 << 0,
Srecent = 1 << 1,
Suidnext = 1 << 2,
Suidvalidity = 1 << 3,
Sunseen = 1 << 4,
};
/*
* parse tree for store command
*/
enum
{
Stflags,
Stflagssilent,
Stmax
};
struct Store
{
uchar sign;
uchar op;
int flags;
};
/*
* parse tree for search command
*/
enum
{
SKnone,
SKcharset,
SKall,
SKanswered,
SKbcc,
SKbefore,
SKbody,
SKcc,
SKdeleted,
SKdraft,
SKflagged,
SKfrom,
SKheader,
SKkeyword,
SKlarger,
SKnew,
SKnot,
SKold,
SKon,
SKor,
SKrecent,
SKseen,
SKsentbefore,
SKsenton,
SKsentsince,
SKset,
SKsince,
SKsmaller,
SKsubject,
SKtext,
SKto,
SKuid,
SKunanswered,
SKundeleted,
SKundraft,
SKunflagged,
SKunkeyword,
SKunseen,
SKmax
};
struct Search
{
int key;
char *s;
char *hdr;
uint num;
int year;
int mon;
int mday;
Msgset *set;
Search *left;
Search *right;
Search *next;
};
struct Nlist
{
uint n;
Nlist *next;
};
struct Slist
{
char *s;
Slist *next;
};
struct Msgset
{
uint from;
uint to;
Msgset *next;
};
struct Pair
{
uint start;
uint stop;
};
struct Uidplus
{
uint uid;
uint uidvalidity;
Uidplus *next;
};
extern Bin *parsebin;
extern Biobuf bout;
extern Biobuf bin;
extern char username[Userlen];
extern char mboxdir[Pathlen];
extern char *fetchpartnames[FPmax];
extern char *binupas;
extern char *site;
extern char *remote;
extern int debug;
extern char logfile[28];
extern Uidplus *uidlist;
extern Uidplus **uidtl;
#include "fns.h"
|