summaryrefslogtreecommitdiff
path: root/sys/src/cmd/upas/send
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-03-12 17:15:03 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2017-03-12 17:15:03 +0100
commit963cfc9a6f6e721f52aa949e6d1af0c3e8dc2ecc (patch)
tree749b74875dbc49bcf6ed0776648b8f0ef9417407 /sys/src/cmd/upas/send
parent8177d20fb2709ba9290dfd41308b8e5bee4e00f8 (diff)
merging erik quanstros nupas
Diffstat (limited to 'sys/src/cmd/upas/send')
-rw-r--r--sys/src/cmd/upas/send/authorize.c2
-rw-r--r--sys/src/cmd/upas/send/bind.c48
-rw-r--r--sys/src/cmd/upas/send/cat_mail.c134
-rw-r--r--sys/src/cmd/upas/send/dest.c89
-rw-r--r--sys/src/cmd/upas/send/filter.c108
-rw-r--r--sys/src/cmd/upas/send/gateway.c4
-rw-r--r--sys/src/cmd/upas/send/local.c65
-rw-r--r--sys/src/cmd/upas/send/log.c11
-rw-r--r--sys/src/cmd/upas/send/main.c425
-rw-r--r--sys/src/cmd/upas/send/makefile46
-rw-r--r--sys/src/cmd/upas/send/message.c195
-rw-r--r--sys/src/cmd/upas/send/mkfile26
-rw-r--r--sys/src/cmd/upas/send/rewrite.c89
-rw-r--r--sys/src/cmd/upas/send/send.h42
-rw-r--r--sys/src/cmd/upas/send/skipequiv.c108
-rw-r--r--sys/src/cmd/upas/send/translate.c2
-rwxr-xr-xsys/src/cmd/upas/send/tryit29
17 files changed, 683 insertions, 740 deletions
diff --git a/sys/src/cmd/upas/send/authorize.c b/sys/src/cmd/upas/send/authorize.c
index 6fa12c57c..98cf1220b 100644
--- a/sys/src/cmd/upas/send/authorize.c
+++ b/sys/src/cmd/upas/send/authorize.c
@@ -12,7 +12,7 @@ authorize(dest *dp)
String *errstr;
dp->authorized = 1;
- pp = proc_start(s_to_c(dp->repl1), (stream *)0, (stream *)0, outstream(), 1, 0);
+ pp = proc_start(s_to_c(dp->repl1), 0, 0, outstream(), 1, 0);
if (pp == 0){
dp->status = d_noforward;
return;
diff --git a/sys/src/cmd/upas/send/bind.c b/sys/src/cmd/upas/send/bind.c
index 8a8fc8eac..5e97b872f 100644
--- a/sys/src/cmd/upas/send/bind.c
+++ b/sys/src/cmd/upas/send/bind.c
@@ -1,20 +1,34 @@
#include "common.h"
#include "send.h"
-static int forward_loop(char *, char *);
+/* Return TRUE if a forwarding loop exists, i.e., the String `system'
+ * is found more than 4 times in the return address.
+ */
+static int
+forward_loop(char *addr, char *system)
+{
+ int len, found;
+
+ found = 0;
+ len = strlen(system);
+ while(addr = strchr(addr, '!'))
+ if (!strncmp(++addr, system, len)
+ && addr[len] == '!' && ++found == 4)
+ return 1;
+ return 0;
+}
+
/* bind the destinations to the commands to be executed */
-extern dest *
+dest *
up_bind(dest *destp, message *mp, int checkforward)
{
- dest *list[2]; /* lists of unbound destinations */
- int li; /* index into list[2] */
- dest *bound=0; /* bound destinations */
- dest *dp;
- int i;
+ int i, li;
+ dest *list[2], *bound, *dp;
+ bound = nil;
list[0] = destp;
- list[1] = 0;
+ list[1] = nil;
/*
* loop once to check for:
@@ -24,7 +38,7 @@ up_bind(dest *destp, message *mp, int checkforward)
* - characters that need escaping
*/
for (dp = d_rm(&list[0]); dp != 0; dp = d_rm(&list[0])) {
- if (!checkforward)
+ if(!checkforward)
dp->authorized = 1;
dp->addr = escapespecial(dp->addr);
if (forward_loop(s_to_c(dp->addr), thissys)) {
@@ -115,19 +129,3 @@ up_bind(dest *destp, message *mp, int checkforward)
return bound;
}
-
-/* Return TRUE if a forwarding loop exists, i.e., the String `system'
- * is found more than 4 times in the return address.
- */
-static int
-forward_loop(char *addr, char *system)
-{
- int len = strlen(system), found = 0;
-
- while (addr = strchr(addr, '!'))
- if (!strncmp(++addr, system, len)
- && addr[len] == '!' && ++found == 4)
- return 1;
- return 0;
-}
-
diff --git a/sys/src/cmd/upas/send/cat_mail.c b/sys/src/cmd/upas/send/cat_mail.c
index cdd16eced..f4001aa09 100644
--- a/sys/src/cmd/upas/send/cat_mail.c
+++ b/sys/src/cmd/upas/send/cat_mail.c
@@ -1,57 +1,121 @@
#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.
+ */
-/* dispose of local addresses */
-int
-cat_mail(dest *dp, message *mp)
+static int
+mbox(dest *dp, message *mp, char *s)
{
- Biobuf *fp;
- char *rcvr, *cp;
+ char *tmp;
+ int i, n, e;
+ Biobuf *b;
Mlock *l;
- String *tmp, *s;
- int i, n;
- s = unescapespecial(s_clone(dp->repl1));
- if (nflg) {
- if(!xflg)
- print("cat >> %s\n", s_to_c(s));
- else
- print("%s\n", s_to_c(dp->addr));
- s_free(s);
- return 0;
- }
for(i = 0;; i++){
- l = syslock(s_to_c(s));
+ l = syslock(s);
if(l == 0)
return refuse(dp, mp, "can't lock mail file", 0, 0);
-
- fp = sysopen(s_to_c(s), "al", MBOXMODE);
- if(fp)
+ b = sysopen(s, "al", Mboxmode);
+ if(b)
break;
- tmp = s_append(0, s_to_c(s));
- s_append(tmp, ".tmp");
- fp = sysopen(s_to_c(tmp), "al", MBOXMODE);
- if(fp){
- syslog(0, "mail", "error: used %s", s_to_c(tmp));
- s_free(tmp);
+ b = sysopen(tmp = smprint("%s.tmp", s), "al", Mboxmode);
+ free(tmp);
+ sysunlock(l);
+ if(b){
+ syslog(0, "mail", "error: used %s.tmp", s);
break;
}
- s_free(tmp);
- sysunlock(l);
if(i >= 5)
return refuse(dp, mp, "mail file cannot be opened", 0, 0);
sleep(1000);
}
- s_free(s);
- n = m_print(mp, fp, (char *)0, 1);
- if (Bprint(fp, "\n") < 0 || Bflush(fp) < 0 || n < 0){
- sysclose(fp);
- sysunlock(l);
+ 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);
}
- sysclose(fp);
- sysunlock(l);
+ 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("upas/mbappend %s\n", s);
+ else
+ print("%s\n", s_to_c(dp->addr));
+ s_free(ss);
+ return 0;
+ }
+ /* avoid lock errors */
+ if(strcmp(s, "/dev/null") == 0){
+ 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;
diff --git a/sys/src/cmd/upas/send/dest.c b/sys/src/cmd/upas/send/dest.c
index 3d7fffe45..f5ff5b825 100644
--- a/sys/src/cmd/upas/send/dest.c
+++ b/sys/src/cmd/upas/send/dest.c
@@ -1,21 +1,17 @@
#include "common.h"
#include "send.h"
-static String* s_parseq(String*, String*);
-
/* exports */
dest *dlist;
-extern dest*
+dest*
d_new(String *addr)
{
dest *dp;
dp = (dest *)mallocz(sizeof(dest), 1);
- if (dp == 0) {
- perror("d_new");
- exit(1);
- }
+ if (dp == 0)
+ sysfatal("malloc: %r");
dp->same = dp;
dp->nsame = 1;
dp->nchar = 0;
@@ -27,7 +23,7 @@ d_new(String *addr)
return dp;
}
-extern void
+void
d_free(dest *dp)
{
if (dp != 0) {
@@ -46,7 +42,7 @@ d_free(dest *dp)
*/
/* Get first element from a circular list linked via 'next'. */
-extern dest *
+dest*
d_rm(dest **listp)
{
dest *dp;
@@ -63,7 +59,7 @@ d_rm(dest **listp)
}
/* Insert a new entry at the end of the list linked via 'next'. */
-extern void
+void
d_insert(dest **listp, dest *new)
{
dest *head;
@@ -82,7 +78,7 @@ d_insert(dest **listp, dest *new)
}
/* Get first element from a circular list linked via 'same'. */
-extern dest *
+dest*
d_rm_same(dest **listp)
{
dest *dp;
@@ -114,17 +110,20 @@ d_same_dup(dest *dp, dest *new)
return 0;
}
-/* Insert an entry into the corresponding list linked by 'same'. Note that
+/*
+ * Insert an entry into the corresponding list linked by 'same'. Note that
* the basic structure is a list of lists.
*/
-extern void
+void
d_same_insert(dest **listp, dest *new)
{
dest *dp;
int len;
if(new->status == d_pipe || new->status == d_cat) {
- len = new->repl2 ? strlen(s_to_c(new->repl2)) : 0;
+ len = 0;
+ if(new->repl2)
+ len = strlen(s_to_c(new->repl2));
if(*listp != 0){
dp = (*listp)->next;
do {
@@ -146,7 +145,10 @@ d_same_insert(dest **listp, dest *new)
dp = dp->next;
} while (dp != (*listp)->next);
}
- new->nchar = strlen(s_to_c(new->repl1)) + len + 1;
+ if(s_to_c(new->repl1))
+ new->nchar = strlen(s_to_c(new->repl1)) + len + 1;
+ else
+ new->nchar = 0;
}
new->next = new;
d_insert(listp, new);
@@ -157,7 +159,7 @@ d_same_insert(dest **listp, dest *new)
* The local! and !local! checks are artificial intelligence,
* there should be a better way.
*/
-extern String*
+String*
d_to(dest *list)
{
dest *np, *sp;
@@ -197,33 +199,6 @@ d_to(dest *list)
return unescapespecial(s);
}
-/* expand a String of destinations into a linked list of destiniations */
-extern dest *
-s_to_dest(String *sp, dest *parent)
-{
- String *addr;
- dest *list=0;
- dest *new;
-
- if (sp == 0)
- return 0;
- addr = s_new();
- while (s_parseq(sp, addr)!=0) {
- addr = escapespecial(addr);
- if(shellchars(s_to_c(addr))){
- while(new = d_rm(&list))
- d_free(new);
- break;
- }
- new = d_new(addr);
- new->parent = parent;
- new->authorized = parent->authorized;
- d_insert(&list, new);
- addr = s_new();
- }
- s_free(addr);
- return list;
-}
#define isspace(c) ((c)==' ' || (c)=='\t' || (c)=='\n')
@@ -257,3 +232,31 @@ s_parseq(String *from, String *to)
return to;
}
+
+/* expand a String of destinations into a linked list of destiniations */
+dest*
+s_to_dest(String *sp, dest *parent)
+{
+ String *addr;
+ dest *list=0;
+ dest *new;
+
+ if (sp == 0)
+ return 0;
+ addr = s_new();
+ while (s_parseq(sp, addr)!=0) {
+ addr = escapespecial(addr);
+ if(shellchars(s_to_c(addr))){
+ while(new = d_rm(&list))
+ d_free(new);
+ break;
+ }
+ new = d_new(addr);
+ new->parent = parent;
+ new->authorized = parent->authorized;
+ d_insert(&list, new);
+ addr = s_new();
+ }
+ s_free(addr);
+ return list;
+}
diff --git a/sys/src/cmd/upas/send/filter.c b/sys/src/cmd/upas/send/filter.c
index 83afd049e..e5fe926e2 100644
--- a/sys/src/cmd/upas/send/filter.c
+++ b/sys/src/cmd/upas/send/filter.c
@@ -1,36 +1,58 @@
#include "common.h"
#include "send.h"
+#include <regexp.h>
Biobuf bin;
-int rmail, tflg;
-char *subjectarg;
+int flagn;
+int flagx;
+int rmail;
+int tflg;
+char *subjectarg;
-char *findbody(char*);
+char*
+findbody(char *p)
+{
+ if(*p == '\n')
+ return p;
+
+ while(*p){
+ if(*p == '\n' && *(p+1) == '\n')
+ return p+1;
+ p++;
+ }
+ return p;
+}
+
+int
+refuse(dest*, message *, char *cp, int, int)
+{
+ fprint(2, "%s", cp);
+ exits("error");
+ return 0;
+}
void
usage(void)
{
- fprint(2, "usage: upas/filter [-bh] rcvr mailbox [regexp file] ...\n");
+ fprint(2, "usage: upas/filter [-nbh] rcvr mailbox [regexp file] ...\n");
exits("usage");
}
void
main(int argc, char *argv[])
{
+ char *cp, file[Pathlen];
+ int i, header, body;
message *mp;
dest *dp;
Reprog *p;
Resub match[10];
- char file[MAXPATHLEN];
- Biobuf *fp;
- char *rcvr, *cp;
- Mlock *l;
- String *tmp;
- int i;
- int header, body;
header = body = 0;
ARGBEGIN {
+ case 'n':
+ flagn = 1;
+ break;
case 'h':
header = 1;
break;
@@ -54,7 +76,6 @@ main(int argc, char *argv[])
mp->sender = s_copy(cp);
}
- dp = d_new(s_copy(argv[0]));
strecpy(file, file+sizeof file, argv[1]);
cp = findbody(s_to_c(mp->body));
for(i = 2; i < argc; i += 2){
@@ -74,62 +95,9 @@ main(int argc, char *argv[])
break;
}
}
-
- /*
- * always lock the normal mail file to avoid too many lock files
- * lying about. This isn't right but it's what the majority prefers.
- */
- l = syslock(argv[1]);
- if(l == 0){
- fprint(2, "can't lock mail file %s\n", argv[1]);
- exit(1);
- }
-
- /*
- * open the destination mail file
- */
- fp = sysopen(file, "ca", MBOXMODE);
- if (fp == 0){
- tmp = s_append(0, file);
- s_append(tmp, ".tmp");
- fp = sysopen(s_to_c(tmp), "cal", MBOXMODE);
- if(fp == 0){
- sysunlock(l);
- fprint(2, "can't open mail file %s\n", file);
- exit(1);
- }
- syslog(0, "mail", "error: used %s", s_to_c(tmp));
- s_free(tmp);
- }
- Bseek(fp, 0, 2);
- if(m_print(mp, fp, (char *)0, 1) < 0
- || Bprint(fp, "\n") < 0
- || Bflush(fp) < 0){
- sysclose(fp);
- sysunlock(l);
- fprint(2, "can't write mail file %s\n", file);
- exit(1);
- }
- sysclose(fp);
-
- sysunlock(l);
- rcvr = argv[0];
- if(cp = strrchr(rcvr, '!'))
- rcvr = cp+1;
- logdelivery(dp, rcvr, mp);
- exit(0);
-}
-
-char*
-findbody(char *p)
-{
- if(*p == '\n')
- return p;
-
- while(*p){
- if(*p == '\n' && *(p+1) == '\n')
- return p+1;
- p++;
- }
- return p;
+ dp = d_new(s_copy(argv[0]));
+ dp->repl1 = s_copy(file);
+ if(cat_mail(dp, mp) != 0)
+ exits("fail");
+ exits("");
}
diff --git a/sys/src/cmd/upas/send/gateway.c b/sys/src/cmd/upas/send/gateway.c
index fac9f42ea..ceb0b0b00 100644
--- a/sys/src/cmd/upas/send/gateway.c
+++ b/sys/src/cmd/upas/send/gateway.c
@@ -1,13 +1,11 @@
#include "common.h"
#include "send.h"
-#define isspace(c) ((c)==' ' || (c)=='\t' || (c)=='\n')
-
/*
* Translate the last component of the sender address. If the translation
* yields the same address, replace the sender with its last component.
*/
-extern void
+void
gateway(message *mp)
{
char *base;
diff --git a/sys/src/cmd/upas/send/local.c b/sys/src/cmd/upas/send/local.c
index 93136b7c6..c1014d3d8 100644
--- a/sys/src/cmd/upas/send/local.c
+++ b/sys/src/cmd/upas/send/local.c
@@ -1,12 +1,21 @@
#include "common.h"
#include "send.h"
+static String*
+mboxpath(char *path, char *user, String *to)
+{
+ char buf[Pathlen];
+
+ mboxpathbuf(buf, sizeof buf, user, path);
+ return s_append(to, buf);
+}
+
static void
mboxfile(dest *dp, String *user, String *path, char *file)
{
char *cp;
- mboxpath(s_to_c(user), s_to_c(dp->addr), path, 0);
+ mboxpath(s_to_c(user), s_to_c(dp->addr), path);
cp = strrchr(s_to_c(path), '/');
if(cp)
path->ptr = cp+1;
@@ -16,6 +25,52 @@ mboxfile(dest *dp, String *user, String *path, char *file)
}
/*
+ * BOTCH, BOTCH
+ * the problem is that we don't want to say a user exists
+ * just because the user has a mail box directory. that
+ * precludes using mode bits to disable mailboxes.
+ *
+ * botch #1: we pretend like we know that there must be a
+ * corresponding file or directory /mail/box/$user[/folder]/mbox
+ * this is wrong, but we get away with this for local mail boxes.
+ *
+ * botch #2: since the file server and not the auth server owns
+ * groups, it's not possible to get groups right. this means that
+ * a mailbox that only allows members of a group to post but
+ * not read wouldn't work.
+ */
+static uint accesstx[] = {
+[OREAD] 1<<2,
+[OWRITE] 1<<1,
+[ORDWR] 3<<1,
+[OEXEC] 1<<0
+};
+
+static int
+accessmbox(char *f, int m)
+{
+ int r, n;
+ Dir *d;
+
+ d = dirstat(f);
+ if(d == nil)
+ return -1;
+ n = 0;
+ if(m < nelem(accesstx))
+ n = accesstx[m];
+ if(d->mode & DMDIR)
+ n |= OEXEC;
+ r = (d->mode & n<<0) == n<<0;
+// if(r == 0 && inlist(mygids(), d->gid) == 0)
+// r = (d->mode & n<<3) == n<<3;
+ if(r == 0 && strcmp(getlog(), d->uid) == 0)
+ r = (d->mode & n<<6) == n<<6;
+ r--;
+ free(d);
+ return r;
+}
+
+/*
* Check forwarding requests
*/
extern dest*
@@ -43,7 +98,7 @@ expand_local(dest *dp)
/* if no replacement string, plug in user's name */
if(dp->repl1 == 0){
dp->repl1 = s_new();
- mboxname(user, dp->repl1);
+ mboxpath("mbox", user, dp->repl1);
}
s = unescapespecial(s_clone(dp->repl1));
@@ -95,7 +150,7 @@ expand_local(dest *dp)
* name passes through a shell. tdb.
*/
mboxfile(dp, dp->repl1, s_reset(file), "pipeto");
- if(sysexist(s_to_c(file))){
+ if(access(s_to_c(file), AEXEC) == 0){
if(debug)
fprint(2, "found a pipeto file\n");
dp->status = d_pipeto;
@@ -118,8 +173,8 @@ expand_local(dest *dp)
/*
* see if the mailbox directory exists
*/
- mboxfile(dp, s, s_reset(file), ".");
- if(sysexist(s_to_c(file)))
+ mboxfile(dp, s, s_reset(file), "mbox");
+ if(accessmbox(s_to_c(file), OWRITE) != -1)
dp->status = d_cat;
else
dp->status = d_unknown;
diff --git a/sys/src/cmd/upas/send/log.c b/sys/src/cmd/upas/send/log.c
index 52df38001..9324267e6 100644
--- a/sys/src/cmd/upas/send/log.c
+++ b/sys/src/cmd/upas/send/log.c
@@ -1,11 +1,8 @@
#include "common.h"
#include "send.h"
-/* configuration */
-#define LOGBiobuf "log/status"
-
/* log mail delivery */
-extern void
+void
logdelivery(dest *list, char *rcvr, message *mp)
{
dest *parent;
@@ -29,7 +26,7 @@ logdelivery(dest *list, char *rcvr, message *mp)
}
/* log mail forwarding */
-extern void
+void
loglist(dest *list, message *mp, char *tag)
{
dest *next;
@@ -57,7 +54,7 @@ loglist(dest *list, message *mp, char *tag)
}
/* log a mail refusal */
-extern void
+void
logrefusal(dest *dp, message *mp, char *msg)
{
char buf[2048];
@@ -67,7 +64,7 @@ logrefusal(dest *dp, message *mp, char *msg)
srcvr = unescapespecial(s_clone(dp->addr));
sender = unescapespecial(s_clone(mp->sender));
- sprint(buf, "error %.256s From %.256s %.256s\nerror+ ", s_to_c(srcvr),
+ snprint(buf, sizeof buf, "error %.256s From %.256s %.256s\nerror+ ", s_to_c(srcvr),
s_to_c(sender), s_to_c(mp->date));
s_free(srcvr);
s_free(sender);
diff --git a/sys/src/cmd/upas/send/main.c b/sys/src/cmd/upas/send/main.c
index dcf518825..77cebc782 100644
--- a/sys/src/cmd/upas/send/main.c
+++ b/sys/src/cmd/upas/send/main.c
@@ -2,94 +2,82 @@
#include "send.h"
/* globals to all files */
-int rmail;
-char *thissys, *altthissys;
-int nflg;
-int xflg;
-int debug;
-int rflg;
-int iflg = 1;
-int nosummary;
+int flagn;
+int flagx;
+int debug;
+int flagi = 1;
+int rmail;
+int nosummary;
+char *thissys;
+char *altthissys;
/* global to this file */
-static String *errstring;
-static message *mp;
-static int interrupt;
-static int savemail;
-static Biobuf in;
-static int forked;
-static int add822headers = 1;
-static String *arglist;
+static String *errstring;
+static message *mp;
+static int interrupt;
+static int savemail;
+static Biobuf in;
+static int forked;
+static int add822headers = 1;
+static String *arglist;
/* predeclared */
-static int send(dest *, message *, int);
-static void lesstedious(void);
-static void save_mail(message *);
-static int complain_mail(dest *, message *);
-static int pipe_mail(dest *, message *);
-static void appaddr(String *, dest *);
-static void mkerrstring(String *, message *, dest *, dest *, char *, int);
-static int replymsg(String *, message *, dest *);
-static int catchint(void*, char*);
+static int send(dest*, message*, int);
+static void lesstedious(void);
+static void save_mail(message*);
+static int complain_mail(dest*, message*);
+static int pipe_mail(dest*, message*);
+static int catchint(void*, char*);
void
usage(void)
{
- fprint(2, "usage: mail [-birtx] list-of-addresses\n");
+ fprint(2, "usage: send [-#bdirx] list-of-addresses\n");
exits("usage");
}
void
main(int argc, char *argv[])
{
- dest *dp=0;
- int checkforward;
- char *base;
int rv;
+ dest *dp;
- /* process args */
ARGBEGIN{
case '#':
- nflg = 1;
+ flagn = 1;
break;
case 'b':
add822headers = 0;
break;
- case 'x':
- nflg = 1;
- xflg = 1;
- break;
case 'd':
debug = 1;
break;
case 'i':
- iflg = 0;
+ flagi = 0;
break;
case 'r':
- rflg = 1;
+ rmail++;
+ break;
+ case 'x':
+ flagn = 1;
+ flagx = 1;
break;
default:
usage();
}ARGEND
- while(*argv){
+ if(*argv == 0)
+ usage();
+ dp = 0;
+ for(; *argv; argv++){
if(shellchars(*argv)){
fprint(2, "illegal characters in destination\n");
exits("syntax");
}
- d_insert(&dp, d_new(s_copy(*argv++)));
+ d_insert(&dp, d_new(s_copy(*argv)));
}
-
- if (dp == 0)
- usage();
arglist = d_to(dp);
- /*
- * get context:
- * - whether we're rmail or mail
- */
- base = basename(argv0);
- checkforward = rmail = (strcmp(base, "rmail")==0) | rflg;
thissys = sysname_read();
altthissys = alt_sysname_read();
if(rmail)
@@ -99,22 +87,22 @@ main(int argc, char *argv[])
* read the mail. If an interrupt occurs while reading, save in
* dead.letter
*/
- if (!nflg) {
+ if (!flagn) {
Binit(&in, 0, OREAD);
if(!rmail)
atnotify(catchint, 1);
- mp = m_read(&in, rmail, !iflg);
+ mp = m_read(&in, rmail, !flagi);
if (mp == 0)
- exit(0);
+ exits(0);
if (interrupt != 0) {
save_mail(mp);
- exit(1);
+ exits("interrupt");
}
} else {
mp = m_new();
if(default_from(mp) < 0){
fprint(2, "%s: can't determine login name\n", argv0);
- exit(1);
+ exits("fail");
}
}
errstring = s_new();
@@ -132,7 +120,7 @@ main(int argc, char *argv[])
* security reasons.
*/
mp->sender = escapespecial(mp->sender);
- if (shellchars(s_to_c(mp->sender)))
+ if(shellchars(s_to_c(mp->sender)))
mp->replyaddr = s_copy("postmaster");
else
mp->replyaddr = s_clone(mp->sender);
@@ -141,21 +129,21 @@ main(int argc, char *argv[])
* reject messages that have been looping for too long
*/
if(mp->received > 32)
- exit(refuse(dp, mp, "possible forward loop", 0, 0));
+ exits(refuse(dp, mp, "possible forward loop", 0, 0)? "refuse": "");
/*
* reject messages that are too long. We don't do it earlier
* in m_read since we haven't set up enough things yet.
*/
if(mp->size < 0)
- exit(refuse(dp, mp, "message too long", 0, 0));
+ exits(refuse(dp, mp, "message too long", 0, 0)? "refuse": "");
- rv = send(dp, mp, checkforward);
+ rv = send(dp, mp, rmail);
if(savemail)
save_mail(mp);
if(mp)
m_free(mp);
- exit(rv);
+ exits(rv? "fail": "");
}
/* send a message to a list of sites */
@@ -183,10 +171,7 @@ send(dest *destp, message *mp, int checkforward)
break;
case d_pipeto:
case d_pipe:
- if (!rmail && !nflg && !forked) {
- forked = 1;
- lesstedious();
- }
+ lesstedious();
errors += pipe_mail(dp, mp);
break;
default:
@@ -206,7 +191,8 @@ lesstedious(void)
if(debug)
return;
-
+ if(rmail || flagn || forked)
+ return;
switch(fork()){
case -1:
break;
@@ -215,9 +201,10 @@ lesstedious(void)
for(i=0; i<3; i++)
close(i);
savemail = 0;
+ forked = 1;
break;
default:
- exit(0);
+ exits("");
}
}
@@ -226,26 +213,23 @@ lesstedious(void)
static void
save_mail(message *mp)
{
+ char buf[Pathlen];
Biobuf *fp;
- String *file;
- file = s_new();
- deadletter(file);
- fp = sysopen(s_to_c(file), "cAt", 0660);
+ mboxpathbuf(buf, sizeof buf, getlog(), "dead.letter");
+ fp = sysopen(buf, "cAt", 0660);
if (fp == 0)
return;
m_bprint(mp, fp);
sysclose(fp);
- fprint(2, "saved in %s\n", s_to_c(file));
- s_free(file);
+ fprint(2, "saved in %s\n", buf);
}
/* remember the interrupt happened */
static int
-catchint(void *a, char *msg)
+catchint(void*, char *msg)
{
- USED(a);
if(strstr(msg, "interrupt") || strstr(msg, "hangup")) {
interrupt = 1;
return 1;
@@ -303,7 +287,7 @@ complain_mail(dest *dp, message *mp)
msg = "unknown d_";
break;
}
- if (nflg) {
+ if (flagn) {
print("%s: %s\n", msg, s_to_c(dp->addr));
return 0;
}
@@ -314,12 +298,22 @@ complain_mail(dest *dp, message *mp)
static int
pipe_mail(dest *dp, message *mp)
{
- dest *next, *list=0;
- String *cmd;
- process *pp;
- int status, r;
+ int status;
char *none;
- String *errstring=s_new();
+ dest *next, *list;
+ process *pp;
+ String *cmd;
+ String *errstring;
+
+ errstring = s_new();
+ list = 0;
+
+ /*
+ * we're just protecting users from their own
+ * pipeto scripts with this none business.
+ * this depends on none being able to append
+ * to a mail file.
+ */
if (dp->status == d_pipeto)
none = "none";
@@ -329,12 +323,12 @@ pipe_mail(dest *dp, message *mp)
* collect the arguments
*/
next = d_rm_same(&dp);
- if(xflg)
+ if(flagx)
cmd = s_new();
else
cmd = s_clone(next->repl1);
for(; next != 0; next = d_rm_same(&dp)){
- if(xflg){
+ if(flagx){
s_append(cmd, s_to_c(next->addr));
s_append(cmd, "\n");
} else {
@@ -346,8 +340,8 @@ pipe_mail(dest *dp, message *mp)
d_insert(&list, next);
}
- if (nflg) {
- if(xflg)
+ if (flagn) {
+ if(flagx)
print("%s", s_to_c(cmd));
else
print("%s\n", s_to_c(cmd));
@@ -375,127 +369,12 @@ pipe_mail(dest *dp, message *mp)
/*
* return status
*/
- if (status != 0) {
- r = refuse(list, mp, s_to_c(errstring), status, 0);
- s_free(errstring);
- return r;
- }
- s_free(errstring);
+ if (status != 0)
+ return refuse(list, mp, s_to_c(errstring), status, 0);
loglist(list, mp, "remote");
return 0;
}
-static void
-appaddr(String *sp, dest *dp)
-{
- dest *parent;
- String *s;
-
- if (dp->parent != 0) {
- for(parent=dp->parent; parent->parent!=0; parent=parent->parent)
- ;
- s = unescapespecial(s_clone(parent->addr));
- s_append(sp, s_to_c(s));
- s_free(s);
- s_append(sp, "' alias `");
- }
- s = unescapespecial(s_clone(dp->addr));
- s_append(sp, s_to_c(s));
- s_free(s);
-}
-
-/*
- * reject delivery
- *
- * returns 0 - if mail has been disposed of
- * other - if mail has not been disposed
- */
-int
-refuse(dest *list, message *mp, char *cp, int status, int outofresources)
-{
- String *errstring=s_new();
- dest *dp;
- int rv;
-
- dp = d_rm(&list);
- mkerrstring(errstring, mp, dp, list, cp, status);
-
- /*
- * log first in case we get into trouble
- */
- logrefusal(dp, mp, s_to_c(errstring));
-
- /*
- * bulk mail is never replied to, if we're out of resources,
- * let the sender try again
- */
- if(rmail){
- /* accept it or request a retry */
- if(outofresources){
- fprint(2, "Mail %s\n", s_to_c(errstring));
- rv = 1; /* try again later */
- } else if(mp->bulk)
- rv = 0; /* silently discard bulk */
- else
- rv = replymsg(errstring, mp, dp); /* try later if we can't reply */
- } else {
- /* aysnchronous delivery only happens if !rmail */
- if(forked){
- /*
- * if spun off for asynchronous delivery, we own the mail now.
- * return it or dump it on the floor. rv really doesn't matter.
- */
- rv = 0;
- if(!outofresources && !mp->bulk)
- replymsg(errstring, mp, dp);
- } else {
- fprint(2, "Mail %s\n", s_to_c(errstring));
- savemail = 1;
- rv = 1;
- }
- }
-
- s_free(errstring);
- return rv;
-}
-
-/* make the error message */
-static void
-mkerrstring(String *errstring, message *mp, dest *dp, dest *list, char *cp, int status)
-{
- dest *next;
- char smsg[64];
- String *sender;
-
- sender = unescapespecial(s_clone(mp->sender));
-
- /* list all aliases */
- s_append(errstring, " from '");
- s_append(errstring, s_to_c(sender));
- s_append(errstring, "'\nto '");
- appaddr(errstring, dp);
- for(next = d_rm(&list); next != 0; next = d_rm(&list)) {
- s_append(errstring, "'\nand '");
- appaddr(errstring, next);
- d_insert(&dp, next);
- }
- s_append(errstring, "'\nfailed with error '");
- s_append(errstring, cp);
- s_append(errstring, "'.\n");
-
- /* >> and | deserve different flavored messages */
- switch(dp->status) {
- case d_pipe:
- s_append(errstring, "The mailer `");
- s_append(errstring, s_to_c(dp->repl1));
- sprint(smsg, "' returned error status %x.\n\n", status);
- s_append(errstring, smsg);
- break;
- }
-
- s_free(sender);
-}
-
/*
* create a new boundary
*/
@@ -542,30 +421,30 @@ replymsg(String *errstring, message *mp, dest *dp)
refp->haveto = 1;
s_append(refp->body, "To: ");
s_append(refp->body, rcvr);
- s_append(refp->body, "\n");
- s_append(refp->body, "Subject: bounced mail\n");
- s_append(refp->body, "MIME-Version: 1.0\n");
- s_append(refp->body, "Content-Type: multipart/mixed;\n");
- s_append(refp->body, "\tboundary=\"");
+ s_append(refp->body, "\n"
+ "Subject: bounced mail\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: multipart/mixed;\n"
+ "\tboundary=\"");
s_append(refp->body, s_to_c(boundary));
- s_append(refp->body, "\"\n");
- s_append(refp->body, "Content-Disposition: inline\n");
- s_append(refp->body, "\n");
- s_append(refp->body, "This is a multi-part message in MIME format.\n");
- s_append(refp->body, "--");
+ s_append(refp->body, "\"\n"
+ "Content-Disposition: inline\n"
+ "\n"
+ "This is a multi-part message in MIME format.\n"
+ "--");
s_append(refp->body, s_to_c(boundary));
- s_append(refp->body, "\n");
- s_append(refp->body, "Content-Disposition: inline\n");
- s_append(refp->body, "Content-Type: text/plain; charset=\"US-ASCII\"\n");
- s_append(refp->body, "Content-Transfer-Encoding: 7bit\n");
- s_append(refp->body, "\n");
- s_append(refp->body, "The attached mail");
+ s_append(refp->body, "\n"
+ "Content-Disposition: inline\n"
+ "Content-Type: text/plain; charset=\"US-ASCII\"\n"
+ "Content-Transfer-Encoding: 7bit\n"
+ "\n"
+ "The attached mail");
s_append(refp->body, s_to_c(errstring));
s_append(refp->body, "--");
s_append(refp->body, s_to_c(boundary));
- s_append(refp->body, "\n");
- s_append(refp->body, "Content-Type: message/rfc822\n");
- s_append(refp->body, "Content-Disposition: inline\n\n");
+ s_append(refp->body, "\n"
+ "Content-Type: message/rfc822\n"
+ "Content-Disposition: inline\n\n");
s_append(refp->body, s_to_c(mp->body));
s_append(refp->body, "--");
s_append(refp->body, s_to_c(boundary));
@@ -577,3 +456,113 @@ replymsg(String *errstring, message *mp, dest *dp)
d_free(ndp);
return rv;
}
+
+static void
+appaddr(String *sp, dest *dp)
+{
+ dest *p;
+ String *s;
+
+ if (dp->parent != 0) {
+ for(p = dp->parent; p->parent; p = p->parent)
+ ;
+ s = unescapespecial(s_clone(p->addr));
+ s_append(sp, s_to_c(s));
+ s_free(s);
+ s_append(sp, "' alias `");
+ }
+ s = unescapespecial(s_clone(dp->addr));
+ s_append(sp, s_to_c(s));
+ s_free(s);
+}
+
+/* make the error message */
+static void
+mkerrstring(String *errstring, message *mp, dest *dp, dest *list, char *cp, int status)
+{
+ dest *next;
+ char smsg[64];
+ String *sender;
+
+ sender = unescapespecial(s_clone(mp->sender));
+
+ /* list all aliases */
+ s_append(errstring, " from '");
+ s_append(errstring, s_to_c(sender));
+ s_append(errstring, "'\nto '");
+ appaddr(errstring, dp);
+ for(next = d_rm(&list); next != 0; next = d_rm(&list)) {
+ s_append(errstring, "'\nand '");
+ appaddr(errstring, next);
+ d_insert(&dp, next);
+ }
+ s_append(errstring, "'\nfailed with error '");
+ s_append(errstring, cp);
+ s_append(errstring, "'.\n");
+
+ /* >> and | deserve different flavored messages */
+ switch(dp->status) {
+ case d_pipe:
+ s_append(errstring, "The mailer `");
+ s_append(errstring, s_to_c(dp->repl1));
+ sprint(smsg, "' returned error status %x.\n\n", status);
+ s_append(errstring, smsg);
+ break;
+ }
+
+ s_free(sender);
+}
+
+/*
+ * reject delivery
+ *
+ * returns 0 - if mail has been disposed of
+ * other - if mail has not been disposed
+ */
+int
+refuse(dest *list, message *mp, char *cp, int status, int outofresources)
+{
+ int rv;
+ String *errstring;
+ dest *dp;
+
+ errstring = s_new();
+ dp = d_rm(&list);
+ mkerrstring(errstring, mp, dp, list, cp, status);
+
+ /*
+ * log first in case we get into trouble
+ */
+ logrefusal(dp, mp, s_to_c(errstring));
+
+ rv = 1;
+ if(rmail){
+ /* accept it or request a retry */
+ if(outofresources){
+ fprint(2, "Mail %s\n", s_to_c(errstring));
+ } else {
+ /*
+ * reject without generating a reply, smtpd returns
+ * 5.0.0 status when it sees "mail refused"
+ */
+ fprint(2, "mail refused: %s\n", s_to_c(errstring));
+ }
+ } else {
+ /* aysnchronous delivery only happens if !rmail */
+ if(forked){
+ /*
+ * if spun off for asynchronous delivery, we own the mail now.
+ * return it or dump it on the floor. rv really doesn't matter.
+ */
+ rv = 0;
+ if(!outofresources && !mp->bulk)
+ replymsg(errstring, mp, dp);
+ } else {
+ fprint(2, "Mail %s\n", s_to_c(errstring));
+ savemail = 1;
+ }
+ }
+
+ s_free(errstring);
+ return rv;
+}
diff --git a/sys/src/cmd/upas/send/makefile b/sys/src/cmd/upas/send/makefile
deleted file mode 100644
index f0abcf0c1..000000000
--- a/sys/src/cmd/upas/send/makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-SSRC= message.c main.c bind.c rewrite.c local.c dest.c process.c translate.c\
- log.c chkfwd.c notify.c gateway.c authorize.o ../common/*.c
-SOBJ= message.o main.o bind.o rewrite.o local.o dest.o process.o translate.o\
- log.o chkfwd.o notify.o gateway.o authorize.o\
- ../config/config.o ../common/common.a ../libc/libc.a
-SINC= ../common/mail.h ../common/string.h ../common/aux.h
-CFLAGS=${UNIX} -g -I. -I../libc -I../common -I/usr/include ${SCFLAGS}
-LFLAGS=-g
-.c.o: ; $(CC) -c $(CFLAGS) $*.c
-LIB=/usr/lib/upas
-
-all: send
-
-send: $(SOBJ)
- $(CC) $(SOBJ) $(LFLAGS) -o send
-
-chkfwd.o: $(SINC) message.h dest.h
-dest.o: $(SINC) dest.h
-local.o: $(SINC) dest.h process.h
-log.o: $(SINC) message.h
-main.o: $(SINC) message.h dest.h process.h
-bind.o: $(SINC) dest.h message.h
-process.o: $(SINC) process.h
-rewrite.o: $(SINC) dest.h
-translate.o: $(SINC) dest.h process.h
-message.o: $(SINC) message.h
-notify.o: $(SINC) message.h
-gateway.o: $(SINC) dest.h message.h
-
-prcan:
- prcan $(SSRC)
-
-clean:
- -rm -f send *.[oO] a.out core *.sL rmail
-
-cyntax:
- cyntax $(CFLAGS) $(SSRC)
-
-install: send
- rm -f $(LIB)/send /bin/rmail
- cp send $(LIB)/send
- cp send /bin/rmail
- strip /bin/rmail
- strip $(LIB)/send
- chown root $(LIB)/send /bin/rmail
- chmod 4755 $(LIB)/send /bin/rmail
diff --git a/sys/src/cmd/upas/send/message.c b/sys/src/cmd/upas/send/message.c
index 69cddd87c..02b7520f2 100644
--- a/sys/src/cmd/upas/send/message.c
+++ b/sys/src/cmd/upas/send/message.c
@@ -1,49 +1,51 @@
#include "common.h"
#include "send.h"
-
+#include <regexp.h>
#include "../smtp/smtp.h"
#include "../smtp/y.tab.h"
+enum{
+ VMLIMIT = 64*1024,
+ MSGLIMIT = 128*1024*1024,
+};
+
/* global to this file */
static Reprog *rfprog;
static Reprog *fprog;
-#define VMLIMIT (64*1024)
-#define MSGLIMIT (128*1024*1024)
-
int received; /* from rfc822.y */
static String* getstring(Node *p);
static String* getaddr(Node *p);
-extern int
+int
default_from(message *mp)
{
char *cp, *lp;
cp = getenv("upasname");
lp = getlog();
- if(lp == nil)
+ if(lp == nil){
+ free(cp);
return -1;
-
+ }
if(cp && *cp)
s_append(mp->sender, cp);
else
s_append(mp->sender, lp);
+ free(cp);
s_append(mp->date, thedate());
return 0;
}
-extern message *
+message*
m_new(void)
{
message *mp;
- mp = (message *)mallocz(sizeof(message), 1);
- if (mp == 0) {
- perror("message:");
- exit(1);
- }
+ mp = (message*)mallocz(sizeof(message), 1);
+ if (mp == 0)
+ sysfatal("m_new: %r");
mp->sender = s_new();
mp->replyaddr = s_new();
mp->date = s_new();
@@ -53,14 +55,11 @@ m_new(void)
return mp;
}
-extern void
+void
m_free(message *mp)
{
- if(mp->fd >= 0){
+ if(mp->fd >= 0)
close(mp->fd);
- sysremove(s_to_c(mp->tmp));
- s_free(mp->tmp);
- }
s_free(mp->sender);
s_free(mp->date);
s_free(mp->body);
@@ -68,34 +67,28 @@ m_free(message *mp)
s_free(mp->havesender);
s_free(mp->havereplyto);
s_free(mp->havesubject);
- free((char *)mp);
+ free(mp);
}
/* read a message into a temp file, return an open fd to it in mp->fd */
static int
m_read_to_file(Biobuf *fp, message *mp)
{
- int fd;
- int n;
- String *file;
- char buf[4*1024];
+ char buf[4*1024], file[Pathlen];
+ int fd, n;
- file = s_new();
+ snprint(file, sizeof file, "%s/mtXXXXXX", UPASTMP);
/*
* create temp file to be removed on close
*/
- abspath("mtXXXXXX", UPASTMP, file);
- mktemp(s_to_c(file));
- if((fd = syscreate(s_to_c(file), ORDWR|ORCLOSE, 0600))<0){
- s_free(file);
+ mktemp(file);
+ if((fd = create(file, ORDWR|ORCLOSE, 0600))<0)
return -1;
- }
- mp->tmp = file;
/*
* read the rest into the temp file
*/
- while((n = Bread(fp, buf, sizeof(buf))) > 0){
+ while((n = Bread(fp, buf, sizeof buf)) > 0){
if(write(fd, buf, n) != n){
close(fd);
return -1;
@@ -132,9 +125,9 @@ getstring(Node *p)
return s;
for(p = p->next; p; p = p->next){
- if(p->s){
+ if(p->s)
s_append(s, s_to_c(p->s));
- }else{
+ else{
s_putc(s, p->c);
s_terminate(s);
}
@@ -144,35 +137,6 @@ getstring(Node *p)
return s;
}
-static char *fieldname[] =
-{
-[WORD-WORD] "WORD",
-[DATE-WORD] "DATE",
-[RESENT_DATE-WORD] "RESENT_DATE",
-[RETURN_PATH-WORD] "RETURN_PATH",
-[FROM-WORD] "FROM",
-[SENDER-WORD] "SENDER",
-[REPLY_TO-WORD] "REPLY_TO",
-[RESENT_FROM-WORD] "RESENT_FROM",
-[RESENT_SENDER-WORD] "RESENT_SENDER",
-[RESENT_REPLY_TO-WORD] "RESENT_REPLY_TO",
-[SUBJECT-WORD] "SUBJECT",
-[TO-WORD] "TO",
-[CC-WORD] "CC",
-[BCC-WORD] "BCC",
-[RESENT_TO-WORD] "RESENT_TO",
-[RESENT_CC-WORD] "RESENT_CC",
-[RESENT_BCC-WORD] "RESENT_BCC",
-[REMOTE-WORD] "REMOTE",
-[PRECEDENCE-WORD] "PRECEDENCE",
-[MIMEVERSION-WORD] "MIMEVERSION",
-[CONTENTTYPE-WORD] "CONTENTTYPE",
-[MESSAGEID-WORD] "MESSAGEID",
-[RECEIVED-WORD] "RECEIVED",
-[MAILER-WORD] "MAILER",
-[BADTOKEN-WORD] "BADTOKEN",
-};
-
/* fix 822 addresses */
static void
rfc822cruft(message *mp)
@@ -251,8 +215,35 @@ rfc822cruft(message *mp)
mp->body = body;
}
+/* append a sub-expression match onto a String */
+static void
+append_match(Resub *subexp, String *sp, int se)
+{
+ char *cp, *ep;
+
+ cp = subexp[se].sp;
+ ep = subexp[se].ep;
+ for (; cp < ep; cp++)
+ s_putc(sp, *cp);
+ s_terminate(sp);
+}
+
+
+static char *REMFROMRE =
+ "^>?From[ \t]+((\".*\")?[^\" \t]+?(\".*\")?[^\" \t]+?)[ \t]+(.+)[ \t]+remote[ \t]+from[ \t]+(.*)\n$";
+static char *FROMRE =
+ "^>?From[ \t]+((\".*\")?[^\" \t]+?(\".*\")?[^\" \t]+?)[ \t]+(.+)\n$";
+
+enum{
+ REMSENDERMATCH = 1,
+ SENDERMATCH = 1,
+ REMDATEMATCH = 4,
+ DATEMATCH = 4,
+ REMSYSMATCH = 5,
+};
+
/* read in a message, interpret the 'From' header */
-extern message *
+message*
m_read(Biobuf *fp, int rmail, int interactive)
{
message *mp;
@@ -326,18 +317,12 @@ m_read(Biobuf *fp, int rmail, int interactive)
*/
mp->size = mp->body->ptr - mp->body->base;
n = s_read(fp, mp->body, VMLIMIT);
- if(n < 0){
- perror("m_read");
- exit(1);
- }
+ if(n < 0)
+ sysfatal("m_read: %r");
mp->size += n;
- if(n == VMLIMIT){
- if(m_read_to_file(fp, mp) < 0){
- perror("m_read");
- exit(1);
- }
- }
-
+ if(n == VMLIMIT)
+ if(m_read_to_file(fp, mp) < 0)
+ sysfatal("m_read: %r");
}
/*
@@ -352,8 +337,8 @@ m_read(Biobuf *fp, int rmail, int interactive)
}
/* return a piece of message starting at `offset' */
-extern int
-m_get(message *mp, long offset, char **pp)
+int
+m_get(message *mp, vlong offset, char **pp)
{
static char buf[4*1024];
@@ -377,10 +362,8 @@ m_get(message *mp, long offset, char **pp)
offset -= s_len(mp->body);
if(mp->fd < 0)
return -1;
- if(seek(mp->fd, offset, 0)<0)
- return -1;
*pp = buf;
- return read(mp->fd, buf, sizeof buf);
+ return pread(mp->fd, buf, sizeof buf, offset);
}
/* output the message body without ^From escapes */
@@ -444,20 +427,22 @@ m_escape(message *mp, Biobuf *fp)
static int
printfrom(message *mp, Biobuf *fp)
{
- String *s;
+// char *p;
int rv;
+ String *s;
if(!returnable(s_to_c(mp->sender)))
return Bprint(fp, "From: Postmaster\n");
- s = username(mp->sender);
- if(s) {
- s_append(s, " <");
- s_append(s, s_to_c(mp->sender));
- s_append(s, ">");
- } else {
+// p = username(s_to_c(mp->sender));
+// if(p) {
+// s_append(s = s_new(), p);
+// s_append(s, " <");
+// s_append(s, s_to_c(mp->sender));
+// s_append(s, ">");
+// } else {
s = s_copy(s_to_c(mp->sender));
- }
+// }
s = unescapespecial(s);
rv = Bprint(fp, "From: %s\n", s_to_c(s));
s_free(s);
@@ -509,34 +494,30 @@ printutf8mime(Biobuf *b)
}
/* output a message */
-extern int
+int
m_print(message *mp, Biobuf *fp, char *remote, int mbox)
{
- String *date, *sender;
- char *f[6];
- int n;
+ char *date, *d, *f[6];
+ int n, r;
+ String *sender;
sender = unescapespecial(s_clone(mp->sender));
-
- if (remote != 0){
- if(print_remote_header(fp,s_to_c(sender),s_to_c(mp->date),remote) < 0){
- s_free(sender);
- return -1;
- }
- } else {
- if(print_header(fp, s_to_c(sender), s_to_c(mp->date)) < 0){
- s_free(sender);
- return -1;
- }
- }
+ date = s_to_c(mp->date);
+ if(remote)
+ r = Bprint(fp, "From %s %s remote from %s\n", s_to_c(sender), date, remote);
+ else
+ r = Bprint(fp, "From %s %s\n", s_to_c(sender), date);
s_free(sender);
+ if(r < 0)
+ return -1;
if(!rmail && !mp->havedate){
/* add a date: line Date: Sun, 19 Apr 1998 12:27:52 -0400 */
- date = s_copy(s_to_c(mp->date));
- n = getfields(s_to_c(date), f, 6, 1, " \t");
+ d = strdup(date);
+ n = getfields(date, f, 6, 1, " \t");
if(n == 6)
Bprint(fp, "Date: %s, %s %s %s %s %s\n", f[0], f[2], f[1],
f[5], f[3], rewritezone(f[4]));
+ free(d);
}
if(!rmail && !mp->havemime && isutf8(mp->body))
printutf8mime(fp);
@@ -559,13 +540,13 @@ m_print(message *mp, Biobuf *fp, char *remote, int mbox)
return -1;
}
- if (!mbox)
+ if(!mbox)
return m_noescape(mp, fp);
return m_escape(mp, fp);
}
/* print just the message body */
-extern int
+int
m_bprint(message *mp, Biobuf *fp)
{
return m_noescape(mp, fp);
diff --git a/sys/src/cmd/upas/send/mkfile b/sys/src/cmd/upas/send/mkfile
index a895cd4a4..549d234f0 100644
--- a/sys/src/cmd/upas/send/mkfile
+++ b/sys/src/cmd/upas/send/mkfile
@@ -1,4 +1,5 @@
</$objtype/mkfile
+<../mkupas
TARG=send\
filter
@@ -12,16 +13,19 @@ OFILES=\
$UOFILES\
../smtp/rfc822.tab.$O\
-SMOBJ=main.$O\
+SOBJ=\
+ authorize.$O\
bind.$O\
- rewrite.$O\
+ cat_mail.$O\
+ gateway.$O\
local.$O\
+ main.$O\
+ rewrite.$O\
translate.$O\
- authorize.$O\
- gateway.$O\
+
+FOBJ=\
cat_mail.$O\
-LIB=../common/libcommon.av\
HFILES=send.h\
../common/common.h\
@@ -29,24 +33,22 @@ HFILES=send.h\
LIB=../common/libcommon.a$O\
-BIN=/$objtype/bin/upas
UPDATE=\
mkfile\
$HFILES\
${UOFILES:%.$O=%.c}\
- ${SMOBJ:%.$O=%.c}\
+ ${SOBJ:%.$O=%.c}\
${TARG:%=%.c}\
</sys/src/cmd/mkmany
CFLAGS=$CFLAGS -I../common
-$O.send: $SMOBJ $OFILES
+$O.send: $SOBJ $OFILES
$LD $LDFLAGS -o $target $prereq $LIB
+$O.filter: $FOBJ
+
message.$O: ../smtp/y.tab.h
../smtp/y.tab.h ../smtp/rfc822.tab.$O: ../smtp/rfc822.y
- @{
- cd ../smtp
- mk rfc822.tab.$O
- }
+ cd ../smtp && mk rfc822.tab.$O
diff --git a/sys/src/cmd/upas/send/rewrite.c b/sys/src/cmd/upas/send/rewrite.c
index 8feebc9ad..3dde19080 100644
--- a/sys/src/cmd/upas/send/rewrite.c
+++ b/sys/src/cmd/upas/send/rewrite.c
@@ -1,5 +1,6 @@
#include "common.h"
#include "send.h"
+#include <regexp.h>
extern int debug;
@@ -32,7 +33,7 @@ static rule *findrule(String *, int);
* Get the next token from `line'. The symbol `\l' is replaced by
* the name of the local system.
*/
-extern String *
+String*
rule_parse(String *line, char *system, int *backl)
{
String *token;
@@ -80,10 +81,8 @@ getrule(String *line, String *type, char *system)
if(re == 0)
return 0;
rp = (rule *)malloc(sizeof(rule));
- if(rp == 0) {
- perror("getrules:");
- exit(1);
- }
+ if(rp == 0)
+ sysfatal("malloc: %r");
rp->next = 0;
s_tolower(re);
rp->matchre = s_new();
@@ -123,16 +122,15 @@ getrule(String *line, String *type, char *system)
* rules are of the form:
* <reg exp> <String> <repl exp> [<repl exp>]
*/
-extern int
+int
getrules(void)
{
- Biobuf *rfp;
- String *line;
- String *type;
- String *file;
+ char file[Pathlen];
+ Biobuf *rfp;
+ String *line, *type;
- file = abspath("rewrite", UPASLIB, (String *)0);
- rfp = sysopen(s_to_c(file), "r", 0);
+ snprint(file, sizeof file, "%s/rewrite", UPASLIB);
+ rfp = sysopen(file, "r", 0);
if(rfp == 0) {
rulep = 0;
return -1;
@@ -145,7 +143,6 @@ getrules(void)
getrule(s_restart(line), type, altthissys);
s_free(type);
s_free(line);
- s_free(file);
sysclose(rfp);
return 0;
}
@@ -168,8 +165,7 @@ findrule(String *addrp, int authorized)
continue;
memset(rp->subexp, 0, sizeof(rp->subexp));
if(debug)
- fprint(2, "matching %s against %s\n", s_to_c(addrp),
- rp->matchre->base);
+ fprint(2, "matching %s aginst %s\n", s_to_c(addrp), rp->matchre->base);
if(regexec(rp->program, s_to_c(addrp), rp->subexp, NSUBEXP))
if(s_to_c(addrp) == rp->subexp[0].sp)
if((s_to_c(addrp) + strlen(s_to_c(addrp))) == rp->subexp[0].ep)
@@ -183,7 +179,7 @@ findrule(String *addrp, int authorized)
* 0 ifaddress matched and ok to forward
* 1 ifaddress matched and not ok to forward
*/
-extern int
+int
rewrite(dest *dp, message *mp)
{
rule *rp; /* rewriting rule */
@@ -279,40 +275,39 @@ substitute(String *source, Resub *subexp, message *mp)
return s_restart(stp);
}
-extern void
+void
regerror(char* s)
{
fprint(2, "rewrite: %s\n", s);
/* make sure the message is seen locally */
- syslog(0, "mail", "regexp error in rewrite: %s", s);
-}
-
-extern void
-dumprules(void)
-{
- rule *rp;
-
- for (rp = rulep; rp != 0; rp = rp->next) {
- fprint(2, "'%s'", rp->matchre->base);
- switch (rp->type) {
- case d_pipe:
- fprint(2, " |");
- break;
- case d_cat:
- fprint(2, " >>");
- break;
- case d_alias:
- fprint(2, " alias");
- break;
- case d_translate:
- fprint(2, " translate");
- break;
- default:
- fprint(2, " UNKNOWN");
- break;
- }
- fprint(2, " '%s'", rp->repl1 ? rp->repl1->base:"...");
- fprint(2, " '%s'\n", rp->repl2 ? rp->repl2->base:"...");
- }
+ syslog(0, "mail", "error in rewrite: %s", s);
}
+//void
+//dumprules(void)
+//{
+// rule *rp;
+//
+// for (rp = rulep; rp != 0; rp = rp->next) {
+// fprint(2, "'%s'", rp->matchre->base);
+// switch (rp->type) {
+// case d_pipe:
+// fprint(2, " |");
+// break;
+// case d_cat:
+// fprint(2, " >>");
+// break;
+// case d_alias:
+// fprint(2, " alias");
+// break;
+// case d_translate:
+// fprint(2, " translate");
+// break;
+// default:
+// fprint(2, " UNKNOWN");
+// break;
+// }
+// fprint(2, " '%s'", rp->repl1 ? rp->repl1->base:"...");
+// fprint(2, " '%s'\n", rp->repl2 ? rp->repl2->base:"...");
+// }
+//}
diff --git a/sys/src/cmd/upas/send/send.h b/sys/src/cmd/upas/send/send.h
index 45fd61c33..1b7d4537d 100644
--- a/sys/src/cmd/upas/send/send.h
+++ b/sys/src/cmd/upas/send/send.h
@@ -1,11 +1,5 @@
-/*
- * these limits are intended to stay within those imposed by SMTP
- * and avoid tickling bugs in other mail systems.
- * they both pertain to attempts to group recipients for the same
- * destination together in a single copy of a message.
- */
-#define MAXSAME 32 /* max recipients; was 16 */
-#define MAXSAMECHAR 1024 /* max chars in the list of recipients */
+#define MAXSAME 16
+#define MAXSAMECHAR 1024
/* status of a destination*/
typedef enum {
@@ -47,43 +41,35 @@ struct message {
String *replyaddr;
String *date;
String *body;
- String *tmp; /* name of temp file */
String *to;
int size;
int fd; /* if >= 0, the file the message is stored in*/
- char haveto;
String *havefrom;
String *havesender;
String *havereplyto;
char havedate;
char havemime;
String *havesubject;
- char bulk; /* if Precedence: Bulk in header */
char rfc822headers;
- int received; /* number of received lines */
char *boundary; /* bondary marker for attachments */
+ char haveto;
+ char bulk; /* if Precedence: Bulk in header */
+ char received; /* number of received lines */
};
-/*
- * exported variables
- */
-extern int rmail;
-extern int onatty;
-extern char *thissys, *altthissys;
-extern int xflg;
-extern int nflg;
-extern int tflg;
-extern int debug;
-extern int nosummary;
+extern int rmail;
+extern int onatty;
+extern char *thissys;
+extern char *altthissys;
+extern int debug;
+extern int nosummary;
+extern int flagn;
+extern int flagx;
-/*
- * exported procedures
- */
extern void authorize(dest*);
extern int cat_mail(dest*, message*);
extern dest *up_bind(dest*, message*, int);
extern int ok_to_forward(char*);
-extern int lookup(char*, char*, Biobuf**, char*, Biobuf**);
extern dest *d_new(String*);
extern void d_free(dest*);
extern dest *d_rm(dest**);
@@ -101,7 +87,7 @@ extern int default_from(message*);
extern message *m_new(void);
extern void m_free(message*);
extern message *m_read(Biobuf*, int, int);
-extern int m_get(message*, long, char**);
+extern int m_get(message*, vlong, char**);
extern int m_print(message*, Biobuf*, char*, int);
extern int m_bprint(message*, Biobuf*);
extern String *rule_parse(String*, char*, int*);
diff --git a/sys/src/cmd/upas/send/skipequiv.c b/sys/src/cmd/upas/send/skipequiv.c
index 43d7b8ac3..c6da2557c 100644
--- a/sys/src/cmd/upas/send/skipequiv.c
+++ b/sys/src/cmd/upas/send/skipequiv.c
@@ -3,10 +3,53 @@
#define isspace(c) ((c)==' ' || (c)=='\t' || (c)=='\n')
+static int
+okfile(char *s, Biobuf *b)
+{
+ char *buf, *p, *e;
+ int len, c;
+
+ len = strlen(s);
+ Bseek(b, 0, 0);
+
+ /* one iteration per system name in the file */
+ while(buf = Brdline(b, '\n')) {
+ e = buf + Blinelen(b);
+ for(p = buf; p < e;){
+ while(isspace(*p) || *p==',')
+ p++;
+ if(strncmp(p, s, len) == 0) {
+ c = p[len];
+ if(isspace(c) || c==',')
+ return 1;
+ }
+ while(p < e && (!isspace(*p)) && *p!=',')
+ p++;
+ }
+ }
+ /* didn't find it, prohibit forwarding */
+ return 0;
+}
+
+/* return 1 if name found in file
+ * 0 if name not found
+ * -1 if
+ */
+static int
+lookup(char *s, char *local, Biobuf **b)
+{
+ char file[Pathlen];
+
+ snprint(file, sizeof file, "%s/%s", UPASLIB, local);
+ if(*b != nil || (*b = sysopen(file, "r", 0)) != nil)
+ return okfile(s, *b);
+ return 0;
+}
+
/*
* skip past all systems in equivlist
*/
-extern char*
+char*
skipequiv(char *base)
{
char *sp;
@@ -17,7 +60,7 @@ skipequiv(char *base)
if(sp==0)
break;
*sp = '\0';
- if(lookup(base, "equivlist", &fp, 0, 0)==1){
+ if(lookup(base, "equivlist", &fp)==1){
/* found or us, forget this system */
*sp='!';
base=sp+1;
@@ -29,64 +72,3 @@ skipequiv(char *base)
}
return base;
}
-
-static int
-okfile(char *cp, Biobuf *fp)
-{
- char *buf;
- int len;
- char *bp, *ep;
- int c;
-
- len = strlen(cp);
- Bseek(fp, 0, 0);
-
- /* one iteration per system name in the file */
- while(buf = Brdline(fp, '\n')) {
- ep = &buf[Blinelen(fp)];
- for(bp=buf; bp < ep;){
- while(isspace(*bp) || *bp==',')
- bp++;
- if(strncmp(bp, cp, len) == 0) {
- c = *(bp+len);
- if(isspace(c) || c==',')
- return 1;
- }
- while(bp < ep && (!isspace(*bp)) && *bp!=',')
- bp++;
- }
- }
-
- /* didn't find it, prohibit forwarding */
- return 0;
-}
-
-/* return 1 if name found in one of the files
- * 0 if name not found in one of the files
- * -1 if neither file exists
- */
-extern int
-lookup(char *cp, char *local, Biobuf **lfpp, char *global, Biobuf **gfpp)
-{
- static String *file = 0;
-
- if (local) {
- if (file == 0)
- file = s_new();
- abspath(local, UPASLIB, s_restart(file));
- if (*lfpp != 0 || (*lfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
- if (okfile(cp, *lfpp))
- return 1;
- } else
- local = 0;
- }
- if (global) {
- abspath(global, UPASLIB, s_restart(file));
- if (*gfpp != 0 || (*gfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
- if (okfile(cp, *gfpp))
- return 1;
- } else
- global = 0;
- }
- return (local || global)? 0 : -1;
-}
diff --git a/sys/src/cmd/upas/send/translate.c b/sys/src/cmd/upas/send/translate.c
index 0332659c0..e2dd7382f 100644
--- a/sys/src/cmd/upas/send/translate.c
+++ b/sys/src/cmd/upas/send/translate.c
@@ -11,7 +11,7 @@ translate(dest *dp)
char *cp;
int n;
- pp = proc_start(s_to_c(dp->repl1), (stream *)0, outstream(), outstream(), 1, 0);
+ pp = proc_start(s_to_c(dp->repl1), 0, outstream(), outstream(), 1, 0);
if (pp == 0) {
dp->status = d_resource;
return 0;
diff --git a/sys/src/cmd/upas/send/tryit b/sys/src/cmd/upas/send/tryit
deleted file mode 100755
index fed3a2a60..000000000
--- a/sys/src/cmd/upas/send/tryit
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-set -x
-
-> /usr/spool/mail/test.local
-echo "Forward to test.local" > /usr/spool/mail/test.forward
-echo "Pipe to cat > /tmp/test.mail" > /usr/spool/mail/test.pipe
-chmod 644 /usr/spool/mail/test.pipe
-
-mail test.local <<EOF
-mailed to test.local
-EOF
-mail test.forward <<EOF
-mailed to test.forward
-EOF
-mail test.pipe <<EOF
-mailed to test.pipe
-EOF
-mail dutoit!bowell!test.local <<EOF
-mailed to dutoit!bowell!test.local
-EOF
-
-sleep 60
-
-ls -l /usr/spool/mail/test.*
-ls -l /tmp/test.mail
-echo ">>>test.local<<<"
-cat /usr/spool/mail/test.local
-echo ">>>test.mail<<<"
-cat /tmp/test.mail