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