aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/upas/common
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-10-29 16:26:32 +0000
committerrsc <devnull@localhost>2005-10-29 16:26:32 +0000
commitd1f529f46f957c78a3db73b42c2fcd2d3c9f8a34 (patch)
treea4d6f28106cca984926b9dd5ecddd6053b654617 /src/cmd/upas/common
parent9f1fdc128738b2ed76258ac22a8574c681f3df3a (diff)
downloadplan9port-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.c155
-rw-r--r--src/cmd/upas/common/aux.c148
-rw-r--r--src/cmd/upas/common/become.c28
-rw-r--r--src/cmd/upas/common/common.h79
-rw-r--r--src/cmd/upas/common/config.c11
-rw-r--r--src/cmd/upas/common/libcommon.abin0 -> 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
new file mode 100644
index 00000000..7266859d
--- /dev/null
+++ b/src/cmd/upas/common/libcommon.a
Binary files differ