diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-03-12 17:15:03 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-03-12 17:15:03 +0100 |
commit | 963cfc9a6f6e721f52aa949e6d1af0c3e8dc2ecc (patch) | |
tree | 749b74875dbc49bcf6ed0776648b8f0ef9417407 /sys/src/cmd/upas/send | |
parent | 8177d20fb2709ba9290dfd41308b8e5bee4e00f8 (diff) |
merging erik quanstros nupas
Diffstat (limited to 'sys/src/cmd/upas/send')
-rw-r--r-- | sys/src/cmd/upas/send/authorize.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/bind.c | 48 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/cat_mail.c | 134 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/dest.c | 89 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/filter.c | 108 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/gateway.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/local.c | 65 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/log.c | 11 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/main.c | 425 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/makefile | 46 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/message.c | 195 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/mkfile | 26 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/rewrite.c | 89 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/send.h | 42 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/skipequiv.c | 108 | ||||
-rw-r--r-- | sys/src/cmd/upas/send/translate.c | 2 | ||||
-rwxr-xr-x | sys/src/cmd/upas/send/tryit | 29 |
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 |