diff --exclude=CVS -durN serialmail-0.75/FILES maildircmd/FILES --- serialmail-0.75/FILES Sat Nov 14 21:28:23 1998 +++ maildircmd/FILES Tue Nov 30 09:02:12 1999 @@ -11,12 +11,16 @@ SYSDEPS TARGETS Makefile +maildircmd.1 +maildircmd.sh maildirqmtp.1 maildirqmtp.sh maildirsmtp.1 maildirsmtp.sh maildirserial.1 maildirserial.c +serialcmd.1 +serialcmd.c serialqmtp.1 serialqmtp.c serialsmtp.1 @@ -80,8 +84,12 @@ byte_copy.c byte_cr.c byte_diff.c +byte_rchr.c str.h +str_chr.c +str_cpy.c str_diff.c +str_diffn.c str_len.c str_rchr.c str_start.c @@ -90,6 +98,8 @@ strerr_die.c env.h env.c +writenv.h +writenv.c case.3 case.h case_diffb.c @@ -185,3 +195,7 @@ lock_exnb.c hasflock.h.do tryflock.c +seek.h +seek_set.c +rewind.c +rewind.1 diff --exclude=CVS -durN serialmail-0.75/Makefile maildircmd/Makefile --- serialmail-0.75/Makefile Sat Nov 14 21:28:23 1998 +++ maildircmd/Makefile Tue Nov 30 09:02:12 1999 @@ -135,6 +135,14 @@ compile env.c str.h env.h ./compile env.c +writenv.a: \ +makelib writenv.o str_cpy.o + ./makelib writenv.a writenv.o str_cpy.o + +writenv.o: \ +compile writenv.c writenv.h str.h + ./compile writenv.c + error.0: \ error.3 nroff -man error.3 > error.0 @@ -315,6 +323,17 @@ strerr.h ./compile maildir.c +maildircmd: \ +warn-auto.sh maildircmd.sh conf-home + cat warn-auto.sh maildircmd.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > maildircmd + chmod 755 maildircmd + +maildircmd.0: \ +maildircmd.1 + nroff -man maildircmd.1 > maildircmd.0 + maildirqmtp: \ warn-auto.sh maildirqmtp.sh conf-home cat warn-auto.sh maildirqmtp.sh \ @@ -380,6 +399,7 @@ chmod 755 makelib man: \ +serialcmd.0 maildircmd.0 rewind.0 \ maildirserial.0 setlock.0 serialsmtp.0 serialqmtp.0 maildirsmtp.0 \ maildirqmtp.0 alloc.0 caldate.0 caldate_mjd.0 caltime.0 caltime_tai.0 \ case.0 config.0 direntry.0 error.0 error_str.0 fd_copy.0 fd_move.0 \ @@ -430,7 +450,7 @@ prog: \ maildirserial setlock serialsmtp serialqmtp maildirsmtp maildirqmtp \ -rts +serialcmd maildircmd rewind rts qmail.o: \ compile qmail.c substdio.h readwrite.h wait.h exit.h fork.h fd.h \ @@ -441,6 +461,18 @@ compile quote.c stralloc.h gen_alloc.h str.h quote.h ./compile quote.c +rewind: \ +load seek_set.o rewind.o + ./load rewind seek_set.o + +rewind.o: \ +compile rewind.c seek.h + ./compile rewind.c + +seek_set.o: \ +compile seek_set.c seek.h + ./compile seek_set.c + rts: \ warn-auto.sh rts.sh conf-home cat warn-auto.sh rts.sh \ @@ -494,6 +526,24 @@ gen_alloc.h sig.h str.h case.h quote.h scan.h env.h ./compile serialsmtp.c +serialcmd: \ +now.o stralloc_num.o \ +load serialcmd.o timeoutread.o timeoutwrite.o quote.o case.a env.a \ +sig.a getln.a stralloc.a strerr.a substdio.a alloc.a error.a \ +wait.a open.a fd.a fs.a writenv.a str.a + ./load serialcmd timeoutread.o timeoutwrite.o quote.o \ + now.o stralloc_num.o \ + case.a env.a sig.a getln.a stralloc.a strerr.a substdio.a \ + alloc.a error.a wait.a open.a fd.a fs.a writenv.a str.a + +rewind.0: \ +rewind.1 + nroff -man rewind.1 > rewind.0 + +serialcmd.0: \ +serialcmd.1 + nroff -man serialcmd.1 > serialcmd.0 + setlock: \ load setlock.o getopt.a strerr.a substdio.a error.a str.a lock.a \ open.a @@ -534,14 +584,32 @@ ./compile sig_pipe.c str.a: \ +byte_rchr.o \ makelib str_len.o str_diff.o str_rchr.o str_start.o byte_chr.o \ -byte_diff.o byte_copy.o byte_cr.o +byte_diff.o byte_copy.o byte_cr.o str_cpy.o str_diffn.o str_chr.o ./makelib str.a str_len.o str_diff.o str_rchr.o \ - str_start.o byte_chr.o byte_diff.o byte_copy.o byte_cr.o + str_start.o byte_chr.o byte_diff.o byte_copy.o byte_cr.o \ + str_cpy.o str_diffn.o str_chr.o byte_rchr.o + +byte_rchr.o: \ +compile byte_rchr.c byte.h + ./compile byte_rchr.c + +str_chr.o: \ +compile str_chr.c str.h + ./compile str_chr.c + +str_cpy.o: \ +compile str_cpy.c str.h + ./compile str_cpy.c str_diff.o: \ compile str_diff.c str.h ./compile str_diff.c + +str_diffn.o: \ +compile str_diffn.c str.h + ./compile str_diffn.c str_len.o: \ compile str_len.c str.h diff --exclude=CVS -durN serialmail-0.75/byte_rchr.c maildircmd/byte_rchr.c --- serialmail-0.75/byte_rchr.c Wed Dec 31 19:00:00 1969 +++ maildircmd/byte_rchr.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,23 @@ +#include "byte.h" + +unsigned int byte_rchr(s,n,c) +char *s; +register unsigned int n; +int c; +{ + register char ch; + register char *t; + register char *u; + + ch = c; + t = s; + u = 0; + for (;;) { + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + } + if (!u) u = t; + return u - s; +} diff --exclude=CVS -durN serialmail-0.75/direntry.h maildircmd/direntry.h --- serialmail-0.75/direntry.h Wed Dec 31 19:00:00 1969 +++ maildircmd/direntry.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,8 @@ +#ifndef DIRENTRY_H +#define DIRENTRY_H + +#include +#include +#define direntry struct dirent + +#endif diff --exclude=CVS -durN serialmail-0.75/fork.h maildircmd/fork.h --- serialmail-0.75/fork.h Wed Dec 31 19:00:00 1969 +++ maildircmd/fork.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,7 @@ +#ifndef FORK_H +#define FORK_H + +extern int fork(); +extern int vfork(); + +#endif diff --exclude=CVS -durN serialmail-0.75/hasflock.h maildircmd/hasflock.h --- serialmail-0.75/hasflock.h Wed Dec 31 19:00:00 1969 +++ maildircmd/hasflock.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1 @@ +#define HASFLOCK 1 diff --exclude=CVS -durN serialmail-0.75/hier.c maildircmd/hier.c --- serialmail-0.75/hier.c Sat Nov 14 21:28:23 1998 +++ maildircmd/hier.c Tue Nov 30 09:02:12 1999 @@ -11,17 +11,23 @@ d(auto_home,"man/man1",-1,-1,02755); d(auto_home,"man/cat1",-1,-1,02755); + c(auto_home,"bin","serialcmd",-1,-1,0755); c(auto_home,"bin","serialqmtp",-1,-1,0755); c(auto_home,"bin","serialsmtp",-1,-1,0755); + c(auto_home,"bin","maildircmd",-1,-1,0755); c(auto_home,"bin","maildirqmtp",-1,-1,0755); c(auto_home,"bin","maildirsmtp",-1,-1,0755); c(auto_home,"bin","maildirserial",-1,-1,0755); c(auto_home,"bin","setlock",-1,-1,0755); + c(auto_home,"man/man1","serialcmd.1",-1,-1,0644); + c(auto_home,"man/cat1","serialcmd.0",-1,-1,0644); c(auto_home,"man/man1","serialqmtp.1",-1,-1,0644); c(auto_home,"man/cat1","serialqmtp.0",-1,-1,0644); c(auto_home,"man/man1","serialsmtp.1",-1,-1,0644); c(auto_home,"man/cat1","serialsmtp.0",-1,-1,0644); + c(auto_home,"man/man1","maildircmd.1",-1,-1,0644); + c(auto_home,"man/cat1","maildircmd.0",-1,-1,0644); c(auto_home,"man/man1","maildirqmtp.1",-1,-1,0644); c(auto_home,"man/cat1","maildirqmtp.0",-1,-1,0644); c(auto_home,"man/man1","maildirsmtp.1",-1,-1,0644); diff --exclude=CVS -durN serialmail-0.75/maildircmd.1 maildircmd/maildircmd.1 --- serialmail-0.75/maildircmd.1 Wed Dec 31 19:00:00 1969 +++ maildircmd/maildircmd.1 Tue Nov 30 09:02:12 1999 @@ -0,0 +1,33 @@ +.TH maildirsmtp 1 +.SH NAME +maildircmd \- pipe a maildir through a command +.SH SYNOPSIS +.B maildircmd +.I dir +.I prefix +.I command + +.SH DESCRIPTION +.B maildircmd +scans a maildir, +.IR dir , +and pipes each message through +.IR command . +It ignores any message whose recipient address does not begin with +.IR prefix . + +.B maildircmd +removes messages successfully handled by +.IR command , +based on the exit status of +.IR command . +It bounces messages permanently rejected by +.I command +back to the envelope sender, +and then removes them. +It treats temporary rejection as permanent rejection +for messages more than two weeks old. + +.SH "SEE ALSO" +maildirserial(1), +serialcmd(1) diff --exclude=CVS -durN serialmail-0.75/maildircmd.sh maildircmd/maildircmd.sh --- serialmail-0.75/maildircmd.sh Wed Dec 31 19:00:00 1969 +++ maildircmd/maildircmd.sh Tue Nov 30 09:32:03 1999 @@ -0,0 +1,4 @@ + +exec \ +HOME/bin/maildirserial -b -t 1209600 -- "$1" "$2" \ +HOME/bin/serialcmd "$1" "$3" diff --exclude=CVS -durN serialmail-0.75/maildirqmtp maildircmd/maildirqmtp --- serialmail-0.75/maildirqmtp Wed Dec 31 19:00:00 1969 +++ maildircmd/maildirqmtp Tue Nov 30 09:02:12 1999 @@ -0,0 +1,7 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! + +exec \ +/usr/local/bin/maildirserial -b -t 1209600 -- "$1" "$2" \ +tcpclient -RHl0 -- "$3" 209 \ +/usr/local/bin/serialqmtp "$2" diff --exclude=CVS -durN serialmail-0.75/maildirsmtp maildircmd/maildirsmtp --- serialmail-0.75/maildirsmtp Wed Dec 31 19:00:00 1969 +++ maildircmd/maildirsmtp Tue Nov 30 09:02:12 1999 @@ -0,0 +1,7 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! + +exec \ +/usr/local/bin/maildirserial -b -t 1209600 -- "$1" "$2" \ +tcpclient -RHl0 -- "$3" 25 \ +/usr/local/bin/serialsmtp "$2" "$4" diff --exclude=CVS -durN serialmail-0.75/rewind.1 maildircmd/rewind.1 --- serialmail-0.75/rewind.1 Wed Dec 31 19:00:00 1969 +++ maildircmd/rewind.1 Tue Nov 30 09:02:12 1999 @@ -0,0 +1,31 @@ +.\" Manpage for rewind, version 0.1.0 +.\" (C) Sun Feb 7 18:24:57 EST 1999, Len Budney +.\" +.TH "rewind" 1 "0.1.0" + + +.SH NAME +rewind \- Reset stdin to start of input, if seekable + +.SH SYNOPSIS +.I rewind + +.SH DESCRIPTION +.P +.I rewind +returns +.I stdin +to the start of its input, if input is coming from a seekable file. If +stdin is not seekable, then +.I rewind +has no effect. + +.P +.I rewind +permits a shell script to perform multiple actions on an input +file. This is particularly handy when input files are email messages, +and a shell script performs multiple actions, such as forwarding and +also filing away. + +.SH "SEE ALSO" +maildircmd(1), serialcmd(1). diff --exclude=CVS -durN serialmail-0.75/rewind.c maildircmd/rewind.c --- serialmail-0.75/rewind.c Wed Dec 31 19:00:00 1969 +++ maildircmd/rewind.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,3 @@ +#include "seek.h" + +int main(void) {seek_begin(0);} diff --exclude=CVS -durN serialmail-0.75/rts maildircmd/rts --- serialmail-0.75/rts Wed Dec 31 19:00:00 1969 +++ maildircmd/rts Tue Nov 30 09:02:12 1999 @@ -0,0 +1,3 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! +env - PATH=".:$PATH" sh rts.tests 2>&1 | cat -v diff --exclude=CVS -durN serialmail-0.75/seek.h maildircmd/seek.h --- serialmail-0.75/seek.h Wed Dec 31 19:00:00 1969 +++ maildircmd/seek.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,9 @@ +#ifndef SEEK_H +#define SEEK_H + +typedef unsigned long seek_pos; + +extern int seek_set(); +#define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) + +#endif diff --exclude=CVS -durN serialmail-0.75/seek_set.c maildircmd/seek_set.c --- serialmail-0.75/seek_set.c Wed Dec 31 19:00:00 1969 +++ maildircmd/seek_set.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,7 @@ +#include +#include "seek.h" + +#define SET 0 /* sigh */ + +int seek_set(fd,pos) int fd; seek_pos pos; +{ if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } diff --exclude=CVS -durN serialmail-0.75/select.h maildircmd/select.h --- serialmail-0.75/select.h Wed Dec 31 19:00:00 1969 +++ maildircmd/select.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,9 @@ +#ifndef SELECT_H +#define SELECT_H + +#include +#include +#include +extern int select(); + +#endif diff --exclude=CVS -durN serialmail-0.75/serialcmd.1 maildircmd/serialcmd.1 --- serialmail-0.75/serialcmd.1 Wed Dec 31 19:00:00 1969 +++ maildircmd/serialcmd.1 Tue Nov 30 09:02:12 1999 @@ -0,0 +1,87 @@ +.\" Manpage for serialcmd, version 0.1.0 +.\" (C) Sun Feb 7 18:24:57 EST 1999, Len Budney +.\" +.TH "serialcmd" 1 "0.1.0" + + +.SH NAME +serialcmd \- Pipe files through a command + + +.SH SYNOPSIS +.B serialcmd +.I prefix +.I command + +.SH DESCRIPTION +.B serialcmd +is similar to +.B serialsmtp +and +.BR serialqmtp , +except that it runs +.I command +under +.IR /bin/sh , +with the message as its standard input. +.I serialcmd +ensures that the standard input is seekable, so scripts can review the +message as often as desired, for example to perform multiple actions on +the same message. + +At the moment, +.I prefix +is ignored. It cannot be omitted, however, and may be used for something +in the future. + +The standard output of +.I command +is assumed to be a one-line, LF-terminated, human-readable status +message. This message is printed to the standard output of +.IR serialcmd , +preceeded by a null-terminated filename and a status byte, as required +by +.IR maildirserial . +Status is determined by the exit status of +.IR program . + +.SH EXIT CODES +.I command's +exit codes are interpreted as follows: 0 means that the message was +successfully processed (and so will be deleted from the maildir); 100 +means that processing has failed +.I permanently +for the message; 111 means that processing has failed but should be +tried again later. + +For compatability with sendmail-oriented filters, exit codes 64, 65, +70, 76, 77, 78, and 112 are also considered fatal errors, and other +exit codes are considered temporary errors, as in qmail-command(8). +New filters should not rely on this behavior. + +.SH "ENVIRONMENT VARIABLES" + +The variable AGE is set to the number of seconds elapsed since the +message was stored in the maildir. Further, +.I serialcmd +tries to set the same environment variables as +.IR qmail-local , +but some cannot be set since they are not known when invoking +.IR serialcmd : +NEWSENDER cannot be known; DEFAULT cannot be reliably determined; and +EXT, EXT1, EXT2, EXT3, and EXT4 can only be guessed (but are likely to +be guessed correctly). + +The remaining variables specified in qmail-command(8) are set +identically by +.IR serialcmd . + +In addition to variables explicitly set by +.IR serialcmd , +any variables inherited by +.I serialcmd +will be passed to +.IR command . + +.SH "SEE ALSO" +qmail-command(8), maildircmd(1), env(1), serialsmtp(1). diff --exclude=CVS -durN serialmail-0.75/serialcmd.c maildircmd/serialcmd.c --- serialmail-0.75/serialcmd.c Wed Dec 31 19:00:00 1969 +++ maildircmd/serialcmd.c Tue Nov 30 09:05:35 1999 @@ -0,0 +1,288 @@ +/* + serialcmd -- apply a command to a mail message. + Copyright 1999, Len Budney + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "strerr.h" +#include "getln.h" +#include "readwrite.h" +#include "subfd.h" +#include "substdio.h" +#include "now.h" +#include "open.h" +#include "stralloc.h" +#include "sig.h" +#include "str.h" +#include "byte.h" + +#define FATAL "serialcmd: fatal: " + +void die_usage() { + strerr_die1x(100,"serialcmd: usage: serialcmd prefix command"); +} +void die_nomem() { + strerr_die2x(111,FATAL,"out of memory"); +} +void die_nohomedir() { + strerr_die2x(111,FATAL,"no home directory"); +} +void die_nousername() { + strerr_die2x(111,FATAL,"no user name"); +} +void die_badexit() { + strerr_die2x(111,FATAL,"child exited abnormally"); +} +void die_output() { + strerr_die2sys(111,FATAL,"unable to write output: "); +} +void die_readmess() { + strerr_die2sys(111,FATAL,"unable to read file: "); +} +void die_openmess() { + strerr_die2sys(111,FATAL,"unable to open file: "); +} +void die_statmess() { + strerr_die2sys(111,FATAL,"unable to stat file: "); +} +void die_readstdin() { + strerr_die2sys(111,FATAL,"unable to read stdin: "); +} + +char *prefix; + +stralloc line = {0}; +stralloc quorecip = {0}; +stralloc quosender = {0}; +stralloc recipient = {0}; +stralloc sender = {0}; + +void result(fnam, code, statmsg) +stralloc fnam; +int code; +char *statmsg; +{ + char ch; + int i; + + if (!stralloc_copyb(&line,fnam.s,fnam.len)) die_nomem(); + switch(code) { + case(0): + case(99): + if (!stralloc_catb(&line,"K",1)) die_nomem(); + break; + case(100): + case(64): + case(65): + case(70): + case(76): + case(77): + case(78): + case(112): + if (!stralloc_catb(&line,"D",1)) die_nomem(); + break; + case(111): + default: + if (!stralloc_catb(&line,"Z",1)) die_nomem(); + break; + } + if (statmsg != NULL) + if (!stralloc_catb(&line,statmsg,strlen(statmsg))) die_nomem(); + if (!stralloc_catb(&line,"\n",1)) die_nomem(); + + if (substdio_put(subfdoutsmall,line.s,line.len) == -1) die_output(); + if (substdio_flush(subfdoutsmall) == -1) die_output(); +} + +void makeenv(void) +{ + int index = 0; + int i = 0; + stralloc foo = {0}; + stralloc user = {0}; + struct passwd *pw = 0; + char *host = 0; + char *ext = 0; + + /* Parse the recipient address. */ + index = byte_rchr(recipient.s,recipient.len,'@'); + *(recipient.s+index) = '\0'; + host = recipient.s + index + 1; + env_put2("LOCAL",recipient.s); + env_put2("HOST",host); + + /* Parse the pieces of the recipient domain. */ + i = str_len(host); + i = byte_rchr(host,i,'.'); + if (!stralloc_copyb(&foo,host,i)) die_nomem(); + if (!stralloc_0(&foo)) die_nomem(); + env_put2("HOST2",foo.s); + i = byte_rchr(host,i,'.'); + if (!stralloc_copyb(&foo,host,i)) die_nomem(); + if (!stralloc_0(&foo)) die_nomem(); + env_put2("HOST3",foo.s); + i = byte_rchr(host,i,'.'); + if (!stralloc_copyb(&foo,host,i)) die_nomem(); + if (!stralloc_0(&foo)) die_nomem(); + env_put2("HOST4",foo.s); + + /* Get the username associated with the effective UID. */ + pw = getpwuid(getuid()); + if (!stralloc_copys(&user,pw->pw_name)) die_nomem(); + if (!stralloc_0(&user)) die_nomem(); + if(pw == NULL) { + if(errno == ENOMEM) die_nomem(); + die_nousername(); + } + env_put2("USER",user.s); + + /* Compare the username with the local part of the recipient. */ + ext = recipient.s; + if(strlen(user.s) <= strlen(ext)) { + if(strncmp(user.s,ext,strlen(user.s)) == 0) { + ext += strlen(user.s); + } + } + ext += str_chr(ext,'-'); if (*ext) ++ext; + env_put2("EXT",ext); + ext += str_chr(ext,'-'); if (*ext) ++ext; + env_put2("EXT2",ext); + ext += str_chr(ext,'-'); if (*ext) ++ext; + env_put2("EXT3",ext); + ext += str_chr(ext,'-'); if (*ext) ++ext; + env_put2("EXT4",ext); + + /* Determine the home directory of user */ + pw = getpwnam(user.s); + if(pw == NULL) { + if(errno == ENOMEM) die_nomem(); + die_nohomedir(); + } + env_put2("HOME",pw->pw_dir); +} + +void runcmd(char **cmd, int fd, stralloc fnam) { + int pid; + int pipedesc[2]; + int status; + char msg[80]; + int msglen; + + status = pipe(pipedesc); + if(status == -1) { + strerr_die2sys(111,FATAL,"unable to open pipe: "); + } + lseek(fd,(off_t) 0,SEEK_SET); + pid = fork(); + if(pid == -1) strerr_die2sys(111,FATAL,"unable to fork: "); + if(pid == 0) { + if(dup2(fd,0) == -1) + strerr_die2sys(111,FATAL,"unable to read message: "); + if(dup2(pipedesc[1],1) == -1) + strerr_die2sys(111,FATAL,"unable to write to pipe: "); + close(pipedesc[1]); + close(pipedesc[0]); + if(execvp(*cmd, cmd) == -1) + strerr_die2sys(111,FATAL,"unable to execvp: "); + } + else { + char c; + int pstat; + /* Read any output from the child. */ + close(pipedesc[1]); + msglen = read(pipedesc[0],msg,79); + if(msglen == -1) + strerr_die2sys(111,FATAL,"unable to read process output: "); + msg[msglen] = '\n'; + msglen = str_chr(msg,'\n'); if(*(msg + msglen)) msg[msglen] = '\0'; + + /* Wait for the child to finish. */ + while(1) { + if(read(pipedesc[0],&c,1)==0) break; + } + wait(&pstat); + if(WIFEXITED(pstat)==0) die_badexit(); + result(fnam,WEXITSTATUS(pstat),msg); + } +} + +void doit(fd, argv, fnam) +int fd; +char *argv[]; +stralloc fnam; +{ + char messbuf[4096]; + substdio ssmess; + int match; + int exit_status; + datetime_sec age; + struct stat st; + + /* Stat the file, and read its age. */ + if(fstat(fd,&st) == -1) die_statmess(); + age = now() - st.st_mtime; + if (!stralloc_catulong0(&line,age,7)) die_nomem(); + env_put2("AGE",line.s); + + /* Initialize a substdio buffer. */ + substdio_fdbuf(&ssmess,read,fd,messbuf,sizeof messbuf); + + /* Look up the envelope sender. */ + if (getln(&ssmess,&line,&match,'\n') == -1) die_readmess(); + if (!match) return; + if (!stralloc_starts(&line,"Return-Path: <")) return; + if (line.s[line.len - 2] != '>') return; + if (line.s[line.len - 1] != '\n') return; + if (!stralloc_copyb(&sender,line.s + 14,line.len - 16)) die_nomem(); + if (!stralloc_catb(&line,"\0",1)) die_nomem(); + env_put2("RPLINE",line.s); + + /* Look up the envelope recipient. */ + if (getln(&ssmess,&line,&match,'\n') == -1) die_readmess(); + if (!match) return; + if (!stralloc_starts(&line,"Delivered-To: ")) return; + if (line.s[line.len - 1] != '\n') return; + if (!stralloc_copyb(&recipient,line.s + 14,line.len - 15)) die_nomem(); + if (!stralloc_catb(&line,"\0",1)) die_nomem(); + env_put2("DTLINE",line.s); + + /* Do some quoting on the sender and recipient. */ + if (!stralloc_0(&sender)) die_nomem(); + if (!quote2(&quosender,sender.s)) die_nomem(); + if (!stralloc_0(&recipient)) die_nomem(); + + /* Export some environment variables. */ + env_put2("SENDER",sender.s); + env_put2("RECIPIENT",recipient.s); + + /* Derive the rest of the environment variables. */ + makeenv(); + + /* Run the command now. */ + argv[0] = "/bin/sh"; + argv[1] = "-c"; + runcmd(argv,fd,fnam); +} + + +int main(char *argc, char *argv[]) { + int match; + stralloc fname = {0}; + char fnamebuf[4096]; + substdio ssfname; + int fd; + + substdio_fdbuf(&ssfname,read,0,fnamebuf,sizeof fnamebuf); + if (getln(&ssfname,&fname,&match,'\0') == -1) die_readstdin(); + if (!match) die_readstdin(); + fd = open_read(fname.s); + if(fd==-1) die_openmess(); + + doit(fd,argv,fname); +} diff --exclude=CVS -durN serialmail-0.75/str_chr.c maildircmd/str_chr.c --- serialmail-0.75/str_chr.c Wed Dec 31 19:00:00 1969 +++ maildircmd/str_chr.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,19 @@ +#include "str.h" + +unsigned int str_chr(s,c) +register char *s; +int c; +{ + register char ch; + register char *t; + + ch = c; + t = s; + for (;;) { + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + } + return t - s; +} diff --exclude=CVS -durN serialmail-0.75/str_cpy.c maildircmd/str_cpy.c --- serialmail-0.75/str_cpy.c Wed Dec 31 19:00:00 1969 +++ maildircmd/str_cpy.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,16 @@ +#include "str.h" + +unsigned int str_copy(s,t) +register char *s; +register char *t; +{ + register int len; + + len = 0; + for (;;) { + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + } +} diff --exclude=CVS -durN serialmail-0.75/str_diffn.c maildircmd/str_diffn.c --- serialmail-0.75/str_diffn.c Wed Dec 31 19:00:00 1969 +++ maildircmd/str_diffn.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,18 @@ +#include "str.h" + +int str_diffn(s,t,len) +register char *s; +register char *t; +unsigned int len; +{ + register char x; + + for (;;) { + if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + } + return ((int)(unsigned int)(unsigned char) x) + - ((int)(unsigned int)(unsigned char) *t); +} diff --exclude=CVS -durN serialmail-0.75/systype maildircmd/systype --- serialmail-0.75/systype Wed Dec 31 19:00:00 1969 +++ maildircmd/systype Tue Nov 30 09:02:12 1999 @@ -0,0 +1 @@ +linux-2.2.0-final-:i386-:-:pentium-:- diff --exclude=CVS -durN serialmail-0.75/uint64.h maildircmd/uint64.h --- serialmail-0.75/uint64.h Wed Dec 31 19:00:00 1969 +++ maildircmd/uint64.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,6 @@ +#ifndef UINT64_H +#define UINT64_H + +typedef unsigned long long uint64; + +#endif diff --exclude=CVS -durN serialmail-0.75/writenv.c maildircmd/writenv.c --- serialmail-0.75/writenv.c Wed Dec 31 19:00:00 1969 +++ maildircmd/writenv.c Tue Nov 30 09:02:12 1999 @@ -0,0 +1,122 @@ +/* env.c, envread.c, env.h: environ library +Daniel J. Bernstein, djb@silverton.berkeley.edu. +Depends on str.h, alloc.h. +Requires environ. +19960113: rewrite. warning: interface is different. +No known patent problems. +*/ + +#include "str.h" +#include "alloc.h" +#include "writenv.h" + +int env_isinit = 0; /* if env_isinit: */ +static int ea; /* environ is a pointer to ea+1 char*'s. */ +static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */ + +static void env_goodbye(i) int i; +{ + alloc_free(environ[i]); + environ[i] = environ[--en]; + environ[en] = 0; +} + +static char *null = 0; + +void env_clear() +{ + if (env_isinit) while (en) env_goodbye(0); + else environ = &null; +} + +static void env_unsetlen(s,len) char *s; int len; +{ + int i; + for (i = en - 1;i >= 0;--i) + if (!str_diffn(s,environ[i],len)) + if (environ[i][len] == '=') + env_goodbye(i); +} + +int env_unset(s) char *s; +{ + if (!env_isinit) if (!env_init()) return 0; + env_unsetlen(s,str_len(s)); + return 1; +} + +static int env_add(s) char *s; +{ + char *t; + t = env_findeq(s); + if (t) env_unsetlen(s,t - s); + if (en == ea) + { + ea += 30; + if (!alloc_re(&environ,(en + 1) * sizeof(char *),(ea + 1) * sizeof(char *))) + { ea = en; return 0; } + } + environ[en++] = s; + environ[en] = 0; + return 1; +} + +int env_put(s) char *s; +{ + char *u; + if (!env_isinit) if (!env_init()) return 0; + u = alloc(str_len(s) + 1); + if (!u) return 0; + str_copy(u,s); + if (!env_add(u)) { alloc_free(u); return 0; } + return 1; +} + +int env_put2(s,t) char *s; char *t; +{ + char *u; + int slen; + if (!env_isinit) if (!env_init()) return 0; + slen = str_len(s); + u = alloc(slen + str_len(t) + 2); + if (!u) return 0; + str_copy(u,s); + u[slen] = '='; + str_copy(u + slen + 1,t); + if (!env_add(u)) { alloc_free(u); return 0; } + return 1; +} + +int env_init() +{ + char **newenviron; + int i; + for (en = 0;environ[en];++en) ; + ea = en + 10; + newenviron = (char **) alloc((ea + 1) * sizeof(char *)); + if (!newenviron) return 0; + for (en = 0;environ[en];++en) + { + newenviron[en] = alloc(str_len(environ[en]) + 1); + if (!newenviron[en]) + { + for (i = 0;i < en;++i) alloc_free(newenviron[i]); + alloc_free(newenviron); + return 0; + } + str_copy(newenviron[en],environ[en]); + } + newenviron[en] = 0; + environ = newenviron; + env_isinit = 1; + return 1; +} + +extern char *env_findeq(s) +char *s; +{ + for (;*s;++s) + if (*s == '=') + return s; + return 0; +} diff --exclude=CVS -durN serialmail-0.75/writenv.h maildircmd/writenv.h --- serialmail-0.75/writenv.h Wed Dec 31 19:00:00 1969 +++ maildircmd/writenv.h Tue Nov 30 09:02:12 1999 @@ -0,0 +1,16 @@ +#ifndef WRITENV_H +#define WRITENV_H + +extern int env_isinit; + +extern int env_init(); +extern int env_put(); +extern int env_put2(); +extern int env_unset(); +extern char *env_pick(); +extern void env_clear(); +extern char *env_findeq(); + +extern char **environ; + +#endif