7 static int copyData(int ffd, int tfd, MbLock *ml);
13 static char curDir[MboxNameLen];
24 if(strcmp(dir, curDir) == 0)
26 if(dir[0] != '/' || strlen(dir) > MboxNameLen)
30 werrstr("mychdir failed: %r");
37 cdCreate(char *dir, char *file, int mode, ulong perm)
41 return create(file, mode, perm);
45 cdDirstat(char *dir, char *file)
53 cdExists(char *dir, char *file)
57 d = cdDirstat(dir, file);
65 cdDirwstat(char *dir, char *file, Dir *d)
69 return dirwstat(file, d);
73 cdOpen(char *dir, char *file, int mode)
77 return open(file, mode);
81 cdRemove(char *dir, char *file)
89 * open the one true mail lock file
97 bye("mail lock deadlock");
98 for(i = 0; i < 5; i++){
99 mLock.fd = openLocked(mboxDir, "L.mbox", OREAD);
111 bye("bad mail unlock");
113 bye("mail unlock when not locked");
119 mbLockRefresh(MbLock *ml)
124 read(ml->fd, buf, 1);
130 return mLock.fd >= 0;
139 if(cistrcmp(name, "inbox") == 0)
140 if(access("msgs", AEXIST) == 0)
144 n = strlen(name) + STRLEN(".imp") + 1;
145 s = binalloc(&parseBin, n, 0);
148 snprint(s, n, "%s.imp", name);
153 * massage the mailbox name into something valid
154 * eliminates all .', and ..',s, redundatant and trailing /'s.
174 n = strlen(s) * MUtf7Max + 1;
175 m = binalloc(&parseBin, n, 0);
178 if(encmutf7(m, n, s) < 0)
190 * n = strlen(s) * UTFmax / (2.67) + 1
191 * UTFMax / 2.67 == 3 / (8/3) == 9 / 8
194 n = (n * 9 + 7) / 8 + 1;
195 m = binalloc(&parseBin, n, 0);
198 if(decmutf7(m, n, s) < 0)
204 splitr(char *s, int c, char **left, char **right)
210 d = binalloc(&parseBin, n + 1, 0);
212 parseErr("out of memory");
226 * create the mailbox and all intermediate components
227 * a trailing / implies the new mailbox is a directory;
228 * otherwise, it's a file.
230 * return with the file open for write, or directory open for read.
233 createBox(char *mbox, int dir)
239 for(m = mbox; *m; m++){
242 if(access(mbox, AEXIST) < 0){
245 fd = cdCreate(mboxDir, mbox, OREAD, DMDIR|0775);
253 fd = cdCreate(mboxDir, mbox, OREAD, DMDIR|0775);
255 fd = cdCreate(mboxDir, mbox, OWRITE, 0664);
260 * move one mail folder to another
261 * destination mailbox doesn't exist.
262 * the source folder may be a directory or a mailbox,
263 * and may be in the same directory as the destination,
264 * or a completely different directory.
267 moveBox(char *from, char *to)
270 char *fd, *fe, *td, *te, *fimp;
272 splitr(from, '/', &fd, &fe);
273 splitr(to, '/', &td, &te);
276 * in the same directory: try rename
278 d = cdDirstat(mboxDir, from);
281 if(strcmp(fd, td) == 0){
284 if(cdDirwstat(mboxDir, from, d) >= 0){
285 fimp = impName(from);
286 d->name = impName(te);
287 cdDirwstat(mboxDir, fimp, d);
294 * directory copy is too hard for now
300 return copyBox(from, to, 1);
304 * copy the contents of one mailbox to another
305 * either truncates or removes the source box if it succeeds.
308 copyBox(char *from, char *to, int doremove)
314 if(cistrcmp(from, "inbox") == 0)
315 if(access("msgs", AEXIST) == 0)
323 ffd = openLocked(mboxDir, from, OREAD);
328 tfd = createBox(to, 0);
335 ok = copyData(ffd, tfd, ml);
343 fimp = impName(from);
345 if(fimp != nil && timp != nil){
346 ffd = cdOpen(mboxDir, fimp, OREAD);
348 tfd = cdCreate(mboxDir, timp, OWRITE, 0664);
350 copyData(ffd, tfd, ml);
356 cdRemove(mboxDir, fimp);
358 cdRemove(mboxDir, from);
360 close(cdOpen(mboxDir, from, OWRITE|OTRUNC));
366 * copies while holding the mail lock,
367 * then tries to copy permissions and group ownership
370 copyData(int ffd, int tfd, MbLock *ml)
377 n = read(ffd, buf, BufSize);
383 if(write(tfd, buf, n) != n)
391 if(dirfwstat(tfd, &td) >= 0){