Thanks to John Cummings.

This commit is contained in:
rsc 2005-10-29 16:26:32 +00:00
parent 9f1fdc1287
commit d1f529f46f
27 changed files with 4344 additions and 0 deletions

View 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
View 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;
}

View 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;
}

View 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)

View 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;

Binary file not shown.