]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/upas/fs/dat.h
upas/fs: fix more locking bugs, remove debugging clutter, remove planb mbox code
[plan9front.git] / sys / src / cmd / upas / fs / dat.h
index 4a1a4b49876d7cae71c1e75a50612a765e4ee290..bd81ad7d397f3592bb3046778bc661edcd6b3a25 100644 (file)
-typedef struct Message Message;
-struct Message
-{
-       int     id;
-       int     refs;
-       int     subname;
-       char    name[Elemlen];
+#include <avl.h>
 
-       // pointers into message
-       char    *start;         // start of message
-       char    *end;           // end of message
-       char    *header;        // start of header
-       char    *hend;          // end of header
-       int     hlen;           // length of header minus ignored fields
-       char    *mheader;       // start of mime header
-       char    *mhend;         // end of mime header
-       char    *body;          // start of body
-       char    *bend;          // end of body
-       char    *rbody;         // raw (unprocessed) body
-       char    *rbend;         // end of raw (unprocessed) body
-       char    *lim;
-       char    deleted;
-       char    inmbox;
-       char    mallocd;        // message is malloc'd
-       char    ballocd;        // body is malloc'd
-       char    hallocd;        // header is malloce'd
-
-       // mail info
-       String  *unixheader;
-       String  *unixfrom;
-       String  *unixdate;
-       String  *from822;
-       String  *sender822;
-       String  *to822;
-       String  *bcc822;
-       String  *cc822;
-       String  *replyto822;
-       String  *date822;
-       String  *inreplyto822;
-       String  *subject822;
-       String  *messageid822;
-       String  *addrs;
-       String  *mimeversion;
-       String  *sdigest;
-
-       // mime info
-       String  *boundary;
-       String  *type;
-       int     encoding;
-       int     disposition;
-       String  *charset;
-       String  *filename;
-       int     converted;
-       int     decoded;
-       char    lines[10];      // number of lines in rawbody
-
-       Message *next;          // same level
-       Message *part;          // down a level
-       Message *whole;         // up a level
-
-       uchar   digest[SHA1dlen];
-
-       vlong   imapuid;        // used by imap4
-
-       char            uidl[80];       // used by pop3
-       int             mesgno;
-};
+enum {
+       /* cache states */
+       Cidx            = 1<<0,
+       Cidxstale       = 1<<1,
+       Cheader         = 1<<2,
+       Cbody           = 1<<3,
 
-enum
-{
-       // encodings
+       /* encodings */
        Enone=  0,
        Ebase64,
        Equoted,
 
-       // disposition possibilities
+       /* dispositions */
        Dnone=  0,
        Dinline,
        Dfile,
        Dignore,
 
-       PAD64=  '=',
+       /* mb create flags */
+       DMcreate        =  0x02000000,
+
+       /* rm flags */
+       Rrecur          = 1<<0,
+       Rtrunc          = 1<<1,
+
+       /* m->deleted flags */
+       Deleted         = 1<<0,
+       Dup             = 1<<1,
+       Dead            = 1<<2,
+       Disappear       = 1<<3,
+       Dmark           = 1<<4, /* temporary mark for idx scan */
+
+       /* mime flags */
+       Mtrunc          = 1<<0, /* message had no boundary */
+
+       Maxmsg          = 75*1024*1024, /* maxmessage size; debugging */
+       Maxcache        = 512*1024,     /* target cache size; set low for debugging */
+       Nctab           = 15,           /* max # of cached messages >10 */
+       Nref            = 10,
+};
+
+typedef struct Idx Idx;
+struct Idx {
+       char    *str;                   /* as read from idx file */
+       uchar   *digest;
+       uchar   flags;
+       uvlong  fileid;
+       ulong   lines;
+       ulong   size;
+       ulong   rawbsize;                       /* nasty imap4d */
+       ulong   ibadchars;
+
+       char    *ffrom;
+       char    *from;
+       char    *to;
+       char    *cc;
+       char    *bcc;
+       char    *replyto;
+       char    *messageid;
+       char    *subject;
+       char    *sender;
+       char    *inreplyto;
+       char    *idxaux;                        /* mailbox specific */
+
+       int     type;                   /* very few types: refstring */
+       int     disposition;            /* very few types: refstring */
+       int     nparts;
+};
+
+typedef struct Message Message;
+struct Message {
+       int     id;
+       int     refs;
+       int     subname;
+       char    name[12];
+
+       /* top-level indexed information */
+       Idx;
+
+       /* caching help */
+       uchar   cstate;
+       ulong   infolen;
+       ulong   csize;
+
+       /*
+        * a plethoria of pointers into message
+        * and some status.  not valid unless cached
+        */
+       char    *start;         /* start of message */
+       char    *end;           /* end of message */
+       char    *header;                /* start of header */
+       char    *hend;          /* end of header */
+       int     hlen;           /* length of header minus ignored fields */
+       char    *mheader;       /* start of mime header */
+       char    *mhend;         /* end of mime header */
+       char    *body;          /* start of body */
+       char    *bend;          /* end of body */
+       char    *rbody;         /* raw (unprocessed) body */
+       char    *rbend;         /* end of raw (unprocessed) body */
+       char    mallocd;                /* message is malloc'd */
+       char    ballocd;                /* body is malloc'd */
+       char    hallocd;                /* header is malloc'd */
+       int     badchars;       /* running count of bad chars. */
+
+       char    deleted;
+       char    inmbox;
+
+       /* mail info */
+       char    *unixheader;
+       char    *unixfrom;
+       char    *date822;
+       char    *references[Nref];
+
+       /* mime info */
+       char    *boundary;
+       int     charset;
+       char    *filename;
+       char    encoding;
+       char    converted;
+       char    decoded;
+       char    mimeflag;
+
+       Message *next;
+       Message *part;
+       Message *whole;
+
+       union{
+               char    *lim;   /* used by plan9; not compatable with cache */
+               vlong   imapuid;        /* used by imap4 */
+               void    *aux;
+       };
+};
+
+typedef struct {
+       Avl;
+       Message *m;
+} Mtree;
+
+typedef struct Mcache Mcache;
+struct Mcache {
+       uvlong  cached;
+       int     ntab;
+       Message *ctab[Nctab];
 };
 
 typedef struct Mailbox Mailbox;
-struct Mailbox
-{
+struct Mailbox {
        QLock;
+       long    idxsem;         /* abort on concurrent index access */
        int     refs;
        Mailbox *next;
        int     id;
-       int     dolock;         // lock when syncing?
-       int     std;
+       int     flags;
+       char    rmflags;
+       char    dolock;         /* lock when syncing? */
+       char    addfrom;
        char    name[Elemlen];
        char    path[Pathlen];
        Dir     *d;
        Message *root;
-       int     vers;           // goes up each time mailbox is read
+       Avltree *mtree;
+       ulong   vers;           /* goes up each time mailbox is changed */
 
-       ulong waketime;
-       char    *(*sync)(Mailbox*, int);
+       /* cache tracking */
+       Mcache;
+
+       /* index tracking */
+       Qid     qid;
+
+       ulong   waketime;
        void    (*close)(Mailbox*);
-       char    *(*fetch)(Mailbox*, Message*);
+       void    (*decache)(Mailbox*, Message*);
+       int     (*fetch)(Mailbox*, Message*, uvlong, ulong);
+       void    (*delete)(Mailbox*, Message*);
        char    *(*ctl)(Mailbox*, int, char**);
-       void    *aux;           // private to Mailbox implementation
+       char    *(*remove)(Mailbox *, int);
+       char    *(*rename)(Mailbox*, char*, int);
+       char    *(*sync)(Mailbox*, int, int*);
+       void    (*modflags)(Mailbox*, Message*, int);
+       void    (*idxwrite)(Biobuf*, Mailbox*);
+       int     (*idxread)(char*, Mailbox*);
+       void    (*idxinvalid)(Mailbox*);
+       void    *aux;           /* private to Mailbox implementation */
 };
 
+/* print argument tango; can't varargck 2 types.  should fix compiler */
+typedef struct Mpair Mpair;
+struct Mpair {
+       Mailbox *mb;
+       Message *m;
+};
+Mpair mpair(Mailbox*, Message*);
+
 typedef char *Mailboxinit(Mailbox*, char*);
 
-extern Message *root;
-extern Mailboxinit     plan9mbox;
-extern Mailboxinit     pop3mbox;
-extern Mailboxinit     imap4mbox;
-extern Mailboxinit     planbmbox;
-extern Mailboxinit     planbvmbox;
+Mailboxinit    plan9mbox;
+Mailboxinit    planbmbox;
+Mailboxinit    pop3mbox;
+Mailboxinit    imap4mbox;
+Mailboxinit    mdirmbox;
+
+void           genericidxwrite(Biobuf*, Mailbox*);
+int            genericidxread(char*, Mailbox*);
+void           genericidxinvalid(Mailbox*);
+
+void           cachehash(Mailbox*, Message*);
+void           newcachehash(Mailbox*, Message*, int);
+int            cacheheaders(Mailbox*, Message*);               /* "getcache" */
+int            cachebody(Mailbox*, Message*);
+int            cacheidx(Mailbox*, Message*);
+int            insurecache(Mailbox*, Message*);
 
+/**/
+void           putcache(Mailbox*, Message*);           /* asymmetricial */
+long           cachefree(Mailbox*, Message*, int);
+
+Message*       gettopmsg(Mailbox*, Message*);
 char*          syncmbox(Mailbox*, int);
-char*          geterrstr(void);
 void*          emalloc(ulong);
 void*          erealloc(void*, ulong);
 Message*       newmessage(Message*);
+void           unnewmessage(Mailbox*, Message*, Message*);
 void           delmessage(Mailbox*, Message*);
-void           delmessages(int, char**);
+char*          delmessages(int, char**);
+char           *flagmessages(int, char**);
+void           digestmessage(Mailbox*, Message*);
+
+uintptr                absbos(void);
+void           eprint(char*, ...);
+void           iprint(char *, ...);
 int            newid(void);
 void           mailplumb(Mailbox*, Message*, int);
-char*          newmbox(char*, char*, int);
+char*          newmbox(char*, char*, int, Mailbox**);
 void           freembox(char*);
-void           logmsg(char*, Message*);
+char*          removembox(char*, int);
+void           syncallmboxes(void);
+void           logmsg(Message*, char*, ...);
 void           msgincref(Message*);
 void           msgdecref(Mailbox*, Message*);
 void           mboxincref(Mailbox*);
 void           mboxdecref(Mailbox*);
+char           *mboxrename(char*, char*, int);
 void           convert(Message*);
 void           decode(Message*);
-int            cistrncmp(char*, char*, int);
-int            cistrcmp(char*, char*);
 int            decquoted(char*, char*, char*, int);
 int            xtoutf(char*, char**, char*, char*);
-void           countlines(Message*);
-int            headerlen(Message*);
-void           parse(Message*, int, Mailbox*, int);
-void           parseheaders(Message*, int, Mailbox*, int);
+ulong          countlines(Message*);
+void           parse(Mailbox*, Message*, int, int);
+void           parseheaders(Mailbox*, Message*, int, int);
 void           parsebody(Message*, Mailbox*);
-void           parseunix(Message*);
-String*        date822tounix(char*);
+char*          date822tounix(Message*, char*);
 int            fidmboxrefs(Mailbox*);
 int            hashmboxrefs(Mailbox*);
 void           checkmboxrefs(void);
+int            strtotm(char*, Tm*);
+char*          lowercase(char*);
 
-extern int     debug;
-extern int     fflag;
-extern int     logging;
-extern char    user[Elemlen];
-extern char    stdmbox[Pathlen];
-extern QLock   mbllock;
-extern Mailbox *mbl;
-extern char    *mntpt;
-extern int     biffing;
-extern int     plumbing;
-extern char*   Enotme;
+char*          sputc(char*, char*, int);
+char*          seappend(char*, char*, char*, int);
 
-enum
-{
-       /* mail subobjects */
-       Qbody,
+int            hdrlen(char*, char*);
+char*          rfc2047(char*, char*, char*, int, int);
+
+char*          localremove(Mailbox*, int);
+char*          localrename(Mailbox*, char*, int);
+void           rmidx(char*, int);
+int            vremove(char*);
+int            rename(char *, char*, int);
+
+int            mtreecmp(Avl*, Avl*);
+int            mtreeisdup(Mailbox *, Message *);
+Message*       mtreefind(Mailbox*, uchar*);
+void           mtreeadd(Mailbox*, Message*);
+void           mtreedelete(Mailbox*, Message*);
+
+enum {
+       /* mail sub-objects; must be sorted */
        Qbcc,
+       Qbody,
        Qcc,
        Qdate,
        Qdigest,
        Qdisposition,
+       Qffrom,
+       Qfileid,
        Qfilename,
+       Qflags,
        Qfrom,
        Qheader,
+       Qinfo,
        Qinreplyto,
        Qlines,
-       Qmimeheader,
        Qmessageid,
+       Qmimeheader,
        Qraw,
        Qrawbody,
        Qrawheader,
        Qrawunix,
+       Qreferences,
        Qreplyto,
        Qsender,
+       Qsize,
        Qsubject,
        Qto,
        Qtype,
-       Qunixheader,
-       Qinfo,
        Qunixdate,
+       Qunixheader,
        Qmax,
 
        /* other files */
@@ -197,12 +317,10 @@ enum
        Qmboxctl,
 };
 
-#define PATH(id, f)    ((((id)&0xfffff)<<10) | (f))
+#define PATH(id, f)    ((((id) & 0xfffff)<<10) | (f))
 #define FILE(p)                ((p) & 0x3ff)
 
-char *dirtab[];
-
-// hash table to aid in name lookup, all files have an entry
+/* hash table to aid in name lookup, all files have an entry */
 typedef struct Hash Hash;
 struct Hash {
        Hash    *next;
@@ -217,5 +335,50 @@ Hash       *hlook(ulong, char*);
 void   henter(ulong, char*, Qid, Message*, Mailbox*);
 void   hfree(ulong, char*);
 
-ulong msgallocd, msgfreed;
+typedef struct {
+       char    *s;
+       int     l;
+       ulong   ref;
+} Refs;
+
+int    newrefs(char*);
+void   delrefs(int);
+void   refsinit(void);
+int    prrefs(Biobuf*);
+int    rdrefs(Biobuf*);
+
+void   idxfree(Idx*);
+int    rdidxfile(Mailbox*, int);
+int    wridxfile(Mailbox*);
+
+char   *modflags(Mailbox*, Message*, char*);
+int    getmtokens(char *, char**, int, int);
+
+extern char    Enotme[];
+extern char    *mntpt;
+extern char    user[Elemlen];
+extern char    *dirtab[];
+extern int     Sflag;
+extern int     iflag;
+extern int     biffing;
+extern ulong   cachetarg;
+extern int     debug;
+extern int     lflag;
+extern int     plumbing;
+extern ulong   msgallocd;
+extern ulong   msgfreed;
+extern Mailbox *mbl;
+extern Message *root;
+extern QLock   mbllock;
+extern Refs    *rtab;
+
+#define        dprint(...)     if(debug) fprint(2, __VA_ARGS__); else {}
+#define        Topmsg(mb, m)   (m->whole == mb->root)
+#pragma        varargck        type    "A"     uchar*
+#pragma        varargck        type    "D"     uvlong
+#pragma        varargck        type    "P"     Mpair
+#pragma        varargck        type    "Δ"    uvlong
+#pragma        varargck        argpos  eprint  1
+#pragma        varargck        argpos  iprint  1
+#pragma        varargck        argpos  logmsg  2