1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <auth.h>
5 #include "imap4d.h"
6
7 /*
8 * reverse string [s:e) in place
9 */
10 void
strrev(char * s,char * e)11 strrev(char *s, char *e)
12 {
13 int c;
14
15 while(--e > s){
16 c = *s;
17 *s++ = *e;
18 *e = c;
19 }
20 }
21
22 int
isdotdot(char * s)23 isdotdot(char *s)
24 {
25 return s[0] == '.' && s[1] == '.' && (s[2] == '/' || s[2] == '\0');
26 }
27
28 int
issuffix(char * suf,char * s)29 issuffix(char *suf, char *s)
30 {
31 int n;
32
33 n = strlen(s) - strlen(suf);
34 if(n < 0)
35 return 0;
36 return strcmp(s + n, suf) == 0;
37 }
38
39 int
isprefix(char * pre,char * s)40 isprefix(char *pre, char *s)
41 {
42 return strncmp(pre, s, strlen(pre)) == 0;
43 }
44
45 int
ciisprefix(char * pre,char * s)46 ciisprefix(char *pre, char *s)
47 {
48 return cistrncmp(pre, s, strlen(pre)) == 0;
49 }
50
51 char*
readFile(int fd)52 readFile(int fd)
53 {
54 Dir *d;
55 long length;
56 char *s;
57
58 d = dirfstat(fd);
59 if(d == nil)
60 return nil;
61 length = d->length;
62 free(d);
63 s = binalloc(&parseBin, length + 1, 0);
64 if(s == nil || read(fd, s, length) != length)
65 return nil;
66 s[length] = '\0';
67 return s;
68 }
69
70 /*
71 * create the imap tmp file.
72 * it just happens that we don't need multiple temporary files.
73 */
74 int
imapTmp(void)75 imapTmp(void)
76 {
77 char buf[ERRMAX], name[MboxNameLen];
78 int tries, fd;
79
80 snprint(name, sizeof(name), "/mail/box/%s/mbox.tmp.imp", username);
81 for(tries = 0; tries < LockSecs*2; tries++){
82 fd = create(name, ORDWR|ORCLOSE|OCEXEC, DMEXCL|0600);
83 if(fd >= 0)
84 return fd;
85 errstr(buf, sizeof buf);
86 if(cistrstr(buf, "locked") == nil)
87 break;
88 sleep(500);
89 }
90 return -1;
91 }
92
93 /*
94 * open a file which might be locked.
95 * if it is, spin until available
96 */
97 int
openLocked(char * dir,char * file,int mode)98 openLocked(char *dir, char *file, int mode)
99 {
100 char buf[ERRMAX];
101 int tries, fd;
102
103 for(tries = 0; tries < LockSecs*2; tries++){
104 fd = cdOpen(dir, file, mode);
105 if(fd >= 0)
106 return fd;
107 errstr(buf, sizeof buf);
108 if(cistrstr(buf, "locked") == nil)
109 break;
110 sleep(500);
111 }
112 return -1;
113 }
114
115 int
fqid(int fd,Qid * qid)116 fqid(int fd, Qid *qid)
117 {
118 Dir *d;
119
120 d = dirfstat(fd);
121 if(d == nil)
122 return -1;
123 *qid = d->qid;
124 free(d);
125 return 0;
126 }
127
128 ulong
mapInt(NamedInt * map,char * name)129 mapInt(NamedInt *map, char *name)
130 {
131 int i;
132
133 for(i = 0; map[i].name != nil; i++)
134 if(cistrcmp(map[i].name, name) == 0)
135 break;
136 return map[i].v;
137 }
138
139 char*
estrdup(char * s)140 estrdup(char *s)
141 {
142 char *t;
143
144 t = emalloc(strlen(s) + 1);
145 strcpy(t, s);
146 return t;
147 }
148
149 void*
emalloc(ulong n)150 emalloc(ulong n)
151 {
152 void *p;
153
154 p = malloc(n);
155 if(p == nil)
156 bye("server out of memory");
157 setmalloctag(p, getcallerpc(&n));
158 return p;
159 }
160
161 void*
ezmalloc(ulong n)162 ezmalloc(ulong n)
163 {
164 void *p;
165
166 p = malloc(n);
167 if(p == nil)
168 bye("server out of memory");
169 setmalloctag(p, getcallerpc(&n));
170 memset(p, 0, n);
171 return p;
172 }
173
174 void*
erealloc(void * p,ulong n)175 erealloc(void *p, ulong n)
176 {
177 p = realloc(p, n);
178 if(p == nil)
179 bye("server out of memory");
180 setrealloctag(p, getcallerpc(&p));
181 return p;
182 }
183