imap-based new upas/fs
This commit is contained in:
parent
1ea614ffaf
commit
941e17134e
15 changed files with 4168 additions and 0 deletions
318
src/cmd/upas/nfs/box.c
Normal file
318
src/cmd/upas/nfs/box.c
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
#include "a.h"
|
||||
|
||||
enum
|
||||
{
|
||||
BoxSubChunk = 16,
|
||||
BoxChunk = 64,
|
||||
MsgChunk = 256,
|
||||
PartChunk = 4,
|
||||
PartSubChunk = 4,
|
||||
};
|
||||
|
||||
Box **boxes;
|
||||
uint nboxes;
|
||||
Box *rootbox;
|
||||
int boxid;
|
||||
|
||||
Box*
|
||||
boxbyname(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* LATER: replace with hash table */
|
||||
for(i=0; i<nboxes; i++)
|
||||
if(boxes[i] && strcmp(boxes[i]->name, name) == 0)
|
||||
return boxes[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
Box*
|
||||
subbox(Box *b, char *elem)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<b->nsub; i++)
|
||||
if(b->sub[i] && strcmp(b->sub[i]->elem, elem) == 0)
|
||||
return b->sub[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
Box*
|
||||
boxbyid(uint id)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* LATER: replace with binary search */
|
||||
for(i=0; i<nboxes; i++)
|
||||
if(boxes[i] && boxes[i]->id == id)
|
||||
return boxes[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
Box*
|
||||
boxcreate(char *name)
|
||||
{
|
||||
char *p;
|
||||
Box *b, *bb;
|
||||
|
||||
if((b = boxbyname(name)) != nil)
|
||||
return b;
|
||||
|
||||
b = emalloc(sizeof *b);
|
||||
b->id = ++boxid;
|
||||
b->time = time(0);
|
||||
b->name = estrdup(name);
|
||||
b->uidnext = 1;
|
||||
p = strrchr(b->name, '/');
|
||||
if(p){
|
||||
*p = 0;
|
||||
bb = boxcreate(b->name);
|
||||
*p = '/';
|
||||
b->elem = p+1;
|
||||
}else{
|
||||
bb = rootbox;
|
||||
b->elem = b->name;
|
||||
}
|
||||
if(nboxes%BoxChunk == 0)
|
||||
boxes = erealloc(boxes, (nboxes+BoxChunk)*sizeof boxes[0]);
|
||||
boxes[nboxes++] = b;
|
||||
if(bb->nsub%BoxSubChunk == 0)
|
||||
bb->sub = erealloc(bb->sub, (bb->nsub+BoxSubChunk)*sizeof bb->sub[0]);
|
||||
bb->sub[bb->nsub++] = b;
|
||||
b->parent = bb;
|
||||
return b;
|
||||
}
|
||||
|
||||
void
|
||||
boxfree(Box *b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(b == nil)
|
||||
return;
|
||||
for(i=0; i<b->nmsg; i++)
|
||||
msgfree(b->msg[i]);
|
||||
free(b->msg);
|
||||
free(b);
|
||||
}
|
||||
|
||||
Part*
|
||||
partcreate(Msg *m, Part *pp)
|
||||
{
|
||||
Part *p;
|
||||
|
||||
if(m->npart%PartChunk == 0)
|
||||
m->part = erealloc(m->part, (m->npart+PartChunk)*sizeof m->part[0]);
|
||||
p = emalloc(sizeof *p);
|
||||
p->msg = m;
|
||||
p->ix = m->npart;
|
||||
m->part[m->npart++] = p;
|
||||
if(pp){
|
||||
if(pp->nsub%PartSubChunk == 0)
|
||||
pp->sub = erealloc(pp->sub, (pp->nsub+PartSubChunk)*sizeof pp->sub[0]);
|
||||
p->pix = pp->nsub;
|
||||
p->parent = pp;
|
||||
pp->sub[pp->nsub++] = p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
partfree(Part *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(p == nil)
|
||||
return;
|
||||
for(i=0; i<p->nsub; i++)
|
||||
partfree(p->sub[i]);
|
||||
free(p->sub);
|
||||
hdrfree(p->hdr);
|
||||
free(p->type);
|
||||
free(p->idstr);
|
||||
free(p->desc);
|
||||
free(p->encoding);
|
||||
free(p->charset);
|
||||
free(p->raw);
|
||||
free(p->rawheader);
|
||||
free(p->rawbody);
|
||||
free(p->mimeheader);
|
||||
free(p->body);
|
||||
free(p);
|
||||
}
|
||||
|
||||
void
|
||||
msgfree(Msg *m)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(m == nil)
|
||||
return;
|
||||
for(i=0; i<m->npart; i++)
|
||||
free(m->part[i]);
|
||||
free(m->part);
|
||||
free(m);
|
||||
}
|
||||
|
||||
void
|
||||
msgplumb(Msg *m, int delete)
|
||||
{
|
||||
static int fd = -1;
|
||||
Plumbmsg p;
|
||||
Plumbattr a[10];
|
||||
char buf[256], date[40];
|
||||
int ai;
|
||||
|
||||
if(m == nil || m->npart < 1 || m->part[0]->hdr == nil)
|
||||
return;
|
||||
if(m->box && strcmp(m->box->name, "mbox") != 0)
|
||||
return;
|
||||
|
||||
p.src = "mailfs";
|
||||
p.dst = "seemail";
|
||||
p.wdir = "/";
|
||||
p.type = "text";
|
||||
|
||||
ai = 0;
|
||||
a[ai].name = "filetype";
|
||||
a[ai].value = "mail";
|
||||
|
||||
a[++ai].name = "mailtype";
|
||||
a[ai].value = delete?"delete":"new";
|
||||
a[ai-1].next = &a[ai];
|
||||
|
||||
if(m->part[0]->hdr->from){
|
||||
a[++ai].name = "sender";
|
||||
a[ai].value = m->part[0]->hdr->from;
|
||||
a[ai-1].next = &a[ai];
|
||||
}
|
||||
|
||||
if(m->part[0]->hdr->subject){
|
||||
a[++ai].name = "subject";
|
||||
a[ai].value = m->part[0]->hdr->subject;
|
||||
a[ai-1].next = &a[ai];
|
||||
}
|
||||
|
||||
if(m->part[0]->hdr->digest){
|
||||
a[++ai].name = "digest";
|
||||
a[ai].value = m->part[0]->hdr->digest;
|
||||
a[ai-1].next = &a[ai];
|
||||
}
|
||||
|
||||
strcpy(date, ctime(m->date));
|
||||
date[strlen(date)-1] = 0; /* newline */
|
||||
a[++ai].name = "date";
|
||||
a[ai].value = date;
|
||||
a[ai-1].next = &a[ai];
|
||||
|
||||
a[ai].next = nil;
|
||||
|
||||
p.attr = a;
|
||||
snprint(buf, sizeof buf, "Mail/%s/%ud", m->box->name, m->id);
|
||||
p.ndata = strlen(buf);
|
||||
p.data = buf;
|
||||
|
||||
if(fd < 0)
|
||||
fd = plumbopen("send", OWRITE);
|
||||
if(fd < 0)
|
||||
return;
|
||||
|
||||
plumbsend(fd, &p);
|
||||
}
|
||||
|
||||
|
||||
Msg*
|
||||
msgcreate(Box *box)
|
||||
{
|
||||
Msg *m;
|
||||
|
||||
m = emalloc(sizeof *m);
|
||||
m->box = box;
|
||||
partcreate(m, nil);
|
||||
m->part[0]->type = estrdup("message/rfc822");
|
||||
if(box->nmsg%MsgChunk == 0)
|
||||
box->msg = erealloc(box->msg, (box->nmsg+MsgChunk)*sizeof box->msg[0]);
|
||||
m->ix = box->nmsg++;
|
||||
box->msg[m->ix] = m;
|
||||
m->id = ++box->msgid;
|
||||
return m;
|
||||
}
|
||||
|
||||
Msg*
|
||||
msgbyimapuid(Box *box, uint uid, int docreate)
|
||||
{
|
||||
int i;
|
||||
Msg *msg;
|
||||
|
||||
if(box == nil)
|
||||
return nil;
|
||||
/* LATER: binary search or something */
|
||||
for(i=0; i<box->nmsg; i++)
|
||||
if(box->msg[i]->imapuid == uid)
|
||||
return box->msg[i];
|
||||
if(!docreate)
|
||||
return nil;
|
||||
msg = msgcreate(box);
|
||||
msg->imapuid = uid;
|
||||
return msg;
|
||||
}
|
||||
|
||||
Msg*
|
||||
msgbyid(Box *box, uint id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(box == nil)
|
||||
return nil;
|
||||
/* LATER: binary search or something */
|
||||
for(i=0; i<box->nmsg; i++)
|
||||
if(box->msg[i]->id == id)
|
||||
return box->msg[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
Part*
|
||||
partbyid(Msg *m, uint id)
|
||||
{
|
||||
if(m == nil)
|
||||
return nil;
|
||||
if(id >= m->npart)
|
||||
return nil;
|
||||
return m->part[id];
|
||||
}
|
||||
|
||||
Part*
|
||||
subpart(Part *p, uint a)
|
||||
{
|
||||
if(p == nil || a >= p->nsub)
|
||||
return nil;
|
||||
return p->sub[a];
|
||||
}
|
||||
|
||||
void
|
||||
hdrfree(Hdr *h)
|
||||
{
|
||||
if(h == nil)
|
||||
return;
|
||||
free(h->date);
|
||||
free(h->subject);
|
||||
free(h->from);
|
||||
free(h->sender);
|
||||
free(h->replyto);
|
||||
free(h->to);
|
||||
free(h->cc);
|
||||
free(h->bcc);
|
||||
free(h->inreplyto);
|
||||
free(h->messageid);
|
||||
free(h->digest);
|
||||
free(h);
|
||||
}
|
||||
|
||||
void
|
||||
boxinit(void)
|
||||
{
|
||||
rootbox = emalloc(sizeof *rootbox);
|
||||
rootbox->name = estrdup("");
|
||||
rootbox->time = time(0);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue