1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <auth.h>
5 #include "imap4d.h"
6
7 /*
8 * iterated over all of the items in the message set.
9 * errors are accumulated, but processing continues.
10 * if uids, then ignore non-existent messages.
11 * otherwise, that's an error
12 */
13 int
forMsgs(Box * box,MsgSet * ms,ulong max,int uids,int (* f)(Box *,Msg *,int,void *),void * rock)14 forMsgs(Box *box, MsgSet *ms, ulong max, int uids, int (*f)(Box*, Msg*, int, void*), void *rock)
15 {
16 Msg *m;
17 ulong id;
18 int ok, rok;
19
20 ok = 1;
21 for(; ms != nil; ms = ms->next){
22 id = ms->from;
23 rok = 0;
24 for(m = box->msgs; m != nil && m->seq <= max; m = m->next){
25 if(!uids && m->seq > id
26 || uids && m->uid > ms->to)
27 break;
28 if(!uids && m->seq == id
29 || uids && m->uid >= id){
30 if(!(*f)(box, m, uids, rock))
31 ok = 0;
32 if(uids)
33 id = m->uid;
34 if(id >= ms->to){
35 rok = 1;
36 break;
37 }
38 if(ms->to == ~0UL)
39 rok = 1;
40 id++;
41 }
42 }
43 if(!uids && !rok)
44 ok = 0;
45 }
46 return ok;
47 }
48
49 Store *
mkStore(int sign,int op,int flags)50 mkStore(int sign, int op, int flags)
51 {
52 Store *st;
53
54 st = binalloc(&parseBin, sizeof(Store), 1);
55 if(st == nil)
56 parseErr("out of memory");
57 st->sign = sign;
58 st->op = op;
59 st->flags = flags;
60 return st;
61 }
62
63 Fetch *
mkFetch(int op,Fetch * next)64 mkFetch(int op, Fetch *next)
65 {
66 Fetch *f;
67
68 f = binalloc(&parseBin, sizeof(Fetch), 1);
69 if(f == nil)
70 parseErr("out of memory");
71 f->op = op;
72 f->next = next;
73 return f;
74 }
75
76 Fetch*
revFetch(Fetch * f)77 revFetch(Fetch *f)
78 {
79 Fetch *last, *next;
80
81 last = nil;
82 for(; f != nil; f = next){
83 next = f->next;
84 f->next = last;
85 last = f;
86 }
87 return last;
88 }
89
90 NList*
mkNList(ulong n,NList * next)91 mkNList(ulong n, NList *next)
92 {
93 NList *nl;
94
95 nl = binalloc(&parseBin, sizeof(NList), 0);
96 if(nl == nil)
97 parseErr("out of memory");
98 nl->n = n;
99 nl->next = next;
100 return nl;
101 }
102
103 NList*
revNList(NList * nl)104 revNList(NList *nl)
105 {
106 NList *last, *next;
107
108 last = nil;
109 for(; nl != nil; nl = next){
110 next = nl->next;
111 nl->next = last;
112 last = nl;
113 }
114 return last;
115 }
116
117 SList*
mkSList(char * s,SList * next)118 mkSList(char *s, SList *next)
119 {
120 SList *sl;
121
122 sl = binalloc(&parseBin, sizeof(SList), 0);
123 if(sl == nil)
124 parseErr("out of memory");
125 sl->s = s;
126 sl->next = next;
127 return sl;
128 }
129
130 SList*
revSList(SList * sl)131 revSList(SList *sl)
132 {
133 SList *last, *next;
134
135 last = nil;
136 for(; sl != nil; sl = next){
137 next = sl->next;
138 sl->next = last;
139 last = sl;
140 }
141 return last;
142 }
143
144 int
BNList(Biobuf * b,NList * nl,char * sep)145 BNList(Biobuf *b, NList *nl, char *sep)
146 {
147 char *s;
148 int n;
149
150 s = "";
151 n = 0;
152 for(; nl != nil; nl = nl->next){
153 n += Bprint(b, "%s%lud", s, nl->n);
154 s = sep;
155 }
156 return n;
157 }
158
159 int
BSList(Biobuf * b,SList * sl,char * sep)160 BSList(Biobuf *b, SList *sl, char *sep)
161 {
162 char *s;
163 int n;
164
165 s = "";
166 n = 0;
167 for(; sl != nil; sl = sl->next){
168 n += Bprint(b, "%s", s);
169 n += Bimapstr(b, sl->s);
170 s = sep;
171 }
172 return n;
173 }
174
175 int
Bimapdate(Biobuf * b,Tm * tm)176 Bimapdate(Biobuf *b, Tm *tm)
177 {
178 char buf[64];
179
180 if(tm == nil)
181 tm = localtime(time(nil));
182 imap4date(buf, sizeof(buf), tm);
183 return Bimapstr(b, buf);
184 }
185
186 int
Brfc822date(Biobuf * b,Tm * tm)187 Brfc822date(Biobuf *b, Tm *tm)
188 {
189 char buf[64];
190
191 if(tm == nil)
192 tm = localtime(time(nil));
193 rfc822date(buf, sizeof(buf), tm);
194 return Bimapstr(b, buf);
195 }
196
197 int
Bimapstr(Biobuf * b,char * s)198 Bimapstr(Biobuf *b, char *s)
199 {
200 char *t;
201 int c;
202
203 if(s == nil)
204 return Bprint(b, "NIL");
205 for(t = s; ; t++){
206 c = *t;
207 if(c == '\0')
208 return Bprint(b, "\"%s\"", s);
209 if(t - s > 64 || c >= 0x7f || strchr("\"\\\r\n", c) != nil)
210 break;
211 }
212 return Bprint(b, "{%lud}\r\n%s", strlen(s), s);
213 }
214