#include "common.h"
#include "send.h"
/*
* warning will robinson
*
* mbox and mdir should likely be merged with ../common/folder.c
* at a minimum, changes need to done in sync.
*/
static int
mbox(dest *dp, message *mp, char *s)
{
char *tmp;
int i, n, e;
Biobuf *b;
Mlock *l;
for(i = 0;; i++){
l = syslock(s);
if(l == 0)
return refuse(dp, mp, "can't lock mail file", 0, 0);
b = sysopen(s, "al", Mboxmode);
if(b)
break;
b = sysopen(tmp = smprint("%s.tmp", s), "al", Mboxmode);
free(tmp);
sysunlock(l);
if(b){
syslog(0, "mail", "error: used %s.tmp", s);
break;
}
if(i >= 5)
return refuse(dp, mp, "mail file cannot be opened", 0, 0);
sleep(1000);
}
e = 0;
n = m_print(mp, b, 0, 1);
if(n == -1 || Bprint(b, "\n") == -1 || Bflush(b) == -1)
e = 1;
sysclose(b);
sysunlock(l);
if(e)
return refuse(dp, mp, "error writing mail file", 0, 0);
return 0;
}
static int
mdir(dest *dp, message *mp, char *s)
{
char buf[100];
int fd, i, n, e;
ulong t;
Biobuf b;
t = time(0);
for(i = 0; i < 100; i++){
snprint(buf, sizeof buf, "%s/%lud.%.2d", s, t, i);
if((fd = create(buf, OWRITE|OEXCL, DMAPPEND|0660)) != -1)
goto found;
}
return refuse(dp, mp, "mdir file cannot be opened", 0, 0);
found:
e = 0;
Binit(&b, fd, OWRITE);
n = m_print(mp, &b, 0, 1);
if(n == -1 || Bprint(&b, "\n") == -1 || Bflush(&b) == -1)
e = 1;
Bterm(&b);
close(fd);
if(e){
remove(buf);
return refuse(dp, mp, "error writing mail file", 0, 0);
}
return 0;
}
/* dispose of local addresses */
int
cat_mail(dest *dp, message *mp)
{
char *rcvr, *cp, *s;
int e, isdir;
Dir *d;
String *ss;
ss = unescapespecial(s_clone(dp->repl1));
s = s_to_c(ss);
if (flagn) {
if(!flagx)
print("cat >> %s\n", s);
else
print("%s\n", s_to_c(dp->addr));
s_free(ss);
return 0;
}
if(d = dirstat(s)){
isdir = d->mode&DMDIR;
free(d);
}else{
isdir = create(s, OREAD, DMDIR|0777);
if(isdir == -1)
return refuse(dp, mp, "mdir cannot be created", 0, 0);
close(isdir);
isdir = 1;
}
if(isdir)
e = mdir(dp, mp, s);
else
e = mbox(dp, mp, s);
s_free(ss);
if(e != 0)
return e;
rcvr = s_to_c(dp->addr);
if(cp = strrchr(rcvr, '!'))
rcvr = cp+1;
logdelivery(dp, rcvr, mp);
return 0;
}
|