plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

box.c (5107B)


      1 #include "a.h"
      2 
      3 enum
      4 {
      5 	BoxSubChunk = 16,
      6 	BoxChunk = 64,
      7 	MsgChunk = 256,
      8 	PartChunk = 4,
      9 	PartSubChunk = 4
     10 };
     11 
     12 Box **boxes;
     13 uint nboxes;
     14 Box *rootbox;
     15 int boxid;
     16 
     17 Box*
     18 boxbyname(char *name)
     19 {
     20 	int i;
     21 
     22 	/* LATER: replace with hash table */
     23 	for(i=0; i<nboxes; i++)
     24 		if(boxes[i] && strcmp(boxes[i]->name, name) == 0)
     25 			return boxes[i];
     26 	return nil;
     27 }
     28 
     29 Box*
     30 subbox(Box *b, char *elem)
     31 {
     32 	int i;
     33 
     34 	for(i=0; i<b->nsub; i++)
     35 		if(b->sub[i] && strcmp(b->sub[i]->elem, elem) == 0)
     36 			return b->sub[i];
     37 	return nil;
     38 }
     39 
     40 Box*
     41 boxbyid(uint id)
     42 {
     43 	int i;
     44 
     45 	/* LATER: replace with binary search */
     46 	for(i=0; i<nboxes; i++)
     47 		if(boxes[i] && boxes[i]->id == id)
     48 			return boxes[i];
     49 	return nil;
     50 }
     51 
     52 Box*
     53 boxcreate(char *name)
     54 {
     55 	char *p;
     56 	Box *b, *bb;
     57 
     58 	if((b = boxbyname(name)) != nil)
     59 		return b;
     60 
     61 	b = emalloc(sizeof *b);
     62 	b->id = ++boxid;
     63 	b->time = time(0);
     64 	b->name = estrdup(name);
     65 	b->uidnext = 1;
     66 	p = strrchr(b->name, '/');
     67 	if(p){
     68 		*p = 0;
     69 		bb = boxcreate(b->name);
     70 		*p = '/';
     71 		b->elem = p+1;
     72 	}else{
     73 		bb = rootbox;
     74 		b->elem = b->name;
     75 	}
     76 	if(nboxes%BoxChunk == 0)
     77 		boxes = erealloc(boxes, (nboxes+BoxChunk)*sizeof boxes[0]);
     78 	boxes[nboxes++] = b;
     79 	if(bb->nsub%BoxSubChunk == 0)
     80 		bb->sub = erealloc(bb->sub, (bb->nsub+BoxSubChunk)*sizeof bb->sub[0]);
     81 	bb->sub[bb->nsub++] = b;
     82 	b->parent = bb;
     83 	return b;
     84 }
     85 
     86 void
     87 boxfree(Box *b)
     88 {
     89 	int i;
     90 
     91 	if(b == nil)
     92 		return;
     93 	for(i=0; i<b->nmsg; i++)
     94 		msgfree(b->msg[i]);
     95 	free(b->msg);
     96 	free(b);
     97 }
     98 
     99 Part*
    100 partcreate(Msg *m, Part *pp)
    101 {
    102 	Part *p;
    103 
    104 	if(m->npart%PartChunk == 0)
    105 		m->part = erealloc(m->part, (m->npart+PartChunk)*sizeof m->part[0]);
    106 	p = emalloc(sizeof *p);
    107 	p->msg = m;
    108 	p->ix = m->npart;
    109 	m->part[m->npart++] = p;
    110 	if(pp){
    111 		if(pp->nsub%PartSubChunk == 0)
    112 			pp->sub = erealloc(pp->sub, (pp->nsub+PartSubChunk)*sizeof pp->sub[0]);
    113 		p->pix = pp->nsub;
    114 		p->parent = pp;
    115 		pp->sub[pp->nsub++] = p;
    116 	}
    117 	return p;
    118 }
    119 
    120 void
    121 partfree(Part *p)
    122 {
    123 	int i;
    124 
    125 	if(p == nil)
    126 		return;
    127 	for(i=0; i<p->nsub; i++)
    128 		partfree(p->sub[i]);
    129 	free(p->sub);
    130 	hdrfree(p->hdr);
    131 	free(p->type);
    132 	free(p->idstr);
    133 	free(p->desc);
    134 	free(p->encoding);
    135 	free(p->charset);
    136 	free(p->raw);
    137 	free(p->rawheader);
    138 	free(p->rawbody);
    139 	free(p->mimeheader);
    140 	free(p->body);
    141 	free(p);
    142 }
    143 
    144 void
    145 msgfree(Msg *m)
    146 {
    147 	int i;
    148 
    149 	if(m == nil)
    150 		return;
    151 	for(i=0; i<m->npart; i++)
    152 		free(m->part[i]);
    153 	free(m->part);
    154 	free(m);
    155 }
    156 
    157 void
    158 msgplumb(Msg *m, int delete)
    159 {
    160 	static int fd = -1;
    161 	Plumbmsg p;
    162 	Plumbattr a[10];
    163 	char buf[256], date[40];
    164 	int ai;
    165 
    166 	if(m == nil || m->npart < 1 || m->part[0]->hdr == nil)
    167 		return;
    168 	if(m->box && strcmp(m->box->name, "mbox") != 0)
    169 		return;
    170 
    171 	p.src = "mailfs";
    172 	p.dst = "seemail";
    173 	p.wdir = "/";
    174 	p.type = "text";
    175 
    176 	ai = 0;
    177 	a[ai].name = "filetype";
    178 	a[ai].value = "mail";
    179 
    180 	a[++ai].name = "mailtype";
    181 	a[ai].value = delete?"delete":"new";
    182 	a[ai-1].next = &a[ai];
    183 
    184 	if(m->part[0]->hdr->from){
    185 		a[++ai].name = "sender";
    186 		a[ai].value = m->part[0]->hdr->from;
    187 		a[ai-1].next = &a[ai];
    188 	}
    189 
    190 	if(m->part[0]->hdr->subject){
    191 		a[++ai].name = "subject";
    192 		a[ai].value = m->part[0]->hdr->subject;
    193 		a[ai-1].next = &a[ai];
    194 	}
    195 
    196 	if(m->part[0]->hdr->digest){
    197 		a[++ai].name = "digest";
    198 		a[ai].value = m->part[0]->hdr->digest;
    199 		a[ai-1].next = &a[ai];
    200 	}
    201 
    202 	strcpy(date, ctime(m->date));
    203 	date[strlen(date)-1] = 0;	/* newline */
    204 	a[++ai].name = "date";
    205 	a[ai].value = date;
    206 	a[ai-1].next = &a[ai];
    207 
    208 	a[ai].next = nil;
    209 
    210 	p.attr = a;
    211 #ifdef PLAN9PORT
    212 	snprint(buf, sizeof buf, "Mail/%s/%ud", m->box->name, m->id);
    213 #else
    214 	snprint(buf, sizeof buf, "/mail/fs/%s/%ud", m->box->name, m->id);
    215 #endif
    216 	p.ndata = strlen(buf);
    217 	p.data = buf;
    218 
    219 	if(fd < 0)
    220 		fd = plumbopen("send", OWRITE);
    221 	if(fd < 0)
    222 		return;
    223 
    224 	plumbsend(fd, &p);
    225 }
    226 
    227 
    228 Msg*
    229 msgcreate(Box *box)
    230 {
    231 	Msg *m;
    232 
    233 	m = emalloc(sizeof *m);
    234 	m->box = box;
    235 	partcreate(m, nil);
    236 	m->part[0]->type = estrdup("message/rfc822");
    237 	if(box->nmsg%MsgChunk == 0)
    238 		box->msg = erealloc(box->msg, (box->nmsg+MsgChunk)*sizeof box->msg[0]);
    239 	m->ix = box->nmsg++;
    240 	box->msg[m->ix] = m;
    241 	m->id = ++box->msgid;
    242 	return m;
    243 }
    244 
    245 Msg*
    246 msgbyimapuid(Box *box, uint uid, int docreate)
    247 {
    248 	int i;
    249 	Msg *msg;
    250 
    251 	if(box == nil)
    252 		return nil;
    253 	/* LATER: binary search or something */
    254 	for(i=0; i<box->nmsg; i++)
    255 		if(box->msg[i]->imapuid == uid)
    256 			return box->msg[i];
    257 	if(!docreate)
    258 		return nil;
    259 	msg = msgcreate(box);
    260 	msg->imapuid = uid;
    261 	return msg;
    262 }
    263 
    264 Msg*
    265 msgbyid(Box *box, uint id)
    266 {
    267 	int i;
    268 
    269 	if(box == nil)
    270 		return nil;
    271 	/* LATER: binary search or something */
    272 	for(i=0; i<box->nmsg; i++)
    273 		if(box->msg[i]->id == id)
    274 			return box->msg[i];
    275 	return nil;
    276 }
    277 
    278 Part*
    279 partbyid(Msg *m, uint id)
    280 {
    281 	if(m == nil)
    282 		return nil;
    283 	if(id >= m->npart)
    284 		return nil;
    285 	return m->part[id];
    286 }
    287 
    288 Part*
    289 subpart(Part *p, uint a)
    290 {
    291 	if(p == nil || a >= p->nsub)
    292 		return nil;
    293 	return p->sub[a];
    294 }
    295 
    296 void
    297 hdrfree(Hdr *h)
    298 {
    299 	if(h == nil)
    300 		return;
    301 	free(h->date);
    302 	free(h->subject);
    303 	free(h->from);
    304 	free(h->sender);
    305 	free(h->replyto);
    306 	free(h->to);
    307 	free(h->cc);
    308 	free(h->bcc);
    309 	free(h->inreplyto);
    310 	free(h->messageid);
    311 	free(h->digest);
    312 	free(h);
    313 }
    314 
    315 void
    316 boxinit(void)
    317 {
    318 	rootbox = emalloc(sizeof *rootbox);
    319 	rootbox->name = estrdup("");
    320 	rootbox->time = time(0);
    321 }