diff options
author | rsc <devnull@localhost> | 2005-10-29 16:26:32 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-10-29 16:26:32 +0000 |
commit | d1f529f46f957c78a3db73b42c2fcd2d3c9f8a34 (patch) | |
tree | a4d6f28106cca984926b9dd5ecddd6053b654617 /src/cmd/upas/common | |
parent | 9f1fdc128738b2ed76258ac22a8574c681f3df3a (diff) | |
download | plan9port-d1f529f46f957c78a3db73b42c2fcd2d3c9f8a34.tar.gz plan9port-d1f529f46f957c78a3db73b42c2fcd2d3c9f8a34.tar.bz2 plan9port-d1f529f46f957c78a3db73b42c2fcd2d3c9f8a34.zip |
Thanks to John Cummings.
Diffstat (limited to 'src/cmd/upas/common')
-rw-r--r-- | src/cmd/upas/common/appendfiletombox.c | 155 | ||||
-rw-r--r-- | src/cmd/upas/common/aux.c | 148 | ||||
-rw-r--r-- | src/cmd/upas/common/become.c | 28 | ||||
-rw-r--r-- | src/cmd/upas/common/common.h | 79 | ||||
-rw-r--r-- | src/cmd/upas/common/config.c | 11 | ||||
-rw-r--r-- | src/cmd/upas/common/libcommon.a | bin | 0 -> 251056 bytes |
6 files changed, 421 insertions, 0 deletions
diff --git a/src/cmd/upas/common/appendfiletombox.c b/src/cmd/upas/common/appendfiletombox.c new file mode 100644 index 00000000..98f51578 --- /dev/null +++ b/src/cmd/upas/common/appendfiletombox.c @@ -0,0 +1,155 @@ +#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; +} + +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; +} + +/* code to escape ' '*From' ' at the beginning of a line */ +int +appendfiletombox(int in, int out) +{ + int addspace; + int n; + char *p; + int sol; + Inbuf *b; + + seek(out, 0, 2); + + b = allocinbuf(in, out); + addspace = 0; + sol = 1; + + for(;;){ + if(b->wp - b->rp < 5){ + n = fill(b, addspace); + addspace = 0; + if(n < 0) + goto error; + if(n == 0) + break; + if(n < 5){ + 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 ", 5) != 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/src/cmd/upas/common/aux.c b/src/cmd/upas/common/aux.c new file mode 100644 index 00000000..7577acae --- /dev/null +++ b/src/cmd/upas/common/aux.c @@ -0,0 +1,148 @@ +#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].s.sp; /* jpc .sp -> .s.sp */ + ep = subexp[se].e.ep; /* jpc .ep -> .e.ep */ + for (; cp < ep; cp++) + s_putc(sp, *cp); + s_terminate(sp); +} + +/* + * check for shell characters in a String + */ +static char *illegalchars = "\r\n"; + +extern int +shellchars(char *cp) +{ + char *sp; + + for(sp=illegalchars; *sp; sp++) + if(strchr(cp, *sp)) + return 1; + return 0; +} + +static char *specialchars = " ()<>{};=\\'\`^&|"; +static char *escape = "%%"; + +int +hexchar(int x) +{ + x &= 0xf; + if(x < 10) + return '0' + x; + else + return 'A' + x - 10; +} + +/* + * rewrite a string to escape shell characters + */ +extern String* +escapespecial(String *s) +{ + String *ns; + char *sp; + + for(sp = specialchars; *sp; sp++) + if(strchr(s_to_c(s), *sp)) + break; + if(*sp == 0) + return s; + + ns = s_new(); + for(sp = s_to_c(s); *sp; sp++){ + if(strchr(specialchars, *sp)){ + s_append(ns, escape); + s_putc(ns, hexchar(*sp>>4)); + s_putc(ns, hexchar(*sp)); + } else + s_putc(ns, *sp); + } + s_terminate(ns); + s_free(s); + return ns; +} + +uint +hex2uint(char x) +{ + if(x >= '0' && x <= '9') + return x - '0'; + if(x >= 'A' && x <= 'F') + return (x - 'A') + 10; + if(x >= 'a' && x <= 'f') + return (x - 'a') + 10; + return -512; +} + +/* + * rewrite a string to remove shell characters escapes + */ +extern String* +unescapespecial(String *s) +{ + String *ns; + char *sp; + uint c, n; + + if(strstr(s_to_c(s), escape) == 0) + return s; + n = strlen(escape); + + ns = s_new(); + 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) + s_putc(ns, *sp); + else { + s_putc(ns, c); + sp += n+2-1; + } + } else + s_putc(ns, *sp); + } + s_terminate(ns); + s_free(s); + return ns; + +} + +int +returnable(char *path) +{ + + return strcmp(path, "/dev/null") != 0; +} diff --git a/src/cmd/upas/common/become.c b/src/cmd/upas/common/become.c new file mode 100644 index 00000000..1b5aa456 --- /dev/null +++ b/src/cmd/upas/common/become.c @@ -0,0 +1,28 @@ +#include "common.h" +#include <auth.h> +#include <ndb.h> + +/* + * become powerless user + */ +int +become(char **cmd, 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) { + werrstr("can't become none"); + return -1; + } + close(fd); + // jpc if(newns("none", 0)) { + // jpc werrstr("can't set new namespace"); + // jpc return -1; + // jpc } + } + return 0; +} + diff --git a/src/cmd/upas/common/common.h b/src/cmd/upas/common/common.h new file mode 100644 index 00000000..d1e93841 --- /dev/null +++ b/src/cmd/upas/common/common.h @@ -0,0 +1,79 @@ +#include "sys.h" + +/* format of REMOTE FROM lines */ +extern char *REMFROMRE; +extern int REMSENDERMATCH; +extern int REMDATEMATCH; +extern int REMSYSMATCH; + +/* 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 +{ + Elemlen= 28, + Errlen= 128, + Pathlen= 256, +}; + +/* + * routines in mail.c + */ +extern int print_header(Biobuf*, char*, char*); +extern int print_remote_header(Biobuf*, char*, char*, char*); +extern int parse_header(char*, String*, String*); + +/* + * 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*); + +/* in copymessage */ +extern int appendfiletombox(int, int); +extern int appendfiletofile(int, int); + +/* mailbox types */ +#define MF_NORMAL 0 +#define MF_PIPE 1 +#define MF_FORWARD 2 +#define MF_NOMBOX 3 +#define MF_NOTMBOX 4 + +/* a pipe between parent and child*/ +typedef struct { + Biobuf bb; + Biobuf *fp; /* parent process end*/ + int fd; /* child process end*/ +} stream; + +/* a child process*/ +typedef struct process{ + 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) diff --git a/src/cmd/upas/common/config.c b/src/cmd/upas/common/config.c new file mode 100644 index 00000000..4bbaff83 --- /dev/null +++ b/src/cmd/upas/common/config.c @@ -0,0 +1,11 @@ +#include "common.h" + +char *MAILROOT = "#9/mail"; +char *UPASLOG = "#9/sys/log"; +char *UPASLIB = "#9/mail/lib"; +char *UPASBIN= "#9/bin/upas"; +char *UPASTMP = "#9/mail/tmp"; +char *SHELL = "#9/bin/rc"; +char *POST = "#9/sys/lib/post/dispatch"; + +int MBOXMODE = 0662; diff --git a/src/cmd/upas/common/libcommon.a b/src/cmd/upas/common/libcommon.a Binary files differnew file mode 100644 index 00000000..7266859d --- /dev/null +++ b/src/cmd/upas/common/libcommon.a |