xref: /plan9/sys/src/cmd/ip/imap4d/store.c (revision 40fe8d0d2a3c60abd3653acf0a5621d0e6f845e5)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <auth.h>
5 #include "imap4d.h"
6 
7 static NamedInt	flagMap[] =
8 {
9 	{"\\Seen",	MSeen},
10 	{"\\Answered",	MAnswered},
11 	{"\\Flagged",	MFlagged},
12 	{"\\Deleted",	MDeleted},
13 	{"\\Draft",	MDraft},
14 	{"\\Recent",	MRecent},
15 	{nil,		0}
16 };
17 
18 int
storeMsg(Box * box,Msg * m,int uids,void * vst)19 storeMsg(Box *box, Msg *m, int uids, void *vst)
20 {
21 	Store *st;
22 	int f, flags;
23 
24 	USED(uids);
25 
26 	if(m->expunged)
27 		return uids;
28 
29 	st = vst;
30 	flags = st->flags;
31 
32 	f = m->flags;
33 	if(st->sign == '+')
34 		f |= flags;
35 	else if(st->sign == '-')
36 		f &= ~flags;
37 	else
38 		f = flags;
39 
40 	/*
41 	 * not allowed to change the recent flag
42 	 */
43 	f = (f & ~MRecent) | (m->flags & MRecent);
44 	setFlags(box, m, f);
45 
46 	if(st->op != STFlagsSilent){
47 		m->sendFlags = 1;
48 		box->sendFlags = 1;
49 	}
50 
51 	return 1;
52 }
53 
54 /*
55  * update flags & global flag counts in box
56  */
57 void
setFlags(Box * box,Msg * m,int f)58 setFlags(Box *box, Msg *m, int f)
59 {
60 	if(f == m->flags)
61 		return;
62 
63 	box->dirtyImp = 1;
64 	if((f & MRecent) != (m->flags & MRecent)){
65 		if(f & MRecent)
66 			box->recent++;
67 		else
68 			box->recent--;
69 	}
70 	m->flags = f;
71 }
72 
73 void
sendFlags(Box * box,int uids)74 sendFlags(Box *box, int uids)
75 {
76 	Msg *m;
77 
78 	if(!box->sendFlags)
79 		return;
80 
81 	box->sendFlags = 0;
82 	for(m = box->msgs; m != nil; m = m->next){
83 		if(!m->expunged && m->sendFlags){
84 			Bprint(&bout, "* %lud FETCH (", m->seq);
85 			if(uids)
86 				Bprint(&bout, "uid %lud ", m->uid);
87 			Bprint(&bout, "FLAGS (");
88 			writeFlags(&bout, m, 1);
89 			Bprint(&bout, "))\r\n");
90 			m->sendFlags = 0;
91 		}
92 	}
93 }
94 
95 void
writeFlags(Biobuf * b,Msg * m,int recentOk)96 writeFlags(Biobuf *b, Msg *m, int recentOk)
97 {
98 	char *sep;
99 	int f;
100 
101 	sep = "";
102 	for(f = 0; flagMap[f].name != nil; f++){
103 		if((m->flags & flagMap[f].v)
104 		&& (flagMap[f].v != MRecent || recentOk)){
105 			Bprint(b, "%s%s", sep, flagMap[f].name);
106 			sep = " ";
107 		}
108 	}
109 }
110 
111 int
msgSeen(Box * box,Msg * m)112 msgSeen(Box *box, Msg *m)
113 {
114 	if(m->flags & MSeen)
115 		return 0;
116 	m->flags |= MSeen;
117 	box->sendFlags = 1;
118 	m->sendFlags = 1;
119 	box->dirtyImp = 1;
120 	return 1;
121 }
122 
123 ulong
mapFlag(char * name)124 mapFlag(char *name)
125 {
126 	return mapInt(flagMap, name);
127 }
128