summaryrefslogtreecommitdiff
path: root/sys/src/cmd/upas/common
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/common
parent8177d20fb2709ba9290dfd41308b8e5bee4e00f8 (diff)
merging erik quanstros nupas
Diffstat (limited to 'sys/src/cmd/upas/common')
-rw-r--r--sys/src/cmd/upas/common/appendfiletombox.c164
-rw-r--r--sys/src/cmd/upas/common/aux.c47
-rw-r--r--sys/src/cmd/upas/common/become.c3
-rw-r--r--sys/src/cmd/upas/common/common.h105
-rw-r--r--sys/src/cmd/upas/common/config.c16
-rw-r--r--sys/src/cmd/upas/common/flags.c73
-rw-r--r--sys/src/cmd/upas/common/fmt.c35
-rw-r--r--sys/src/cmd/upas/common/folder.c361
-rw-r--r--sys/src/cmd/upas/common/libsys.c668
-rw-r--r--sys/src/cmd/upas/common/mail.c57
-rw-r--r--sys/src/cmd/upas/common/makefile18
-rw-r--r--sys/src/cmd/upas/common/mkfile18
-rw-r--r--sys/src/cmd/upas/common/process.c19
-rw-r--r--sys/src/cmd/upas/common/sys.h100
-rw-r--r--sys/src/cmd/upas/common/totm.c36
15 files changed, 831 insertions, 889 deletions
diff --git a/sys/src/cmd/upas/common/appendfiletombox.c b/sys/src/cmd/upas/common/appendfiletombox.c
deleted file mode 100644
index 16bdd48aa..000000000
--- a/sys/src/cmd/upas/common/appendfiletombox.c
+++ /dev/null
@@ -1,164 +0,0 @@
-#include "common.h"
-
-enum {
- Buffersize = 64*1024,
-};
-
-typedef struct Inbuf Inbuf;
-struct Inbuf
-{
- char buf[Buffersize];
- char *wp;
- char *rp;
- int eof;
- int in;
- int out;
- int last;
- ulong bytes;
-};
-
-static Inbuf*
-allocinbuf(int in, int out)
-{
- Inbuf *b;
-
- b = mallocz(sizeof(Inbuf), 1);
- if(b == nil)
- sysfatal("reading mailbox: %r");
- b->rp = b->wp = b->buf;
- b->in = in;
- b->out = out;
- return b;
-}
-
-/* should only be called at start of file or when b->rp[-1] == '\n' */
-static int
-fill(Inbuf *b, int addspace)
-{
- int i, n;
-
- if(b->eof && b->wp - b->rp == 0)
- return 0;
-
- n = b->rp - b->buf;
- if(n > 0){
- i = write(b->out, b->buf, n);
- if(i != n)
- return -1;
- b->last = b->buf[n-1];
- b->bytes += n;
- }
- if(addspace){
- if(write(b->out, " ", 1) != 1)
- return -1;
- b->last = ' ';
- b->bytes++;
- }
-
- n = b->wp - b->rp;
- memmove(b->buf, b->rp, n);
- b->rp = b->buf;
- b->wp = b->rp + n;
-
- i = read(b->in, b->buf+n, sizeof(b->buf)-n);
- if(i < 0)
- return -1;
- b->wp += i;
-
- return b->wp - b->rp;
-}
-
-enum { Fromlen = sizeof "From " - 1, };
-
-/* code to escape ' '*From' ' at the beginning of a line */
-int
-appendfiletombox(int in, int out)
-{
- int addspace, n, sol;
- char *p;
- Inbuf *b;
-
- seek(out, 0, 2);
-
- b = allocinbuf(in, out);
- addspace = 0;
- sol = 1;
-
- for(;;){
- if(b->wp - b->rp < Fromlen){
- /*
- * not enough unread bytes in buffer to match "From ",
- * so get some more. We must only inject a space at
- * the start of a line (one that begins with "From ").
- */
- if (b->rp == b->buf || b->rp[-1] == '\n') {
- n = fill(b, addspace);
- addspace = 0;
- } else
- n = fill(b, 0);
- if(n < 0)
- goto error;
- if(n == 0)
- break;
- if(n < Fromlen){ /* still can't match? */
- b->rp = b->wp;
- continue;
- }
- }
-
- /* state machine looking for ' '*From' ' */
- if(!sol){
- p = memchr(b->rp, '\n', b->wp - b->rp);
- if(p == nil)
- b->rp = b->wp;
- else{
- b->rp = p+1;
- sol = 1;
- }
- continue;
- } else {
- if(*b->rp == ' ' || strncmp(b->rp, "From ", Fromlen) != 0){
- b->rp++;
- continue;
- }
- addspace = 1;
- sol = 0;
- }
- }
-
- /* mailbox entries always terminate with two newlines */
- n = b->last == '\n' ? 1 : 2;
- if(write(out, "\n\n", n) != n)
- goto error;
- n += b->bytes;
- free(b);
- return n;
-error:
- free(b);
- return -1;
-}
-
-int
-appendfiletofile(int in, int out)
-{
- int n;
- Inbuf *b;
-
- seek(out, 0, 2);
-
- b = allocinbuf(in, out);
- for(;;){
- n = fill(b, 0);
- if(n < 0)
- goto error;
- if(n == 0)
- break;
- b->rp = b->wp;
- }
- n = b->bytes;
- free(b);
- return n;
-error:
- free(b);
- return -1;
-}
diff --git a/sys/src/cmd/upas/common/aux.c b/sys/src/cmd/upas/common/aux.c
index 8786acb50..985e3f296 100644
--- a/sys/src/cmd/upas/common/aux.c
+++ b/sys/src/cmd/upas/common/aux.c
@@ -1,42 +1,5 @@
#include "common.h"
-/* expand a path relative to some `.' */
-extern String *
-abspath(char *path, char *dot, String *to)
-{
- if (*path == '/') {
- to = s_append(to, path);
- } else {
- to = s_append(to, dot);
- to = s_append(to, "/");
- to = s_append(to, path);
- }
- return to;
-}
-
-/* return a pointer to the base component of a pathname */
-extern char *
-basename(char *path)
-{
- char *cp;
-
- cp = strrchr(path, '/');
- return cp==0 ? path : cp+1;
-}
-
-/* append a sub-expression match onto a String */
-extern 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);
-}
-
/*
* check for shell characters in a String
*/
@@ -95,7 +58,7 @@ escapespecial(String *s)
return ns;
}
-int
+uint
hex2uint(char x)
{
if(x >= '0' && x <= '9')
@@ -113,10 +76,9 @@ hex2uint(char x)
extern String*
unescapespecial(String *s)
{
- int c;
- String *ns;
char *sp;
- uint n;
+ uint c, n;
+ String *ns;
if(strstr(s_to_c(s), escape) == 0)
return s;
@@ -126,7 +88,7 @@ unescapespecial(String *s)
for(sp = s_to_c(s); *sp; sp++){
if(strncmp(sp, escape, n) == 0){
c = (hex2uint(sp[n])<<4) | hex2uint(sp[n+1]);
- if(c < 0)
+ if(c & 0x80)
s_putc(ns, *sp);
else {
s_putc(ns, c);
@@ -144,6 +106,5 @@ unescapespecial(String *s)
int
returnable(char *path)
{
-
return strcmp(path, "/dev/null") != 0;
}
diff --git a/sys/src/cmd/upas/common/become.c b/sys/src/cmd/upas/common/become.c
index 8c012d212..37cd11997 100644
--- a/sys/src/cmd/upas/common/become.c
+++ b/sys/src/cmd/upas/common/become.c
@@ -6,11 +6,10 @@
* become powerless user
*/
int
-become(char **cmd, char *who)
+become(char **, char *who)
{
int fd;
- USED(cmd);
if(strcmp(who, "none") == 0) {
fd = open("#c/user", OWRITE);
if(fd < 0 || write(fd, "none", strlen("none")) < 0) {
diff --git a/sys/src/cmd/upas/common/common.h b/sys/src/cmd/upas/common/common.h
index 3f9acbd18..9cefc0531 100644
--- a/sys/src/cmd/upas/common/common.h
+++ b/sys/src/cmd/upas/common/common.h
@@ -1,80 +1,79 @@
-#include "sys.h"
+enum
+{
+ Elemlen = 56,
+ Pathlen = 256,
+};
-/* format of REMOTE FROM lines */
-extern char *REMFROMRE;
-extern int REMSENDERMATCH;
-extern int REMDATEMATCH;
-extern int REMSYSMATCH;
+#include "sys.h"
+#include <String.h>
-/* format of mailbox FROM lines */
-#define IS_HEADER(p) ((p)[0]=='F'&&(p)[1]=='r'&&(p)[2]=='o'&&(p)[3]=='m'&&(p)[4]==' ')
-#define IS_TRAILER(p) ((p)[0]=='m'&&(p)[1]=='o'&&(p)[2]=='r'&&(p)[3]=='F'&&(p)[4]=='\n')
-extern char *FROMRE;
-extern int SENDERMATCH;
-extern int DATEMATCH;
+enum{
+ Fields = 18,
-enum
-{
- Elemlen= 28,
- Errlen= ERRMAX,
- Pathlen= 256,
+ /* flags */
+ Fanswered = 1<<0, /* a */
+ Fdeleted = 1<<1, /* D */
+ Fdraft = 1<<2, /* d */
+ Fflagged = 1<<3, /* f */
+ Frecent = 1<<4, /* r we are the first fs to see this */
+ Fseen = 1<<5, /* s */
+ Fstored = 1<<6, /* S */
+ Nflags = 7,
};
-enum { Atnoteunknown, Atnoterecog };
/*
- * routines in mail.c
+ * flag.c
*/
-extern int print_header(Biobuf*, char*, char*);
-extern int print_remote_header(Biobuf*, char*, char*, char*);
-extern int parse_header(char*, String*, String*);
+char *flagbuf(char*, int);
+int buftoflags(char*);
+char *txflags(char*, uchar*);
/*
* routines in aux.c
*/
-extern String *abspath(char*, char*, String*);
-extern String *mboxpath(char*, char*, String*, int);
-extern char *basename(char*);
-extern int delivery_status(String*);
-extern void append_match(Resub*, String*, int);
-extern int shellchars(char*);
-extern String* escapespecial(String*);
-extern String* unescapespecial(String*);
-extern int returnable(char*);
+char *mboxpathbuf(char*, int, char*, char*);
+char *basename(char*);
+int shellchars(char*);
+String *escapespecial(String*);
+String *unescapespecial(String*);
+int returnable(char*);
-/* in copymessage */
-extern int appendfiletombox(int, int);
-extern int appendfiletofile(int, int);
+/* folder.c */
+Biobuf *openfolder(char*, long);
+int closefolder(Biobuf*);
+int appendfolder(Biobuf*, char*, long*, int);
+int fappendfolder(char*, long, char *, int);
+int fappendfile(char*, char*, int);
+char* foldername(char*, char*, char*);
+char* ffoldername(char*, char*, char*);
-/* mailbox types */
-#define MF_NORMAL 0
-#define MF_PIPE 1
-#define MF_FORWARD 2
-#define MF_NOMBOX 3
-#define MF_NOTMBOX 4
+/* fmt.c */
+void mailfmtinstall(void); /* 'U' = 2047fmt */
+#pragma varargck type "U" char*
+
+/* totm.c */
+int fromtotm(char*, Tm*);
/* a pipe between parent and child*/
-typedef struct {
+typedef struct{
Biobuf bb;
Biobuf *fp; /* parent process end*/
int fd; /* child process end*/
} stream;
/* a child process*/
-typedef struct process{
+typedef struct{
stream *std[3]; /* standard fd's*/
int pid; /* process identifier*/
int status; /* exit status*/
Waitmsg *waitmsg;
} process;
-extern stream *instream(void);
-extern stream *outstream(void);
-extern void stream_free(stream*);
-extern process *noshell_proc_start(char**, stream*, stream*, stream*, int, char*);
-extern process *proc_start(char*, stream*, stream*, stream*, int, char*);
-extern int proc_wait(process*);
-extern int proc_free(process*);
-extern int proc_kill(process*);
-
-/* tell compiler we're using a value so it won't complain */
-#define USE(x) if(x)
+stream *instream(void);
+stream *outstream(void);
+void stream_free(stream*);
+process *noshell_proc_start(char**, stream*, stream*, stream*, int, char*);
+process *proc_start(char*, stream*, stream*, stream*, int, char*);
+int proc_wait(process*);
+int proc_free(process*);
+//int proc_kill(process*);
diff --git a/sys/src/cmd/upas/common/config.c b/sys/src/cmd/upas/common/config.c
index f322783ef..6bf8ef923 100644
--- a/sys/src/cmd/upas/common/config.c
+++ b/sys/src/cmd/upas/common/config.c
@@ -1,11 +1,9 @@
#include "common.h"
-char *MAILROOT = "/mail";
-char *UPASLOG = "/sys/log";
-char *UPASLIB = "/mail/lib";
-char *UPASBIN= "/bin/upas";
-char *UPASTMP = "/mail/tmp";
-char *SHELL = "/bin/rc";
-char *POST = "/sys/lib/post/dispatch";
-
-int MBOXMODE = 0662;
+char *MAILROOT = "/mail";
+char *SPOOL = "/mail";
+char *UPASLOG = "/sys/log";
+char *UPASLIB = "/mail/lib";
+char *UPASBIN = "/bin/upas";
+char *UPASTMP = "/mail/tmp";
+char *SHELL = "/bin/rc";
diff --git a/sys/src/cmd/upas/common/flags.c b/sys/src/cmd/upas/common/flags.c
new file mode 100644
index 000000000..2dc022032
--- /dev/null
+++ b/sys/src/cmd/upas/common/flags.c
@@ -0,0 +1,73 @@
+#include "common.h"
+
+static uchar flagtab[] = {
+ 'a', Fanswered,
+ 'D', Fdeleted,
+ 'd', Fdraft,
+ 'f', Fflagged,
+ 'r', Frecent,
+ 's', Fseen,
+ 'S', Fstored,
+};
+
+char*
+flagbuf(char *buf, int flags)
+{
+ char *p, c;
+ int i;
+
+ p = buf;
+ for(i = 0; i < nelem(flagtab); i += 2){
+ c = '-';
+ if(flags & flagtab[i+1])
+ c = flagtab[i];
+ *p++ = c;
+ }
+ *p = 0;
+ return buf;
+}
+
+int
+buftoflags(char *p)
+{
+ uchar flags;
+ int i;
+
+ flags = 0;
+ for(i = 0; i < nelem(flagtab); i += 2)
+ if(p[i>>1] == flagtab[i])
+ flags |= flagtab[i + 1];
+ return flags;
+}
+
+char*
+txflags(char *p, uchar *flags)
+{
+ uchar neg, f, c, i;
+
+ for(;;){
+ neg = 0;
+ again:
+ if((c = *p++) == '-'){
+ neg = 1;
+ goto again;
+ }else if(c == '+'){
+ neg = 0;
+ goto again;
+ }
+ if(c == 0)
+ return nil;
+ for(i = 0;; i += 2){
+ if(i == nelem(flagtab))
+ return "bad flag";
+ if(c == flagtab[i]){
+ f = flagtab[i+1];
+ break;
+ }
+ }
+ if(neg)
+ *flags &= ~f;
+ else
+ *flags |= f;
+ }
+}
diff --git a/sys/src/cmd/upas/common/fmt.c b/sys/src/cmd/upas/common/fmt.c
new file mode 100644
index 000000000..e159ad269
--- /dev/null
+++ b/sys/src/cmd/upas/common/fmt.c
@@ -0,0 +1,35 @@
+#include "common.h"
+
+int
+rfc2047fmt(Fmt *fmt)
+{
+ char *s, *p;
+
+ s = va_arg(fmt->args, char*);
+ if(s == nil)
+ return fmtstrcpy(fmt, "");
+ for(p=s; *p; p++)
+ if((uchar)*p >= 0x80)
+ goto hard;
+ return fmtstrcpy(fmt, s);
+
+hard:
+ fmtprint(fmt, "=?utf-8?q?");
+ for(p = s; *p; p++){
+ if(*p == ' ')
+ fmtrune(fmt, '_');
+ else if(*p == '_' || *p == '\t' || *p == '=' || *p == '?' ||
+ (uchar)*p >= 0x80)
+ fmtprint(fmt, "=%.2uX", (uchar)*p);
+ else
+ fmtrune(fmt, (uchar)*p);
+ }
+ fmtprint(fmt, "?=");
+ return 0;
+}
+
+void
+mailfmtinstall(void)
+{
+ fmtinstall('U', rfc2047fmt);
+}
diff --git a/sys/src/cmd/upas/common/folder.c b/sys/src/cmd/upas/common/folder.c
new file mode 100644
index 000000000..1d5e34542
--- /dev/null
+++ b/sys/src/cmd/upas/common/folder.c
@@ -0,0 +1,361 @@
+#include "common.h"
+
+enum{
+ Mbox = 1,
+ Mdir,
+};
+
+typedef struct Folder Folder;
+struct Folder{
+ int open;
+ int ofd;
+ int type;
+ Biobuf *out;
+ Mlock *l;
+};
+static Folder ftab[5];
+
+static Folder*
+getfolder(Biobuf *out)
+{
+ int i;
+ Folder *f;
+
+ for(i = 0; i < nelem(ftab); i++){
+ f = ftab+i;
+ if(f->open == 0){
+ f->open = 1;
+ f->ofd = -1;
+ f->type = 0;
+ return f;
+ }
+ if(f->out == out)
+ return f;
+ }
+ sysfatal("folder.c:ftab too small");
+ return 0;
+}
+
+static int
+putfolder(Folder *f)
+{
+ int r;
+
+ r = 0;
+ if(f->l)
+ sysunlock(f->l);
+ if(f->out)
+ r |= Bterm(f->out);
+ if(f->ofd > 0){
+ close(f->ofd);
+ free(f->out);
+ }
+ memset(f, 0, sizeof *f);
+ return r;
+}
+
+static Biobuf*
+mboxopen(char *s)
+{
+ Folder *f;
+
+ f = getfolder(0);
+ f->l = syslock(s); /* traditional botch: ignore failure */
+ if((f->ofd = open(s, OWRITE)) == -1)
+ if((f->ofd = create(s, OWRITE|OEXCL, DMAPPEND|0600)) == -1){
+ putfolder(f);
+ return nil;
+ }
+ seek(f->ofd, 0, 2);
+ f->out = malloc(sizeof *f->out);
+ Binit(f->out, f->ofd, OWRITE);
+ f->type = Mbox;
+ return f->out;
+}
+
+/*
+ * sync with send/cat_mail.c:/^mdir
+ */
+static Biobuf*
+mdiropen(char *s, long t)
+{
+ char buf[64];
+ long i;
+ Folder *f;
+
+ f = getfolder(0);
+ for(i = 0; i < 100; i++){
+ snprint(buf, sizeof buf, "%s/%lud.%.2ld", s, t, i);
+ if((f->ofd = create(buf, OWRITE|OEXCL, DMAPPEND|0660)) != -1)
+ goto found;
+ }
+ putfolder(f);
+ return nil;
+found:
+ werrstr("");
+ f->out = malloc(sizeof *f->out);
+ Binit(f->out, f->ofd, OWRITE);
+ f->type = Mdir;
+ return f->out;
+}
+
+Biobuf*
+openfolder(char *s, long t)
+{
+ int isdir;
+ Dir *d;
+
+ if(d = dirstat(s)){
+ isdir = d->mode&DMDIR;
+ free(d);
+ }else{
+ isdir = create(s, OREAD, DMDIR|0777);
+ if(isdir == -1)
+ return nil;
+ close(isdir);
+ isdir = 1;
+ }
+ if(isdir)
+ return mdiropen(s, t);
+ else
+ return mboxopen(s);
+}
+
+int
+renamefolder(Biobuf *b, long t)
+{
+ char buf[32];
+ int i;
+ Dir d;
+ Folder *f;
+
+ f = getfolder(b);
+ if(f->type != Mdir)
+ return 0;
+ for(i = 0; i < 100; i++){
+ nulldir(&d);
+ snprint(buf, sizeof buf, "%lud.%.2d", t, i);
+ d.name = buf;
+ if(dirfwstat(Bfildes(b), &d) > 0)
+ return 0;
+ }
+ return -1;
+}
+
+int
+closefolder(Biobuf *b)
+{
+ return putfolder(getfolder(b));
+}
+
+/*
+ * escape "From " at the beginning of a line;
+ * translate \r\n to \n for imap
+ */
+static int
+mboxesc(Biobuf *in, Biobuf *out, int type)
+{
+ char *s;
+ int n;
+
+ for(; s = Brdstr(in, '\n', 0); free(s)){
+ if(!strncmp(s, "From ", 5))
+ Bputc(out, ' ');
+ n = strlen(s);
+ if(n > 1 && s[n-2] == '\r'){
+ s[n-2] = '\n';
+ n--;
+ }
+ if(Bwrite(out, s, n) == Beof){
+ free(s);
+ return -1;
+ }
+ if(s[n-1] != '\n')
+ Bputc(out, '\n');
+ }
+ if(type == Mbox)
+ Bputc(out, '\n');
+ if(Bflush(out) == Beof)
+ return -1;
+ return 0;
+}
+
+int
+appendfolder(Biobuf *b, char *addr, long *t, int fd)
+{
+ char *s;
+ int r;
+ Biobuf bin;
+ Folder *f;
+ Tm tm;
+
+ f = getfolder(b);
+ Bseek(f->out, 0, 2);
+ Binit(&bin, fd, OREAD);
+ s = Brdstr(&bin, '\n', 0);
+ if(!s || strncmp(s, "From ", 5))
+ Bprint(f->out, "From %s %.28s\n", addr, ctime(*t));
+ else if(fromtotm(s, &tm) >= 0)
+ *t = tm2sec(&tm);
+ if(s)
+ Bwrite(f->out, s, strlen(s));
+ free(s);
+ r = mboxesc(&bin, f->out, f->type);
+ return r | Bterm(&bin);
+}
+
+int
+fappendfolder(char *addr, long t, char *s, int fd)
+{
+ long t0, r;
+ Biobuf *b;
+
+ b = openfolder(s, t);
+ if(b == nil)
+ return -1;
+ t0 = t;
+ r = appendfolder(b, addr, &t, fd);
+ if(t != t0)
+ renamefolder(b, t);
+ r |= closefolder(b);
+ return r;
+}
+
+/*
+ * BOTCH sync with ../imap4d/mbox.c:/^okmbox
+ */
+
+static char *specialfile[] =
+{
+ "L.mbox",
+ "forward",
+ "headers",
+ "imap.subscribed",
+ "names",
+ "pipefrom",
+ "pipeto",
+};
+
+static int
+special(char *s)
+{
+ char *p;
+ int i;
+
+ p = strrchr(s, '/');
+ if(p == nil)
+ p = s;
+ else
+ p++;
+ for(i = 0; i < nelem(specialfile); i++)
+ if(strcmp(p, specialfile[i]) == 0)
+ return 1;
+ return 0;
+}
+
+static char*
+mkmbpath(char *s, int n, char *user, char *mb, char *path)
+{
+ char *p, *e, *r, buf[Pathlen];
+
+ if(!mb)
+ return mboxpathbuf(s, n, user, path);
+ e = buf+sizeof buf;
+ p = seprint(buf, e, "%s", mb);
+ if(r = strrchr(buf, '/'))
+ p = r;
+ seprint(p, e, "/%s", path);
+ return mboxpathbuf(s, n, user, buf);
+}
+
+
+/*
+ * fancy processing for ned:
+ * we default to storing in $mail/f then just in $mail.
+ */
+char*
+ffoldername(char *mb, char *user, char *rcvr)
+{
+ char *p;
+ int c, n;
+ Dir *d;
+ static char buf[Pathlen];
+
+ d = dirstat(mkmbpath(buf, sizeof buf, user, mb, "f/"));
+ n = strlen(buf);
+ if(!d || d->qid.type != QTDIR)
+ buf[n -= 2] = 0;
+ free(d);
+
+ if(p = strrchr(rcvr, '!'))
+ rcvr = p+1;
+ while(n < sizeof buf-1 && (c = *rcvr++)){
+ if(c== '@')
+ break;
+ if(c == '/')
+ c = '_';
+ buf[n++] = c;
+ }
+ buf[n] = 0;
+
+ if(special(buf)){
+ fprint(2, "!won't overwrite %s\n", buf);
+ return nil;
+ }
+ return buf;
+}
+
+char*
+foldername(char *mb, char *user, char *path)
+{
+ static char buf[Pathlen];
+
+ mkmbpath(buf, sizeof buf, user, mb, path);
+ if(special(buf)){
+ fprint(2, "!won't overwrite %s\n", buf);
+ return nil;
+ }
+ return buf;
+}
+
+static int
+append(Biobuf *in, Biobuf *out)
+{
+ char *buf;
+ int n, m;
+
+ buf = malloc(8192);
+ for(;;){
+ m = 0;
+ n = Bread(in, buf, 8192);
+ if(n <= 0)
+ break;
+ m = Bwrite(out, buf, n);
+ if(m != n)
+ break;
+ }
+ if(m != n)
+ n = -1;
+ else
+ n = 1;
+ free(buf);
+ return n;
+}
+
+/* symmetry for nedmail; misnamed */
+int
+fappendfile(char*, char *target, int in)
+{
+ int fd, r;
+ Biobuf bin, out;
+
+ if((fd = create(target, ORDWR|OEXCL, 0666)) == -1)
+ return -1;
+ Binit(&out, fd, OWRITE);
+ Binit(&bin, in, OREAD);
+ r = append(&bin, &out);
+ Bterm(&bin);
+ Bterm(&out);
+ close(fd);
+ return r;
+}
diff --git a/sys/src/cmd/upas/common/libsys.c b/sys/src/cmd/upas/common/libsys.c
index f0b8f35a4..969c2ff67 100644
--- a/sys/src/cmd/upas/common/libsys.c
+++ b/sys/src/cmd/upas/common/libsys.c
@@ -3,67 +3,42 @@
#include <ndb.h>
/*
- * number of predefined fd's
- */
-int nsysfile=3;
-
-static char err[Errlen];
-
-/*
* return the date
*/
-extern char *
+char*
thedate(void)
{
static char now[64];
- char *cp;
strcpy(now, ctime(time(0)));
- cp = strchr(now, '\n');
- if(cp)
- *cp = 0;
+ now[28] = 0;
return now;
}
/*
* return the user id of the current user
*/
-extern char *
+char *
getlog(void)
{
- static char user[64];
- int fd;
- int n;
-
- fd = open("/dev/user", 0);
- if(fd < 0)
- return nil;
- if((n=read(fd, user, sizeof(user)-1)) <= 0)
- return nil;
- close(fd);
- user[n] = 0;
- return user;
+ return getuser();
}
/*
* return the lock name (we use one lock per directory)
*/
-static String *
-lockname(char *path)
+static void
+lockname(Mlock *l, char *path)
{
- String *lp;
- char *cp;
-
- /*
- * get the name of the lock file
- */
- lp = s_new();
- cp = strrchr(path, '/');
- if(cp)
- s_nappend(lp, path, cp - path + 1);
- s_append(lp, "L.mbox");
+ char *e, *q;
- return lp;
+ seprint(l->name, e = l->name+sizeof l->name, "%s", path);
+ q = strrchr(l->name, '/');
+ if(q == nil)
+ q = l->name;
+ else
+ q++;
+ seprint(q, e, "%s", "L.mbox");
}
int
@@ -92,58 +67,43 @@ static int
openlockfile(Mlock *l)
{
int fd;
- Dir *d;
- Dir nd;
+ Dir *d, nd;
char *p;
- fd = open(s_to_c(l->name), OREAD);
- if(fd >= 0){
- l->fd = fd;
+ l->fd = open(l->name, OREAD);
+ if(l->fd >= 0)
return 0;
+ if(d = dirstat(l->name)){
+ free(d);
+ return 1; /* try again later */
}
-
- d = dirstat(s_to_c(l->name));
- if(d == nil){
- /* file doesn't exist */
- /* try creating it */
- fd = create(s_to_c(l->name), OREAD, DMEXCL|0666);
- if(fd >= 0){
- nulldir(&nd);
- nd.mode = DMEXCL|0666;
- if(dirfwstat(fd, &nd) < 0){
- /* if we can't chmod, don't bother */
- /* live without the lock but log it */
- syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
- remove(s_to_c(l->name));
- }
- l->fd = fd;
- return 0;
- }
-
- /* couldn't create */
- /* do we have write access to the directory? */
- p = strrchr(s_to_c(l->name), '/');
- if(p != 0){
- *p = 0;
- fd = access(s_to_c(l->name), 2);
- *p = '/';
- if(fd < 0){
- /* live without the lock but log it */
- syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
- return 0;
- }
- } else {
- fd = access(".", 2);
- if(fd < 0){
- /* live without the lock but log it */
- syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
- return 0;
- }
+ l->fd = create(l->name, OREAD, DMEXCL|0666);
+ if(l->fd >= 0){
+ nulldir(&nd);
+ nd.mode = DMEXCL|0666;
+ if(dirfwstat(l->fd, &nd) < 0){
+ /* if we can't chmod, don't bother */
+ /* live without the lock but log it */
+ close(l->fd);
+ l->fd = -1;
+ syslog(0, "mail", "lock error: %s: %r", l->name);
+ remove(l->name);
}
- } else
- free(d);
-
- return 1; /* try again later */
+ return 0;
+ }
+ /* couldn't create; let's see what we can whine about */
+ p = strrchr(l->name, '/');
+ if(p != 0){
+ *p = 0;
+ fd = access(l->name, 2);
+ *p = '/';
+ }else
+ fd = access(".", 2);
+ if(fd < 0)
+ /* live without the lock but log it */
+ syslog(0, "mail", "lock error: %s: %r", l->name);
+ close(fd);
+ return 0;
}
#define LSECS 5*60
@@ -152,7 +112,7 @@ openlockfile(Mlock *l)
* Set a lock for a particular file. The lock is a file in the same directory
* and has L. prepended to the name of the last element of the file name.
*/
-extern Mlock *
+Mlock*
syslock(char *path)
{
Mlock *l;
@@ -162,25 +122,18 @@ syslock(char *path)
if(l == 0)
return nil;
- l->name = lockname(path);
-
+ lockname(l, path);
/*
* wait LSECS seconds for it to unlock
*/
- for(tries = 0; tries < LSECS*2; tries++){
+ for(tries = 0; tries < LSECS*2; tries++)
switch(openlockfile(l)){
case 0:
return l;
case 1:
sleep(500);
break;
- default:
- goto noway;
}
- }
-
-noway:
- s_free(l->name);
free(l);
return nil;
}
@@ -188,20 +141,19 @@ noway:
/*
* like lock except don't wait
*/
-extern Mlock *
+Mlock *
trylock(char *path)
{
- Mlock *l;
char buf[1];
int fd;
+ Mlock *l;
- l = malloc(sizeof(Mlock));
+ l = mallocz(sizeof(Mlock), 1);
if(l == 0)
return 0;
- l->name = lockname(path);
+ lockname(l, path);
if(openlockfile(l) != 0){
- s_free(l->name);
free(l);
return 0;
}
@@ -217,12 +169,12 @@ trylock(char *path)
if(pread(fd, buf, 1, 0) < 0)
break;
}
- _exits(0);
+ _exits(nil);
}
return l;
}
-extern void
+void
syslockrefresh(Mlock *l)
{
char buf[1];
@@ -230,16 +182,12 @@ syslockrefresh(Mlock *l)
pread(l->fd, buf, 1, 0);
}
-extern void
+void
sysunlock(Mlock *l)
{
if(l == 0)
return;
- if(l->name){
- s_free(l->name);
- }
- if(l->fd >= 0)
- close(l->fd);
+ close(l->fd);
if(l->pid > 0)
postnote(PNPROC, l->pid, "time to die");
free(l);
@@ -254,15 +202,10 @@ sysunlock(Mlock *l)
* w - writable
* A - append only (doesn't exist in Bio)
*/
-extern Biobuf *
+Biobuf*
sysopen(char *path, char *mode, ulong perm)
{
- int sysperm;
- int sysmode;
- int fd;
- int docreate;
- int append;
- int truncate;
+ int sysperm, sysmode, fd, docreate, append, truncate;
Dir *d, nd;
Biobuf *bp;
@@ -274,7 +217,7 @@ sysopen(char *path, char *mode, ulong perm)
docreate = 0;
append = 0;
truncate = 0;
- for(; mode && *mode; mode++)
+ for(; *mode; mode++)
switch(*mode){
case 'A':
sysmode = OWRITE;
@@ -372,15 +315,6 @@ sysclose(Biobuf *bp)
}
/*
- * create a file
- */
-int
-syscreate(char *file, int mode, ulong perm)
-{
- return create(file, mode, perm);
-}
-
-/*
* make a directory
*/
int
@@ -395,75 +329,44 @@ sysmkdir(char *file, ulong perm)
}
/*
- * change the group of a file
- */
-int
-syschgrp(char *file, char *group)
-{
- Dir nd;
-
- if(group == 0)
- return -1;
- nulldir(&nd);
- nd.gid = group;
- return dirwstat(file, &nd);
-}
-
-extern int
-sysdirreadall(int fd, Dir **d)
-{
- return dirreadall(fd, d);
-}
-
-/*
* read in the system name
*/
-extern char *
+char *
sysname_read(void)
{
static char name[128];
- char *cp;
-
- cp = getenv("site");
- if(cp == 0 || *cp == 0)
- cp = alt_sysname_read();
- if(cp == 0 || *cp == 0)
- cp = "kremvax";
- strecpy(name, name+sizeof name, cp);
+ char *s, *c;
+
+ c = s = getenv("site");
+ if(!c)
+ c = alt_sysname_read();
+ if(!c)
+ c = "kremvax";
+ strecpy(name, name+sizeof name, c);
+ free(s);
return name;
}
-extern char *
+
+char *
alt_sysname_read(void)
{
- static char name[128];
- int n, fd;
-
- fd = open("/dev/sysname", OREAD);
- if(fd < 0)
- return 0;
- n = read(fd, name, sizeof(name)-1);
- close(fd);
- if(n <= 0)
- return 0;
- name[n] = 0;
- return name;
+ return sysname();
}
/*
* get all names
*/
-extern char**
+char**
sysnames_read(void)
{
- static char **namev;
- Ndbtuple *t, *nt;
int n;
- char *cp;
+ Ndbtuple *t, *nt;
+ static char **namev;
if(namev)
return namev;
- free(csgetvalue(0, "sys", alt_sysname_read(), "dom", &t));
+ free(csgetvalue(0, "sys", sysname(), "dom", &t));
n = 0;
for(nt = t; nt; nt = nt->entry)
@@ -471,13 +374,10 @@ sysnames_read(void)
n++;
namev = (char**)malloc(sizeof(char *)*(n+3));
-
if(namev){
- n = 0;
- namev[n++] = strdup(sysname_read());
- cp = alt_sysname_read();
- if(cp)
- namev[n++] = strdup(cp);
+ namev[0] = strdup(sysname_read());
+ namev[1] = strdup(alt_sysname_read());
+ n = 2;
for(nt = t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0)
namev[n++] = strdup(nt->val);
@@ -492,69 +392,21 @@ sysnames_read(void)
/*
* read in the domain name
*/
-extern char *
+char*
domainname_read(void)
{
- char **namev;
+ char **p;
- for(namev = sysnames_read(); *namev; namev++)
- if(strchr(*namev, '.'))
- return *namev;
+ for(p = sysnames_read(); *p; p++)
+ if(strchr(*p, '.'))
+ return *p;
return 0;
}
/*
- * return true if the last error message meant file
- * did not exist.
- */
-extern int
-e_nonexistent(void)
-{
- rerrstr(err, sizeof(err));
- return strcmp(err, "file does not exist") == 0;
-}
-
-/*
- * return true if the last error message meant file
- * was locked.
- */
-extern int
-e_locked(void)
-{
- rerrstr(err, sizeof(err));
- return strcmp(err, "open/create -- file is locked") == 0;
-}
-
-/*
- * return the length of a file
- */
-extern long
-sysfilelen(Biobuf *fp)
-{
- Dir *d;
- long rv;
-
- d = dirfstat(Bfildes(fp));
- if(d == nil)
- return -1;
- rv = d->length;
- free(d);
- return rv;
-}
-
-/*
- * remove a file
- */
-extern int
-sysremove(char *path)
-{
- return remove(path);
-}
-
-/*
* rename a file, fails unless both are in the same directory
*/
-extern int
+int
sysrename(char *old, char *new)
{
Dir d;
@@ -579,81 +431,27 @@ sysrename(char *old, char *new)
return dirwstat(old, &d);
}
-/*
- * see if a file exists
- */
-extern int
+int
sysexist(char *file)
{
- Dir *d;
-
- d = dirstat(file);
- if(d == nil)
- return 0;
- free(d);
- return 1;
-}
-
-/*
- * return nonzero if file is a directory
- */
-extern int
-sysisdir(char *file)
-{
- Dir *d;
- int rv;
-
- d = dirstat(file);
- if(d == nil)
- return 0;
- rv = d->mode & DMDIR;
- free(d);
- return rv;
+ return access(file, AEXIST) == 0;
}
-/*
- * kill a process or process group
- */
-
-static int
-stomp(int pid, char *file)
-{
- char name[64];
- int fd;
-
- snprint(name, sizeof(name), "/proc/%d/%s", pid, file);
- fd = open(name, 1);
- if(fd < 0)
- return -1;
- if(write(fd, "die: yankee pig dog\n", sizeof("die: yankee pig dog\n") - 1) <= 0){
- close(fd);
- return -1;
- }
- close(fd);
- return 0;
-
-}
+static char yankeepig[] = "die: yankee pig dog";
-/*
- * kill a process
- */
-extern int
+int
syskill(int pid)
{
- return stomp(pid, "note");
-
+ return postnote(PNPROC, pid, yankeepig);
}
-/*
- * kill a process group
- */
-extern int
+int
syskillpg(int pid)
{
- return stomp(pid, "notepg");
+ return postnote(PNGROUP, pid, yankeepig);
}
-extern int
+int
sysdetach(void)
{
if(rfork(RFENVG|RFNAMEG|RFNOTEG) < 0) {
@@ -668,11 +466,10 @@ sysdetach(void)
*/
static int *closedflag;
static int
-catchpipe(void *a, char *msg)
+catchpipe(void *, char *msg)
{
static char *foo = "sys: write on closed pipe";
- USED(a);
if(strncmp(msg, foo, strlen(foo)) == 0){
if(closedflag)
*closedflag = 1;
@@ -692,30 +489,21 @@ pipesigoff(void)
atnotify(catchpipe, 0);
}
-void
-exit(int i)
-{
- char buf[32];
-
- if(i == 0)
- exits(0);
- snprint(buf, sizeof(buf), "%d", i);
- exits(buf);
-}
-
-static int
+int
islikeatty(int fd)
{
char buf[64];
+ int l;
if(fd2path(fd, buf, sizeof buf) != 0)
return 0;
/* might be /mnt/term/dev/cons */
- return strlen(buf) >= 9 && strcmp(buf+strlen(buf)-9, "/dev/cons") == 0;
+ l = strlen(buf);
+ return l >= 9 && strcmp(buf+l-9, "/dev/cons") == 0;
}
-extern int
+int
holdon(void)
{
int fd;
@@ -729,20 +517,20 @@ holdon(void)
return fd;
}
-extern int
+int
sysopentty(void)
{
return open("/dev/cons", ORDWR);
}
-extern void
+void
holdoff(int fd)
{
write(fd, "holdoff", 7);
close(fd);
}
-extern int
+int
sysfiles(void)
{
return 128;
@@ -754,142 +542,66 @@ sysfiles(void)
* if the path starts with / or ./, don't change it
*
*/
-extern String *
-mboxpath(char *path, char *user, String *to, int dot)
+char*
+mboxpathbuf(char *to, int n, char *user, char *path)
{
- if (dot || *path=='/' || strncmp(path, "./", 2) == 0
- || strncmp(path, "../", 3) == 0) {
- to = s_append(to, path);
- } else {
- to = s_append(to, MAILROOT);
- to = s_append(to, "/box/");
- to = s_append(to, user);
- to = s_append(to, "/");
- to = s_append(to, path);
- }
+ if(*path == '/' || !strncmp(path, "./", 2) || !strncmp(path, "../", 3))
+ snprint(to, n, "%s", path);
+ else
+ snprint(to, n, "%s/box/%s/%s", MAILROOT, user, path);
return to;
}
-extern String *
-mboxname(char *user, String *to)
-{
- return mboxpath("mbox", user, to, 0);
-}
-
-extern String *
-deadletter(String *to) /* pass in sender??? */
-{
- char *cp;
-
- cp = getlog();
- if(cp == 0)
- return 0;
- return mboxpath("dead.letter", cp, to, 0);
-}
-
-char *
-homedir(char *user)
-{
- USED(user);
- return getenv("home");
-}
-
-String *
-readlock(String *file)
-{
- char *cp;
-
- cp = getlog();
- if(cp == 0)
- return 0;
- return mboxpath("reading", cp, file, 0);
-}
-
-String *
-username(String *from)
+/*
+ * warning: we're not quoting bad characters. we're not encoding
+ * non-ascii characters. basically this function sucks. don't use.
+ */
+char*
+username0(Biobuf *b, char *from)
{
+ char *p, *f[6];
int n;
- Biobuf *bp;
- char *p, *q;
- String *s;
+ static char buf[32];
- bp = Bopen("/adm/keys.who", OREAD);
- if(bp == 0)
- bp = Bopen("/adm/netkeys.who", OREAD);
- if(bp == 0)
- return 0;
-
- s = 0;
- n = strlen(s_to_c(from));
- for(;;) {
- p = Brdline(bp, '\n');
+ n = strlen(from);
+ buf[0] = 0;
+ for(;; free(p)) {
+ p = Brdstr(b, '\n', 1);
if(p == 0)
break;
- p[Blinelen(bp)-1] = 0;
- if(strncmp(p, s_to_c(from), n))
+ if(strncmp(p, from, n) || p[n] != '|')
continue;
- p += n;
- if(*p != ' ' && *p != '\t') /* must be full match */
+ if(getfields(p, f, nelem(f), 0, "|") < 3)
continue;
- while(*p && (*p == ' ' || *p == '\t'))
- p++;
- if(*p == 0)
- continue;
- for(q = p; *q; q++)
- if(('0' <= *q && *q <= '9') || *q == '<')
- break;
- while(q > p && q[-1] != ' ' && q[-1] != '\t')
- q--;
- while(q > p && (q[-1] == ' ' || q[-1] == '\t'))
- q--;
- *q = 0;
- s = s_new();
- s_append(s, "\"");
- s_append(s, p);
- s_append(s, "\"");
- break;
+ snprint(buf, sizeof buf, "\"%s\"", f[2]);
+ /* no break; last match wins */
}
- Bterm(bp);
- return s;
+ return buf[0]? buf: 0;
}
-char *
-remoteaddr(int fd, char *dir)
+char*
+username(char *from)
{
- char buf[128], *p;
- int n;
-
- if(dir == 0){
- if(fd2path(fd, buf, sizeof(buf)) != 0)
- return "";
+ char *s;
+ Biobuf *b;
- /* parse something of the form /net/tcp/nnnn/data */
- p = strrchr(buf, '/');
- if(p == 0)
- return "";
- strncpy(p+1, "remote", sizeof(buf)-(p-buf)-2);
- } else
- snprint(buf, sizeof buf, "%s/remote", dir);
- buf[sizeof(buf)-1] = 0;
-
- fd = open(buf, OREAD);
- if(fd < 0)
- return "";
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if(n > 0){
- buf[n] = 0;
- p = strchr(buf, '!');
- if(p)
- *p = 0;
- return strdup(buf);
+ s = 0;
+ if(b = Bopen("/adm/keys.who", OREAD)){
+ s = username0(b, from);
+ Bterm(b);
+ }
+ if(s == 0 && (b = Bopen("/adm/netkeys.who", OREAD))){
+ s = username0(b, from);
+ Bterm(b);
}
- return "";
+ return s;
}
-// create a file and
-// 1) ensure the modes we asked for
-// 2) make gid == uid
+/*
+ * create a file and
+ * 1) ensure the modes we asked for
+ * 2) make gid == uid
+ */
static int
docreate(char *file, int perm)
{
@@ -897,7 +609,7 @@ docreate(char *file, int perm)
Dir ndir;
Dir *d;
- // create the mbox
+ /* create the mbox */
fd = create(file, OREAD, perm);
if(fd < 0){
fprint(2, "couldn't create %s\n", file);
@@ -917,55 +629,77 @@ docreate(char *file, int perm)
return 0;
}
-// create a mailbox
-int
-creatembox(char *user, char *folder)
+static int
+createfolder0(char *user, char *folder, char *ftype)
{
- char *p;
- String *mailfile;
- char buf[512];
- Mlock *ml;
-
- mailfile = s_new();
- if(folder == 0)
- mboxname(user, mailfile);
- else {
- snprint(buf, sizeof(buf), "%s/mbox", folder);
- mboxpath(buf, user, mailfile, 0);
- }
+ char *p, *s, buf[Pathlen];
+ int isdir, mode;
+ Dir *d;
- // don't destroy existing mailbox
- if(access(s_to_c(mailfile), 0) == 0){
- fprint(2, "mailbox already exists\n");
+ assert(folder != 0);
+ mboxpathbuf(buf, sizeof buf, user, folder);
+ if(access(buf, 0) == 0){
+ fprint(2, "%s already exists\n", ftype);
return -1;
}
- fprint(2, "creating new mbox: %s\n", s_to_c(mailfile));
+ fprint(2, "creating new %s: %s\n", ftype, buf);
- // make sure preceding levels exist
- for(p = s_to_c(mailfile); p; p++) {
- if(*p == '/') /* skip leading or consecutive slashes */
+ /*
+ * if we can deliver to this mbox, it needs
+ * to be read/execable all the way down
+ */
+ mode = 0711;
+ if(!strncmp(buf, "/mail/box/", 10))
+ if((s = strrchr(buf, '/')) && !strcmp(s+1, "mbox"))
+ mode = 0755;
+ for(p = buf; p; p++) {
+ if(*p == '/')
continue;
p = strchr(p, '/');
if(p == 0)
break;
*p = 0;
- if(access(s_to_c(mailfile), 0) != 0){
- if(docreate(s_to_c(mailfile), DMDIR|0711) < 0)
- return -1;
- }
+ if(access(buf, 0) != 0)
+ if(docreate(buf, DMDIR|mode) < 0)
+ return -1;
*p = '/';
}
-
- // create the mbox
- if(docreate(s_to_c(mailfile), 0622|DMAPPEND|DMEXCL) < 0)
- return -1;
+ /* must match folder.c:/^openfolder */
+ isdir = create(buf, OREAD, DMDIR|0777);
/*
- * create the lock file if it doesn't exist
+ * make sure everyone can write here if it's a mailbox
+ * rather than a folder
*/
- ml = trylock(s_to_c(mailfile));
- if(ml != nil)
- sysunlock(ml);
+ if(mode == 0755)
+ if(isdir >= 0 && (d = dirfstat(isdir))){
+ d->mode |= 0773;
+ dirfwstat(isdir, d);
+ free(d);
+ }
+ if(isdir == -1){
+ fprint(2, "can't create %s: %s\n", ftype, buf);
+ return -1;
+ }
+ close(isdir);
return 0;
}
+
+int
+createfolder(char *user, char *folder)
+{
+ return createfolder0(user, folder, "folder");
+}
+
+int
+creatembox(char *user, char *mbox)
+{
+ char buf[Pathlen];
+
+ if(mbox == 0)
+ snprint(buf, sizeof buf, "mbox");
+ else
+ snprint(buf, sizeof buf, "%s/mbox", mbox);
+ return createfolder0(user, buf, "mbox");
+}
diff --git a/sys/src/cmd/upas/common/mail.c b/sys/src/cmd/upas/common/mail.c
deleted file mode 100644
index 5347c6550..000000000
--- a/sys/src/cmd/upas/common/mail.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "common.h"
-
-/* format of REMOTE FROM lines */
-char *REMFROMRE =
- "^>?From[ \t]+((\".*\")?[^\" \t]+?(\".*\")?[^\" \t]+?)[ \t]+(.+)[ \t]+remote[ \t]+from[ \t]+(.*)\n$";
-int REMSENDERMATCH = 1;
-int REMDATEMATCH = 4;
-int REMSYSMATCH = 5;
-
-/* format of LOCAL FROM lines */
-char *FROMRE =
- "^>?From[ \t]+((\".*\")?[^\" \t]+?(\".*\")?[^\" \t]+?)[ \t]+(.+)\n$";
-int SENDERMATCH = 1;
-int DATEMATCH = 4;
-
-/* output a unix style local header */
-int
-print_header(Biobuf *fp, char *sender, char *date)
-{
- return Bprint(fp, "From %s %s\n", sender, date);
-}
-
-/* output a unix style remote header */
-int
-print_remote_header(Biobuf *fp, char *sender, char *date, char *system)
-{
- return Bprint(fp, "From %s %s remote from %s\n", sender, date, system);
-}
-
-/* parse a mailbox style header */
-int
-parse_header(char *line, String *sender, String *date)
-{
- if (!IS_HEADER(line))
- return -1;
- line += sizeof("From ") - 1;
- s_restart(sender);
- while(*line==' '||*line=='\t')
- line++;
- if(*line == '"'){
- s_putc(sender, *line++);
- while(*line && *line != '"')
- s_putc(sender, *line++);
- s_putc(sender, *line++);
- } else {
- while(*line && *line != ' ' && *line != '\t')
- s_putc(sender, *line++);
- }
- s_terminate(sender);
- s_restart(date);
- while(*line==' '||*line=='\t')
- line++;
- while(*line)
- s_putc(date, *line++);
- s_terminate(date);
- return 0;
-}
diff --git a/sys/src/cmd/upas/common/makefile b/sys/src/cmd/upas/common/makefile
deleted file mode 100644
index c7beae817..000000000
--- a/sys/src/cmd/upas/common/makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-CFLAGS=${UNIX} -g -I. -I../libc -I../common -I/usr/include ${SCFLAGS}
-OBJS=mail.o aux.o string.o ${SYSOBJ}
-AR=ar
-.c.o: ; ${CC} -c ${CFLAGS} $*.c
-
-common.a: ${OBJS}
- ${AR} cr common.a ${OBJS}
- -ranlib common.a
-
-aux.o: aux.h string.h mail.h
-string.o: string.h mail.h
-mail.o: mail.h
-syslog.o: sys.h
-mail.h: sys.h
-
-clean:
- -rm -f *.[oO] core a.out *.a *.sL common.a
-
diff --git a/sys/src/cmd/upas/common/mkfile b/sys/src/cmd/upas/common/mkfile
index 7422fbe3a..5a628ae47 100644
--- a/sys/src/cmd/upas/common/mkfile
+++ b/sys/src/cmd/upas/common/mkfile
@@ -1,13 +1,17 @@
</$objtype/mkfile
+<../mkupas
LIB=libcommon.a$O
-OFILES=aux.$O\
+OFILES=\
+ aux.$O\
become.$O\
- mail.$O\
- process.$O\
- libsys.$O\
config.$O\
- appendfiletombox.$O\
+ folder.$O\
+ flags.$O\
+ fmt.$O\
+ libsys.$O\
+ process.$O\
+ totm.$O\
HFILES=common.h\
sys.h\
@@ -18,3 +22,7 @@ UPDATE=\
$HFILES\
</sys/src/cmd/mklib
+
+nuke:V:
+ mk clean
+ rm -f libcommon.a[$OS]
diff --git a/sys/src/cmd/upas/common/process.c b/sys/src/cmd/upas/common/process.c
index f698c9600..b7c0df0ca 100644
--- a/sys/src/cmd/upas/common/process.c
+++ b/sys/src/cmd/upas/common/process.c
@@ -96,8 +96,7 @@ noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg
if(who)
become(av, who);
exec(av[0], av);
- perror("proc_start");
- exits("proc_start");
+ sysfatal("proc_start");
default:
for (i=0; i<3; i++)
if (pp->std[i] != 0) {
@@ -126,12 +125,12 @@ extern int
proc_wait(process *pp)
{
Waitmsg *status;
- char err[Errlen];
+ char err[ERRMAX];
for(;;){
status = wait();
if(status == nil){
- rerrstr(err, sizeof(err));
+ errstr(err, sizeof(err));
if(strstr(err, "interrupt") == 0)
break;
}
@@ -161,13 +160,13 @@ proc_free(process *pp)
if (pp->pid >= 0)
proc_wait(pp);
free(pp->waitmsg);
- free((char *)pp);
+ free(pp);
return 0;
}
/* kill a process */
-extern int
-proc_kill(process *pp)
-{
- return syskill(pp->pid);
-}
+//extern int
+//proc_kill(process *pp)
+//{
+// return syskill(pp->pid);
+//}
diff --git a/sys/src/cmd/upas/common/sys.h b/sys/src/cmd/upas/common/sys.h
index a50f27284..a860df15f 100644
--- a/sys/src/cmd/upas/common/sys.h
+++ b/sys/src/cmd/upas/common/sys.h
@@ -1,85 +1,63 @@
-/*
- * System dependent header files for research
- */
-
#include <u.h>
#include <libc.h>
-#include <regexp.h>
#include <bio.h>
-#include "String.h"
/*
* for the lock routines in libsys.c
*/
typedef struct Mlock Mlock;
struct Mlock {
- int fd;
- int pid;
- String *name;
+ int fd;
+ int pid;
+ char name[Pathlen];
};
/*
* from config.c
*/
extern char *MAILROOT; /* root of mail system */
+extern char *SPOOL; /* spool directory; for spam ctl */
extern char *UPASLOG; /* log directory */
extern char *UPASLIB; /* upas library directory */
extern char *UPASBIN; /* upas binary directory */
extern char *UPASTMP; /* temporary directory */
extern char *SHELL; /* path name of shell */
-extern char *POST; /* path name of post server addresses */
-extern int MBOXMODE; /* default mailbox protection mode */
-/*
- * files in libsys.c
- */
-extern char *sysname_read(void);
-extern char *alt_sysname_read(void);
-extern char *domainname_read(void);
-extern char **sysnames_read(void);
-extern char *getlog(void);
-extern char *thedate(void);
-extern Biobuf *sysopen(char*, char*, ulong);
-extern int sysopentty(void);
-extern int sysclose(Biobuf*);
-extern int sysmkdir(char*, ulong);
-extern int syschgrp(char*, char*);
-extern Mlock *syslock(char *);
-extern void sysunlock(Mlock *);
-extern void syslockrefresh(Mlock *);
-extern int e_nonexistent(void);
-extern int e_locked(void);
-extern long sysfilelen(Biobuf*);
-extern int sysremove(char*);
-extern int sysrename(char*, char*);
-extern int sysexist(char*);
-extern int sysisdir(char*);
-extern int syskill(int);
-extern int syskillpg(int);
-extern int syscreate(char*, int, ulong);
-extern Mlock *trylock(char *);
-extern void exit(int);
-extern void pipesig(int*);
-extern void pipesigoff(void);
-extern int holdon(void);
-extern void holdoff(int);
-extern int syscreatelocked(char*, int, int);
-extern int sysopenlocked(char*, int);
-extern int sysunlockfile(int);
-extern int sysfiles(void);
-extern int become(char**, char*);
-extern int sysdetach(void);
-extern int sysdirreadall(int, Dir**);
-extern String *username(String*);
-extern char* remoteaddr(int, char*);
-extern int creatembox(char*, char*);
-
-extern String *readlock(String*);
-extern char *homedir(char*);
-extern String *mboxname(char*, String*);
-extern String *deadletter(String*);
+enum {
+ Mboxmode = 0622,
+};
/*
- * maximum size for a file path
+ * files in libsys.c
*/
-#define MAXPATHLEN 128
+char *sysname_read(void);
+char *alt_sysname_read(void);
+char *domainname_read(void);
+char **sysnames_read(void);
+char *getlog(void);
+char *thedate(void);
+Biobuf *sysopen(char*, char*, ulong);
+int sysopentty(void);
+int sysclose(Biobuf*);
+int sysmkdir(char*, ulong);
+Mlock *syslock(char *);
+void sysunlock(Mlock *);
+void syslockrefresh(Mlock *);
+int sysrename(char*, char*);
+int sysexist(char*);
+int syskill(int);
+int syskillpg(int);
+Mlock *trylock(char *);
+void pipesig(int*);
+void pipesigoff(void);
+int holdon(void);
+void holdoff(int);
+int syscreatelocked(char*, int, int);
+int sysopenlocked(char*, int);
+int sysunlockfile(int);
+int sysfiles(void);
+int become(char**, char*);
+int sysdetach(void);
+char *username(char*);
+int creatembox(char*, char*);
+int createfolder(char*, char*);
diff --git a/sys/src/cmd/upas/common/totm.c b/sys/src/cmd/upas/common/totm.c
new file mode 100644
index 000000000..8c05fb758
--- /dev/null
+++ b/sys/src/cmd/upas/common/totm.c
@@ -0,0 +1,36 @@
+#include <common.h>
+
+static char mtab[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+int
+ctimetotm(char *s, Tm *tm)
+{
+ char buf[32];
+
+ if(strlen(s) < 28)
+ return -1;
+ snprint(buf, sizeof buf, "%s", s);
+ memset(tm, 0, sizeof *tm);
+ buf[7] = 0;
+ tm->mon = (strstr(mtab, buf+4) - mtab)/3;
+ tm->mday = atoi(buf+8);
+ tm->hour = atoi(buf+11);
+ tm->min = atoi(buf+14);
+ tm->sec = atoi(buf+17);
+ tm->zone[0] = buf[20];
+ tm->zone[1] = buf[21];
+ tm->zone[2] = buf[22];
+ tm->year = atoi(buf+24) - 1900;
+ return 0;
+}
+
+int
+fromtotm(char *s, Tm *tm)
+{
+ char buf[256], *f[3];
+
+ snprint(buf, sizeof buf, "%s", s);
+ if(getfields(buf, f, nelem(f), 0, " ") != 3)
+ return -1;
+ return ctimetotm(f[2], tm);
+}