Thanks to John Cummings.
This commit is contained in:
parent
9f1fdc1287
commit
d1f529f46f
27 changed files with 4344 additions and 0 deletions
155
src/cmd/upas/common/appendfiletombox.c
Normal file
155
src/cmd/upas/common/appendfiletombox.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
148
src/cmd/upas/common/aux.c
Normal file
148
src/cmd/upas/common/aux.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
28
src/cmd/upas/common/become.c
Normal file
28
src/cmd/upas/common/become.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
79
src/cmd/upas/common/common.h
Normal file
79
src/cmd/upas/common/common.h
Normal file
|
|
@ -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)
|
||||
11
src/cmd/upas/common/config.c
Normal file
11
src/cmd/upas/common/config.c
Normal file
|
|
@ -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;
|
||||
BIN
src/cmd/upas/common/libcommon.a
Normal file
BIN
src/cmd/upas/common/libcommon.a
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue