379 lines
6.5 KiB
C
379 lines
6.5 KiB
C
|
/*
|
||
|
* mailbox and message representations
|
||
|
*
|
||
|
* these structures are allocated with emalloc and must be explicitly freed
|
||
|
*/
|
||
|
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;
|
||
|
|
||
|
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 */
|
||
|
MboxNameLen = 256, /* max. length of upas/fs mbox name */
|
||
|
MsgNameLen = 32, /* max. length of a file in a upas/fs mbox */
|
||
|
UserNameLen = 64, /* max. length of user's name */
|
||
|
|
||
|
MUtf7Max = 6, /* max length for a modified utf7 character: &bbbb- */
|
||
|
|
||
|
/*
|
||
|
* message flags
|
||
|
*/
|
||
|
MSeen = 1 << 0,
|
||
|
MAnswered = 1 << 1,
|
||
|
MFlagged = 1 << 2,
|
||
|
MDeleted = 1 << 3,
|
||
|
MDraft = 1 << 4,
|
||
|
MRecent = 1 << 5,
|
||
|
|
||
|
/*
|
||
|
* message bogus flags
|
||
|
*/
|
||
|
NotBogus = 0, /* the message is displayable */
|
||
|
BogusHeader = 1, /* the header had bad characters */
|
||
|
BogusBody = 2, /* the body had bad characters */
|
||
|
BogusTried = 4, /* attempted to open the fake message */
|
||
|
};
|
||
|
|
||
|
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 */
|
||
|
ulong max; /* maximum msgs->seq, same as number of messages */
|
||
|
ulong toldMax; /* last value sent to client */
|
||
|
ulong recent; /* number of recently received messaged */
|
||
|
ulong toldRecent; /* last value sent to client */
|
||
|
ulong uidnext; /* next uid value assigned to a message */
|
||
|
ulong uidvalidity; /* uid of mailbox */
|
||
|
Msg *msgs;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* fields of Msg->info
|
||
|
*/
|
||
|
enum
|
||
|
{
|
||
|
/*
|
||
|
* read from upasfs
|
||
|
*/
|
||
|
IFrom,
|
||
|
ITo,
|
||
|
ICc,
|
||
|
IReplyTo,
|
||
|
IUnixDate,
|
||
|
ISubject,
|
||
|
IType,
|
||
|
IDisposition,
|
||
|
IFilename,
|
||
|
IDigest,
|
||
|
IBcc,
|
||
|
IInReplyTo, /* aka internal date */
|
||
|
IDate,
|
||
|
ISender,
|
||
|
IMessageId,
|
||
|
ILines, /* number of lines of raw body */
|
||
|
|
||
|
IMax
|
||
|
};
|
||
|
|
||
|
struct Header
|
||
|
{
|
||
|
char *buf; /* header, including terminating \r\n */
|
||
|
ulong size; /* strlen(buf) */
|
||
|
ulong 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 *prev;
|
||
|
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? */
|
||
|
uchar bogus; /* implies the message is invalid, ie contains nulls; see flags above */
|
||
|
ulong uid; /* imap unique identifier */
|
||
|
ulong seq; /* position in box; 1 is oldest */
|
||
|
ulong 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 */
|
||
|
|
||
|
ulong size; /* size of fs/rawbody, in bytes, with \r added before \n */
|
||
|
ulong 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;
|
||
|
ulong num;
|
||
|
int year;
|
||
|
int mon;
|
||
|
int mday;
|
||
|
MsgSet *set;
|
||
|
Search *left;
|
||
|
Search *right;
|
||
|
Search *next;
|
||
|
};
|
||
|
|
||
|
struct NList
|
||
|
{
|
||
|
ulong n;
|
||
|
NList *next;
|
||
|
};
|
||
|
|
||
|
struct SList
|
||
|
{
|
||
|
char *s;
|
||
|
SList *next;
|
||
|
};
|
||
|
|
||
|
struct MsgSet
|
||
|
{
|
||
|
ulong from;
|
||
|
ulong to;
|
||
|
MsgSet *next;
|
||
|
};
|
||
|
|
||
|
struct Pair
|
||
|
{
|
||
|
ulong start;
|
||
|
ulong stop;
|
||
|
};
|
||
|
|
||
|
#include "bin.h"
|
||
|
|
||
|
extern Bin *parseBin;
|
||
|
extern Biobuf bout;
|
||
|
extern Biobuf bin;
|
||
|
extern char username[UserNameLen];
|
||
|
extern char mboxDir[MboxNameLen];
|
||
|
extern char *fetchPartNames[FPMax];
|
||
|
extern char *site;
|
||
|
extern char *remote;
|
||
|
extern int debug;
|
||
|
|
||
|
#include "fns.h"
|