dot-forward-0.71/004075500000000000001000000000000653025560500140405ustar00rootother00000000000000dot-forward-0.71/BLURB010064400000000000001000000007160653025572600146360ustar00rootother00000000000000dot-forward reads sendmail's .forward files under qmail. You can run it in the qmail startup script to support all your existing .forward files automatically. Individual users can switch to the .qmail mechanism at their leisure. dot-forward supports forwarding, program deliveries, and comments. It does not support file deliveries or :include:. (However, it recognizes file delivery attempts, and defers delivery to give you a chance to set up a .qmail file.) dot-forward-0.71/README010064400000000000001000000015060653025572600147230ustar00rootother00000000000000dot-forward 0.71, beta. 19980519 Copyright 1998 D. J. Bernstein, djb@pobox.com dot-forward reads sendmail's .forward files under qmail. See BLURB for a more detailed advertisement. INSTALL says how to set up dot-forward. You may distribute unmodified copies of the dot-forward package. The rest of this file is a list of systypes where various versions of dot-forward have been reported to work. 0.70: bsd.os-2.0.1-:i386-:-:pentium-:- 0.51: freebsd-2.2.2-release-:i386-:-:i486-dx-:- (tnx MM) 0.51: freebsd-3.0-current-:i386-:-:pentium-:- (tnx KB) 0.70: irix-5.3-11091811-:-:-:ip19-:- (tnx JB) 0.51: linux-2.0.30-:i386-:-:pentium-:- (tnx MAP) 0.51: linux-2.0.30-:i386-:-:ppro-:- (tnx LN) 0.51: netbsd-1.2g-:i386-:-:intel.pentium.(p54c).(586-class)-:- (tnx GW) 0.51: sunos-5.5.1-generic_103640-08-:sparc-:sun4-:sun4m-:sun4m- (tnx ESM) dot-forward-0.71/TODO010064400000000000001000000000050653025572600145240ustar00rootother00000000000000test dot-forward-0.71/THANKS010064400000000000001000000002120653025572600147470ustar00rootother00000000000000ESM = Edward S. Marshall GW = Geoff Wing JB = Jos Backus KB = Keith Burdis LN = Lukas Nellen MAP = Michael A. Peck MM = Martin Mersberger dot-forward-0.71/CHANGES010064400000000000001000000014720653025572600150400ustar00rootother0000000000000019980519 version: dot-forward 0.71, beta. 19980519 doc: simplified INSTALL. 19980519 doc: documented -n in dot-forward.1. 19980519 code: eliminated home+df. 19980519 doc: put version and home page into dot-forward.1. 19980519 code: switched to new install. 19980421 dot-forward 0.70, beta. 19980421 code: recognized $USER@$HOST the same way as $USER. 19980421 doc: reorganized compatibility warnings in dot-forward.0. 19980421 doc: eliminated *.3. 19980421 doc: added note about file deferrals to BLURB. 19980421 code: added home+df.sh; updated INSTALL accordingly. 19980421 code: moved installation from /usr/local to /var/qmail. 19971001 doc: eliminated hassgprm.h from SYSDEPS. tnx JB. 19971001 dot-forward 0.51, alpha. 19971001 doc: changed ./forward to .forward in man page and INSTALL. 19970930 dot-forward 0.50, alpha. dot-forward-0.71/FILES010064400000000000001000000020470653025572600146310ustar00rootother00000000000000BLURB README TODO THANKS CHANGES FILES VERSION SYSDEPS Makefile TARGETS dot-forward.1 dot-forward.c conf-cc conf-ld find-systype.sh make-compile.sh make-load.sh make-makelib.sh trycpp.c warn-auto.sh conf-qmail auto_qmail.h qmail.h qmail.c INSTALL hier.c auto-str.c install.c instcheck.c sgetopt.h sgetopt.c subgetopt.h subgetopt.c substdio.h substdio.c substdi.c substdo.c substdio_copy.c subfd.h subfderr.c readwrite.h exit.h strerr.h strerr_sys.c strerr_die.c byte.h byte_chr.c byte_copy.c byte_cr.c str.h str_diffn.c str_len.c error.h error.c error_str.c wait.h wait_pid.c trywaitp.c fork.h1 fork.h2 tryvfork.c fd.h fd_copy.c fd_move.c getln.h getln.c getln2.c gen_alloc.h gen_allocdefs.h stralloc.h stralloc_eady.c stralloc_pend.c stralloc_copy.c stralloc_opyb.c stralloc_opys.c stralloc_cat.c stralloc_catb.c stralloc_cats.c alloc.h alloc.c alloc_re.c env.h envread.c open.h open_read.c open_trunc.c sig.h sig_catch.c sig_pipe.c trysgact.c token822.h token822.c control.h control.c fmt.h fmt_ulong.c scan.h scan_ulong.c case.h case_diffb.c seek.h seek_set.c dot-forward-0.71/VERSION010064400000000000001000000000210653025572600151020ustar00rootother00000000000000dot-forward 0.71 dot-forward-0.71/SYSDEPS010064400000000000001000000000550653025572600151160ustar00rootother00000000000000VERSION systype fork.h hassgact.h haswaitp.h dot-forward-0.71/Makefile010064400000000000001000000210100653025572600154730ustar00rootother00000000000000# Don't edit Makefile! Use conf-* for configuration. SHELL=/bin/sh default: it alloc.a: \ makelib alloc.o alloc_re.o ./makelib alloc.a alloc.o alloc_re.o alloc.o: \ compile alloc.c alloc.h error.h ./compile alloc.c alloc_re.o: \ compile alloc_re.c alloc.h byte.h ./compile alloc_re.c auto-ccld.sh: \ conf-cc conf-ld warn-auto.sh ( cat warn-auto.sh; \ echo CC=\'`head -1 conf-cc`\'; \ echo LD=\'`head -1 conf-ld`\' \ ) > auto-ccld.sh auto-str: \ load auto-str.o substdio.a error.a str.a ./load auto-str substdio.a error.a str.a auto-str.o: \ compile auto-str.c substdio.h readwrite.h exit.h ./compile auto-str.c auto_qmail.c: \ auto-str conf-qmail ./auto-str auto_qmail `head -1 conf-qmail` > auto_qmail.c auto_qmail.o: \ compile auto_qmail.c ./compile auto_qmail.c byte_chr.o: \ compile byte_chr.c byte.h ./compile byte_chr.c byte_copy.o: \ compile byte_copy.c byte.h ./compile byte_copy.c byte_cr.o: \ compile byte_cr.c byte.h ./compile byte_cr.c case.a: \ makelib case_diffb.o ./makelib case.a case_diffb.o case_diffb.o: \ compile case_diffb.c case.h ./compile case_diffb.c check: \ it instcheck ./instcheck compile: \ make-compile warn-auto.sh systype ( cat warn-auto.sh; ./make-compile "`cat systype`" ) > \ compile chmod 755 compile control.o: \ compile control.c readwrite.h open.h getln.h stralloc.h gen_alloc.h \ substdio.h error.h control.h alloc.h scan.h ./compile control.c dot-forward: \ load dot-forward.o control.o qmail.o auto_qmail.o token822.o env.a \ getln.a getopt.a strerr.a error.a substdio.a stralloc.a alloc.a \ case.a str.a sig.a seek.a open.a wait.a fd.a fs.a ./load dot-forward control.o qmail.o auto_qmail.o \ token822.o env.a getln.a getopt.a strerr.a error.a \ substdio.a stralloc.a alloc.a case.a str.a sig.a seek.a \ open.a wait.a fd.a fs.a dot-forward.0: \ dot-forward.1 nroff -man dot-forward.1 > dot-forward.0 dot-forward.o: \ compile dot-forward.c sgetopt.h subgetopt.h substdio.h readwrite.h \ stralloc.h gen_alloc.h getln.h strerr.h error.h exit.h open.h wait.h \ seek.h env.h str.h fmt.h token822.h gen_alloc.h control.h qmail.h \ substdio.h auto_qmail.h ./compile dot-forward.c env.a: \ makelib envread.o ./makelib env.a envread.o envread.o: \ compile envread.c env.h str.h ./compile envread.c error.a: \ makelib error.o error_str.o ./makelib error.a error.o error_str.o error.o: \ compile error.c error.h ./compile error.c error_str.o: \ compile error_str.c error.h ./compile error_str.c fd.a: \ makelib fd_copy.o fd_move.o ./makelib fd.a fd_copy.o fd_move.o fd_copy.o: \ compile fd_copy.c fd.h ./compile fd_copy.c fd_move.o: \ compile fd_move.c fd.h ./compile fd_move.c find-systype: \ find-systype.sh auto-ccld.sh cat auto-ccld.sh find-systype.sh > find-systype chmod 755 find-systype fmt_ulong.o: \ compile fmt_ulong.c fmt.h ./compile fmt_ulong.c fork.h: \ compile load tryvfork.c fork.h1 fork.h2 ( ( ./compile tryvfork.c && ./load tryvfork ) >/dev/null \ 2>&1 \ && cat fork.h2 || cat fork.h1 ) > fork.h rm -f tryvfork.o tryvfork fs.a: \ makelib fmt_ulong.o scan_ulong.o ./makelib fs.a fmt_ulong.o scan_ulong.o getln.a: \ makelib getln.o getln2.o ./makelib getln.a getln.o getln2.o getln.o: \ compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h ./compile getln.c getln2.o: \ compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h ./compile getln2.c getopt.a: \ makelib subgetopt.o sgetopt.o ./makelib getopt.a subgetopt.o sgetopt.o hassgact.h: \ trysgact.c compile load ( ( ./compile trysgact.c && ./load trysgact ) >/dev/null \ 2>&1 \ && echo \#define HASSIGACTION 1 || exit 0 ) > hassgact.h rm -f trysgact.o trysgact haswaitp.h: \ trywaitp.c compile load ( ( ./compile trywaitp.c && ./load trywaitp ) >/dev/null \ 2>&1 \ && echo \#define HASWAITPID 1 || exit 0 ) > haswaitp.h rm -f trywaitp.o trywaitp hier.o: \ compile hier.c auto_qmail.h ./compile hier.c install: \ load install.o hier.o auto_qmail.o strerr.a substdio.a error.a open.a \ str.a ./load install hier.o auto_qmail.o strerr.a substdio.a \ error.a open.a str.a install.o: \ compile install.c substdio.h strerr.h error.h open.h readwrite.h \ exit.h ./compile install.c instcheck: \ load instcheck.o hier.o auto_qmail.o strerr.a substdio.a error.a \ str.a ./load instcheck hier.o auto_qmail.o strerr.a substdio.a \ error.a str.a instcheck.o: \ compile instcheck.c strerr.h error.h readwrite.h exit.h ./compile instcheck.c it: \ prog man load: \ make-load warn-auto.sh systype ( cat warn-auto.sh; ./make-load "`cat systype`" ) > load chmod 755 load make-compile: \ make-compile.sh auto-ccld.sh cat auto-ccld.sh make-compile.sh > make-compile chmod 755 make-compile make-load: \ make-load.sh auto-ccld.sh cat auto-ccld.sh make-load.sh > make-load chmod 755 make-load make-makelib: \ make-makelib.sh auto-ccld.sh cat auto-ccld.sh make-makelib.sh > make-makelib chmod 755 make-makelib makelib: \ make-makelib warn-auto.sh systype ( cat warn-auto.sh; ./make-makelib "`cat systype`" ) > \ makelib chmod 755 makelib man: \ dot-forward.0 open.a: \ makelib open_read.o open_trunc.o ./makelib open.a open_read.o open_trunc.o open_read.o: \ compile open_read.c open.h ./compile open_read.c open_trunc.o: \ compile open_trunc.c open.h ./compile open_trunc.c prog: \ dot-forward qmail.o: \ compile qmail.c substdio.h readwrite.h wait.h exit.h fork.h fd.h \ qmail.h substdio.h auto_qmail.h ./compile qmail.c scan_ulong.o: \ compile scan_ulong.c scan.h ./compile scan_ulong.c seek.a: \ makelib seek_set.o ./makelib seek.a seek_set.o seek_set.o: \ compile seek_set.c seek.h ./compile seek_set.c setup: \ it install ./install sgetopt.o: \ compile sgetopt.c substdio.h subfd.h substdio.h sgetopt.h subgetopt.h \ subgetopt.h ./compile sgetopt.c sig.a: \ makelib sig_catch.o sig_pipe.o ./makelib sig.a sig_catch.o sig_pipe.o sig_catch.o: \ compile sig_catch.c sig.h hassgact.h ./compile sig_catch.c sig_pipe.o: \ compile sig_pipe.c sig.h ./compile sig_pipe.c str.a: \ makelib str_len.o str_diffn.o byte_chr.o byte_copy.o byte_cr.o ./makelib str.a str_len.o str_diffn.o byte_chr.o \ byte_copy.o byte_cr.o str_diffn.o: \ compile str_diffn.c str.h ./compile str_diffn.c str_len.o: \ compile str_len.c str.h ./compile str_len.c stralloc.a: \ makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \ stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \ stralloc_catb.o ./makelib stralloc.a stralloc_eady.o stralloc_pend.o \ stralloc_copy.o stralloc_opys.o stralloc_opyb.o \ stralloc_cat.o stralloc_cats.o stralloc_catb.o stralloc_cat.o: \ compile stralloc_cat.c byte.h stralloc.h gen_alloc.h ./compile stralloc_cat.c stralloc_catb.o: \ compile stralloc_catb.c stralloc.h gen_alloc.h byte.h ./compile stralloc_catb.c stralloc_cats.o: \ compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h ./compile stralloc_cats.c stralloc_copy.o: \ compile stralloc_copy.c byte.h stralloc.h gen_alloc.h ./compile stralloc_copy.c stralloc_eady.o: \ compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \ gen_allocdefs.h ./compile stralloc_eady.c stralloc_opyb.o: \ compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h ./compile stralloc_opyb.c stralloc_opys.o: \ compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h ./compile stralloc_opys.c stralloc_pend.o: \ compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ gen_allocdefs.h ./compile stralloc_pend.c strerr.a: \ makelib strerr_sys.o strerr_die.o ./makelib strerr.a strerr_sys.o strerr_die.o strerr_die.o: \ compile strerr_die.c substdio.h subfd.h substdio.h exit.h strerr.h ./compile strerr_die.c strerr_sys.o: \ compile strerr_sys.c error.h strerr.h ./compile strerr_sys.c subfderr.o: \ compile subfderr.c readwrite.h substdio.h subfd.h substdio.h ./compile subfderr.c subgetopt.o: \ compile subgetopt.c subgetopt.h ./compile subgetopt.c substdi.o: \ compile substdi.c substdio.h byte.h error.h ./compile substdi.c substdio.a: \ makelib substdio.o substdi.o substdo.o subfderr.o substdio_copy.o ./makelib substdio.a substdio.o substdi.o substdo.o \ subfderr.o substdio_copy.o substdio.o: \ compile substdio.c substdio.h ./compile substdio.c substdio_copy.o: \ compile substdio_copy.c substdio.h ./compile substdio_copy.c substdo.o: \ compile substdo.c substdio.h str.h byte.h error.h ./compile substdo.c systype: \ find-systype trycpp.c ./find-systype > systype token822.o: \ compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \ gen_alloc.h gen_allocdefs.h ./compile token822.c wait.a: \ makelib wait_pid.o ./makelib wait.a wait_pid.o wait_pid.o: \ compile wait_pid.c error.h haswaitp.h ./compile wait_pid.c dot-forward-0.71/TARGETS010064400000000000001000000016140653025572600150770ustar00rootother00000000000000auto-ccld.sh make-load find-systype systype load make-compile compile dot-forward.o control.o fork.h qmail.o auto-str.o make-makelib makelib substdio.o substdi.o substdo.o subfderr.o substdio_copy.o substdio.a error.o error_str.o error.a str_len.o str_diffn.o byte_chr.o byte_copy.o byte_cr.o str.a auto-str auto_qmail.c auto_qmail.o token822.o envread.o env.a getln.o getln2.o getln.a subgetopt.o sgetopt.o getopt.a strerr_sys.o strerr_die.o strerr.a stralloc_eady.o stralloc_pend.o stralloc_copy.o stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o stralloc_catb.o stralloc.a alloc.o alloc_re.o alloc.a case_diffb.o case.a hassgact.h sig_catch.o sig_pipe.o sig.a seek_set.o seek.a open_read.o open_trunc.o open.a haswaitp.h wait_pid.o wait.a fd_copy.o fd_move.o fd.a fmt_ulong.o scan_ulong.o fs.a dot-forward prog dot-forward.0 man it install.o hier.o install setup instcheck.o instcheck check dot-forward-0.71/dot-forward.1010064400000000000001000000106740653025572600163630ustar00rootother00000000000000.TH dot-forward 1 .SH NAME dot-forward \- read a .forward file under qmail .SH SYNOPSIS in .BR ~/.qmail : .B | dot-forward [ .B \-nN ] .I file ... .SH OVERVIEW .B dot-forward forwards incoming messages according to sendmail-style instructions in .IR file , if .I file exists. Normally .I file is .BR .forward . .B WARNING: If you create a .B .qmail file to enable .BR dot-forward , make sure to add a second line specifying delivery to your normal mailbox. For example: .EX |dot-forward .forward .br ./Mailbox .EE .B COMPATIBILITY WARNING: .B dot-forward does not support .B :include: or mbox deliveries. You can use the delivery mechanism described in .BR dot-qmail (5) instead. .SH OPTIONS .TP 5 .B \-N (Default.) Read and forward a message. .TP .B \-n Parse .I file and print the forwarding instructions in it, one per line; do not follow the instructions. You can use this option from the command line to see how your .B .forward file will be interpreted: .EX dot-forward -n .forward .EE .SH "FILE HANDLING" When a message arrives, .B dot-forward opens .I file and handles it as discussed below. It exits 99, so .B qmail-local will ignore further instructions in .BR .qmail . Exception: If .I file specifies delivery directly to you, .B dot-forward exits 0, so .B qmail-local will read further instructions in .BR .qmail . If .I file does not exist, .B dot-forward exits 0. You can list several .IR file s; then .B dot-forward will try each one in turn, using the first one that exists, or exiting 0 if none exist. .B COMPATIBILITY WARNING: .B dot-forward treats an empty .I file as if it did not exist. Versions of sendmail before V8 would throw away the incoming message. .B COMPATIBILITY WARNING: If .B dot-forward encounters a temporary error opening .IR file , it exits 111, so that .B qmail-local will try again later. sendmail assumes incorrectly that .I file does not exist. .B COMPATIBILITY WARNING: .I file must be readable by .BR dot-forward , which is normally running as the user. sendmail places different constraints on its .B .forward permissions, since it is normally running as root. .SH "FORWARDING" Normally .I file contains an address. .B dot-forward forwards the message to that address. The address is parsed as if it were in an RFC 822 message header. Parenthesized comments and bracketed addresses are permitted: .EX bob (Bob, the postmaster) @heaven.af.mil .EE Addresses with special characters must be quoted: .EX "spaced out mailbox"@heaven.af.mil .EE Address groups are not permitted. .I file can contain any number of lines, each line containing any number of addresses. .B dot-forward forwards the message to each address: .EX bob, fred, susan .br Joe Shmoe .EE An address without a fully qualified domain name is handled as described in .BR qmail-header (5). Exception: Certain addresses without domain names are handled specially, as described below. .SH "DIRECT DELIVERY" If an address does not contain a domain name, and matches the environment variable .B $USER (without regard to case), it specifies delivery directly to you. If an address matches .B $USER@$HOST (without regard to case), it specifies delivery directly to you. .B COMPATIBILITY WARNING: sendmail's handling of quotes and backslashes violates RFC 821 and RFC 822, and is not supported by .BR dot-forward . .B dot-forward treats .B \ejoe the same way as .BR joe . The .B dot-qmail delivery mechanism lets each user manage several addresses, so there is no need for a special syntax to get around forwarding. .SH "COMMANDS" If an address does not contain a domain name, and begins with a vertical bar, .B dot-forward takes the rest of the address as a command to run: .EX bob, "|vacation bob" .EE .B dot-forward feeds the message to the command, preceded by the environment variables .BR $UFLINE , .BR $RPLINE , and .BR $DTLINE . .B COMPATIBILITY WARNING: Internet addresses can legitimately start with a slash or vertical bar. .B dot-forward treats anything with an unquoted @ as an address. sendmail appears to have various problems coping with these addresses, and with commands that contain @ signs. .SH "COMMENTS" Any line in .I file that begins with # is ignored: .EX # this is a comment .EE .B COMPATIBILITY WARNING: Versions of sendmail before V8 did not allow comments in .B .forward files. .SH VERSION This is .B dot-forward 0.71. The .B dot-forward home page is .BR http://pobox.com/~djb/dot-forward.html . .SH "SEE ALSO" qmail-header(5), dot-qmail(5) dot-forward-0.71/dot-forward.c010064400000000000001000000232440653025572600164420ustar00rootother00000000000000#include "sgetopt.h" #include "substdio.h" #include "readwrite.h" #include "stralloc.h" #include "getln.h" #include "strerr.h" #include "error.h" #include "exit.h" #include "open.h" #include "wait.h" #include "seek.h" #include "env.h" #include "str.h" #include "fmt.h" #include "token822.h" #include "control.h" #include "qmail.h" #include "auto_qmail.h" #define FATAL "dot-forward: fatal: " #define INFO "dot-forward: info: " void die_nomem() { strerr_die2x(111,FATAL,"out of memory"); } void die_control() { strerr_die2sys(111,FATAL,"unable to read controls: "); } void die_qq() { strerr_die2sys(111,FATAL,"unable to run qq: "); } void die_readmess() { strerr_die2sys(111,FATAL,"unable to read message: "); } stralloc line = {0}; void die_parse() { if (!stralloc_0(&line)) die_nomem(); strerr_die3x(111,FATAL,"unable to parse this line: ",line.s); } int flagdoit = 1; int flagacted; int flagdirect; char *ufline; char *rpline; char *dtline; char *sender; char *user; int userlen; char *host; int hostlen; char messbuf[1024]; substdio ssmess; char childbuf[1024]; substdio sschild; int blindwrite(fd,buf,len) int fd; char *buf; int len; { write(fd,buf,len); return len; } void run(cmd) char *cmd; { int child; int pi[2]; char *args[4]; int wstat; if (!flagdoit) { strerr_warn2("pipe through ",cmd,0); return; } if (pipe(pi) == -1) strerr_die2sys(111,FATAL,"unable to create pipe: "); switch (child = fork()) { case -1: strerr_die2sys(111,FATAL,"unable to fork: "); case 0: close(pi[1]); if (fd_move(0,pi[0]) == -1) strerr_die2sys(111,FATAL,"unable to set fd: "); args[0] = "/bin/sh"; args[1] = "-c"; args[2] = cmd; args[3] = 0; sig_pipedefault(); execv(*args,args); strerr_die2sys(111,FATAL,"unable to run /bin/sh: "); } close(pi[0]); substdio_fdbuf(&ssmess,read,0,messbuf,sizeof messbuf); substdio_fdbuf(&sschild,blindwrite,pi[1],childbuf,sizeof childbuf); substdio_puts(&sschild,ufline); substdio_puts(&sschild,rpline); substdio_puts(&sschild,dtline); if (substdio_copy(&sschild,&ssmess) != 0) die_readmess(); substdio_flush(&sschild); close(pi[1]); wait_pid(&wstat,child); if (wait_crashed(wstat)) strerr_die2x(111,FATAL,"child crashed"); switch(wait_exitcode(wstat)) { case 100: case 64: case 65: case 70: case 76: case 77: case 78: case 112: _exit(100); case 0: break; default: _exit(111); } if (seek_begin(0) == -1) strerr_die2sys(111,FATAL,"unable to rewind input: "); } stralloc targets = {0}; stralloc me = {0}; stralloc defaulthost = {0}; stralloc defaultdomain = {0}; stralloc plusdomain = {0}; void readcontrols() { int r; int fddir; fddir = open_read("."); if (fddir == -1) strerr_die2sys(111,FATAL,"unable to open current directory: "); if (chdir(auto_qmail) == -1) strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": "); r = control_readline(&me,"control/me"); if (r == -1) die_control(); if (!r) if (!stralloc_copys(&me,"me")) die_nomem(); r = control_readline(&defaultdomain,"control/defaultdomain"); if (r == -1) die_control(); if (!r) if (!stralloc_copy(&defaultdomain,&me)) die_nomem(); r = control_readline(&defaulthost,"control/defaulthost"); if (r == -1) die_control(); if (!r) if (!stralloc_copy(&defaulthost,&me)) die_nomem(); r = control_readline(&plusdomain,"control/plusdomain"); if (r == -1) die_control(); if (!r) if (!stralloc_copy(&plusdomain,&me)) die_nomem(); if (fchdir(fddir) == -1) strerr_die2sys(111,FATAL,"unable to set current directory: "); } stralloc cbuf = {0}; token822_alloc toks = {0}; token822_alloc tokaddr = {0}; stralloc address = {0}; void gotaddr() { int i; int j; int flaghasat; token822_reverse(&tokaddr); if (token822_unquote(&address,&tokaddr) != 1) die_nomem(); flaghasat = 0; for (i = 0;i < tokaddr.len;++i) if (tokaddr.t[i].type == TOKEN822_AT) flaghasat = 1; tokaddr.len = 0; if (!address.len) return; if (!flaghasat) if (address.len == userlen) if (!case_diffb(address.s,address.len,user)) { flagacted = 1; flagdirect = 1; return; } if (flaghasat) if (address.len == userlen + 1 + hostlen) if (!case_diffb(address.s,userlen,user)) if (address.s[userlen] == '@') if (!case_diffb(address.s + userlen + 1,hostlen,host)) { flagacted = 1; flagdirect = 1; return; } if (!flaghasat) if (address.s[0] == '/') { if (!stralloc_0(&address)) die_nomem(); strerr_die4x(111,FATAL,"file delivery ",address.s," not supported"); } if (!flaghasat) if (address.s[0] == '|') { if (!stralloc_0(&address)) die_nomem(); flagacted = 1; run(address.s + 1); return; } if (!flaghasat) { if (!stralloc_cats(&address,"@")) die_nomem(); if (!stralloc_cat(&address,&defaulthost)) die_nomem(); } if (address.s[address.len - 1] == '+') { address.s[address.len - 1] = '.'; if (!stralloc_cat(&address,&plusdomain)) die_nomem(); } j = 0; for (i = 0;i < address.len;++i) if (address.s[i] == '@') j = i; for (i = j;i < address.len;++i) if (address.s[i] == '.') break; if (i == address.len) { if (!stralloc_cats(&address,".")) die_nomem(); if (!stralloc_cat(&address,&defaultdomain)) die_nomem(); } if (!stralloc_0(&address)) die_nomem(); if (!stralloc_cats(&targets,"T")) die_nomem(); if (!stralloc_cats(&targets,address.s)) die_nomem(); if (!stralloc_0(&targets)) die_nomem(); if (!flagdoit) strerr_warn2("forward ",address.s,0); } void parseline() { int wordok; struct token822 *t; struct token822 *beginning; int r; r = token822_parse(&toks,&line,&cbuf); if (r == -1) die_nomem(); if (r == 0) die_parse(); beginning = toks.t; t = toks.t + toks.len; wordok = 1; if (!token822_readyplus(&tokaddr,1)) die_nomem(); tokaddr.len = 0; while (t > beginning) switch((--t)->type) { case TOKEN822_SEMI: break; /*XXX*/ case TOKEN822_COLON: break; /*XXX*/ case TOKEN822_RIGHT: if (tokaddr.len) gotaddr(); while ((t > beginning) && (t[-1].type != TOKEN822_LEFT)) if (!token822_append(&tokaddr,--t)) die_nomem(); gotaddr(); if (t <= beginning) die_parse(); --t; while ((t > beginning) && ((t[-1].type == TOKEN822_COMMENT) || (t[-1].type == TOKEN822_ATOM) || (t[-1].type == TOKEN822_QUOTE) || (t[-1].type == TOKEN822_AT) || (t[-1].type == TOKEN822_DOT))) --t; wordok = 0; continue; case TOKEN822_ATOM: case TOKEN822_QUOTE: case TOKEN822_LITERAL: if (!wordok) if (tokaddr.len) gotaddr(); wordok = 0; if (!token822_append(&tokaddr,t)) die_nomem(); continue; case TOKEN822_COMMENT: /* comment is lexically a space; shouldn't affect wordok */ break; case TOKEN822_COMMA: if (tokaddr.len) gotaddr(); wordok = 1; break; default: wordok = 1; if (!token822_append(&tokaddr,t)) die_nomem(); continue; } if (tokaddr.len) gotaddr(); } struct qmail qq; unsigned long qp; char *qqx; char strnum[FMT_ULONG]; int mywrite(fd,buf,len) int fd; char *buf; int len; { qmail_put(&qq,buf,len); return len; } char qqbuf[256]; substdio ssqq = SUBSTDIO_FDBUF(mywrite,-1,qqbuf,sizeof qqbuf); char inbuf[256]; void try(fn) char *fn; { int fd; int match; substdio ss; fd = open_read(fn); if (fd == -1) { if (errno == error_noent) return; strerr_die4sys(111,FATAL,"unable to open ",fn,": "); } if (!stralloc_copys(&targets,"")) die_nomem(); flagacted = 0; flagdirect = 0; substdio_fdbuf(&ss,read,fd,inbuf,sizeof inbuf); for (;;) { if (getln(&ss,&line,&match,'\n') == -1) strerr_die4sys(111,FATAL,"unable to read ",fn,": "); if (!line.len) break; if (line.s[0] != '#') parseline(); if (!match) break; } close(fd); if (targets.len) { flagacted = 1; if (flagdoit) { if (qmail_open(&qq) == -1) strerr_die2sys(111,FATAL,"unable to run qmail-queue: "); qp = qmail_qp(&qq); qmail_puts(&qq,dtline); substdio_fdbuf(&ssmess,read,0,messbuf,sizeof messbuf); if (substdio_copy(&ssqq,&ssmess) != 0) die_readmess(); substdio_flush(&ssqq); qmail_from(&qq,sender); qmail_put(&qq,targets.s,targets.len); qqx = qmail_close(&qq); if (*qqx == 'D') strerr_die3x(100,FATAL,"unable to forward message: ",qqx + 1); if (*qqx) strerr_die3x(111,FATAL,"unable to forward message: ",qqx + 1); strnum[fmt_ulong(strnum,qp)] = 0; strerr_warn3(INFO,"qp ",strnum,0); } } if (flagdirect) { if (!flagdoit) strerr_warn1("direct delivery",0); _exit(0); } if (!flagacted) { if (!flagdoit) strerr_warn2("skipping empty file ",fn,0); return; } _exit(99); } void main(argc,argv) int argc; char **argv; { int opt; int fddir; sig_pipeignore(); while ((opt = getopt(argc,argv,"nN")) != opteof) switch(opt) { case 'n': flagdoit = 0; break; case 'N': flagdoit = 1; break; default: strerr_die1x(100,"dot-forward: usage: dot-forward [ -nN ] file ..."); } argv += optind; ufline = env_get("UFLINE"); if (!ufline) ufline = ""; rpline = env_get("RPLINE"); if (!rpline) rpline = ""; dtline = env_get("DTLINE"); if (!dtline) dtline = ""; sender = env_get("NEWSENDER"); if (!sender) sender = ""; user = env_get("USER"); if (!user) user = ""; userlen = str_len(user); host = env_get("HOST"); if (!host) host = ""; hostlen = str_len(host); readcontrols(); while (*argv) try(*argv++); if (!flagdoit) strerr_warn1("direct delivery",0); _exit(0); } dot-forward-0.71/conf-cc010064400000000000001000000000570653025572600152760ustar00rootother00000000000000cc -O2 This will be used to compile .c files. dot-forward-0.71/conf-ld010064400000000000001000000000760653025572600153110ustar00rootother00000000000000cc -s This will be used to link .o files into an executable. dot-forward-0.71/find-systype.sh010064400000000000001000000065030653025572600170370ustar00rootother00000000000000# oper-:arch-:syst-:chip-:kern- # oper = operating system type; e.g., sunos-4.1.4 # arch = machine language; e.g., sparc # syst = which binaries can run; e.g., sun4 # chip = chip model; e.g., micro-2-80 # kern = kernel version; e.g., sun4m # dependence: arch --- chip # \ \ # oper --- syst --- kern # so, for example, syst is interpreted in light of oper, but chip is not. # anyway, no slashes, no extra colons, no uppercase letters. # the point of the extra -'s is to ease parsing: can add hierarchies later. # e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, # and i386-486 (486s do have more instructions, you know) as well as i386. # the idea here is to include ALL useful available information. exec 2>/dev/null sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" if [ x"$sys" != x ] then unamer="`uname -r | tr /: ..`" unamem="`uname -m | tr /: ..`" unamev="`uname -v | tr /: ..`" case "$sys" in bsd.os) # in bsd 4.4, uname -v does not have useful info. # in bsd 4.4, uname -m is arch, not chip. oper="$sys-$unamer" arch="$unamem" syst="" chip="`sysctl -n hw.model`" kern="" ;; freebsd) # see above about bsd 4.4 oper="$sys-$unamer" arch="$unamem" syst="" chip="`sysctl -n hw.model`" # hopefully kern="" ;; netbsd) # see above about bsd 4.4 oper="$sys-$unamer" arch="$unamem" syst="" chip="`sysctl -n hw.model`" # hopefully kern="" ;; linux) # as in bsd 4.4, uname -v does not have useful info. oper="$sys-$unamer" syst="" chip="$unamem" kern="" case "$chip" in i386|i486|i586|i686) arch="i386" ;; alpha) arch="alpha" ;; esac ;; aix) # naturally IBM has to get uname -r and uname -v backwards. dorks. oper="$sys-$unamev-$unamer" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; sunos) oper="$sys-$unamer-$unamev" arch="`(uname -p || mach) | tr /: ..`" syst="`arch | tr /: ..`" chip="$unamem" # this is wrong; is there any way to get the real info? kern="`arch -k | tr /: ..`" ;; unix_sv) oper="$sys-$unamer-$unamev" arch="`uname -m`" syst="" chip="$unamem" kern="" ;; *) oper="$sys-$unamer-$unamev" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; esac else $CC -c trycpp.c $LD -o trycpp trycpp.o case `./trycpp` in nextstep) oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" syst="" chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" kern="" ;; *) oper="unknown" arch="" syst="" chip="" kern="" ;; esac rm -f trycpp.o trycpp fi case "$chip" in 80486) # let's try to be consistent here. (BSD/OS) chip=i486 ;; i486DX) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx ;; i486.DX2) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx2 ;; Intel.586) # no, you nitwits, there is no such chip. (NeXTStep) chip=pentium ;; i586) # no, you nitwits, there is no such chip. (Linux) chip=pentium ;; i686) # STOP SAYING THAT! (Linux) chip=ppro esac echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' dot-forward-0.71/make-compile.sh010064400000000000001000000000370653025572600167400ustar00rootother00000000000000echo exec "$CC" -c '${1+"$@"}' dot-forward-0.71/make-load.sh010064400000000000001000000001110653025572600162200ustar00rootother00000000000000echo 'main="$1"; shift' echo exec "$LD" '-o "$main" "$main".o ${1+"$@"}' dot-forward-0.71/make-makelib.sh010064400000000000001000000003220653025572600167110ustar00rootother00000000000000echo 'main="$1"; shift' echo 'rm -f "$main"' echo 'ar cr "$main" ${1+"$@"}' case "$1" in sunos-5.*) ;; unix_sv*) ;; irix64-*) ;; irix-*) ;; dgux-*) ;; hp-ux-*) ;; sco*) ;; *) echo 'ranlib "$main"' ;; esac dot-forward-0.71/trycpp.c010064400000000000001000000001440653025572600155250ustar00rootother00000000000000void main() { #ifdef NeXT printf("nextstep\n"); exit(0); #endif printf("unknown\n"); exit(0); } dot-forward-0.71/warn-auto.sh010064400000000000001000000001000653025572600163010ustar00rootother00000000000000#!/bin/sh # WARNING: This file was auto-generated. Do not edit! dot-forward-0.71/conf-qmail010064400000000000001000000003370653025572600160150ustar00rootother00000000000000/var/qmail This is the qmail home directory. The dot-forward program will be installed in the bin subdirectory; it also needs to know where qmail is so that it can handle unqualified host names and forward mail properly. dot-forward-0.71/auto_qmail.h010064400000000000001000000001150653025572600163420ustar00rootother00000000000000#ifndef AUTO_QMAIL_H #define AUTO_QMAIL_H extern char auto_qmail[]; #endif dot-forward-0.71/qmail.h010064400000000000001000000006040653025572600153150ustar00rootother00000000000000#ifndef QMAIL_H #define QMAIL_H #include "substdio.h" struct qmail { int flagerr; unsigned long pid; int fdm; int fde; substdio ss; char buf[1024]; } ; extern int qmail_open(); extern void qmail_put(); extern void qmail_puts(); extern void qmail_from(); extern void qmail_to(); extern void qmail_fail(); extern char *qmail_close(); extern unsigned long qmail_qp(); #endif dot-forward-0.71/qmail.c010064400000000000001000000065430653025572600153200ustar00rootother00000000000000#include "substdio.h" #include "readwrite.h" #include "wait.h" #include "exit.h" #include "fork.h" #include "fd.h" #include "qmail.h" #include "auto_qmail.h" static char *binqqargs[2] = { "bin/qmail-queue", 0 } ; int qmail_open(qq) struct qmail *qq; { int pim[2]; int pie[2]; if (pipe(pim) == -1) return -1; if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; } switch(qq->pid = vfork()) { case -1: close(pim[0]); close(pim[1]); close(pie[0]); close(pie[1]); return -1; case 0: close(pim[1]); close(pie[1]); if (fd_move(0,pim[0]) == -1) _exit(120); if (fd_move(1,pie[0]) == -1) _exit(120); if (chdir(auto_qmail) == -1) _exit(61); execv(*binqqargs,binqqargs); _exit(120); } qq->fdm = pim[1]; close(pim[0]); qq->fde = pie[1]; close(pie[0]); substdio_fdbuf(&qq->ss,write,qq->fdm,qq->buf,sizeof(qq->buf)); qq->flagerr = 0; return 0; } unsigned long qmail_qp(qq) struct qmail *qq; { return qq->pid; } void qmail_fail(qq) struct qmail *qq; { qq->flagerr = 1; } void qmail_put(qq,s,len) struct qmail *qq; char *s; int len; { if (!qq->flagerr) if (substdio_put(&qq->ss,s,len) == -1) qq->flagerr = 1; } void qmail_puts(qq,s) struct qmail *qq; char *s; { if (!qq->flagerr) if (substdio_puts(&qq->ss,s) == -1) qq->flagerr = 1; } void qmail_from(qq,s) struct qmail *qq; char *s; { if (substdio_flush(&qq->ss) == -1) qq->flagerr = 1; close(qq->fdm); substdio_fdbuf(&qq->ss,write,qq->fde,qq->buf,sizeof(qq->buf)); qmail_put(qq,"F",1); qmail_puts(qq,s); qmail_put(qq,"",1); } void qmail_to(qq,s) struct qmail *qq; char *s; { qmail_put(qq,"T",1); qmail_puts(qq,s); qmail_put(qq,"",1); } char *qmail_close(qq) struct qmail *qq; { int wstat; int exitcode; qmail_put(qq,"",1); if (!qq->flagerr) if (substdio_flush(&qq->ss) == -1) qq->flagerr = 1; close(qq->fde); if (wait_pid(&wstat,qq->pid) != qq->pid) return "Zqq waitpid surprise (#4.3.0)"; if (wait_crashed(wstat)) return "Zqq crashed (#4.3.0)"; exitcode = wait_exitcode(wstat); switch(exitcode) { case 115: /* compatibility */ case 11: return "Denvelope address too long for qq (#5.1.3)"; case 31: return "Dmail server permanently rejected message (#5.3.0)"; case 51: return "Zqq out of memory (#4.3.0)"; case 52: return "Zqq timeout (#4.3.0)"; case 53: return "Zqq write error or disk full (#4.3.0)"; case 0: if (!qq->flagerr) return ""; /* fall through */ case 54: return "Zqq read error (#4.3.0)"; case 55: return "Zqq unable to read configuration (#4.3.0)"; case 56: return "Zqq trouble making network connection (#4.3.0)"; case 61: return "Zqq trouble in home directory (#4.3.0)"; case 63: case 64: case 65: case 66: case 62: return "Zqq trouble creating files in queue (#4.3.0)"; case 71: return "Zmail server temporarily rejected message (#4.3.0)"; case 72: return "Zconnection to mail server timed out (#4.4.1)"; case 73: return "Zconnection to mail server rejected (#4.4.1)"; case 74: return "Zcommunication with mail server failed (#4.4.2)"; case 91: /* fall through */ case 81: return "Zqq internal bug (#4.3.0)"; case 120: return "Zunable to exec qq (#4.3.0)"; default: if ((exitcode >= 11) && (exitcode <= 40)) return "Dqq permanent problem (#5.3.0)"; return "Zqq temporary problem (#4.3.0)"; } } dot-forward-0.71/INSTALL010064400000000000001000000012670653025572600151000ustar00rootother00000000000000Like any other piece of software (and information generally), dot-forward comes with NO WARRANTY. Things you have to decide before starting: * The location of the qmail home directory, normally /var/qmail. (To change this directory, edit conf-qmail now.) How to install: 1. Create and install the programs and man pages: # make setup check 2. With qmail 1.02 and above: To set up .forward handling for all users, install a /var/qmail/rc script that invokes dot-forward. Several scripts are supplied in /var/qmail/boot/*+df. That's it! To report success: % ( echo 'First M. Last'; cat `cat SYSDEPS` ) | mail djb-qst@cr.yp.to Replace First M. Last with your name. dot-forward-0.71/hier.c010064400000000000001000000005700653025572600151360ustar00rootother00000000000000#include "auto_qmail.h" void hier() { h(auto_qmail,-1,-1,0755); d(auto_qmail,"bin",-1,-1,0755); d(auto_qmail,"man",-1,-1,0755); d(auto_qmail,"man/man1",-1,-1,0755); d(auto_qmail,"man/cat1",-1,-1,0755); c(auto_qmail,"bin","dot-forward",-1,-1,0755); c(auto_qmail,"man/man1","dot-forward.1",-1,-1,0644); c(auto_qmail,"man/cat1","dot-forward.0",-1,-1,0644); } dot-forward-0.71/auto-str.c010064400000000000001000000013520653025572600157640ustar00rootother00000000000000#include "substdio.h" #include "readwrite.h" #include "exit.h" char buf1[256]; substdio ss1 = SUBSTDIO_FDBUF(write,1,buf1,sizeof(buf1)); void puts(s) char *s; { if (substdio_puts(&ss1,s) == -1) _exit(111); } void main(argc,argv) int argc; char **argv; { char *name; char *value; unsigned char ch; char octal[4]; name = argv[1]; if (!name) _exit(100); value = argv[2]; if (!value) _exit(100); puts("char "); puts(name); puts("[] = \"\\\n"); while (ch = *value++) { puts("\\"); octal[3] = 0; octal[2] = '0' + (ch & 7); ch >>= 3; octal[1] = '0' + (ch & 7); ch >>= 3; octal[0] = '0' + (ch & 7); puts(octal); } puts("\\\n\";\n"); if (substdio_flush(&ss1) == -1) _exit(111); _exit(0); } dot-forward-0.71/install.c010064400000000000001000000055470653025572600156660ustar00rootother00000000000000#include "substdio.h" #include "strerr.h" #include "error.h" #include "open.h" #include "readwrite.h" #include "exit.h" extern void hier(); #define FATAL "install: fatal: " int fdsourcedir = -1; void h(home,uid,gid,mode) char *home; int uid; int gid; int mode; { if (mkdir(home,0700) == -1) if (errno != error_exist) strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); if (chown(home,uid,gid) == -1) strerr_die4sys(111,FATAL,"unable to chown ",home,": "); if (chmod(home,mode) == -1) strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); } void d(home,subdir,uid,gid,mode) char *home; char *subdir; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (mkdir(subdir,0700) == -1) if (errno != error_exist) strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); if (chown(subdir,uid,gid) == -1) strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); if (chmod(subdir,mode) == -1) strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); } char inbuf[SUBSTDIO_INSIZE]; char outbuf[SUBSTDIO_OUTSIZE]; substdio ssin; substdio ssout; void c(home,subdir,file,uid,gid,mode) char *home; char *subdir; char *file; int uid; int gid; int mode; { int fdin; int fdout; if (fchdir(fdsourcedir) == -1) strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); fdin = open_read(file); if (fdin == -1) strerr_die4sys(111,FATAL,"unable to read ",file,": "); substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof inbuf); if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (chdir(subdir) == -1) strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); fdout = open_trunc(file); if (fdout == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); switch(substdio_copy(&ssout,&ssin)) { case -2: strerr_die4sys(111,FATAL,"unable to read ",file,": "); case -3: strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); } close(fdin); if (substdio_flush(&ssout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (fsync(fdout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (close(fdout) == -1) /* NFS silliness */ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (chown(file,uid,gid) == -1) strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); if (chmod(file,mode) == -1) strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); } void main() { fdsourcedir = open_read("."); if (fdsourcedir == -1) strerr_die2sys(111,FATAL,"unable to open current directory: "); umask(077); hier(); _exit(0); } dot-forward-0.71/instcheck.c010064400000000000001000000034600653025572600161630ustar00rootother00000000000000#include #include #include "strerr.h" #include "error.h" #include "readwrite.h" #include "exit.h" extern void hier(); #define FATAL "instcheck: fatal: " #define WARNING "instcheck: warning: " void perm(prefix1,prefix2,prefix3,file,type,uid,gid,mode) char *prefix1; char *prefix2; char *prefix3; char *file; int type; int uid; int gid; int mode; { struct stat st; if (stat(file,&st) == -1) { if (errno == error_noent) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," does not exist",0); else strerr_warn4(WARNING,"unable to stat .../",file,": ",&strerr_sys); return; } if ((uid != -1) && (st.st_uid != uid)) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong owner",0); if ((gid != -1) && (st.st_gid != gid)) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong group",0); if ((st.st_mode & 07777) != mode) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong permissions",0); if ((st.st_mode & S_IFMT) != type) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong type",0); } void h(home,uid,gid,mode) char *home; int uid; int gid; int mode; { perm("","","",home,S_IFDIR,uid,gid,mode); } void d(home,subdir,uid,gid,mode) char *home; char *subdir; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); perm("",home,"/",subdir,S_IFDIR,uid,gid,mode); } void c(home,subdir,file,uid,gid,mode) char *home; char *subdir; char *file; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (chdir(subdir) == -1) strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); perm(".../",subdir,"/",file,S_IFREG,uid,gid,mode); } void main() { hier(); _exit(0); } dot-forward-0.71/sgetopt.h010064400000000000001000000006410653025572600157000ustar00rootother00000000000000#ifndef SGETOPT_H #define SGETOPT_H #ifndef SGETOPTNOSHORT #define getopt sgetoptmine #define optarg subgetoptarg #define optind subgetoptind #define optpos subgetoptpos #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname #define opteof subgetoptdone #endif #include "subgetopt.h" extern int sgetoptmine(); extern int sgetopterr; extern char *sgetoptprogname; #endif dot-forward-0.71/sgetopt.c010064400000000000001000000023750653025572600157010ustar00rootother00000000000000/* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer D. J. Bernstein, djb@pobox.com. Depends on subgetopt.h, substdio.h, subfd.h. No system requirements. 19970208: Cleanups. 931201: Baseline. No known patent problems. Documentation in sgetopt.3. */ #include "substdio.h" #include "subfd.h" #define SGETOPTNOSHORT #include "sgetopt.h" #define SUBGETOPTNOSHORT #include "subgetopt.h" #define getopt sgetoptmine #define optind subgetoptind #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname int opterr = 1; char *optprogname = 0; int getopt(argc,argv,opts) int argc; char **argv; char *opts; { int c; char *s; if (!optprogname) { optprogname = *argv; if (!optprogname) optprogname = ""; for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1; } c = subgetopt(argc,argv,opts); if (opterr) if (c == '?') { char chp[2]; chp[0] = optproblem; chp[1] = '\n'; substdio_puts(subfderr,optprogname); if (argv[optind] && (optind < argc)) substdio_puts(subfderr,": illegal option -- "); else substdio_puts(subfderr,": option requires an argument -- "); substdio_put(subfderr,chp,2); substdio_flush(subfderr); } return c; } dot-forward-0.71/subgetopt.h010064400000000000001000000010100653025572600162160ustar00rootother00000000000000#ifndef SUBGETOPT_H #define SUBGETOPT_H #ifndef SUBGETOPTNOSHORT #define sgopt subgetopt #define sgoptarg subgetoptarg #define sgoptind subgetoptind #define sgoptpos subgetoptpos #define sgoptproblem subgetoptproblem #define sgoptprogname subgetoptprogname #define sgoptdone subgetoptdone #endif #define SUBGETOPTDONE -1 extern int subgetopt(); extern char *subgetoptarg; extern int subgetoptind; extern int subgetoptpos; extern int subgetoptproblem; extern char *subgetoptprogname; extern int subgetoptdone; #endif dot-forward-0.71/subgetopt.c010064400000000000001000000031510653025572600162210ustar00rootother00000000000000/* subgetopt.c, subgetopt.h: (yet another) improved getopt clone, inner layer D. J. Bernstein, djb@pobox.com. No dependencies. No system requirements. 19970228: Cleanups. 931129: Adapted from getopt.c. No known patent problems. Documentation in subgetopt.3. */ #define SUBGETOPTNOSHORT #include "subgetopt.h" #define sgopt subgetopt #define optind subgetoptind #define optpos subgetoptpos #define optarg subgetoptarg #define optproblem subgetoptproblem #define optdone subgetoptdone int optind = 1; int optpos = 0; char *optarg = 0; int optproblem = 0; int optdone = SUBGETOPTDONE; int sgopt(argc,argv,opts) int argc; char **argv; char *opts; { int c; char *s; optarg = 0; if (!argv || (optind >= argc) || !argv[optind]) return optdone; if (optpos && !argv[optind][optpos]) { ++optind; optpos = 0; if ((optind >= argc) || !argv[optind]) return optdone; } if (!optpos) { if (argv[optind][0] != '-') return optdone; ++optpos; c = argv[optind][1]; if ((c == '-') || (c == 0)) { if (c) ++optind; optpos = 0; return optdone; } /* otherwise c is reassigned below */ } c = argv[optind][optpos]; ++optpos; s = opts; while (*s) { if (c == *s) { if (s[1] == ':') { optarg = argv[optind] + optpos; ++optind; optpos = 0; if (!*optarg) { optarg = argv[optind]; if ((optind >= argc) || !optarg) { /* argument past end */ optproblem = c; return '?'; } ++optind; } } return c; } ++s; if (*s == ':') ++s; } optproblem = c; return '?'; } dot-forward-0.71/substdio.h010064400000000000001000000017140653025572600160510ustar00rootother00000000000000#ifndef SUBSTDIO_H #define SUBSTDIO_H typedef struct substdio { char *x; int p; int n; int fd; int (*op)(); } substdio; #define SUBSTDIO_FDBUF(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } extern void substdio_fdbuf(); extern int substdio_flush(); extern int substdio_put(); extern int substdio_bput(); extern int substdio_putflush(); extern int substdio_puts(); extern int substdio_bputs(); extern int substdio_putsflush(); extern int substdio_get(); extern int substdio_bget(); extern int substdio_feed(); extern char *substdio_peek(); extern void substdio_seek(); #define substdio_fileno(s) ((s)->fd) #define SUBSTDIO_INSIZE 8192 #define SUBSTDIO_OUTSIZE 8192 #define substdio_PEEK(s) ( (s)->x + (s)->n ) #define substdio_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) #define substdio_BPUTC(s,c) \ ( ((s)->n != (s)->p) \ ? ( (s)->x[(s)->p++] = (c), 0 ) \ : substdio_bput((s),&(c),1) \ ) extern int substdio_copy(); #endif dot-forward-0.71/substdio.c010064400000000000001000000003470653025572600160450ustar00rootother00000000000000#include "substdio.h" void substdio_fdbuf(s,op,fd,buf,len) register substdio *s; register int (*op)(); register int fd; register char *buf; register int len; { s->x = buf; s->fd = fd; s->op = op; s->p = 0; s->n = len; } dot-forward-0.71/substdi.c010064400000000000001000000031170653025572600156640ustar00rootother00000000000000#include "substdio.h" #include "byte.h" #include "error.h" static int oneread(op,fd,buf,len) register int (*op)(); register int fd; register char *buf; register int len; { register int r; for (;;) { r = op(fd,buf,len); if (r == -1) if (errno == error_intr) continue; return r; } } static int getthis(s,buf,len) register substdio *s; register char *buf; register int len; { register int r; register int q; r = s->p; q = r - len; if (q > 0) { r = len; s->p = q; } else s->p = 0; byte_copy(buf,r,s->x + s->n); s->n += r; return r; } int substdio_feed(s) register substdio *s; { register int r; register int q; if (s->p) return s->p; q = s->n; r = oneread(s->op,s->fd,s->x,q); if (r <= 0) return r; s->p = r; q -= r; s->n = q; if (q > 0) /* damn, gotta shift */ byte_copyr(s->x + q,r,s->x); return r; } int substdio_bget(s,buf,len) register substdio *s; register char *buf; register int len; { register int r; if (s->p > 0) return getthis(s,buf,len); r = s->n; if (r <= len) return oneread(s->op,s->fd,buf,r); r = substdio_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } int substdio_get(s,buf,len) register substdio *s; register char *buf; register int len; { register int r; if (s->p > 0) return getthis(s,buf,len); if (s->n <= len) return oneread(s->op,s->fd,buf,len); r = substdio_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } char *substdio_peek(s) register substdio *s; { return s->x + s->n; } void substdio_seek(s,len) register substdio *s; register int len; { s->n += len; s->p -= len; } dot-forward-0.71/substdo.c010064400000000000001000000037450653025572600157010ustar00rootother00000000000000#include "substdio.h" #include "str.h" #include "byte.h" #include "error.h" static int allwrite(op,fd,buf,len) register int (*op)(); register int fd; register char *buf; register int len; { register int w; while (len) { w = op(fd,buf,len); if (w == -1) { if (errno == error_intr) continue; return -1; /* note that some data may have been written */ } if (w == 0) ; /* luser's fault */ buf += w; len -= w; } return 0; } int substdio_flush(s) register substdio *s; { register int p; p = s->p; if (!p) return 0; s->p = 0; return allwrite(s->op,s->fd,s->x,p); } int substdio_bput(s,buf,len) register substdio *s; register char *buf; register int len; { register int n; while (len > (n = s->n - s->p)) { byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; if (substdio_flush(s) == -1) return -1; } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int substdio_put(s,buf,len) register substdio *s; register char *buf; register int len; { register int n; n = s->n; if (len > n - s->p) { if (substdio_flush(s) == -1) return -1; /* now s->p == 0 */ if (n < SUBSTDIO_OUTSIZE) n = SUBSTDIO_OUTSIZE; while (len > s->n) { if (n > len) n = len; if (allwrite(s->op,s->fd,buf,n) == -1) return -1; buf += n; len -= n; } } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int substdio_putflush(s,buf,len) register substdio *s; register char *buf; register int len; { if (substdio_flush(s) == -1) return -1; return allwrite(s->op,s->fd,buf,len); } int substdio_bputs(s,buf) register substdio *s; register char *buf; { return substdio_bput(s,buf,str_len(buf)); } int substdio_puts(s,buf) register substdio *s; register char *buf; { return substdio_put(s,buf,str_len(buf)); } int substdio_putsflush(s,buf) register substdio *s; register char *buf; { return substdio_putflush(s,buf,str_len(buf)); } dot-forward-0.71/substdio_copy.c010064400000000000001000000005330653025572600170740ustar00rootother00000000000000#include "substdio.h" int substdio_copy(ssout,ssin) register substdio *ssout; register substdio *ssin; { register int n; register char *x; for (;;) { n = substdio_feed(ssin); if (n < 0) return -2; if (!n) return 0; x = substdio_PEEK(ssin); if (substdio_put(ssout,x,n) == -1) return -3; substdio_SEEK(ssin,n); } } dot-forward-0.71/subfd.h010064400000000000001000000004070653025572600153160ustar00rootother00000000000000#ifndef SUBFD_H #define SUBFD_H #include "substdio.h" extern substdio *subfdin; extern substdio *subfdinsmall; extern substdio *subfdout; extern substdio *subfdoutsmall; extern substdio *subfderr; extern int subfd_read(); extern int subfd_readsmall(); #endif dot-forward-0.71/subfderr.c010064400000000000001000000002620653025572600160210ustar00rootother00000000000000#include "readwrite.h" #include "substdio.h" #include "subfd.h" char subfd_errbuf[256]; static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256); substdio *subfderr = ⁢ dot-forward-0.71/readwrite.h010064400000000000001000000001300653025572600161720ustar00rootother00000000000000#ifndef READWRITE_H #define READWRITE_H extern int read(); extern int write(); #endif dot-forward-0.71/exit.h010064400000000000001000000000740653025572600151640ustar00rootother00000000000000#ifndef EXIT_H #define EXIT_H extern void _exit(); #endif dot-forward-0.71/strerr.h010064400000000000001000000064430653025572600155420ustar00rootother00000000000000#ifndef STRERR_H #define STRERR_H struct strerr { struct strerr *who; char *x; char *y; char *z; } ; extern struct strerr strerr_sys; extern void strerr_sysinit(); extern char *strerr(); extern void strerr_warn(); extern void strerr_die(); #define STRERR(r,se,a) \ { se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS(r,se,a) \ { se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS3(r,se,a,b,c) \ { se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; } #define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se)) #define strerr_warn5(x1,x2,x3,x4,x5,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se)) #define strerr_warn4(x1,x2,x3,x4,se) \ strerr_warn((x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_warn3(x1,x2,x3,se) \ strerr_warn((x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_warn2(x1,x2,se) \ strerr_warn((x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_warn1(x1,se) \ strerr_warn((x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se)) #define strerr_die5(e,x1,x2,x3,x4,x5,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se)) #define strerr_die4(e,x1,x2,x3,x4,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_die3(e,x1,x2,x3,se) \ strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_die2(e,x1,x2,se) \ strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_die1(e,x1,se) \ strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) #define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys) #define strerr_die5sys(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,&strerr_sys) #define strerr_die4sys(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,&strerr_sys) #define strerr_die3sys(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,&strerr_sys) #define strerr_die2sys(e,x1,x2) \ strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys) #define strerr_die1sys(e,x1) \ strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys) #define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) 0) #define strerr_die5x(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) 0) #define strerr_die4x(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) 0) #define strerr_die3x(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) #define strerr_die2x(e,x1,x2) \ strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) #define strerr_die1x(e,x1) \ strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) #endif dot-forward-0.71/strerr_sys.c010064400000000000001000000003000653025572600164150ustar00rootother00000000000000#include "error.h" #include "strerr.h" struct strerr strerr_sys; void strerr_sysinit() { strerr_sys.who = 0; strerr_sys.x = error_str(errno); strerr_sys.y = ""; strerr_sys.z = ""; } dot-forward-0.71/strerr_die.c010064400000000000001000000015460653025572600163550ustar00rootother00000000000000#include "substdio.h" #include "subfd.h" #include "exit.h" #include "strerr.h" void strerr_warn(x1,x2,x3,x4,x5,x6,se) char *x1; char *x2; char *x3; char *x4; char *x5; char *x6; struct strerr *se; { strerr_sysinit(); if (x1) substdio_puts(subfderr,x1); if (x2) substdio_puts(subfderr,x2); if (x3) substdio_puts(subfderr,x3); if (x4) substdio_puts(subfderr,x4); if (x5) substdio_puts(subfderr,x5); if (x6) substdio_puts(subfderr,x6); while(se) { if (se->x) substdio_puts(subfderr,se->x); if (se->y) substdio_puts(subfderr,se->y); if (se->z) substdio_puts(subfderr,se->z); se = se->who; } substdio_puts(subfderr,"\n"); substdio_flush(subfderr); } void strerr_die(e,x1,x2,x3,x4,x5,x6,se) int e; char *x1; char *x2; char *x3; char *x4; char *x5; char *x6; struct strerr *se; { strerr_warn(x1,x2,x3,x4,x5,x6,se); _exit(e); } dot-forward-0.71/byte.h010064400000000000001000000004010653025572600151500ustar00rootother00000000000000#ifndef BYTE_H #define BYTE_H extern unsigned int byte_chr(); extern unsigned int byte_rchr(); extern void byte_copy(); extern void byte_copyr(); extern int byte_diff(); extern void byte_zero(); #define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) #endif dot-forward-0.71/byte_chr.c010064400000000000001000000006020653025572600160020ustar00rootother00000000000000#include "byte.h" unsigned int byte_chr(s,n,c) char *s; register unsigned int n; int c; { register char ch; register char *t; ch = c; t = s; for (;;) { if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; } return t - s; } dot-forward-0.71/byte_copy.c010064400000000000001000000004530653025572600162040ustar00rootother00000000000000#include "byte.h" void byte_copy(to,n,from) register char *to; register unsigned int n; register char *from; { for (;;) { if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; } } dot-forward-0.71/byte_cr.c010064400000000000001000000005040653025572600156330ustar00rootother00000000000000#include "byte.h" void byte_copyr(to,n,from) register char *to; register unsigned int n; register char *from; { to += n; from += n; for (;;) { if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; } } dot-forward-0.71/str.h010064400000000000001000000004270653025572600150250ustar00rootother00000000000000#ifndef STR_H #define STR_H extern unsigned int str_copy(); extern int str_diff(); extern int str_diffn(); extern unsigned int str_len(); extern unsigned int str_chr(); extern unsigned int str_rchr(); extern int str_start(); #define str_equal(s,t) (!str_diff((s),(t))) #endif dot-forward-0.71/str_diffn.c010064400000000000001000000010460653025572600161640ustar00rootother00000000000000#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); } dot-forward-0.71/str_len.c010064400000000000001000000003570653025572600156600ustar00rootother00000000000000#include "str.h" unsigned int str_len(s) register char *s; { register char *t; t = s; for (;;) { if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; } } dot-forward-0.71/error.h010064400000000000001000000006570653025572600153530ustar00rootother00000000000000#ifndef ERROR_H #define ERROR_H extern int errno; extern int error_intr; extern int error_nomem; extern int error_noent; extern int error_txtbsy; extern int error_io; extern int error_exist; extern int error_timeout; extern int error_inprogress; extern int error_wouldblock; extern int error_again; extern int error_pipe; extern int error_perm; extern int error_acces; extern char *error_str(); extern int error_temp(); #endif dot-forward-0.71/error.c010064400000000000001000000015760653025572600153470ustar00rootother00000000000000#include #include "error.h" /* warning: as coverage improves here, should update error_{str,temp} */ int error_intr = #ifdef EINTR EINTR; #else -1; #endif int error_nomem = #ifdef ENOMEM ENOMEM; #else -2; #endif int error_noent = #ifdef ENOENT ENOENT; #else -3; #endif int error_txtbsy = #ifdef ETXTBSY ETXTBSY; #else -4; #endif int error_io = #ifdef EIO EIO; #else -5; #endif int error_exist = #ifdef EEXIST EEXIST; #else -6; #endif int error_timeout = #ifdef ETIMEDOUT ETIMEDOUT; #else -7; #endif int error_inprogress = #ifdef EINPROGRESS EINPROGRESS; #else -8; #endif int error_wouldblock = #ifdef EWOULDBLOCK EWOULDBLOCK; #else -9; #endif int error_again = #ifdef EAGAIN EAGAIN; #else -10; #endif int error_pipe = #ifdef EPIPE EPIPE; #else -11; #endif int error_perm = #ifdef EPERM EPERM; #else -12; #endif int error_acces = #ifdef EACCES EACCES; #else -13; #endif dot-forward-0.71/error_str.c010064400000000000001000000126670653025572600162420ustar00rootother00000000000000#include #include "error.h" #define X(e,s) if (i == e) return s; char *error_str(i) int i; { X(0,"no error") X(error_intr,"interrupted system call") X(error_nomem,"out of memory") X(error_noent,"file does not exist") X(error_txtbsy,"text busy") X(error_io,"input/output error") X(error_exist,"file already exists") X(error_timeout,"timed out") X(error_inprogress,"operation in progress") X(error_again,"temporary failure") X(error_wouldblock,"input/output would block") X(error_pipe,"broken pipe") X(error_perm,"permission denied") X(error_acces,"access denied") #ifdef ESRCH X(ESRCH,"no such process") #endif #ifdef ENXIO X(ENXIO,"device not configured") #endif #ifdef E2BIG X(E2BIG,"argument list too long") #endif #ifdef ENOEXEC X(ENOEXEC,"exec format error") #endif #ifdef EBADF X(EBADF,"file descriptor not open") #endif #ifdef ECHILD X(ECHILD,"no child processes") #endif #ifdef EDEADLK X(EDEADLK,"operation would cause deadlock") #endif #ifdef EFAULT X(EFAULT,"bad address") #endif #ifdef ENOTBLK X(ENOTBLK,"not a block device") #endif #ifdef EBUSY X(EBUSY,"device busy") #endif #ifdef EXDEV X(EXDEV,"cross-device link") #endif #ifdef ENODEV X(ENODEV,"device does not support operation") #endif #ifdef ENOTDIR X(ENOTDIR,"not a directory") #endif #ifdef EISDIR X(EISDIR,"is a directory") #endif #ifdef EINVAL X(EINVAL,"invalid argument") #endif #ifdef ENFILE X(ENFILE,"system cannot open more files") #endif #ifdef EMFILE X(EMFILE,"process cannot open more files") #endif #ifdef ENOTTY X(ENOTTY,"not a tty") #endif #ifdef EFBIG X(EFBIG,"file too big") #endif #ifdef ENOSPC X(ENOSPC,"out of disk space") #endif #ifdef ESPIPE X(ESPIPE,"unseekable descriptor") #endif #ifdef EROFS X(EROFS,"read-only file system") #endif #ifdef EMLINK X(EMLINK,"too many links") #endif #ifdef EDOM X(EDOM,"input out of range") #endif #ifdef ERANGE X(ERANGE,"output out of range") #endif #ifdef EALREADY X(EALREADY,"operation already in progress") #endif #ifdef ENOTSOCK X(ENOTSOCK,"not a socket") #endif #ifdef EDESTADDRREQ X(EDESTADDRREQ,"destination address required") #endif #ifdef EMSGSIZE X(EMSGSIZE,"message too long") #endif #ifdef EPROTOTYPE X(EPROTOTYPE,"incorrect protocol type") #endif #ifdef ENOPROTOOPT X(ENOPROTOOPT,"protocol not available") #endif #ifdef EPROTONOSUPPORT X(EPROTONOSUPPORT,"protocol not supported") #endif #ifdef ESOCKTNOSUPPORT X(ESOCKTNOSUPPORT,"socket type not supported") #endif #ifdef EOPNOTSUPP X(EOPNOTSUPP,"operation not supported") #endif #ifdef EPFNOSUPPORT X(EPFNOSUPPORT,"protocol family not supported") #endif #ifdef EAFNOSUPPORT X(EAFNOSUPPORT,"address family not supported") #endif #ifdef EADDRINUSE X(EADDRINUSE,"address already used") #endif #ifdef EADDRNOTAVAIL X(EADDRNOTAVAIL,"address not available") #endif #ifdef ENETDOWN X(ENETDOWN,"network down") #endif #ifdef ENETUNREACH X(ENETUNREACH,"network unreachable") #endif #ifdef ENETRESET X(ENETRESET,"network reset") #endif #ifdef ECONNABORTED X(ECONNABORTED,"connection aborted") #endif #ifdef ECONNRESET X(ECONNRESET,"connection reset") #endif #ifdef ENOBUFS X(ENOBUFS,"out of buffer space") #endif #ifdef EISCONN X(EISCONN,"already connected") #endif #ifdef ENOTCONN X(ENOTCONN,"not connected") #endif #ifdef ESHUTDOWN X(ESHUTDOWN,"socket shut down") #endif #ifdef ETOOMANYREFS X(ETOOMANYREFS,"too many references") #endif #ifdef ECONNREFUSED X(ECONNREFUSED,"connection refused") #endif #ifdef ELOOP X(ELOOP,"symbolic link loop") #endif #ifdef ENAMETOOLONG X(ENAMETOOLONG,"file name too long") #endif #ifdef EHOSTDOWN X(EHOSTDOWN,"host down") #endif #ifdef EHOSTUNREACH X(EHOSTUNREACH,"host unreachable") #endif #ifdef ENOTEMPTY X(ENOTEMPTY,"directory not empty") #endif #ifdef EPROCLIM X(EPROCLIM,"too many processes") #endif #ifdef EUSERS X(EUSERS,"too many users") #endif #ifdef EDQUOT X(EDQUOT,"disk quota exceeded") #endif #ifdef ESTALE X(ESTALE,"stale NFS file handle") #endif #ifdef EREMOTE X(EREMOTE,"too many levels of remote in path") #endif #ifdef EBADRPC X(EBADRPC,"RPC structure is bad") #endif #ifdef ERPCMISMATCH X(ERPCMISMATCH,"RPC version mismatch") #endif #ifdef EPROGUNAVAIL X(EPROGUNAVAIL,"RPC program unavailable") #endif #ifdef EPROGMISMATCH X(EPROGMISMATCH,"program version mismatch") #endif #ifdef EPROCUNAVAIL X(EPROCUNAVAIL,"bad procedure for program") #endif #ifdef ENOLCK X(ENOLCK,"no locks available") #endif #ifdef ENOSYS X(ENOSYS,"system call not available") #endif #ifdef EFTYPE X(EFTYPE,"bad file type") #endif #ifdef EAUTH X(EAUTH,"authentication error") #endif #ifdef ENEEDAUTH X(ENEEDAUTH,"not authenticated") #endif #ifdef ENOSTR X(ENOSTR,"not a stream device") #endif #ifdef ETIME X(ETIME,"timer expired") #endif #ifdef ENOSR X(ENOSR,"out of stream resources") #endif #ifdef ENOMSG X(ENOMSG,"no message of desired type") #endif #ifdef EBADMSG X(EBADMSG,"bad message type") #endif #ifdef EIDRM X(EIDRM,"identifier removed") #endif #ifdef ENONET X(ENONET,"machine not on network") #endif #ifdef ERREMOTE X(ERREMOTE,"object not local") #endif #ifdef ENOLINK X(ENOLINK,"link severed") #endif #ifdef EADV X(EADV,"advertise error") #endif #ifdef ESRMNT X(ESRMNT,"srmount error") #endif #ifdef ECOMM X(ECOMM,"communication error") #endif #ifdef EPROTO X(EPROTO,"protocol error") #endif #ifdef EMULTIHOP X(EMULTIHOP,"multihop attempted") #endif #ifdef EREMCHG X(EREMCHG,"remote address changed") #endif return "unknown error"; } dot-forward-0.71/wait.h010064400000000000001000000004470653025572600151630ustar00rootother00000000000000#ifndef WAIT_H #define WAIT_H extern int wait_pid(); extern int wait_nohang(); extern int wait_stop(); extern int wait_stopnohang(); #define wait_crashed(w) ((w) & 127) #define wait_exitcode(w) ((w) >> 8) #define wait_stopsig(w) ((w) >> 8) #define wait_stopped(w) (((w) & 127) == 127) #endif dot-forward-0.71/wait_pid.c010064400000000000001000000013050653025572600160040ustar00rootother00000000000000#include #include #include "error.h" #include "haswaitp.h" #ifdef HASWAITPID int wait_pid(wstat,pid) int *wstat; int pid; { int r; do r = waitpid(pid,wstat,0); while ((r == -1) && (errno == error_intr)); return r; } #else /* XXX untested */ /* XXX breaks down with more than two children */ static int oldpid = 0; static int oldwstat; /* defined if(oldpid) */ int wait_pid(wstat,pid) int *wstat; int pid; { int r; if (pid == oldpid) { *wstat = oldwstat; oldpid = 0; return pid; } do { r = wait(wstat); if ((r != pid) && (r != -1)) { oldwstat = *wstat; oldpid = r; continue; } } while ((r == -1) && (errno == error_intr)); return r; } #endif dot-forward-0.71/trywaitp.c010064400000000000001000000001200653025572600160610ustar00rootother00000000000000#include #include void main() { waitpid(0,0,0); } dot-forward-0.71/fork.h1010064400000000000001000000001150653025572600152310ustar00rootother00000000000000#ifndef FORK_H #define FORK_H extern int fork(); #define vfork fork #endif dot-forward-0.71/fork.h2010064400000000000001000000001160653025572600152330ustar00rootother00000000000000#ifndef FORK_H #define FORK_H extern int fork(); extern int vfork(); #endif dot-forward-0.71/tryvfork.c010064400000000000001000000000330653025572600160670ustar00rootother00000000000000void main() { vfork(); } dot-forward-0.71/fd.h010064400000000000001000000001170653025572600146020ustar00rootother00000000000000#ifndef FD_H #define FD_H extern int fd_copy(); extern int fd_move(); #endif dot-forward-0.71/fd_copy.c010064400000000000001000000003410653025572600156260ustar00rootother00000000000000#include #include "fd.h" int fd_copy(to,from) int to; int from; { if (to == from) return 0; if (fcntl(from,F_GETFL,0) == -1) return -1; close(to); if (fcntl(from,F_DUPFD,to) == -1) return -1; return 0; } dot-forward-0.71/fd_move.c010064400000000000001000000002340653025572600156230ustar00rootother00000000000000#include "fd.h" int fd_move(to,from) int to; int from; { if (to == from) return 0; if (fd_copy(to,from) == -1) return -1; close(from); return 0; } dot-forward-0.71/getln.h010064400000000000001000000001220653025572600153160ustar00rootother00000000000000#ifndef GETLN_H #define GETLN_H extern int getln(); extern int getln2(); #endif dot-forward-0.71/getln.c010064400000000000001000000005760653025572600153260ustar00rootother00000000000000#include "substdio.h" #include "byte.h" #include "stralloc.h" #include "getln.h" int getln(ss,sa,match,sep) register substdio *ss; register stralloc *sa; int *match; int sep; { char *cont; unsigned int clen; if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1; if (!clen) { *match = 0; return 0; } if (!stralloc_catb(sa,cont,clen)) return -1; *match = 1; return 0; } dot-forward-0.71/getln2.c010064400000000000001000000012600653025572600153770ustar00rootother00000000000000#include "substdio.h" #include "stralloc.h" #include "byte.h" #include "getln.h" int getln2(ss,sa,cont,clen,sep) register substdio *ss; register stralloc *sa; /*@out@*/char **cont; /*@out@*/unsigned int *clen; int sep; { register char *x; register unsigned int i; int n; if (!stralloc_ready(sa,0)) return -1; sa->len = 0; for (;;) { n = substdio_feed(ss); if (n < 0) return -1; if (n == 0) { *clen = 0; return 0; } x = substdio_PEEK(ss); i = byte_chr(x,n,sep); if (i < n) { substdio_SEEK(ss,*clen = i + 1); *cont = x; return 0; } if (!stralloc_readyplus(sa,n)) return -1; i = sa->len; sa->len = i + substdio_get(ss,sa->s + i,n); } } dot-forward-0.71/gen_alloc.h010064400000000000001000000002550653025572600161370ustar00rootother00000000000000#ifndef GEN_ALLOC_H #define GEN_ALLOC_H #define GEN_ALLOC_typedef(ta,type,field,len,a) \ typedef struct ta { type *field; unsigned int len; unsigned int a; } ta; #endif dot-forward-0.71/gen_allocdefs.h010064400000000000001000000022620653025572600170010ustar00rootother00000000000000#ifndef GEN_ALLOC_DEFS_H #define GEN_ALLOC_DEFS_H #define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ int ta_ready(x,n) register ta *x; register unsigned int n; \ { register unsigned int i; \ if (x->field) { \ i = x->a; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \ int ta_rplus(x,n) register ta *x; register unsigned int n; \ { register unsigned int i; \ if (x->field) { \ i = x->a; n += x->len; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \ int ta_append(x,i) register ta *x; register type *i; \ { if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } #endif dot-forward-0.71/stralloc.h010064400000000000001000000007600653025572600160400ustar00rootother00000000000000#ifndef STRALLOC_H #define STRALLOC_H #include "gen_alloc.h" GEN_ALLOC_typedef(stralloc,char,s,len,a) extern int stralloc_ready(); extern int stralloc_readyplus(); extern int stralloc_copy(); extern int stralloc_cat(); extern int stralloc_copys(); extern int stralloc_cats(); extern int stralloc_copyb(); extern int stralloc_catb(); extern int stralloc_append(); /* beware: this takes a pointer to 1 char */ extern int stralloc_starts(); #define stralloc_0(sa) stralloc_append(sa,"") #endif dot-forward-0.71/stralloc_eady.c010064400000000000001000000003130653025572600170270ustar00rootother00000000000000#include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready) GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus) dot-forward-0.71/stralloc_pend.c010064400000000000001000000002310653025572600170320ustar00rootother00000000000000#include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append) dot-forward-0.71/stralloc_copy.c010064400000000000001000000002430653025572600170610ustar00rootother00000000000000#include "byte.h" #include "stralloc.h" int stralloc_copy(sato,safrom) stralloc *sato; stralloc *safrom; { return stralloc_copyb(sato,safrom->s,safrom->len); } dot-forward-0.71/stralloc_opyb.c010064400000000000001000000003770653025572600170700ustar00rootother00000000000000#include "stralloc.h" #include "byte.h" int stralloc_copyb(sa,s,n) stralloc *sa; char *s; unsigned int n; { if (!stralloc_ready(sa,n + 1)) return 0; byte_copy(sa->s,n,s); sa->len = n; sa->s[n] = 'Z'; /* ``offensive programming'' */ return 1; } dot-forward-0.71/stralloc_opys.c010064400000000000001000000002300653025572600170750ustar00rootother00000000000000#include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_copys(sa,s) stralloc *sa; char *s; { return stralloc_copyb(sa,s,str_len(s)); } dot-forward-0.71/stralloc_cat.c010064400000000000001000000002410653025572600166540ustar00rootother00000000000000#include "byte.h" #include "stralloc.h" int stralloc_cat(sato,safrom) stralloc *sato; stralloc *safrom; { return stralloc_catb(sato,safrom->s,safrom->len); } dot-forward-0.71/stralloc_catb.c010064400000000000001000000005000653025572600170140ustar00rootother00000000000000#include "stralloc.h" #include "byte.h" int stralloc_catb(sa,s,n) stralloc *sa; char *s; unsigned int n; { if (!sa->s) return stralloc_copyb(sa,s,n); if (!stralloc_readyplus(sa,n + 1)) return 0; byte_copy(sa->s + sa->len,n,s); sa->len += n; sa->s[sa->len] = 'Z'; /* ``offensive programming'' */ return 1; } dot-forward-0.71/stralloc_cats.c010064400000000000001000000002260653025572600170420ustar00rootother00000000000000#include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_cats(sa,s) stralloc *sa; char *s; { return stralloc_catb(sa,s,str_len(s)); } dot-forward-0.71/alloc.h010064400000000000001000000002030653025572600152770ustar00rootother00000000000000#ifndef ALLOC_H #define ALLOC_H extern /*@null@*//*@out@*/char *alloc(); extern void alloc_free(); extern int alloc_re(); #endif dot-forward-0.71/alloc.c010064400000000000001000000015010653025572600152740ustar00rootother00000000000000#include "alloc.h" #include "error.h" extern char *malloc(); extern void free(); #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ #define SPACE 4096 /* must be multiple of ALIGNMENT */ typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; static aligned realspace[SPACE / ALIGNMENT]; #define space ((char *) realspace) static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ /*@null@*//*@out@*/char *alloc(n) unsigned int n; { char *x; n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ if (n <= avail) { avail -= n; return space + avail; } x = malloc(n); if (!x) errno = error_nomem; return x; } void alloc_free(x) char *x; { if (x >= space) if (x < space + SPACE) return; /* XXX: assuming that pointers are flat */ free(x); } dot-forward-0.71/alloc_re.c010064400000000000001000000003260653025572600157660ustar00rootother00000000000000#include "alloc.h" #include "byte.h" int alloc_re(x,m,n) char **x; unsigned int m; unsigned int n; { char *y; y = alloc(n); if (!y) return 0; byte_copy(y,m,*x); alloc_free(*x); *x = y; return 1; } dot-forward-0.71/env.h010064400000000000001000000004400653025572600150000ustar00rootother00000000000000#ifndef ENV_H #define ENV_H extern int env_isinit; extern int env_init(); extern int env_put(); extern int env_put2(); extern int env_unset(); extern /*@null@*/char *env_get(); extern char *env_pick(); extern void env_clear(); extern char *env_findeq(); extern char **environ; #endif dot-forward-0.71/envread.c010064400000000000001000000006670653025572600156420ustar00rootother00000000000000#include "env.h" #include "str.h" extern /*@null@*/char *env_get(s) char *s; { int i; unsigned int slen; char *envi; slen = str_len(s); for (i = 0;envi = environ[i];++i) if ((!str_diffn(s,envi,slen)) && (envi[slen] == '=')) return envi + slen + 1; return 0; } extern char *env_pick() { return environ[0]; } extern char *env_findeq(s) char *s; { for (;*s;++s) if (*s == '=') return s; return 0; } dot-forward-0.71/open.h010064400000000000001000000002430653025572600151520ustar00rootother00000000000000#ifndef OPEN_H #define OPEN_H extern int open_read(); extern int open_excl(); extern int open_append(); extern int open_trunc(); extern int open_write(); #endif dot-forward-0.71/open_read.c010064400000000000001000000002020653025572600161330ustar00rootother00000000000000#include #include #include "open.h" int open_read(fn) char *fn; { return open(fn,O_RDONLY | O_NDELAY); } dot-forward-0.71/open_trunc.c010064400000000000001000000002340653025572600163600ustar00rootother00000000000000#include #include #include "open.h" int open_trunc(fn) char *fn; { return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } dot-forward-0.71/sig.h010064400000000000001000000016460653025572600150030ustar00rootother00000000000000#ifndef SIG_H #define SIG_H extern void sig_catch(); extern void sig_block(); extern void sig_unblock(); extern void sig_blocknone(); extern void sig_pause(); extern void sig_dfl(); extern void sig_miscignore(); extern void sig_bugcatch(); extern void sig_pipeignore(); extern void sig_pipedefault(); extern void sig_contblock(); extern void sig_contunblock(); extern void sig_contcatch(); extern void sig_contdefault(); extern void sig_termblock(); extern void sig_termunblock(); extern void sig_termcatch(); extern void sig_termdefault(); extern void sig_alarmblock(); extern void sig_alarmunblock(); extern void sig_alarmcatch(); extern void sig_alarmdefault(); extern void sig_childblock(); extern void sig_childunblock(); extern void sig_childcatch(); extern void sig_childdefault(); extern void sig_hangupblock(); extern void sig_hangupunblock(); extern void sig_hangupcatch(); extern void sig_hangupdefault(); #endif dot-forward-0.71/sig_catch.c010064400000000000001000000005350653025572600161340ustar00rootother00000000000000#include #include "sig.h" #include "hassgact.h" void sig_catch(sig,f) int sig; void (*f)(); { #ifdef HASSIGACTION struct sigaction sa; sa.sa_handler = f; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(sig,&sa,(struct sigaction *) 0); #else signal(sig,f); /* won't work under System V, even nowadays---dorks */ #endif } dot-forward-0.71/sig_pipe.c010064400000000000001000000002230653025572600160010ustar00rootother00000000000000#include #include "sig.h" void sig_pipeignore() { sig_catch(SIGPIPE,SIG_IGN); } void sig_pipedefault() { sig_catch(SIGPIPE,SIG_DFL); } dot-forward-0.71/trysgact.c010064400000000000001000000002530653025572600160450ustar00rootother00000000000000#include void main() { struct sigaction sa; sa.sa_handler = 0; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(0,&sa,(struct sigaction *) 0); } dot-forward-0.71/token822.h010064400000000000001000000013430653025572600155670ustar00rootother00000000000000#ifndef TOKEN822_H #define TOKEN822_H struct token822 { int type; char *s; int slen; } ; #include "gen_alloc.h" GEN_ALLOC_typedef(token822_alloc,struct token822,t,len,a) extern int token822_parse(); extern int token822_addrlist(); extern int token822_unquote(); extern int token822_unparse(); extern void token822_free(); extern void token822_reverse(); extern int token822_ready(); extern int token822_readyplus(); extern int token822_append(); #define TOKEN822_ATOM 1 #define TOKEN822_QUOTE 2 #define TOKEN822_LITERAL 3 #define TOKEN822_COMMENT 4 #define TOKEN822_LEFT 5 #define TOKEN822_RIGHT 6 #define TOKEN822_AT 7 #define TOKEN822_COMMA 8 #define TOKEN822_SEMI 9 #define TOKEN822_COLON 10 #define TOKEN822_DOT 11 #endif dot-forward-0.71/token822.c010064400000000000001000000262240653025572600155670ustar00rootother00000000000000#include "stralloc.h" #include "alloc.h" #include "str.h" #include "token822.h" #include "gen_allocdefs.h" static struct token822 comma = { TOKEN822_COMMA }; void token822_reverse(ta) token822_alloc *ta; { int i; int n; struct token822 temp; n = ta->len - 1; for (i = 0;i + i < n;++i) { temp = ta->t[i]; ta->t[i] = ta->t[n - i]; ta->t[n - i] = temp; } } GEN_ALLOC_ready(token822_alloc,struct token822,t,len,a,i,n,x,30,token822_ready) GEN_ALLOC_readyplus(token822_alloc,struct token822,t,len,a,i,n,x,30,token822_readyplus) GEN_ALLOC_append(token822_alloc,struct token822,t,len,a,i,n,x,30,token822_readyplus,token822_append) static int needspace(t1,t2) int t1; int t2; { if (!t1) return 0; if (t1 == TOKEN822_COLON) return 1; if (t1 == TOKEN822_COMMA) return 1; if (t2 == TOKEN822_LEFT) return 1; switch(t1) { case TOKEN822_ATOM: case TOKEN822_LITERAL: case TOKEN822_QUOTE: case TOKEN822_COMMENT: switch(t2) { case TOKEN822_ATOM: case TOKEN822_LITERAL: case TOKEN822_QUOTE: case TOKEN822_COMMENT: return 1; } } return 0; } static int atomok(ch) char ch; { switch(ch) { case ' ': case '\t': case '\r': case '\n': case '(': case '[': case '"': case '<': case '>': case ';': case ':': case '@': case ',': case '.': return 0; } return 1; } static void atomcheck(t) struct token822 *t; { int i; char ch; for (i = 0;i < t->slen;++i) { ch = t->s[i]; if ((ch < 32) || (ch > 126) || (ch == ')') || (ch == ']') || (ch == '\\')) { t->type = TOKEN822_QUOTE; return; } } } int token822_unparse(sa,ta,linelen) stralloc *sa; token822_alloc *ta; unsigned int linelen; { struct token822 *t; int len; int ch; int i; int j; int lasttype; int newtype; char *s; char *lineb; char *linee; len = 0; lasttype = 0; for (i = 0;i < ta->len;++i) { t = ta->t + i; newtype = t->type; if (needspace(lasttype,newtype)) ++len; lasttype = newtype; switch(newtype) { case TOKEN822_COMMA: len += 3; break; case TOKEN822_AT: case TOKEN822_DOT: case TOKEN822_LEFT: case TOKEN822_RIGHT: case TOKEN822_SEMI: case TOKEN822_COLON: ++len; break; case TOKEN822_ATOM: case TOKEN822_QUOTE: case TOKEN822_LITERAL: case TOKEN822_COMMENT: if (t->type != TOKEN822_ATOM) len += 2; for (j = 0;j < t->slen;++j) switch(ch = t->s[j]) { case '"': case '[': case ']': case '(': case ')': case '\\': case '\r': case '\n': ++len; default: ++len; } break; } } len += 2; if (!stralloc_ready(sa,len)) return -1; s = sa->s; lineb = s; linee = 0; lasttype = 0; for (i = 0;i < ta->len;++i) { t = ta->t + i; newtype = t->type; if (needspace(lasttype,newtype)) *s++ = ' '; lasttype = newtype; switch(newtype) { case TOKEN822_COMMA: *s++ = ','; #define NSUW \ s[0] = '\n'; s[1] = ' '; \ if (linee && (!linelen || (s - lineb <= linelen))) \ { while (linee < s) { linee[0] = linee[2]; ++linee; } linee -= 2; } \ else { if (linee) lineb = linee + 1; linee = s; s += 2; } NSUW break; case TOKEN822_AT: *s++ = '@'; break; case TOKEN822_DOT: *s++ = '.'; break; case TOKEN822_LEFT: *s++ = '<'; break; case TOKEN822_RIGHT: *s++ = '>'; break; case TOKEN822_SEMI: *s++ = ';'; break; case TOKEN822_COLON: *s++ = ':'; break; case TOKEN822_ATOM: case TOKEN822_QUOTE: case TOKEN822_LITERAL: case TOKEN822_COMMENT: if (t->type == TOKEN822_QUOTE) *s++ = '"'; if (t->type == TOKEN822_LITERAL) *s++ = '['; if (t->type == TOKEN822_COMMENT) *s++ = '('; for (j = 0;j < t->slen;++j) switch(ch = t->s[j]) { case '"': case '[': case ']': case '(': case ')': case '\\': case '\r': case '\n': *s++ = '\\'; default: *s++ = ch; } if (t->type == TOKEN822_QUOTE) *s++ = '"'; if (t->type == TOKEN822_LITERAL) *s++ = ']'; if (t->type == TOKEN822_COMMENT) *s++ = ')'; break; } } NSUW --s; sa->len = s - sa->s; return 1; } int token822_unquote(sa,ta) stralloc *sa; token822_alloc *ta; { struct token822 *t; int len; int i; int j; char *s; len = 0; for (i = 0;i < ta->len;++i) { t = ta->t + i; switch(t->type) { case TOKEN822_COMMA: case TOKEN822_AT: case TOKEN822_DOT: case TOKEN822_LEFT: case TOKEN822_RIGHT: case TOKEN822_SEMI: case TOKEN822_COLON: ++len; break; case TOKEN822_LITERAL: len += 2; case TOKEN822_ATOM: case TOKEN822_QUOTE: len += t->slen; } } if (!stralloc_ready(sa,len)) return -1; s = sa->s; for (i = 0;i < ta->len;++i) { t = ta->t + i; switch(t->type) { case TOKEN822_COMMA: *s++ = ','; break; case TOKEN822_AT: *s++ = '@'; break; case TOKEN822_DOT: *s++ = '.'; break; case TOKEN822_LEFT: *s++ = '<'; break; case TOKEN822_RIGHT: *s++ = '>'; break; case TOKEN822_SEMI: *s++ = ';'; break; case TOKEN822_COLON: *s++ = ':'; break; case TOKEN822_ATOM: case TOKEN822_QUOTE: case TOKEN822_LITERAL: if (t->type == TOKEN822_LITERAL) *s++ = '['; for (j = 0;j < t->slen;++j) *s++ = t->s[j]; if (t->type == TOKEN822_LITERAL) *s++ = ']'; break; case TOKEN822_COMMENT: break; } } sa->len = s - sa->s; return 1; } int token822_parse(ta,sa,buf) token822_alloc *ta; stralloc *sa; stralloc *buf; { int i; int salen; int level; struct token822 *t; int numtoks; int numchars; char *cbuf; salen = sa->len; numchars = 0; numtoks = 0; for (i = 0;i < salen;++i) switch(sa->s[i]) { case '.': case ',': case '@': case '<': case '>': case ':': case ';': ++numtoks; break; case ' ': case '\t': case '\r': case '\n': break; case ')': case ']': return 0; /* other control chars and non-ASCII chars are also bad, in theory */ case '(': level = 1; while (level) { if (++i >= salen) return 0; switch(sa->s[i]) { case '(': ++level; break; case ')': --level; break; case '\\': if (++i >= salen) return 0; default: ++numchars; } } ++numtoks; break; case '"': level = 1; while (level) { if (++i >= salen) return 0; switch(sa->s[i]) { case '"': --level; break; case '\\': if (++i >= salen) return 0; default: ++numchars; } } ++numtoks; break; case '[': level = 1; while (level) { if (++i >= salen) return 0; switch(sa->s[i]) { case ']': --level; break; case '\\': if (++i >= salen) return 0; default: ++numchars; } } ++numtoks; break; default: do { if (sa->s[i] == '\\') if (++i >= salen) break; ++numchars; if (++i >= salen) break; } while (atomok(sa->s[i])); --i; ++numtoks; } if (!token822_ready(ta,numtoks)) return -1; if (!stralloc_ready(buf,numchars)) return -1; cbuf = buf->s; ta->len = numtoks; t = ta->t; for (i = 0;i < salen;++i) switch(sa->s[i]) { case '.': t->type = TOKEN822_DOT; ++t; break; case ',': t->type = TOKEN822_COMMA; ++t; break; case '@': t->type = TOKEN822_AT; ++t; break; case '<': t->type = TOKEN822_LEFT; ++t; break; case '>': t->type = TOKEN822_RIGHT; ++t; break; case ':': t->type = TOKEN822_COLON; ++t; break; case ';': t->type = TOKEN822_SEMI; ++t; break; case ' ': case '\t': case '\r': case '\n': break; case '(': t->type = TOKEN822_COMMENT; t->s = cbuf; t->slen = 0; level = 1; while (level) { ++i; /* assert: < salen */ switch(sa->s[i]) { case '(': ++level; break; case ')': --level; break; case '\\': ++i; /* assert: < salen */ default: *cbuf++ = sa->s[i]; ++t->slen; } } ++t; break; case '"': t->type = TOKEN822_QUOTE; t->s = cbuf; t->slen = 0; level = 1; while (level) { ++i; /* assert: < salen */ switch(sa->s[i]) { case '"': --level; break; case '\\': ++i; /* assert: < salen */ default: *cbuf++ = sa->s[i]; ++t->slen; } } ++t; break; case '[': t->type = TOKEN822_LITERAL; t->s = cbuf; t->slen = 0; level = 1; while (level) { ++i; /* assert: < salen */ switch(sa->s[i]) { case ']': --level; break; case '\\': ++i; /* assert: < salen */ default: *cbuf++ = sa->s[i]; ++t->slen; } } ++t; break; default: t->type = TOKEN822_ATOM; t->s = cbuf; t->slen = 0; do { if (sa->s[i] == '\\') if (++i >= salen) break; *cbuf++ = sa->s[i]; ++t->slen; if (++i >= salen) break; } while (atomok(sa->s[i])); atomcheck(t); --i; ++t; } return 1; } static int gotaddr(taout,taaddr,callback) token822_alloc *taout; token822_alloc *taaddr; int (*callback)(); { int i; if (callback(taaddr) != 1) return 0; if (!token822_readyplus(taout,taaddr->len)) return 0; for (i = 0;i < taaddr->len;++i) taout->t[taout->len++] = taaddr->t[i]; taaddr->len = 0; return 1; } int token822_addrlist(taout,taaddr,ta,callback) token822_alloc *taout; token822_alloc *taaddr; token822_alloc *ta; int (*callback)(); { struct token822 *t; struct token822 *beginning; int ingroup; int wordok; taout->len = 0; taaddr->len = 0; if (!token822_readyplus(taout,1)) return -1; if (!token822_readyplus(taaddr,1)) return -1; ingroup = 0; wordok = 1; beginning = ta->t + 2; t = ta->t + ta->len - 1; /* rfc 822 address lists are easy to parse from right to left */ #define FLUSH if (taaddr->len) if (!gotaddr(taout,taaddr,callback)) return -1; #define FLUSHCOMMA if (taaddr->len) { \ if (!gotaddr(taout,taaddr,callback)) return -1; \ if (!token822_append(taout,&comma)) return -1; } #define ADDRLEFT if (!token822_append(taaddr,t--)) return -1; #define OUTLEFT if (!token822_append(taout,t--)) return -1; while (t >= beginning) { switch(t->type) { case TOKEN822_SEMI: FLUSHCOMMA if (ingroup) return 0; ingroup = 1; wordok = 1; break; case TOKEN822_COLON: FLUSH if (!ingroup) return 0; ingroup = 0; while ((t >= beginning) && (t->type != TOKEN822_COMMA)) OUTLEFT if (t >= beginning) OUTLEFT wordok = 1; continue; case TOKEN822_RIGHT: FLUSHCOMMA OUTLEFT while ((t >= beginning) && (t->type != TOKEN822_LEFT)) ADDRLEFT /* important to use address here even if it's empty: <> */ if (!gotaddr(taout,taaddr,callback)) return -1; if (t < beginning) return 0; OUTLEFT while ((t >= beginning) && ((t->type == TOKEN822_COMMENT) || (t->type == TOKEN822_ATOM) || (t->type == TOKEN822_QUOTE) || (t->type == TOKEN822_AT) || (t->type == TOKEN822_DOT))) OUTLEFT wordok = 0; continue; case TOKEN822_ATOM: case TOKEN822_QUOTE: case TOKEN822_LITERAL: if (!wordok) FLUSHCOMMA wordok = 0; ADDRLEFT continue; case TOKEN822_COMMENT: /* comment is lexically a space; shouldn't affect wordok */ break; case TOKEN822_COMMA: FLUSH wordok = 1; break; default: wordok = 1; ADDRLEFT continue; } OUTLEFT } FLUSH ++t; while (t > ta->t) if (!token822_append(taout,--t)) return -1; token822_reverse(taout); return 1; } dot-forward-0.71/control.h010064400000000000001000000003000653025572600156630ustar00rootother00000000000000#ifndef CONTROL_H #define CONTROL_H extern int control_init(); extern int control_readline(); extern int control_rldef(); extern int control_readint(); extern int control_readfile(); #endif dot-forward-0.71/control.c010064400000000000001000000043500653025572600156670ustar00rootother00000000000000#include "readwrite.h" #include "open.h" #include "getln.h" #include "stralloc.h" #include "substdio.h" #include "error.h" #include "control.h" #include "alloc.h" #include "scan.h" static char inbuf[64]; static stralloc line = {0}; static stralloc me = {0}; static int meok = 0; static void striptrailingwhitespace(sa) stralloc *sa; { while (sa->len > 0) switch(sa->s[sa->len - 1]) { case '\n': case ' ': case '\t': --sa->len; break; default: return; } } int control_init() { int r; r = control_readline(&me,"control/me"); if (r == 1) meok = 1; return r; } int control_rldef(sa,fn,flagme,def) stralloc *sa; char *fn; int flagme; char *def; { int r; r = control_readline(sa,fn); if (r) return r; if (flagme) if (meok) return stralloc_copy(sa,&me) ? 1 : -1; if (def) return stralloc_copys(sa,def) ? 1 : -1; return r; } int control_readline(sa,fn) stralloc *sa; char *fn; { substdio ss; int fd; int match; fd = open_read(fn); if (fd == -1) { if (errno == error_noent) return 0; return -1; } substdio_fdbuf(&ss,read,fd,inbuf,sizeof(inbuf)); if (getln(&ss,sa,&match,'\n') == -1) { close(fd); return -1; } striptrailingwhitespace(sa); close(fd); return 1; } int control_readint(i,fn) int *i; char *fn; { unsigned long u; switch(control_readline(&line,fn)) { case 0: return 0; case -1: return -1; } if (!stralloc_0(&line)) return -1; if (!scan_ulong(line.s,&u)) return 0; *i = u; return 1; } int control_readfile(sa,fn,flagme) stralloc *sa; char *fn; int flagme; { substdio ss; int fd; int match; if (!stralloc_copys(sa,"")) return -1; fd = open_read(fn); if (fd == -1) { if (errno == error_noent) { if (flagme && meok) { if (!stralloc_copy(sa,&me)) return -1; if (!stralloc_0(sa)) return -1; return 1; } return 0; } return -1; } substdio_fdbuf(&ss,read,fd,inbuf,sizeof(inbuf)); for (;;) { if (getln(&ss,&line,&match,'\n') == -1) break; if (!match && !line.len) { close(fd); return 1; } striptrailingwhitespace(&line); if (!stralloc_0(&line)) break; if (line.s[0]) if (line.s[0] != '#') if (!stralloc_cat(sa,&line)) break; if (!match) { close(fd); return 1; } } close(fd); return -1; } dot-forward-0.71/fmt.h010064400000000000001000000012440653025572600150010ustar00rootother00000000000000#ifndef FMT_H #define FMT_H #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ #define FMT_LEN ((char *) 0) /* convenient abbreviation */ extern unsigned int fmt_uint(); extern unsigned int fmt_uint0(); extern unsigned int fmt_xint(); extern unsigned int fmt_nbbint(); extern unsigned int fmt_ushort(); extern unsigned int fmt_xshort(); extern unsigned int fmt_nbbshort(); extern unsigned int fmt_ulong(); extern unsigned int fmt_xlong(); extern unsigned int fmt_nbblong(); extern unsigned int fmt_plusminus(); extern unsigned int fmt_minus(); extern unsigned int fmt_0x(); extern unsigned int fmt_str(); extern unsigned int fmt_strn(); #endif dot-forward-0.71/fmt_ulong.c010064400000000000001000000005000653025572600161720ustar00rootother00000000000000#include "fmt.h" unsigned int fmt_ulong(s,u) register char *s; register unsigned long u; { register unsigned int len; register unsigned long q; len = 1; q = u; while (q > 9) { ++len; q /= 10; } if (s) { s += len; do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ } return len; } dot-forward-0.71/scan.h010064400000000000001000000012660653025572600151430ustar00rootother00000000000000#ifndef SCAN_H #define SCAN_H extern unsigned int scan_uint(); extern unsigned int scan_xint(); extern unsigned int scan_nbbint(); extern unsigned int scan_ushort(); extern unsigned int scan_xshort(); extern unsigned int scan_nbbshort(); extern unsigned int scan_ulong(); extern unsigned int scan_xlong(); extern unsigned int scan_nbblong(); extern unsigned int scan_plusminus(); extern unsigned int scan_0x(); extern unsigned int scan_whitenskip(); extern unsigned int scan_nonwhitenskip(); extern unsigned int scan_charsetnskip(); extern unsigned int scan_noncharsetnskip(); extern unsigned int scan_strncmp(); extern unsigned int scan_memcmp(); extern unsigned int scan_long(); #endif dot-forward-0.71/scan_ulong.c010064400000000000001000000005300653025572600163330ustar00rootother00000000000000#include "scan.h" unsigned int scan_ulong(s,u) register char *s; register unsigned long *u; { register unsigned int pos; register unsigned long result; register unsigned long c; pos = 0; result = 0; while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) { result = result * 10 + c; ++pos; } *u = result; return pos; } dot-forward-0.71/case.h010064400000000000001000000003640653025572600151300ustar00rootother00000000000000#ifndef CASE_H #define CASE_H extern void case_lowers(); extern void case_lowerb(); extern int case_diffs(); extern int case_diffb(); extern int case_starts(); extern int case_startb(); #define case_equals(s,t) (!case_diffs((s),(t))) #endif dot-forward-0.71/case_diffb.c010064400000000000001000000006470653025572600162610ustar00rootother00000000000000#include "case.h" int case_diffb(s,len,t) register char *s; unsigned int len; register char *t; { register unsigned char x; register unsigned char y; while (len > 0) { --len; x = *s++ - 'A'; if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; y = *t++ - 'A'; if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; if (x != y) return ((int)(unsigned int) x) - ((int)(unsigned int) y); } return 0; } dot-forward-0.71/seek.h010064400000000000001000000003430653025572600151410ustar00rootother00000000000000#ifndef SEEK_H #define SEEK_H typedef unsigned long seek_pos; extern seek_pos seek_cur(); extern int seek_set(); extern int seek_end(); extern int seek_trunc(); #define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) #endif dot-forward-0.71/seek_set.c010064400000000000001000000002550653025572600160110ustar00rootother00000000000000#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; }