xref: /plan9/sys/src/cmd/ip/imap4d/store.c (revision 40fe8d0d2a3c60abd3653acf0a5621d0e6f845e5)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
49a747e4fSDavid du Colombier #include <auth.h>
57dd7cddfSDavid du Colombier #include "imap4d.h"
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier static NamedInt	flagMap[] =
87dd7cddfSDavid du Colombier {
97dd7cddfSDavid du Colombier 	{"\\Seen",	MSeen},
107dd7cddfSDavid du Colombier 	{"\\Answered",	MAnswered},
117dd7cddfSDavid du Colombier 	{"\\Flagged",	MFlagged},
127dd7cddfSDavid du Colombier 	{"\\Deleted",	MDeleted},
137dd7cddfSDavid du Colombier 	{"\\Draft",	MDraft},
147dd7cddfSDavid du Colombier 	{"\\Recent",	MRecent},
157dd7cddfSDavid du Colombier 	{nil,		0}
167dd7cddfSDavid du Colombier };
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier int
storeMsg(Box * box,Msg * m,int uids,void * vst)197dd7cddfSDavid du Colombier storeMsg(Box *box, Msg *m, int uids, void *vst)
207dd7cddfSDavid du Colombier {
217dd7cddfSDavid du Colombier 	Store *st;
227dd7cddfSDavid du Colombier 	int f, flags;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier 	USED(uids);
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier 	if(m->expunged)
277dd7cddfSDavid du Colombier 		return uids;
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier 	st = vst;
307dd7cddfSDavid du Colombier 	flags = st->flags;
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier 	f = m->flags;
337dd7cddfSDavid du Colombier 	if(st->sign == '+')
347dd7cddfSDavid du Colombier 		f |= flags;
357dd7cddfSDavid du Colombier 	else if(st->sign == '-')
367dd7cddfSDavid du Colombier 		f &= ~flags;
377dd7cddfSDavid du Colombier 	else
387dd7cddfSDavid du Colombier 		f = flags;
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier 	/*
417dd7cddfSDavid du Colombier 	 * not allowed to change the recent flag
427dd7cddfSDavid du Colombier 	 */
437dd7cddfSDavid du Colombier 	f = (f & ~MRecent) | (m->flags & MRecent);
447dd7cddfSDavid du Colombier 	setFlags(box, m, f);
457dd7cddfSDavid du Colombier 
467dd7cddfSDavid du Colombier 	if(st->op != STFlagsSilent){
477dd7cddfSDavid du Colombier 		m->sendFlags = 1;
487dd7cddfSDavid du Colombier 		box->sendFlags = 1;
497dd7cddfSDavid du Colombier 	}
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 	return 1;
527dd7cddfSDavid du Colombier }
537dd7cddfSDavid du Colombier 
547dd7cddfSDavid du Colombier /*
557dd7cddfSDavid du Colombier  * update flags & global flag counts in box
567dd7cddfSDavid du Colombier  */
577dd7cddfSDavid du Colombier void
setFlags(Box * box,Msg * m,int f)587dd7cddfSDavid du Colombier setFlags(Box *box, Msg *m, int f)
597dd7cddfSDavid du Colombier {
607dd7cddfSDavid du Colombier 	if(f == m->flags)
617dd7cddfSDavid du Colombier 		return;
627dd7cddfSDavid du Colombier 
637dd7cddfSDavid du Colombier 	box->dirtyImp = 1;
647dd7cddfSDavid du Colombier 	if((f & MRecent) != (m->flags & MRecent)){
657dd7cddfSDavid du Colombier 		if(f & MRecent)
667dd7cddfSDavid du Colombier 			box->recent++;
677dd7cddfSDavid du Colombier 		else
687dd7cddfSDavid du Colombier 			box->recent--;
697dd7cddfSDavid du Colombier 	}
707dd7cddfSDavid du Colombier 	m->flags = f;
717dd7cddfSDavid du Colombier }
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier void
sendFlags(Box * box,int uids)747dd7cddfSDavid du Colombier sendFlags(Box *box, int uids)
757dd7cddfSDavid du Colombier {
767dd7cddfSDavid du Colombier 	Msg *m;
777dd7cddfSDavid du Colombier 
787dd7cddfSDavid du Colombier 	if(!box->sendFlags)
797dd7cddfSDavid du Colombier 		return;
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier 	box->sendFlags = 0;
827dd7cddfSDavid du Colombier 	for(m = box->msgs; m != nil; m = m->next){
837dd7cddfSDavid du Colombier 		if(!m->expunged && m->sendFlags){
84*40fe8d0dSDavid du Colombier 			Bprint(&bout, "* %lud FETCH (", m->seq);
857dd7cddfSDavid du Colombier 			if(uids)
867dd7cddfSDavid du Colombier 				Bprint(&bout, "uid %lud ", m->uid);
87*40fe8d0dSDavid du Colombier 			Bprint(&bout, "FLAGS (");
887dd7cddfSDavid du Colombier 			writeFlags(&bout, m, 1);
897dd7cddfSDavid du Colombier 			Bprint(&bout, "))\r\n");
907dd7cddfSDavid du Colombier 			m->sendFlags = 0;
917dd7cddfSDavid du Colombier 		}
927dd7cddfSDavid du Colombier 	}
937dd7cddfSDavid du Colombier }
947dd7cddfSDavid du Colombier 
957dd7cddfSDavid du Colombier void
writeFlags(Biobuf * b,Msg * m,int recentOk)967dd7cddfSDavid du Colombier writeFlags(Biobuf *b, Msg *m, int recentOk)
977dd7cddfSDavid du Colombier {
987dd7cddfSDavid du Colombier 	char *sep;
997dd7cddfSDavid du Colombier 	int f;
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier 	sep = "";
1027dd7cddfSDavid du Colombier 	for(f = 0; flagMap[f].name != nil; f++){
1037dd7cddfSDavid du Colombier 		if((m->flags & flagMap[f].v)
1047dd7cddfSDavid du Colombier 		&& (flagMap[f].v != MRecent || recentOk)){
1057dd7cddfSDavid du Colombier 			Bprint(b, "%s%s", sep, flagMap[f].name);
1067dd7cddfSDavid du Colombier 			sep = " ";
1077dd7cddfSDavid du Colombier 		}
1087dd7cddfSDavid du Colombier 	}
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier 
1117dd7cddfSDavid du Colombier int
msgSeen(Box * box,Msg * m)1127dd7cddfSDavid du Colombier msgSeen(Box *box, Msg *m)
1137dd7cddfSDavid du Colombier {
1147dd7cddfSDavid du Colombier 	if(m->flags & MSeen)
1157dd7cddfSDavid du Colombier 		return 0;
1167dd7cddfSDavid du Colombier 	m->flags |= MSeen;
1177dd7cddfSDavid du Colombier 	box->sendFlags = 1;
1187dd7cddfSDavid du Colombier 	m->sendFlags = 1;
1197dd7cddfSDavid du Colombier 	box->dirtyImp = 1;
1207dd7cddfSDavid du Colombier 	return 1;
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier ulong
mapFlag(char * name)1247dd7cddfSDavid du Colombier mapFlag(char *name)
1257dd7cddfSDavid du Colombier {
1267dd7cddfSDavid du Colombier 	return mapInt(flagMap, name);
1277dd7cddfSDavid du Colombier }
128