diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-04-08 22:50:17 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-04-08 22:50:17 +0200 |
commit | fd78f6722efb439b9dd640886096f8f2b3c2f8f0 (patch) | |
tree | d3a3bd910c86b20be11c5173d4023408eafcdede /sys/src/cmd/upas/common | |
parent | 00fbdd622aeb6ab3665a9970d7acb6bdd225028b (diff) |
upas/common: deliver mail to mdir as .tmp file and rename after it has been fully written
theres a race condition when mail delivery to mdir is slow,
then upas/fs sees partial mail file and caches the truncated
file size.
to avoid this, delivery will create the new mail file with
the .tmp extension (which is ignored by upas/fs) and after
everything has been written, rename it to the final name.
Diffstat (limited to 'sys/src/cmd/upas/common')
-rw-r--r-- | sys/src/cmd/upas/common/common.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/upas/common/folder.c | 62 |
2 files changed, 31 insertions, 33 deletions
diff --git a/sys/src/cmd/upas/common/common.h b/sys/src/cmd/upas/common/common.h index 9cefc0531..f7e8ad5e9 100644 --- a/sys/src/cmd/upas/common/common.h +++ b/sys/src/cmd/upas/common/common.h @@ -41,7 +41,7 @@ int returnable(char*); /* folder.c */ Biobuf *openfolder(char*, long); int closefolder(Biobuf*); -int appendfolder(Biobuf*, char*, long*, int); +int appendfolder(Biobuf*, char*, int); int fappendfolder(char*, long, char *, int); int fappendfile(char*, char*, int); char* foldername(char*, char*, char*); diff --git a/sys/src/cmd/upas/common/folder.c b/sys/src/cmd/upas/common/folder.c index 1d5e34542..715f6b1af 100644 --- a/sys/src/cmd/upas/common/folder.c +++ b/sys/src/cmd/upas/common/folder.c @@ -12,6 +12,7 @@ struct Folder{ int type; Biobuf *out; Mlock *l; + long t; }; static Folder ftab[5]; @@ -44,12 +45,12 @@ putfolder(Folder *f) r = 0; if(f->l) sysunlock(f->l); - if(f->out) + if(f->out){ r |= Bterm(f->out); - if(f->ofd > 0){ - close(f->ofd); free(f->out); } + if(f->ofd >= 0) + close(f->ofd); memset(f, 0, sizeof *f); return r; } @@ -59,7 +60,7 @@ mboxopen(char *s) { Folder *f; - f = getfolder(0); + f = getfolder(nil); f->l = syslock(s); /* traditional botch: ignore failure */ if((f->ofd = open(s, OWRITE)) == -1) if((f->ofd = create(s, OWRITE|OEXCL, DMAPPEND|0600)) == -1){ @@ -79,13 +80,13 @@ mboxopen(char *s) static Biobuf* mdiropen(char *s, long t) { - char buf[64]; - long i; + char buf[Pathlen]; Folder *f; + int i; - f = getfolder(0); + f = getfolder(nil); for(i = 0; i < 100; i++){ - snprint(buf, sizeof buf, "%s/%lud.%.2ld", s, t, i); + snprint(buf, sizeof buf, "%s/%lud.%.2d.tmp", s, t, i); if((f->ofd = create(buf, OWRITE|OEXCL, DMAPPEND|0660)) != -1) goto found; } @@ -96,6 +97,7 @@ found: f->out = malloc(sizeof *f->out); Binit(f->out, f->ofd, OWRITE); f->type = Mdir; + f->t = t; return f->out; } @@ -122,32 +124,31 @@ openfolder(char *s, long t) } int -renamefolder(Biobuf *b, long t) +closefolder(Biobuf *b) { char buf[32]; - int i; - Dir d; Folder *f; + Dir d; + int i; + if(b == nil) + return 0; f = getfolder(b); if(f->type != Mdir) - return 0; - for(i = 0; i < 100; i++){ - nulldir(&d); - snprint(buf, sizeof buf, "%lud.%.2d", t, i); - d.name = buf; - if(dirfwstat(Bfildes(b), &d) > 0) - return 0; + return putfolder(f); + if(Bflush(b) == 0){ + for(i = 0; i < 100; i++){ + nulldir(&d); + snprint(buf, sizeof buf, "%lud.%.2d", f->t, i); + d.name = buf; + if(dirfwstat(f->ofd, &d) > 0) + return putfolder(f); + } } + putfolder(f); return -1; } -int -closefolder(Biobuf *b) -{ - return putfolder(getfolder(b)); -} - /* * escape "From " at the beginning of a line; * translate \r\n to \n for imap @@ -181,7 +182,7 @@ mboxesc(Biobuf *in, Biobuf *out, int type) } int -appendfolder(Biobuf *b, char *addr, long *t, int fd) +appendfolder(Biobuf *b, char *addr, int fd) { char *s; int r; @@ -194,9 +195,9 @@ appendfolder(Biobuf *b, char *addr, long *t, int fd) Binit(&bin, fd, OREAD); s = Brdstr(&bin, '\n', 0); if(!s || strncmp(s, "From ", 5)) - Bprint(f->out, "From %s %.28s\n", addr, ctime(*t)); + Bprint(f->out, "From %s %.28s\n", addr, ctime(f->t)); else if(fromtotm(s, &tm) >= 0) - *t = tm2sec(&tm); + f->t = tm2sec(&tm); if(s) Bwrite(f->out, s, strlen(s)); free(s); @@ -207,16 +208,13 @@ appendfolder(Biobuf *b, char *addr, long *t, int fd) int fappendfolder(char *addr, long t, char *s, int fd) { - long t0, r; Biobuf *b; + int r; b = openfolder(s, t); if(b == nil) return -1; - t0 = t; - r = appendfolder(b, addr, &t, fd); - if(t != t0) - renamefolder(b, t); + r = appendfolder(b, addr, fd); r |= closefolder(b); return r; } |