sendfile-2.1b/0000755000175100001440000000000011025466700013034 5ustar framstaguserssendfile-2.1b/Makefile0000644000175100001440000000273711025466700014505 0ustar framstagusers# Do not edit this file! # It is autogenerated by "makeconfig" and will be overwritten next time! # If you want to change some values, so do it in "makeconfig". PROJECT=sendfile-2.1b all: develop/config.log . cd src; make install: develop/config.log . sh develop/install userinstall: develop/config.log . sh develop/userinstall reinstall: develop/config.log . sh develop/install reinstall config: ./makeconfig develop/config.log: makeconfig ./makeconfig clean: rm -f *~ */*~ sendfile-*tar.gz ./makeconfig clean cd contrib/xhoppel && make clean cd develop && rm -rf config.cache config.log autom4te.cache cd src && make clean && rm -f config.h globals.h wc: @cd src; wc -cl \ sendfile.c sendfiled.c sendmsg.c receive.c utf7encode.c fetchfile.c \ string.[ch] utf7.[ch] pstring.[ch] message.[ch] peername.[ch] \ io.[ch] net.[ch] address.[ch] spool.[ch] reply.[ch] getline.[ch] \ lock.[ch] wlock.c bsd.h pussy \ ../develop/install ../develop/makefile* ../makeconfig \ ../etc/check_sendfile ../etc/xinetd \ ../etc/sf_cleanup ../etc/sfconf ../etc/sfdconf ../etc/sendfile.cf dist: clean @mkdir $(PROJECT) @tar cf - `cat develop/FILES` | (cd $(PROJECT); tar xf - ) tar cvf - $(PROJECT) | gzip > $(PROJECT).tar.gz @rm -rf $(PROJECT) @ls -l $(PROJECT).tar.gz floppy: clean cd ..; tar cvzf /dev/fd0 $(PROJECT) @cd ..; tar czf /tmp/sf.tgz $(PROJECT) @echo "insert a new disk and press enter"; read dummy mformat a:; mcopy /tmp/sf.tgz a:; rm -f /tmp/sf.tgz sendfile-2.1b/COPYING0000777000175100001440000000000011025466700015664 2doc/COPYINGustar framstaguserssendfile-2.1b/etc/0000755000175100001440000000000011025466700013607 5ustar framstaguserssendfile-2.1b/etc/sendfile.deny0000644000175100001440000000006610251132201016245 0ustar framstagusersdaemon bin ftp lpr uucp anonymous nobody OUTGOING LOG sendfile-2.1b/etc/sf_install0000755000175100001440000001317210251132201015661 0ustar framstagusers#!/bin/sh # # Das Schnellinstallations-Script fuer sendfile im /sw. # Bei Aufruf ohne Parameter wird ein Hilfetext ausgegeben. # mkdir_recursive() { if [ ! -d $1 ]; then mkdir `echo $1 | awk -F/ '{ for (i=2; $i!=""; i++) { for (j=2; j<=i; j++) printf("/"$j) printf(" ") } }' ` 2>/dev/null fi } RESTART=false SPOOL=/var/spool/sendfile CONFIG=/usr/local/etc ALLOW=/usr/local/etc/sendfile.allow DENY=/usr/local/etc/sendfile.deny if [ "$2" = "" ]; then SERVERDIR=/usr/local/sbin else SERVERDIR=$2 fi if [ "$1" != "ok" ]; then more <0) sfd=$7; if (substr(sfd,1,1)=="?") sfd=substr(sfd,2); print sfd; }' /etc/inetd.conf` if [ "$SENDFILED" != "$SERVERDIR/sendfiled" -a "$SENDFILED" != "" ]; then echo "WARNING: cannot install sendfiled in $SERVERDIR because in /etc/inetd.conf" echo " there is $SENDFILED specified! Check it!" else echo "installing the sendfile-daemon in $SERVERDIR" mkdir_recursive $SERVERDIR cp sendfiled $SERVERDIR chmod 755 $SERVERDIR/sendfiled fi mkdir_recursive $CONFIG NOSENDFILE=$CONFIG/nosendfile if [ -f $NOSENDFILE ]; then if grep ^allow-only $NOSENDFILE >/dev/null; then echo "Information: $NOSENDFILE is now $ALLOW (autoconverted)" grep -v ^allow-only $NOSENDFILE > $ALLOW else echo "Information: $NOSENDFILE is now $DENY (autoconverted)" mv $NOSENDFILE $DENY fi fi if [ ! -f $DENY -a ! -f $ALLOW]; then echo "installing $DENY" cp sendfile.deny $DENY chmod 644 $DENY fi if [ ! -f $CONFIG/sendfile.cf ]; then echo installing $CONFIG/sendfile.cf cp sendfile.cf $CONFIG/sendfile.cf chmod 644 $CONFIG/sendfile.cf else if [ "`diff sendfile.cf $CONFIG`" ]; then echo "`pwd`/sendfile.cf differs from $CONFIG/sendfile.cf !" echo "Bitte von Hand nachschauen was sich geaendert hat!" fi fi SERVICES="`awk '/[ \t]487\/tcp/' /etc/services`" if [ "$SERVICES" != "" ]; then case "$SERVICES" in saft*) ;; *) echo "install-error: tcp-port 487 ist bereits belegt!"; exit 1;; esac else echo configuring /etc/services echo "#" >>/etc/services echo "saft 487/tcp # simple asynchronous file transfer" >>/etc/services fi if [ "`grep '^saft' /etc/inetd.conf`" = "" ]; then if [ -f /usr/sbin/tcpd ]; then SFD="/usr/sbin/tcpd $SERVERDIR/sendfiled" else SFD="$SERVERDIR/sendfiled sendfiled" fi RESTART=true echo configuring /etc/inetd.conf echo "#" >>/etc/inetd.conf echo "# simple asynchronous file transfer" >>/etc/inetd.conf echo "saft stream tcp nowait root $SFD" >>/etc/inetd.conf fi if [ -f /etc/inetd.sec ]; then if [ "`grep '^saft' /etc/inetd.sec`" = "" ]; then echo >> /etc/inetd.sec echo "saft allow" >> /etc/inetd.sec fi fi if [ -f /etc/profile ]; then if [ "`grep check_sendfile /etc/profile`" = "" ]; then echo adding check_sendfile to /etc/profile echo >>/etc/profile echo "test -x /client/bin/check_sendfile && /client/bin/check_sendfile" \ >>/etc/profile fi fi if [ -f /etc/csh.login ]; then if [ "`grep check_sendfile /etc/csh.login`" = "" ]; then echo adding check_sendfile to /etc/csh.login echo >>/etc/csh.login echo "test -x /client/bin/check_sendfile && /client/bin/check_sendfile" \ >>/etc/csh.login fi fi if [ ! -d "$SPOOL" ]; then echo creating $SPOOL mkdir_recursive $SPOOL fi if [ ! -d "$SPOOL/LOG" ]; then mkdir $SPOOL/LOG; fi if [ ! -d "$SPOOL/OUTGOING" ]; then mkdir $SPOOL/OUTGOING; fi chmod 755 $SPOOL chmod 700 $SPOOL/LOG chmod 1777 $SPOOL/OUTGOING free=`$SENDFILED -f` minfree=`awk '/minfree =/{print $3}' $CONFIG/sendfile.cf` if [ $free -le $minfree ]; then cat </dev/null fi done sendfile-2.1b/etc/xinetd0000644000175100001440000000035110251132201015006 0ustar framstagusers# default: on # description: SAFT - Simple Asynchronous File Transfer Protocol # service saft { socket_type = stream wait = no user = root server = /usr/local/sbin/sendfiled server_args = nice = 10 disable = no } sendfile-2.1b/etc/sfdconf0000755000175100001440000001147010251132201015144 0ustar framstagusers#!/bin/sh # File: sfdconf # # Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) # # History: # # 1997-11-23 Framstag initial version # 1998-01-04 Framstag added -r option # # The daemon configuration helper program for the sendfile package. # # Copyright © 1997,1998 Ulli Horlacher # This file is covered by the GNU General Public License #SPOOL=`sendfile -qW=spool` SPOOL=/var/spool/sendfile INLOG=/var/spool/sendfile/LOG/in OUTLOG=/var/spool/sendfile/LOG/out CONFIG=/usr/local/etc/sendfile.cf ALIASES=/usr/local/etc/sendfile.aliases DENY=/usr/local/etc/sendfile.deny ALLOW=/usr/local/etc/sendfile.allow EDITOR=${EDITOR:=vi} PAGER=${PAGER:=more} PRG=`basename $0` FILE= usage() { echo "$PRG is the sendfiled configuration helper" echo "usage: $PRG OPTION ARGUMENT" echo "options: -l -- list" echo " -e -- edit" echo " -i -- initialize (= edit with default values)" echo " -r -- receiving mode" echo "arguments for options -l -e -i :" echo " config -- sendfiled configuration file" echo " redirect -- system alias (redirection) file" echo " allow -- users allow-only file" echo " deny -- users deny file" echo "arguments for option -l :" echo " inlog -- input log file" echo " outlog -- output log file" echo "arguments for option -r :" echo " enable -- enable receiving" echo " disable -- disable receiving" echo "examples:" echo " $PRG -l deny # list the deny file" echo " $PRG -e config # edit the configuration file" exit } testfile() { error="`(cat $1 >/dev/null) 2>&1 | sed 's/cat: //'`" if [ "$error" ]; then echo "%$PRG-Error: $error" >&2 exit 1 fi } init_append() { if [ -r $FILE ]; then cat <> $FILE.tmp ## The next lines are from your old `basename $FILE` file. ## You may want to delete them (if they are garbage). EOD cat $FILE >> $FILE.tmp fi mv $FILE.tmp $FILE } init_aliases() { cat < $FILE.tmp || exit 1 ## This is the global aliases file for sendfiled. ## It is used only for redirection of incoming files or messages! ## Text after a # is a comment and will be ignored. ## The syntax is: ALIAS USER[@HOST], examples: # zrxh0370 framstag # root admin@bigvax.saft.net EOD init_append } init_config() { cat < $FILE.tmp || exit 1 CONFIG EOD init_append } init_deny() { cat < $FILE.tmp || exit 1 ## This is the exclusion list for sendfiled. ## Users which are listed here are not allowed to receive files or messages. ## Warning: if sendfile.allow contains any user names it will be used as an ## allow-only list and this file here will be ignored. ## Text after a # is a comment. daemon bin news ftp lpr uucp anonymous nobody OUTGOING LOG EOD init_append } init_allow() { cat < $FILE.tmp || exit 1 ## This is the allow-only list for sendfiled. ## Only users which are listed here are allowed to receive files or messages. ## If this files contains no user names at all, it will be ignored and ## senfile.deny will be used instead as an exclusion list. ## Text after a # is a comment. EOD init_append } #args=`getopt h?lei $*` || usage #set -- x $args #while shift; do # case $1 in # -\?|-h) usage;; # -l) list=true;; # -e) edit=true;; # -i) init=true;; # --) shift; break;; # esac #done list= edit= init= rmode= case "$1" in -l) list=true;; -e) edit=true;; -i) init=true;; -r) rmode=true;; *) usage;; esac if [ "$rmode" = true ]; then case "$2" in e|enable|y) rmode=enable;; d|disable|n) rmode=disable;; *) rmode=show;; esac else case "$2" in r|redirect) FILE=$ALIASES;; c|conf|config) FILE=$CONFIG;; a|allow) FILE=$ALLOW;; d|deny) FILE=$DENY;; i|inlog) FILE=$INLOG; log=true;; o|outlog) FILE=$OUTLOG; log=true;; *) usage;; esac fi if [ "$rmode" ]; then status=0 case "$rmode" in enable) rm -f $SPOOL/.nosendfile; status=$?;; disable) touch $SPOOL/.nosendfile; status=$?;; esac if [ -f $SPOOL/.nosendfile ]; then echo "receiving of files is disabled" else echo "receiving of files is enabled" fi exit $status fi if [ "$log" = true ]; then if [ "$list" != true ]; then usage; fi testfile $FILE utf7decode $FILE | $PAGER exit $? fi if [ "$list" = true ]; then testfile $FILE $PAGER $FILE exit $? fi if [ "$edit" = true ]; then if [ -f $FILE ]; then $EDITOR $FILE exit $? else echo "%$PRG-Error: $FILE does not exist" >&2 echo "%$PRG-Info: you can create it with: $PRG -i $2" >&2 exit 1 fi fi if [ "$init" = true ]; then trap "rm -f $FILE.tmp;exit" 1 2 3 15 case $FILE in *aliases) init_aliases;; *cf) init_config;; *allow) init_allow;; *deny) init_deny;; esac $EDITOR $FILE exit $? fi sendfile-2.1b/etc/sendfile.cf0000644000175100001440000000661710765525312015731 0ustar framstagusers## This is the sendfiled configuration file. ## Text after a # is a comment and will be ignored. ## If your sendfile-spool is on a NFS volume, you have to distinguish between ## the NFS-clients and the NFS-server ! # accept only messages or files # (NFS-clients must set "acceptonly = messages" !) # acceptonly = messages # forward address to your generic SAFT-server (e.g. for NFS) # saftserver = saft.banana.net ### the following section is only relevant if you have a local sendfile spool ### ( = if the sendfile spool is not an a remote NFS volume) ### # you can set here your domain name if necessary # domain = my.host.org # where shall new user configuration directories be created (SPOOL/HOME) userconfig = SPOOL # allow automatic forwarding of files by the local user (on/off) forwarding = on # allow automatic postprocessing of files by the local user (on/off) piping = on # allow remote sender to delete his files afterwards (on/off) deleting = on # maximum allowed files to receive per user # setting this option too high will slow down your machine! maxfiles = 200 # minimum free disk space for your spool partition in MB minfree = 5 # maximum total disk space usage for spool in MB # (WARNING! Defining this option will sendfile slow down! Better use minfree) # maxspool = 100 # dontcompress is a list of file extension, which indicate that the # correspondening file is not compressible. dontcompress = .zip,.zoo,.arj,.z,.gz,.bz,.bz2,.tgz,.mp3,.gif,.jpg,.tif,.tiff,.png,.avi,.mpeg,.pgp,.rpm,.rar,.deb # default compression methode (none/gzip/bzip2) defaultcompress = gzip # lanspeed defines what to your LAN belongs: if sending to hosts is faster # than this value (KB/s), then files will not be compressed. If you set # lanspeed = 0 then this feature will be disabled and every file which # is not in the dontcompress list (see above) will be compressed. lanspeed = 100 # notification by message, mail, both or none when a file arrives notification = message # ring the gong when a message arrives (on/off) bell = on # keep files in spool at least xx days, then delete them (0=infinity) keep = 0 # delete aborted or corrupted spool files after xx days (0=never) deljunk = 10 # global logging of file transfer (in/out/both/none) log = in # packet size to send/receive in one chunk # if you are on a fast and reliable network, set this option to 1024 or 4096 packet = 512 # logging of incoming messages in the user log file (on/off) msglog = off # allow O-SAFT fetchfile extension (on/off) fetchfile = on # internal environment variable PATH for sendfiled PATH = /usr/local/bin:/bin:/usr/bin:/opt/bin # where is the pgp program? (used for O-SAFT/fetchfile) # optional, if pgp is found in the PATH variable above # pgp = /usr/local/bin/pgp # enforce secure incoming file transfer with pgp (sign/encrypt/both/none) forcepgp = none # allow spooling of outgoing files (on/nostart/off) # (nostart means a client is not allowed to start the spool daemon) spooling = on # allow parallel sending of spooled files = multiple daemons (on/off) parallel = on # limit thruput of outgoing files to xx KB/s (0 = no limit) # this makes only sense if parallel = off (see above) maxthruput = 0 # bounce files from outgoing spool back to the local user after xx days # (when remote host is unreachable) bounce = 5 # retry delivering of files from outgoing spool after xx minutes retry = 10 # timeout for clients in seconds timeout = 300 sendfile-2.1b/etc/sfconf0000755000175100001440000001421010251132201014773 0ustar framstagusers#!/bin/sh # File: sfconf # # Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) # # History: # # 1997-11-22 Framstag initial version # 1997-11-23 Framstag substituted "-" with "_" in all identifiers # 1998-01-10 Framstag added option -m # 1998-03-15 Framstag look for spool and configdir in $HOME # 1998-07-11 Framstag added notify program support # 2005-05-30 Framstag better USER detection # # The configuration helper program for the sendfile package. # # Copyright © 1997-2005 Ulli Horlacher # This file is covered by the GNU General Public License if [ "$LOGNAME" ]; then USER=$LOGNAME else USER=`id | sed 's/[()]/ /g' | awk '{print $2}'` fi SPOOL=$HOME/.sfspool test -d $SPOOL || SPOOL=/var/spool/sendfile/$USER CONFIG=$HOME/.sendfile EDITOR=${EDITOR:=vi} PAGER=${PAGER:=more} PRG=`basename $0` TMP=$CONFIG/$$.tmp FILE= if [ ! -d $CONFIG ]; then if [ -d $SPOOL/config ]; then ln -s $SPOOL/config $CONFIG else mkdir $CONFIG fi fi usage() { echo "$PRG is the sendfile user configuration helper" echo "usage: $PRG OPTION ARGUMENT" echo "options: -l -- list" echo " -e -- edit" echo " -i -- initialize (= edit with default values)" echo " -m -- message receiving" echo "arguments for options -l -e -i :" echo " config -- user configuration file" echo " aliases -- user alias file" echo " filter -- user restrictions file" echo " notify -- notify program for file receiving" echo "arguments for option -l :" echo " log -- sendfile log file" echo " msglog -- sendmsg log file" echo "arguments for option -m :" echo " all -- messages can be written on all ttys" echo " here -- messages can be written only on this tty" echo "examples:" echo " $PRG -l aliases # list the aliases file" echo " $PRG -m here # messages will be written only on this tty" exit } testfile() { if [ ! -f "$1" ]; then echo "%$PRG-Error: $1 does not exist" >&2 exit 1 fi if [ ! -r "$1" ]; then echo "%$PRG-Error: $1 is not readable by you" >&2 exit 1 fi } init_append() { if [ -r $FILE ]; then cat <> $TMP ## The next lines are from your old `basename $FILE` file. ## You may want to delete them (if they are garbage). EOD cat $FILE >> $TMP fi mv $TMP $FILE } init_aliases() { cat < $TMP ## This is the user aliases file for sendfile/sendmsg. ## The syntax is: ALIAS ADDRESS, example: frams framstag@bofh.belwue.de EOD init_append } init_config() { cat < $TMP ## This is the user configuration file for sendfile/sendmsg. ## Text after a # is a comment and will be ignored. # ring the gong when a message arrives (on/off) bell = on # allow remote sender to delete his files afterwards (on/off) deleting = on # logging of incoming messages in the user log file (on/off) msglog = off # Notification by message, mail, both or none when a file arrives. # You may specify a second argument as a recipients address. # Extra: when you specify "notification = program" then the notify-program # in your sendfile configuration directory will be executed. # Type "sfconf -i notify" for an example. # notification = mail tome@somewhere.inthe.net # notification = program notification = message # enforce secure incoming transfer with pgp (sign/encrypt/both/none) forcepgp = none # forward incoming files to another SAFT address # forward = tome@on.another.org # if you have an O-SAFT account, specify it here # (the fetchfile client will use it) # o-saft = othername@saft.banana.net # default compression methode (none/gzip/bzip2) defaultcompress = gzip EOD init_append } init_restrictions() { cat < $TMP ## This is the user restrictions file for sendfile/sendmsg. ## It contains addresses from where you don't want messages or files. ## The format is: user@host [mfb] ## m stands for messages, f for files and b for both. ## Wildcards * and ? are allowed. Examples: ## bgates@microsoft.com b ## *aol.com m ## Text after a # is a comment, like these first lines. EOD init_append } init_notify() { cat < $TMP #!/bin/sh # This program will be called whenever someone has sent you some files AND # when you have set the option "notification = program" with "sfconf -e config". # # The shell-argument \$1 contains the name of the sender, # in \$2..\$n are the spool file numbers. # This here is just an example what you can do! from=\$1; shift n=\`echo \$* | wc -w\` sendmsg -f -s "\$n new file(s) from \$from!" \$USER exit EOD chmod 700 $TMP init_append } #args=`getopt h?lei $*` || usage #set -- x $args #while shift; do # case $1 in # -\?|-h) usage;; # -l) list=true;; # -e) edit=true;; # -i) init=true;; # --) shift; break;; # esac #done case "$1" in -l) list=true;; -e) edit=true;; -i) init=true;; -m) msg=true;; *) usage;; esac if [ "$msg" = true ]; then case "$2" in a|all) sendmsg -M;; h|here|t|this) sendmsg -m;; *) usage;; esac exit; fi case "$2" in a|alias|aliases) FILE=$CONFIG/aliases;; c|conf|config) FILE=$CONFIG/config;; f|filter|r|restrictions) FILE=$CONFIG/restrictions;; n|notify) FILE=$CONFIG/notify if [ $USER = root ]; then echo "%$PRG-Error: for security reasons, root is not allowed to use a notify program" >&2 exit 1 fi;; l|log) log=true; FILE=$SPOOL/log;; m|msg|msglog) log=true; FILE=$SPOOL/msglog;; *) usage;; esac if [ "$log" = true ]; then if [ "$edit" = true ]; then usage; fi testfile $FILE awk '{if (NR>1 || $1!="#") print $0}' $FILE | utf7decode | $PAGER exit $? fi if [ "$list" = true ]; then testfile $FILE $PAGER $FILE exit $? fi if [ "$edit" = true ]; then if [ -f $FILE ]; then $EDITOR $FILE exit $? else echo "%$PRG-Error: $FILE does not exist" >&2 echo "%$PRG-Info: you can create it with: $PRG -i $2" >&2 exit 1 fi fi if [ "$init" = true ]; then trap "rm -f $TMP;exit" 1 2 3 15 case $FILE in *aliases) init_aliases;; *config) init_config;; *restrictions) init_restrictions;; *notify) init_notify;; esac $EDITOR $FILE exit $? fi sendfile-2.1b/etc/check_sendfile0000755000175100001440000000021010251132201016436 0ustar framstagusers#!/bin/sh if [ ! -z "`receive -l 2>/dev/null`" ]; then echo echo 'You have files in your spool directory. Type "receive"' echo fi sendfile-2.1b/etc/sf_swinstall0000755000175100001440000000515310251132201016233 0ustar framstagusers#!/bin/sh #makeconfig CC=cc #make prg=`basename $0` arch=${1:-`ls -ld /client | awk -F/ '{print $NF}'`} sfd=/sw/$arch/sendfile-2.1 sfold=/sw/$arch/sendfile-2.0 sfs=`pwd` if [ -d $sfold ]; then cd $sfold echo . | /client/sbin/SWdeinstall -c /sw/clients/$arch cd $sfs rm -rf $sfold fi if [ -f /usr/man/man7/locale.7 -o -f /usr/man/man7/term.7 ]; then manmisc=7 else manmisc=5 fi if [ -f /usr/man/man8/inetd.8 ]; then manadmin=8 else manadmin=1m fi rm -rf $sfd mkdir $sfd $sfd/bin $sfd/etc $sfd/install $sfd/doc mkdir $sfd/man $sfd/man/man1 mkdir $sfd/man/man$manmisc $sfd/man/man$manadmin cd src cp receive sendfile sendmsg utf7encode wlock ewl $sfd/bin/ || exit 1 cp sendfiled $sfd/install/ || exit 1 cd $sfd/bin ln -s utf7encode utf7decode 2>/dev/null ln -s sendfile sf 2>/dev/null ln -s sendmsg sm 2>/dev/null ln -s receive rf 2>/dev/null cd $sfs/etc cp sfconf sfdconf sf_cleanup $sfd/bin/ || exit 1 cp sendfile.deny $sfd/install/ || exit 1 sed 's/msglog = off/msglog = on/ s|:/usr/bin|:/usr/bin:/client/bin|' sendfile.cf > $sfd/etc/sendfile.cf || exit 1 awk '{if ($0 != "CONFIG") print $0; else system("cat '$sfd/etc/sendfile.cf'")}' \ sfdconf > $sfd/bin/sfdconf || exit 1 sed "s:receive -l:/client/bin/receive -l:" check_sendfile >$sfd/bin/check_sendfile if [ $arch = pmax_ul43 ]; then sed "s:/bin/sh:/bin/sh5: s:SW_INSTALL:$sfd/install:" sf_install >$sfd/bin/sf_install else sed "s:SW_INSTALL:$sfd/install:" sf_install >$sfd/bin/sf_install fi chmod 775 $sfd/bin/* cd ../doc cp *.1 $sfd/man/man1/ (cd $sfd/man/man1; ln -s utf7encode.1 utf7decode.1) cp fetchfile.7 $sfd/man/man$manmisc/fetchfile.$manmisc cp sendfiled.8 $sfd/man/man$manadmin/sendfiled.$manadmin cp LIESMICH.neu LIESMICH.auch doku.ps $sfd/doc/ cd $sfd rm -f *~ */*~ if [ "$prg" = swupdate ]; then echo . | /client/sbin/SWrelease echo cd bin chmod 755 * exit fi echo . | /client/sbin/SWdeinstall -c /sw/clients/$arch 2>/dev/null rm Links 2>/dev/null /client/sbin/SWlink -c /sw/clients/$arch /client/sbin/SWmklinks -c /sw/clients/$arch /client/sbin/SWmkreadme head -5 README >qq mv qq README cat <>README Source: ftp.rus.uni-stuttgart.de:/pub/unix/comm/misc/sendfile.tar.gz Kurzbeschreibung: asynchroner File und Message Transfer Short-Description: asynchronous file and message transfer Provider: rus.uni-stuttgart.de Compiled-By: Ulli Horlacher (framstag@rus.uni-stuttgart.de) Support: framstag@rus.uni-stuttgart.de Documentation: man-pages, /client/doc/sendfile-2.1 Copyright: GPL Status: available User-Interface: Text EOD echo . | /client/sbin/SWrelease echo . | /client/sbin/SWinstall -c /sw/clients/$arch echo cd bin chmod 755 * sendfile-2.1b/makeconfig0000755000175100001440000001355510441555533015102 0ustar framstagusers#!/bin/sh # Here are the default settings for compiling sendfile. # # You can change them by editing this file or put your variables in one of # these files: # $SF_DEVELENV # .develenv # $HOME/.develenv # or simply call: makeconfig CC=gcc ... # default compiling settings CC=gcc CFLAGS=-O2 LDFLAGS=-s # default installation settings SPOOL=/var/spool/sendfile BINDIR=/usr/local/bin MANDIR=/usr/local/man CONFIG=/usr/local/etc SERVERDIR=/usr/local/sbin INETDCONF=/etc/inetd.conf # xinetd will be automaticly recognized SERVICES=/etc/services ############################# OPTIONAL SETTINGS ############################## # Normaly these programs will be called via $PATH, so define them ONLY, if you # really need absolute paths. #TAR=/usr/bin/tar #GZIP=/usr/bin/gzip #BZIP2=/usr/local/bin/bzip2 #PGP=/usr/local/bin/pgp #RECODE=/usr/local/bin/recode #METAMAIL=/usr/local/bin/metamail #SENDMAIL=/usr/lib/sendmail ######################### END OF USER CONFIGURATION ########################## export CC CFLAGS LINK LDFLAGS BINDIR SERVERDIR MANDIR CONFIG SPOOL FIFODIR export INETDCONF SERVICES VERSION export TAR GZIP BZIP2 PGP RECODE METAMAIL SENDMAIL topmake() { sed "s/!SYSTEM/$SYSTEM/g s/!VERSION/$VERSION/g " develop/makefile.top > Makefile } # determine sendfile version and revision eval `grep VERSION= develop/configure.in` # only create new toplevel Makefile? if [ "$1" = clean ]; then topmake exit fi # source in developer environment variables if found if [ -f "$SF_DEVELENV" ]; then . $SF_DEVELENV elif [ -f .develenv ]; then . .develenv elif [ -f $HOME/.develenv ]; then . $HOME/.develenv fi # check at last if there are env-settings in $* case "$1" in *=*) eval "$@";; esac LINK=${LINK:-$CC} cd develop rm -f config.cache ./configure \ --libexecdir=$SERVERDIR \ --bindir=$BINDIR \ --mandir=$MANDIR \ --sysconfdir=$CONFIG \ || exit $? if [ -d /var/run ]; then FIFODIR=/var/run/sfm; fi SYSTEM=`./config.guess` case "$SYSTEM" in *linux*) SYSTEM=LINUX;; *sunos4*) SYSTEM=SOLARIS1 if [ -f /lib/lib44bsd.a -o -f /usr/lib/lib44bsd.a ]; then LIBS="-l44bsd" fi;; *solaris2*) SYSTEM=SOLARIS2;; *hp-ux*) SYSTEM=HPUX;; *aix*) SYSTEM=AIX;; *irix*) SYSTEM=IRIX;; *next*) SYSTEM=NEXT;; *convex*) SYSTEM=CONVEXOS;; *osf*) SYSTEM=OSF1;; *bsd*) SYSTEM=BSD;; *darwin*) SYSTEM=DARWIN;; *) SYSTEM=UNKNOWN;; # *) SYSTEM=`uname -a | tr '[a-z]' '[A-Z]'` # case "$SYSTEM" in # *SUNOS*) case `echo $SYSTEM | $AWK '{print $3}'` in # 4*) SYSTEM=SOLARIS1;; # esac;; # *) SYSTEM=UNKNOWN;; # esac;; esac cd ../src echo now in `pwd` for i in nsl socket readline; do if grep -i "have_lib$i 1" config.h >/dev/null; then LIBS="$LIBS -l$i"; fi done case "$LIBS" in *readline*) LIBS="$LIBS -L/usr/lib/termcap -ltermcap";; esac echo creating globals.h cat <globals.h /* * Do not edit this file! * It is autogenerated by "makeconfig" and will be overwritten next time! * If you want to change some values, so do it in "makeconfig". */ #define BINDIR "$BINDIR" #define MANDIR "$MANDIR" #define SERVERDIR "$SERVERDIR" #define CONFIG "$CONFIG/sendfile.cf" #define ALIASES "$CONFIG/sendfile.aliases" #define ALLOW "$CONFIG/sendfile.allow" #define DENY "$CONFIG/sendfile.deny" #define SPOOL "$SPOOL" #define OUTGOING "$SPOOL/OUTGOING" #define INLOG "$SPOOL/LOG/in" #define OUTLOG "$SPOOL/LOG/out" #define RECEIVE "$BINDIR/receive" #define TAR "${TAR:-tar}" #define GZIP "${GZIP:-gzip}" #define BZIP2 "${BZIP2:-bzip2}" #define PGP "${PGP:-pgp}" #define RECODE "${RECODE:-recode}" #define METAMAIL "${METAMAIL:-metamail}" #define SENDMAIL "${SENDMAIL:-/usr/lib/sendmail}" #define FIFODIR "${FIFODIR:-/tmp/sfm}" #define DBF "/var/log/sendfiled.dbg" #define DATEFORMAT "%Y-%m-%d %H:%M:%S" /* see strftime(3) */ #define CHARSET "ISO_8859-1:1987" /* this is ISO Latin 1 */ #define PROTOCOL "SAFT" #define SAFT 487 /* SAFT tcp port */ #define DAYSEC 86400 /* seconds per day */ #define OVERSIZE 32768 /* string oversize length */ #define MAXLEN 4096 /* max length of various strings */ #define FLEN 256 /* file name length */ #define DLEN 30 /* date string length */ #define PACKET 512 /* data size per packet */ #undef DEBUG /* more debugging output */ #undef ALT_MESSAGES /* alternative user message format */ #undef RESPECT_MAIL_ALIASES /* look for elm aliases, too */ #undef ENABLE_MULTIPROTOCOL /* ipv6 support for Linux */ #ifdef ENABLE_MULTIPROTOCOL #define SERVICE "saft" /* service entry for saft */ #define PORT_STRING "487" /* SAFT tcp port in ASCII text */ #endif EOD cat <>config.h #define SYSTEM "$SYSTEM" #ifdef NEXT #define _POSIX_SOURCE #define S_IRUSR _S_IRUSR #define S_IWUSR _S_IWUSR #define S_IWGRP 0000020 #define S_IXUSR _S_IXUSR #define S_IRWXG 0000070 #define S_IRWXO 0000007 #define S_IRWXU 0000700 #define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) #define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) #endif #if defined(SOLARIS2) #define __EXTENSIONS__ #endif #if defined(LINUX) || defined(BSD) #ifndef HAVE_STRERROR #define HAVE_STRERROR #endif #ifndef _POSIX_SOURCE #define _POSIX_SOURCE #endif #ifndef __USE_BSD #define __USE_BSD #endif #endif #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif /* from /usr/include/features.h */ #ifndef _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #endif EOD case $CC in gcc*) CFLAGS="$CFLAGS -Wall" esac #case `uname -a 2>/dev/null` in # *\ moep\ *|*\ juhu\ *) CFLAGS="-Wall -ansi -pedantic -DBETA";; # *\ bofh.*) CFLAGS="-Wall -ansi -pedantic -O2 -DBETA";; #esac echo creating Makefile sed "s^!CC^$CC^g s^!CFLAGS^$CFLAGS^g s^!SYSTEM^$SYSTEM^g s^!LINK^$LINK^g s^!LDFLAGS^$LDFLAGS^g s^!LIBS^$LIBS^g " ../develop/makefile.src > Makefile cd .. topmake sendfile-2.1b/README0000777000175100001440000000000011025466700015336 2doc/READMEustar framstaguserssendfile-2.1b/develop/0000755000175100001440000000000011025466700014472 5ustar framstaguserssendfile-2.1b/develop/stamp-h.in0000644000175100001440000000001210251132201016346 0ustar framstaguserstimestamp sendfile-2.1b/develop/FILES0000644000175100001440000000432510504206652015262 0ustar framstagusers./COPYING ./LIESMICH ./Makefile ./README ./makeconfig ./develop/FILES ./develop/Makefile.am ./develop/Makefile.in ./develop/aclocal.m4 ./develop/config.guess ./develop/config.status ./develop/config.sub ./develop/configure ./develop/configure.in ./develop/install ./develop/userinstall ./develop/install-sh ./develop/makefile.src ./develop/makefile.top ./develop/mkinstalldirs ./develop/stamp-h.in ./doc/AUTHORS ./doc/COPYING ./doc/ChangeLog ./doc/LIESMICH ./doc/LIESMICH.auch ./doc/LIESMICH.entwickler ./doc/LIESMICH.fetchfile ./doc/LIESMICH.neu ./doc/LIESMICH.ups ./doc/LIESMICH.spool ./doc/Makefile ./doc/Makefile.am ./doc/Makefile.in ./doc/NEWS ./doc/README ./doc/README.too ./doc/README.fetchfile ./doc/THANKS ./doc/doc.txt ./doc/doku.txt ./doc/features ./doc/vorteile ./doc/install-with-configure.old ./doc/receive.1 ./doc/sendfile.1 ./doc/sendmsg.1 ./doc/wlock.1 ./doc/utf7encode.1 ./doc/sendfiled.8 ./doc/fetchfile.1 ./doc/fetchfile.7 ./etc/check_sendfile ./etc/sendfile.deny ./etc/sendfile.cf ./etc/sfconf ./etc/sfdconf ./etc/sf_cleanup ./etc/sf_install ./etc/sf_swinstall ./etc/xinetd ./src/Makefile ./src/Makefile.am ./src/Makefile.in ./src/acconfig.h ./src/address.c ./src/address.h ./src/bsd.h ./src/config.h.in ./src/getdate.c ./src/io.c ./src/io.h ./src/message.c ./src/message.h ./src/net.c ./src/net.h ./src/peername.c ./src/peername.h ./src/pstring.c ./src/pstring.h ./src/receive.c ./src/reply.c ./src/reply.h ./src/fetchfile.c ./src/sendfile.c ./src/sendfiled.c ./src/sendmsg.c ./src/snprintf.c ./src/snprintf.h ./src/spool.c ./src/spool.h ./src/string.c ./src/string.h ./src/utf7.c ./src/utf7.h ./src/utf7encode.c ./src/getline.c ./src/getline.h ./src/wlock.c ./src/lock.c ./src/lock.h ./src/pussy ./contrib/java/SaftVersion.class ./contrib/java/SaftVersion.java ./contrib/perl/Utf7.pm ./contrib/perl/distr.pl ./contrib/perl/distrX.pl ./contrib/perl/perlmodule_unicode_utf7.tar.gz ./contrib/perl/psendmsg.pl ./contrib/moep ./contrib/xhoppel/Mailbox.c ./contrib/xhoppel/Mailbox.h ./contrib/xhoppel/MailboxP.h ./contrib/xhoppel/Makefile ./contrib/xhoppel/README ./contrib/xhoppel/hoppelda.gif ./contrib/xhoppel/hoppelda.xbm ./contrib/xhoppel/nohoppel.gif ./contrib/xhoppel/nohoppel.xbm ./contrib/xhoppel/xbiff.man ./contrib/xhoppel/xhoppel.c sendfile-2.1b/develop/Makefile.am0000644000175100001440000000046510251132201016515 0ustar framstagusers## Process this file with automake to generate Makefile.in AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 SUBDIRS = src doc EXTRA_DIST = sendfile.cf nosendfile sf_cleanup check_sendfile \ HISTORY stamp-h.in build sysconf_DATA = sendfile.cf nosendfile bin_SCRIPTS = sf_cleanup check_sendfile sendfile-2.1b/develop/install0000755000175100001440000002731310251132201016056 0ustar framstagusers#!/bin/sh # # File: install # # Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) # # Contribs: Stefan Zehl (sec@42.org) # Michael Neumayer (eumel@42.org) # # History: # # 1995-09-18 Framstag initial version (insserv) # 1995-10-24 Framstag changed SAFT-port # 1995-11-25 Framstag new version: install # 1995-12-18 Framstag better error checking # 1995-12-21 Framstag new default for nosendfile: # /usr/local/etc/ # 1996-03-24 Framstag added utf7encode binary # 1996-04-04 Framstag better HP-UX support # 1996-06-23 Framstag added INLOG and OUTLOG # 1996-09-13 Framstag added $BINDIR to check_sendfile # better /etc/inetd.conf parsing # 1997-02-24 Framstag fixed MANDIR # 1997-03-20 Framstag added Amiga support # 1997-06-18 Framstag added check for new sendfile.cf # 1997-09-30 Framstag better (own) spool free-space check # 1997-11-22 Framstag added sfconf # 1997-11-23 Framstag moved NOSENDFILE to ALLOW and DENY files # added sfdconf # 1998-01-05 Framstag better sfdconf installation # 1998-02-27 sec added reinstall option # 1998-03-01 sec fixed "text file busy" # 1998-03-06 Framstag better man sections locations # 1998-03-13 Eumel fixed rm-logfile-bug # 1998-04-17 sec better man-section detection # 1998-09-29 Framstag added ewl # 1999-01-28 Framstag added symlinks: sf sm rf # 2005-05-30 Framstag added xinetd detection # # Shell script to install the server, the clients and the man-pages for the # sendfile service. It also configures /etc/inetd.conf, /etc/xinetd.d/sendfile, # /etc/services, /etc/profile and /etc/csh.login # This script is called by make. # # If you want to change the default directories look in file build. # You should not edit this file! # # This file is covered by the GNU General Public License mkdir_recursive() { if [ ! -d $1 ]; then mkdir `echo $1 | awk -F/ '{ for (i=2; $i!=""; i++) { for (j=2; j<=i; j++) printf("/"$j) printf(" ") } }' ` 2>/dev/null fi } make_dirs() { mkdir_recursive $BINDIR mkdir_recursive $MANDIR/man1 mkdir_recursive $SERVERDIR mkdir_recursive `dirname $DENY` mkdir_recursive `dirname $CONFIG` mkdir $MANDIR/man$manmisc $MANDIR/man$manadmin 2>/dev/null } make_man() { sed "s:/usr/local/etc/sendfile.allow:$ALLOW: s:/usr/local/etc/sendfile.deny:$DENY: s:/usr/local/etc/sendfile.cf:$CONFIG: s:/var/spool/sendfile:$SPOOL: " doc/$1.$2 >$MANDIR/man$3/$1.$3 } install_man() { make_man sendfile 1 1 make_man sendmsg 1 1 make_man receive 1 1 make_man fetchfile 1 1 make_man fetchfile 7 $manmisc make_man sendfiled 8 $manadmin cp doc/wlock.1 doc/utf7encode.1 $MANDIR/man1 (cd $MANDIR/man1; ln -s utf7encode.1 utf7decode.1 2>/dev/null) } SYSTEM=$1 RESTART=false if [ "$SYSTEM" = "" ]; then echo "To invoke install, type: make install" exit fi if [ "$LOGNAME" != root ]; then if [ "`whoami`" != root ]; then echo echo "You are not root! You probably run into problems now..." echo fi fi eval `awk -F\" '/define BINDIR/ {print "BINDIR="$2} /define MANDIR/ {print "MANDIR="$2} /define SERVERDIR/ {print "SERVERDIR="$2} /define SPOOL/ {print "SPOOL="$2} /define CONFIG/ {print "CONFIG="$2} /define DENY/ {print "DENY="$2} /define ALLOW/ {print "ALLOW="$2} /define ALIASES/ {print "ALIASES="$2} /define INLOG/ {print "INLOG="$2} /define OUTLOG/ {print "OUTLOG="$2} ' src/globals.h` if [ "$BINDIR" = "" ]; then BINDIR=/usr/local/bin; fi if [ "$MANDIR" = "" ]; then MANDIR=/usr/local/man; fi if [ "$SERVERDIR" = "" ]; then SERVERDIR=/usr/local/sbin; fi if [ "$CONFIG" = "" ]; then CONFIG=/usr/local/etc/sendfile.cf; fi if [ "$DENY" = "" ]; then DENY=/usr/local/etc/sendfile.deny; fi if [ "$ALLOW" = "" ]; then ALLOW=/usr/local/etc/sendfile.allow; fi if [ "$ALIASES" = "" ]; then ALIASES=/usr/local/etc/sendfile.aliases; fi if [ "$SPOOL" = "" ]; then SPOOL=/var/spool/sendfile; fi if [ "$INLOG" = "" ]; then INLOG=$SPOOL/LOG/in; fi if [ "$OUTLOG" = "" ]; then OUTLOG=$SPOOL/LOG/out; fi if [ "$INETDCONF" = "" ]; then INETDCONF=/etc/inetd.conf; fi if [ "$SERVICES" = "" ]; then SERVICES=/etc/services; fi if [ -f /etc/xinetd.conf -a -d /etc/xinetd.d ]; then INETDCONF=/etc/xinetd.d/sendfile fi case "$SYSTEM" in *BSD*) manmisc=7; manadmin=8;; *) manmisc=5; manadmin=1m;; esac # purge old logfiles (bug from sendfile revision < 19980310) rm -f $SPOOL*/.sendfile*.log if [ "$2" = "reinstall" ] ; then umask 022 cd src || exit 1 make_dirs cp sendfile sendmsg receive utf7encode fetchfile wlock $BINDIR/ [ -x $SERVERDIR/sendfiled ] && mv $SERVERDIR/sendfiled $SERVERDIR/sendfiled.old && rm -f $SERVERDIR/sendfiled.old cp sendfiled $SERVERDIR cd ../etc cp sfconf sfdconf $BINDIR/ cd .. install_man echo Done. exit 0 fi cat < $BINDIR/sf_cleanup sed "s:SPOOL=/var/spool/sendfile:SPOOL=$SPOOL: s:INLOG=/var/spool/sendfile/LOG/in:INLOG=$INLOG: s:OUTLOG=/var/spool/sendfile/LOG/in:OUTLOG=$OUTLOG: s:CONFIG=/usr/local/etc/sendfile.cf:CONFIG=$CONFIG: s:ALIASES=/usr/local/etc/sendfile.aliases:ALIASES=$ALIASES: s:DENY=/usr/local/etc/sendfile.deny:DENY=$DENY: s:ALLOW=/usr/local/etc/sendfile.allow:ALLOW=$ALLOW: " sfdconf \ | awk '{if ($0 != "CONFIG") print $0; else system("cat sendfile.cf")}' \ > $BINDIR/sfdconf sed "s:/var/spool/sendfile:$SPOOL:" sfconf >$BINDIR/sfconf sed "s:receive :$BINDIR/receive :" check_sendfile >$BINDIR/check_sendfile cd ../src || exit 1 cp sendfile sendmsg receive utf7encode fetchfile wlock $BINDIR/ cd .. (cd $BINDIR ln -s utf7encode utf7decode 2>/dev/null ln -s sendfile sf 2>/dev/null ln -s sendmsg sm 2>/dev/null ln -s receive rf 2>/dev/null chmod 755 sfconf sfdconf /dev/null`/nosendfile if [ -f $NOSENDFILE ]; then if grep ^allow-only $NOSENDFILE >/dev/null; then echo "Information: $NOSENDFILE is now $ALLOW (autoconverted)" grep -v ^allow-only $NOSENDFILE > $ALLOW else echo "Information: $NOSENDFILE is now $DENY (autoconverted)" mv $NOSENDFILE $DENY fi fi if [ ! -f $DENY -a ! -f $ALLOW ]; then echo "installing the sendfile deny file as $DENY" cp etc/sendfile.deny $DENY chmod 644 $DENY fi if [ ! -f $CONFIG ]; then echo "installing the global sendfile config file as $CONFIG" cp etc/sendfile.cf $CONFIG chmod 644 $CONFIG else if [ "`diff etc/sendfile.cf $CONFIG`" ]; then echo "Warning: `pwd`/etc/sendfile.cf differs from $CONFIG !" echo "Please take a look what has been changed!" fi fi if [ "$SYSTEM" = NEXT ]; then SERVICE="`nidump services . | awk '/[ \t]487\/tcp/'`" else SERVICE="`awk '/[ \t]487\/tcp/' /etc/services`" fi if [ "$SERVICE" != "" ]; then case "$SERVICE" in saft*) ;; *) echo "ERROR: tcp-port 487 is already in use!"; exit 1;; esac else if [ "$SYSTEM" = NEXT ]; then echo "configuring services" echo "saft 487/tcp # simple asynchronous file transfer" | niload services . else echo "configuring $SERVICES" echo "#" >>$SERVICES echo "saft 487/tcp # simple asynchronous file transfer" >>$SERVICES fi fi case "$INETDCONF" in *xinetd*) if [ -f $INETDCONF ]; then echo $INETDCONF does already exist -skipping else echo installing $INETDCONF sed "s:/usr/local/sbin/sendfiled:$SERVERDIR/sendfiled:" etc/xinetd >$INETDCONF RESTART=true fi SENDFILED=`awk '/[ \t]*server[ \t]*=/ { print $3 }' $INETDCONF` ;; *) SENDFILED=`awk '/^saft/ { sfd=$6; if (index($7,"/sendfiled")>0) sfd=$7; if (substr(sfd,1,1)=="?") sfd=substr(sfd,2); print sfd; }' $INETDCONF` if [ "$SENDFILED" = "" ]; then if [ -f /usr/sbin/tcpd ]; then SFD="/usr/sbin/tcpd $SERVERDIR/sendfiled" else SFD="$SERVERDIR/sendfiled sendfiled" fi RESTART=true echo "configuring $INETDCONF" echo "#" >>$INETDCONF echo "# simple asynchronous file transfer" >>$INETDCONF echo "saft stream tcp nowait root $SFD" >>$INETDCONF fi ;; esac if [ "$SENDFILED" != "$SERVERDIR/sendfiled" -a "$SENDFILED" != "" ]; then echo "WARNING: you have specified $SENDFILED in $INETDCONF, but" echo " there is $SERVERDIR/sendfiled in makeconfig! Check it!" fi if [ -f /etc/inetd.sec ]; then if [ "`grep '^saft' /etc/inetd.sec`" = "" ]; then echo >> /etc/inetd.sec echo "saft allow" >> /etc/inetd.sec fi fi if [ -f /etc/profile ]; then if [ "`grep check_sendfile /etc/profile`" = "" ]; then echo "adding check_sendfile to /etc/profile" echo >>/etc/profile echo "test -x $BINDIR/check_sendfile && $BINDIR/check_sendfile"\ >>/etc/profile fi fi if [ -f /etc/csh.login ]; then if [ "`grep check_sendfile /etc/csh.login`" = "" ]; then echo "adding check_sendfile to /etc/csh.login" echo >>/etc/csh.login echo "test -x $BINDIR/check_sendfile && $BINDIR/check_sendfile" \ >>/etc/csh.login fi fi if [ ! -d "$SPOOL/OUTGOING" ]; then echo "creating $SPOOL" mkdir_recursive $SPOOL/OUTGOING chmod 755 $SPOOL || exit 1 chmod 1777 $SPOOL/OUTGOING fi if [ ! -d `dirname "$INLOG"` ]; then mkdir_recursive `dirname $INLOG` chmod 700 `dirname $INLOG` fi if [ ! -d `dirname "$OUTLOG"` ]; then mkdir_recursive `dirname $OUTLOG` chmod 700 `dirname $OUTLOG` fi if [ ! -f "$INLOG" ]; then echo "# use \"utf7decode $INLOG\" to view this file" > $INLOG echo >> $INLOG chmod 600 $INLOG fi if [ ! -f "$OUTLOG" ]; then echo "# use \"utf7decode $OUTLOG\" to view this file" > $OUTLOG echo >> $OUTLOG chmod 600 $OUTLOG fi free=`$SERVERDIR/sendfiled -f` minfree=`awk '/minfree =/{print $3}' $CONFIG` if [ "$free" -le "$minfree" ]; then cat </dev/null; then /etc/init.d/xinetd reload else /etc/init.d/xinetd stop /etc/init.d/xinetd start fi else echo echo "please restart now your inetd ( or simply reboot :-) )" echo fi fi sendfile-2.1b/develop/config.sub0000755000175100001440000007550010251132201016446 0ustar framstagusers#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-05-12' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | msp430 \ | ns16k | ns32k \ | openrisc | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; or32 | or32-*) basic_machine=or32-unknown os=-coff ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sh64) basic_machine=sh64-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* | -skyos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: sendfile-2.1b/develop/config.status0000755000175100001440000005166111025466146017224 0ustar framstagusers#! /bin/bash # Generated by configure. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=${CONFIG_SHELL-/bin/bash} ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " # Files that config.status was made for. config_headers=" ../src/config.h" config_commands=" default-1" ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." ac_cs_version="\ config.status configured by ./configure, generated by GNU Autoconf 2.61, with options \"'--libexecdir=/usr/local/sbin' '--bindir=/usr/local/bin' '--mandir=/usr/local/man' '--sysconfdir=/usr/local/etc' 'CC=gcc' 'CFLAGS=-O2' 'LDFLAGS=-s'\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='/home/framstag/sendfile/sendfile-2.1b/develop' srcdir='.' # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi if $ac_cs_recheck; then echo "running CONFIG_SHELL=/bin/bash /bin/bash ./configure " '--libexecdir=/usr/local/sbin' '--bindir=/usr/local/bin' '--mandir=/usr/local/man' '--sysconfdir=/usr/local/etc' 'CC=gcc' 'CFLAGS=-O2' 'LDFLAGS=-s' $ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=/bin/bash export CONFIG_SHELL exec /bin/bash "./configure" '--libexecdir=/usr/local/sbin' '--bindir=/usr/local/bin' '--mandir=/usr/local/man' '--sysconfdir=/usr/local/etc' 'CC=gcc' 'CFLAGS=-O2' 'LDFLAGS=-s' $ac_configure_extra_args --no-create --no-recursion fi exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 # # INIT-COMMANDS # # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "../src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS ../src/config.h" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } for ac_tag in :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :H) # # CONFIG_HEADER # # First, check the format of the line: cat >"$tmp/defines.sed" <<\CEOF /^[ ]*#[ ]*undef[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[ ]*$/b def /^[ ]*#[ ]*define[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[( ]/b def b :def s/$/ / s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_NAME\)[ (].*,\1define\2 "" , s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_TARNAME\)[ (].*,\1define\2 "" , s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_VERSION\)[ (].*,\1define\2 "" , s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_STRING\)[ (].*,\1define\2 "" , s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_BUGREPORT\)[ (].*,\1define\2 "" , s,^\([ #]*\)[^ ]*\([ ]*PACKAGE\)[ (].*,\1define\2 "sendfile" , s,^\([ #]*\)[^ ]*\([ ]*VERSION\)[ (].*,\1define\2 "2.1b" , s,^\([ #]*\)[^ ]*\([ ]*REVISION\)[ (].*,\1define\2 "20080616" , s,^\([ #]*\)[^ ]*\([ ]*HAVE_DIRENT_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*STDC_HEADERS\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_WAIT_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_TYPES_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_STAT_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMORY_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRINGS_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_INTTYPES_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDINT_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDDEF_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDARG_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_GETOPT_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_FCNTL_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_PATHS_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_TIME_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_STATVFS_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_LIBNSL\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_LIBREADLINE\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRUCT_STAT_ST_BLKSIZE\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_ST_BLKSIZE\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*TIME_WITH_SYS_TIME\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_ALLOCA_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_ALLOCA\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*RETSIGTYPE\)[ (].*,\1define\2 void , s,^\([ #]*\)[^ ]*\([ ]*HAVE_UTIME_H\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_UTIME_NULL\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_GETHOSTNAME\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_GETTIMEOFDAY\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_MKDIR\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SOCKET\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNAME\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRERROR\)[ (].*,\1define\2 1 , s,^\([ #]*\)[^ ]*\([ ]*HAVE_SNPRINTF\)[ (].*,\1define\2 1 , s/ $// s,^[ #]*u.*,/* & */, CEOF sed -f "$tmp/defines.sed" $ac_file_inputs >"$tmp/out1" ac_result="$tmp/out1" if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "default-1":C) test -z "$CONFIG_HEADER" || echo timestamp > ../src/stamp-h ;; esac done # for ac_tag { (exit 0); exit 0; } sendfile-2.1b/develop/mkinstalldirs0000744000175100001440000000133210251132201017257 0ustar framstagusers#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$? fi if test ! -d "$pathcomp"; then errstatus=$lasterr fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here sendfile-2.1b/develop/makefile.top0000644000175100001440000000276110251326114016773 0ustar framstagusers# Do not edit this file! # It is autogenerated by "makeconfig" and will be overwritten next time! # If you want to change some values, so do it in "makeconfig". PROJECT=sendfile-!VERSION all: develop/config.log . cd src; make install: develop/config.log . sh develop/install !SYSTEM userinstall: develop/config.log . sh develop/userinstall reinstall: develop/config.log . sh develop/install !SYSTEM reinstall config: ./makeconfig develop/config.log: makeconfig ./makeconfig clean: rm -f *~ */*~ sendfile-*tar.gz ./makeconfig clean cd contrib/xhoppel && make clean cd develop && rm -rf config.cache config.log autom4te.cache cd src && make clean && rm -f config.h globals.h wc: @cd src; wc -cl \ sendfile.c sendfiled.c sendmsg.c receive.c utf7encode.c fetchfile.c \ string.[ch] utf7.[ch] pstring.[ch] message.[ch] peername.[ch] \ io.[ch] net.[ch] address.[ch] spool.[ch] reply.[ch] getline.[ch] \ lock.[ch] wlock.c bsd.h pussy \ ../develop/install ../develop/makefile* ../makeconfig \ ../etc/check_sendfile ../etc/xinetd \ ../etc/sf_cleanup ../etc/sfconf ../etc/sfdconf ../etc/sendfile.cf dist: clean @mkdir $(PROJECT) @tar cf - `cat develop/FILES` | (cd $(PROJECT); tar xf - ) tar cvf - $(PROJECT) | gzip > $(PROJECT).tar.gz @rm -rf $(PROJECT) @ls -l $(PROJECT).tar.gz floppy: clean cd ..; tar cvzf /dev/fd0 $(PROJECT) @cd ..; tar czf /tmp/sf.tgz $(PROJECT) @echo "insert a new disk and press enter"; read dummy mformat a:; mcopy /tmp/sf.tgz a:; rm -f /tmp/sf.tgz sendfile-2.1b/develop/makefile.src0000644000175100001440000000575110251132201016752 0ustar framstagusers# Do not edit this file! # It is autogenerated by "makeconfig" and will be overwritten next time! # If you want to change some values, so do it in "makeconfig". CC=!CC CFLAGS=!CFLAGS -D!SYSTEM LINK=!LINK LDFLAGS=!LDFLAGS LIBS=!LIBS PROJECT= sendfile sendmsg receive sendfiled utf7encode fetchfile wlock SENDFILE_OBJ= sendfile.o message.o utf7.o pstring.o string.o io.o net.o \ address.o spool.o FETCHFILE_OBJ= fetchfile.o message.o utf7.o pstring.o string.o io.o net.o \ address.o spool.o getline.o SENDMSG_OBJ= sendmsg.o message.o utf7.o pstring.o string.o io.o net.o \ address.o getline.o RECEIVE_OBJ= receive.o message.o utf7.o pstring.o string.o io.o spool.o \ getdate.o getline.o lock.o SENDFILED_OBJ= sendfiled.o message.o utf7.o pstring.o string.o io.o net.o \ spool.o peername.o reply.o address.o lock.o UTF7ENCODE_OBJ= utf7encode.o message.o utf7.o pstring.o string.o io.o all: $(PROJECT) @ls -l $(PROJECT) @echo @echo "and now type (as root): make install" @echo install: sendfile sendmsg receive sendfiled fetchfile utf7encode @cd ..;sh install !SYSTEM sendfile: $(SENDFILE_OBJ) $(LINK) $(LDFLAGS) $(SENDFILE_OBJ) -o sendfile $(LIBS) fetchfile: $(FETCHFILE_OBJ) $(LINK) $(LDFLAGS) $(FETCHFILE_OBJ) -o fetchfile $(LIBS) sendmsg: $(SENDMSG_OBJ) $(LINK) $(LDFLAGS) $(SENDMSG_OBJ) -o sendmsg $(LIBS) receive: $(RECEIVE_OBJ) $(LINK) $(LDFLAGS) $(RECEIVE_OBJ) -o receive $(LIBS) sendfiled: $(SENDFILED_OBJ) $(LINK) $(LDFLAGS) $(SENDFILED_OBJ) -o sendfiled $(LIBS) utf7encode: $(UTF7ENCODE_OBJ) $(LINK) $(LDFLAGS) $(UTF7ENCODE_OBJ) -o utf7encode $(LIBS) @rm -f utf7decode ln -s utf7encode utf7decode wlock: wlock.o string.o $(LINK) $(LDFLAGS) wlock.o string.o -o wlock clean: rm -rf core *.o *~ a.out .deps \ sendfile sendfiled sendmsg receive fetchfile utf7??code wlock trimeol: perl -pi -e 's/[ \t]+$//' *.c *.h .c.o: $(CC) $(CFLAGS) -c $< sendfile.o: sendfile.c config.h globals.h utf7.h string.h io.h address.h fetchfile.o: fetchfile.c config.h globals.h utf7.h string.h io.h sendmsg.o: sendmsg.c config.h globals.h utf7.h string.h address.h receive.o: receive.c config.h globals.h utf7.h spool.h string.h io.h sendfiled.o: sendfiled.c reply.h config.h globals.h utf7.h spool.h string.h spoolid.o: spoolid.c config.h globals.h message.o: message.c message.h config.h globals.h utf7.o: utf7.c utf7.h config.h globals.h string.h base64.o: base64.c base64.h config.h globals.h pstring.o: pstring.c pstring.h config.h globals.h peername.o: peername.c peername.h string.h config.h globals.h net.o: net.c net.h io.h config.h globals.h io.o: io.c io.h config.h globals.h string.o: string.c string.h config.h globals.h address.o: address.c address.h config.h globals.h string.h spool.o: spool.c spool.h config.h globals.h string.h reply.o: reply.c reply.h config.h globals.h net.h getdate.o: getdate.c config.h getline.o: getline.c config.h lock.o: lock.c lock.h utf7encode.o: utf7encode.c config.h globals.h utf7.h sendfile-2.1b/develop/configure0000755000175100001440000053217711025463615016422 0ustar framstagusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="../src/sendfile.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_list= ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias PACKAGE VERSION REVISION build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LN_S SET_MAKE CPP GREP EGREP ALLOCA LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi ac_header_list="$ac_header_list utime.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers ../src/config.h" ac_config_commands="$ac_config_commands default-1" PACKAGE=sendfile cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF VERSION=2.1b cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF REVISION=20080616 cat >>confdefs.h <<_ACEOF #define REVISION "$REVISION" _ACEOF ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6; } if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6; } if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { echo "$as_me:$LINENO: checking target system type" >&5 echo $ECHO_N "checking target system type... $ECHO_C" >&6; } if test "${ac_cv_target+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { echo "$as_me:$LINENO: result: $ac_cv_target" >&5 echo "${ECHO_T}$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 echo "$as_me: error: invalid value of canonical target" >&2;} { (exit 1); exit 1; }; };; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking whether ln -s works" >&5 echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 echo "${ECHO_T}no, using $LN_S" >&6; } fi { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi { echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdlib.h stddef.h unistd.h stdarg.h getopt.h string.h fcntl.h paths.h sys/time.h sys/statvfs.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_socket_socket=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_socket=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6; } if test $ac_cv_lib_socket_socket = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; } if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_nsl_gethostbyname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; } if test $ac_cv_lib_nsl_gethostbyname = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi { echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline -ltermcap -L/usr/lib/termcap $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_readline_readline=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6; } if test $ac_cv_lib_readline_readline = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" fi { echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi { echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } if test "${ac_cv_type_uid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then cat >>confdefs.h <<\_ACEOF #define uid_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define gid_t int _ACEOF fi { echo "$as_me:$LINENO: checking for mode_t" >&5 echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; } if test "${ac_cv_type_mode_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef mode_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_mode_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_mode_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 echo "${ECHO_T}$ac_cv_type_mode_t" >&6; } if test $ac_cv_type_mode_t = yes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi { echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef pid_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi { echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6; } if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5 echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6; } if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static struct stat ac_aggr; if (ac_aggr.st_blksize) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_stat_st_blksize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static struct stat ac_aggr; if (sizeof ac_aggr.st_blksize) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_member_struct_stat_st_blksize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_stat_st_blksize=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5 echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6; } if test $ac_cv_member_struct_stat_st_blksize = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_ST_BLKSIZE 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6; } if test "${ac_cv_struct_tm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 echo "${ECHO_T}$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then cat >>confdefs.h <<\_ACEOF #define TM_IN_SYS_TIME 1 _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { echo "$as_me:$LINENO: checking for working alloca.h" >&5 echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; } if test "${ac_cv_working_alloca_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 echo "${ECHO_T}$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi { echo "$as_me:$LINENO: checking for alloca" >&5 echo $ECHO_N "checking for alloca... $ECHO_C" >&6; } if test "${ac_cv_func_alloca_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 echo "${ECHO_T}$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF { echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; } if test "${ac_cv_os_cray+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 echo "${ECHO_T}$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; } if test "${ac_cv_c_stack_direction+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int find_stack_direction () { static char *addr = 0; auto char dummy; if (addr == 0) { addr = &dummy; return find_stack_direction (); } else return (&dummy > addr) ? 1 : -1; } int main () { return find_stack_direction () < 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 echo "${ECHO_T}$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi { echo "$as_me:$LINENO: checking return type of signal handlers" >&5 echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } if test "${ac_cv_type_signal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_signal=int else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 echo "${ECHO_T}$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_header in $ac_header_list do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking whether utime accepts a null argument" >&5 echo $ECHO_N "checking whether utime accepts a null argument... $ECHO_C" >&6; } if test "${ac_cv_func_utime_null+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else rm -f conftest.data; >conftest.data # Sequent interprets utime(file, 0) to mean use start of epoch. Wrong. if test "$cross_compiling" = yes; then ac_cv_func_utime_null=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_UTIME_H # include #endif int main () { struct stat s, t; return ! (stat ("conftest.data", &s) == 0 && utime ("conftest.data", 0) == 0 && stat ("conftest.data", &t) == 0 && t.st_mtime >= s.st_mtime && t.st_mtime - s.st_mtime < 120); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_utime_null=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_utime_null=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_func_utime_null" >&5 echo "${ECHO_T}$ac_cv_func_utime_null" >&6; } if test $ac_cv_func_utime_null = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UTIME_NULL 1 _ACEOF fi rm -f conftest.data for ac_func in gethostname gettimeofday mkdir socket uname strerror do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in snprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "../src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS ../src/config.h" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } for ac_tag in :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "default-1":C) test -z "$CONFIG_HEADER" || echo timestamp > ../src/stamp-h ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi sendfile-2.1b/develop/configure.in0000644000175100001440000000253711025463607017015 0ustar framstagusersdnl Process this file with autoconf to produce a configure script. AC_INIT(../src/sendfile.c) AM_CONFIG_HEADER(../src/config.h) dnl Set this for automake PACKAGE=sendfile AC_SUBST(PACKAGE) AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") VERSION=2.1b AC_SUBST(VERSION) AC_DEFINE_UNQUOTED(VERSION, "$VERSION") REVISION=20080616 AC_SUBST(REVISION) AC_DEFINE_UNQUOTED(REVISION, "$REVISION") AC_CANONICAL_SYSTEM dnl SYSTEM="$build_alias" dnl AC_SUBST(SYSTEM) dnl AC_DEFINE_UNQUOTED(SYSTEM, "$SYSTEM") dnl Checks for programs. AC_PROG_CC dnl AM_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_ARG_PROGRAM dnl Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(stdlib.h stddef.h unistd.h stdarg.h getopt.h string.h fcntl.h paths.h sys/time.h sys/statvfs.h) dnl Checks for libraries. AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, gethostbyname) AC_CHECK_LIB(readline, readline, , , -ltermcap -L/usr/lib/termcap) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_TYPE_MODE_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_STRUCT_ST_BLKSIZE AC_HEADER_TIME AC_STRUCT_TM dnl Checks for library functions. AC_FUNC_ALLOCA AC_TYPE_SIGNAL AC_FUNC_UTIME_NULL AC_CHECK_FUNCS(gethostname gettimeofday mkdir socket uname strerror) AC_CHECK_FUNCS(snprintf) AC_OUTPUT() dnl AC_OUTPUT([Makefile src/Makefile doc/Makefile]) sendfile-2.1b/develop/Makefile.in0000644000175100001440000002155510251132201016531 0ustar framstagusers# Makefile.in generated automatically by automake 1.1l from Makefile.am # Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ target_alias = @target_alias@ build_alias = @build_alias@ host_triplet = @host@ target_triplet = @target@ build_triplet = @build@ host_alias = @host_alias@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE = @PACKAGE@ SYSTEM = @SYSTEM@ CC = @CC@ VERSION = @VERSION@ REVISION = @REVISION@ AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 SUBDIRS = src doc EXTRA_DIST = sendfile.cf nosendfile sf_cleanup check_sendfile \ HISTORY stamp-h.in build sysconf_DATA = sendfile.cf nosendfile bin_SCRIPTS = sf_cleanup check_sendfile ACLOCAL = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ././src/config.h CONFIG_CLEAN_FILES = SCRIPTS = $(bin_SCRIPTS) DATA = $(sysconf_DATA) DIST_COMMON = README AUTHORS COPYING ChangeLog Makefile.am Makefile.in \ NEWS README THANKS aclocal.m4 config.guess config.sub configure \ configure.in install-sh mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ $(TEXINFOS) $(MANS) $(EXTRA_DIST) TAR = tar default: all .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL) cd $(top_srcdir) && automake --gnits Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(srcdir)/aclocal.m4: configure.in cd $(srcdir) && aclocal config.status: configure $(SHELL) ./config.status --recheck $(srcdir)/configure: configure.in $(ACLOCAL) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && autoconf install-binSCRIPTS: $(bin_SCRIPTS) $(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list="$(bin_SCRIPTS)"; for p in $$list; do \ if test -f $$p; then \ echo "$(INSTALL_SCRIPT) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else if test -f $(srcdir)/$$p; then \ echo "$(INSTALL_SCRIPT) $(srcdir)/$$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $(srcdir)/$$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; fi; \ done uninstall-binSCRIPTS: list="$(bin_SCRIPTS)"; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done install-sysconfDATA: $(sysconf_DATA) $(NORMAL_INSTALL) $(mkinstalldirs) $(sysconfdir) @list="$(sysconf_DATA)"; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ echo "$(INSTALL_DATA) $(srcdir)/$$p $(sysconfdir)/$$p"; \ $(INSTALL_DATA) $(srcdir)/$$p $(sysconfdir)/$$p; \ else if test -f $$p; then \ echo "$(INSTALL_DATA) $$p $(sysconfdir)/$$p"; \ $(INSTALL_DATA) $$p $(sysconfdir)/$$p; \ fi; fi; \ done uninstall-sysconfDATA: list="$(sysconf_DATA)"; for p in $$list; do \ rm -f $(sysconfdir)/$$p; \ done # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive \ mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @for subdir in $(SUBDIRS); do \ target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) \ || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list="$(SUBDIRS)"; for subdir in $$list; do \ (cd $$subdir && $(MAKE) tags); \ done tags: TAGS TAGS: distdir = $(PACKAGE)-$(VERSION) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist rm -rf $(distdir) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) \ && $(MAKE) dvi \ && $(MAKE) check \ && $(MAKE) install \ && $(MAKE) installcheck \ && $(MAKE) dist rm -rf $(distdir) @echo "========================"; \ echo "$(distdir).tar.gz is ready for distribution"; \ echo "========================" dist: distdir -chmod -R a+r $(distdir) $(TAR) chozf $(distdir).tar.gz $(distdir) rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) $(TAR) chozf $(distdir).tar.gz $(distdir) rm -rf $(distdir) distdir: $(DISTFILES) @if sed 15q $(srcdir)/NEWS | fgrep -e "$(VERSION)" > /dev/null; then :; else \ echo "NEWS not updated; not releasing" 1>&2; \ exit 1; \ fi rm -rf $(distdir) mkdir $(distdir) -chmod 755 $(distdir) here=`pwd`; distdir=`cd $(distdir) && pwd` \ && cd $(srcdir) \ && automake --include-deps --build-dir=$$here --srcdir-name=$(srcdir) --output-dir=$$distdir --gnits @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done for subdir in $(SUBDIRS); do \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 755 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ done info: info-recursive dvi: dvi-recursive check: all-am $(MAKE) check-recursive installcheck: installcheck-recursive all-am: $(SCRIPTS) $(DATA) Makefile install-exec-am: install-binSCRIPTS install-sysconfDATA uninstall-am: uninstall-binSCRIPTS uninstall-sysconfDATA install-exec: install-exec-recursive install-exec-am $(NORMAL_INSTALL) install-data: install-data-recursive $(NORMAL_INSTALL) install: install-recursive install-exec-am @: uninstall: uninstall-recursive uninstall-am all: all-recursive all-am install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install installdirs: installdirs-recursive $(mkinstalldirs) $(bindir) $(sysconfdir) mostlyclean-generic: test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: rm -f Makefile $(DISTCLEANFILES) rm -f config.cache config.log stamp-h test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean-am: mostlyclean-generic clean-am: clean-generic mostlyclean-am distclean-am: distclean-generic clean-am maintainer-clean-am: maintainer-clean-generic distclean-am mostlyclean: mostlyclean-am mostlyclean-recursive clean: clean-am clean-recursive distclean: distclean-am distclean-recursive rm -f config.status maintainer-clean: maintainer-clean-am maintainer-clean-recursive @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f config.status .PHONY: default uninstall-binSCRIPTS install-binSCRIPTS \ uninstall-sysconfDATA install-sysconfDATA install-data-recursive \ uninstall-data-recursive install-exec-recursive \ uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ all-recursive check-recursive installcheck-recursive info-recursive \ dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive distdir info dvi \ installcheck all-am install-exec-am uninstall-am install-exec \ install-data install uninstall all installdirs mostlyclean-generic \ distclean-generic clean-generic maintainer-clean-generic clean \ mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sendfile-2.1b/develop/aclocal.m40000644000175100001440000000143010251132201016312 0ustar framstagusersdnl aclocal.m4 generated automatically by aclocal 1.1l # Like AC_CONFIG_HEADER, but automatically create stamp file. AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. dnl This file resides in the same directory as the config header dnl that is generated. We must strip everything past the first ":", dnl and everything past the last "/". AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl test -z "<<$>>CONFIG_HEADER" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl changequote([,]))]) # serial 1 dnl AC_DEFUN(AM_PROG_INSTALL, dnl [AC_REQUIRE([AC_PROG_INSTALL]) dnl test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' dnl AC_SUBST(INSTALL_SCRIPT)dnl dnl ]) sendfile-2.1b/develop/userinstall0000755000175100001440000000241710251132201016753 0ustar framstagusers#!/bin/sh # # File: userinstall # # Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) # # History: # # 12 Mar 98 Framstag initial version # # Shell script to install pussy, sendfile, receive, fetchfile, utf7decode, # and utf7encode in $HOME/bin. # This script is called by make. # # This file is covered by the GNU General Public License USERBIN=$HOME/bin USERMAN=$HOME/man cat<$HOME/.sendfile/.profile PATH=\$PATH:$USERBIN MANPATH=\$MANPATH:$USERMAN MAILPATH=\$MAILPATH:\$HOME/.sfspool/log?'new file in \$HOME/.sfspool!' export MAILPATH if [ ! -z "`receive -l 2>/dev/null`" ]; then echo echo 'You have files in your spool directory. Type "receive"' echo fi EOD if [ ! -d $USERBIN ]; then mkdir $USERBIN; fi cp src/sendfile src/receive src/fetchfile src/pussy src/utf7*code $USERBIN cp etc/sfconf $USERBIN/ if [ ! -d $USERMAN ]; then mkdir $USERMAN; fi if [ ! -d $USERMAN/man1 ]; then mkdir $USERMAN/man1; fi if [ ! -d $USERMAN/man7 ]; then mkdir $USERMAN/man7; fi cp doc/*.1 $USERMAN/man1/ cp doc/*.7 $USERMAN/man7/ echo installed in $USERBIN: cd $USERBIN ls -l sendfile receive fetchfile pussy utf7decode utf7encode sfconf echo echo "you may now want to add to your \$HOME/.profile (sorry, no csh-support) :" echo ". $HOME/.sendfile/.profile" echo sendfile-2.1b/develop/config.guess0000755000175100001440000012647110251132201017007 0ustar framstagusers#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2005-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; amd64:OpenBSD:*:*) echo x86_64-unknown-openbsd${UNAME_RELEASE} exit ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit ;; cats:OpenBSD:*:*) echo arm-unknown-openbsd${UNAME_RELEASE} exit ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit ;; luna88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit ;; macppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit ;; mvmeppc:OpenBSD:*:*) echo powerpc-unknown-openbsd${UNAME_RELEASE} exit ;; sgi:OpenBSD:*:*) echo mips64-unknown-openbsd${UNAME_RELEASE} exit ;; sun3:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then # avoid double evaluation of $set_cc_for_build test -n "$CC_FOR_BUILD" || eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[34]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #ifdef __INTEL_COMPILER LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: sendfile-2.1b/develop/install-sh0000744000175100001440000001124510251132201016461 0ustar framstagusers#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 sendfile-2.1b/contrib/0000755000175100001440000000000011025466700014474 5ustar framstaguserssendfile-2.1b/contrib/moep0000755000175100001440000000270710504220333015357 0ustar framstagusers#!/client/bin/perl -w # This little sendfile helper program watches the sendfile msglog file. # When it founds a new SAFT message beginning with an "!" it displays it # within a xmessage window. use Text::Tabs; use Fcntl qw(:DEFAULT :flock); $log = "/var/spool/sendfile/$ENV{USER}/msglog"; $sleep = shift || 3; $| = 1; open L,$log or die "$0: cannot open $log (do you have msglog=on in your sendfile config?) - $!\n"; flock(L, LOCK_EX|LOCK_NB) or die "$0: $log is locked\n"; seek L,0,2; for (;;) { while () { next unless /^FROM/; @msg = (); push @msg,expand(utf7toiso($_)); $_ = ; s/^(MSG\t)!/$1/ or next; $_ = utf7toiso($_); s/\n(.)/\n\t$1/g; push @msg,expand($_); $_ = ; push @msg,expand(utf7toiso($_)); print "\n",@msg; open P,"|xmessage -nearmouse -font fixed -file - 2>/dev/null" or die "$0: cannot start subshell - $!\n"; print P @msg; close P or die "$0: cannot run subshell - $!\n"; } sleep $sleep; } sub utf7toiso { my $l = shift; $l =~ s/\+-/+ACs-/g; # arghl! $l =~ s/\+(.*?)-/deb64($1)/ge; return $l; } sub deb64 { my $l = shift; $l =~ tr#A-Za-z0-9+/##cd; # remove non-base64 chars $l =~ tr#A-Za-z0-9+/# -_#; # convert to uuencoded format $len = pack("c", 32 + 0.75*length($l)); # compute length byte $l = unpack("u", $len . $l); # uudecode $l =~ s/(.)(.)/$1 ne "\000" ? '_' : $2/ges; return $l; } sendfile-2.1b/contrib/xhoppel/0000755000175100001440000000000011025466700016153 5ustar framstaguserssendfile-2.1b/contrib/xhoppel/Mailbox.h0000600000175100001440000000454406304126052017713 0ustar framstagusers/* $XConsortium: Mailbox.h,v 1.21 94/04/17 20:43:27 rws Exp $ */ /* Copyright (c) 1988 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ #ifndef _XawMailbox_h #define _XawMailbox_h /* * Mailbox widget; looks a lot like the clock widget, don't it... */ /* resource names used by mailbox widget that aren't defined in StringDefs.h */ #ifndef _XtStringDefs_h_ #define XtNupdate "update" #endif /* command to exec */ #define XtNcheckCommand "checkCommand" #define XtNonceOnly "onceOnly" /* Int: volume for bell */ #define XtNvolume "volume" #define XtNfullPixmap "fullPixmap" #define XtNfullPixmapMask "fullPixmapMask" #define XtNemptyPixmap "emptyPixmap" #define XtNemptyPixmapMask "emptyPixmapMask" #define XtNflip "flip" #define XtNshapeWindow "shapeWindow" #define XtCCheckCommand "CheckCommand" #define XtCVolume "Volume" #define XtCPixmapMask "PixmapMask" #define XtCFlip "Flip" #define XtCShapeWindow "ShapeWindow" /* structures */ typedef struct _MailboxRec *MailboxWidget; /* see MailboxP.h */ typedef struct _MailboxClassRec *MailboxWidgetClass; /* see MailboxP.h */ extern WidgetClass mailboxWidgetClass; #endif /* _XawMailbox_h */ /* DON'T ADD STUFF AFTER THIS #endif */ sendfile-2.1b/contrib/xhoppel/hoppelda.xbm0000600000175100001440000000370706304126052020453 0ustar framstagusers#define hoppelda_width 56 #define hoppelda_height 53 static char hoppelda_bits[] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0xff,0xf1,0xff,0xff,0xff, 0xff,0x1f,0xfe,0xf0,0xff,0xff,0xff,0xff,0x4f,0x7c,0xe4,0xff,0xff,0xff,0xff, 0xe7,0x7c,0xce,0xff,0xff,0xff,0xff,0xe7,0x39,0xcf,0xff,0xff,0xff,0xff,0xe7, 0xb3,0x8f,0xff,0xff,0xff,0xff,0xe3,0x93,0x8f,0xff,0xff,0xff,0xff,0xe3,0x83, 0x9f,0xff,0xff,0xff,0xff,0xe3,0x87,0x8f,0xff,0xff,0xff,0xff,0xe7,0x87,0x8f, 0xff,0xff,0xff,0xff,0xe7,0x87,0xcf,0xff,0xff,0xff,0xff,0xe7,0x83,0xcf,0xff, 0xff,0xff,0xff,0xcf,0x83,0xef,0xff,0xff,0xff,0xff,0x9f,0x01,0xf4,0xff,0xff, 0xff,0xff,0x1f,0x70,0xf0,0xff,0xff,0xff,0xff,0x1f,0xff,0xc7,0xff,0xff,0xff, 0xff,0xc7,0xff,0x8f,0xff,0xff,0xff,0xff,0xe3,0xff,0x3f,0xfe,0xff,0xff,0xff, 0xf1,0xff,0x7f,0xfe,0xff,0xff,0xff,0xb9,0xff,0x7f,0xfe,0xff,0xff,0xff,0x18, 0xff,0xf1,0xfe,0xff,0xff,0x0f,0x18,0xfe,0xf0,0xc0,0xff,0xff,0x81,0x18,0xfe, 0xf0,0x06,0xfe,0x7f,0xf8,0x18,0xff,0x71,0x3e,0xf8,0x3f,0xfe,0xf9,0xff,0x7f, 0xfe,0xf1,0x8f,0xff,0xf1,0x13,0x3f,0xfe,0xc7,0xc7,0xff,0xe0,0x83,0x1f,0xf8, 0x8f,0xe7,0x3f,0xe0,0x87,0x0f,0xf0,0x1f,0xe3,0x3f,0x40,0x00,0x08,0xe0,0x1f, 0xe3,0x1f,0x0f,0x31,0xe2,0xc3,0x1f,0xe7,0x0f,0x22,0x00,0x30,0xc0,0x9f,0xc7, 0x4f,0x22,0x00,0x30,0xc0,0x8f,0x8f,0x0f,0x03,0x00,0x20,0xc0,0xc7,0x3f,0x1e, 0x80,0xff,0x0f,0xe0,0xf1,0x7f,0xf8,0xe0,0xff,0x3f,0x3c,0xf8,0xff,0x03,0xff, 0xff,0xff,0x03,0xff,0xff,0x0f,0xc0,0xff,0x0f,0xc0,0xff,0xff,0x1f,0x00,0x00, 0x00,0xc0,0xff,0xff,0x1f,0x00,0x00,0x30,0xc0,0xff,0xff,0x1f,0x00,0x00,0x30, 0xc0,0xff,0xff,0x1f,0x00,0x00,0x30,0xc0,0xff,0xff,0x1f,0x00,0x00,0x30,0xc0, 0xff,0xff,0x1f,0x00,0x00,0x30,0xc0,0xff,0xff,0x0f,0x00,0x00,0x30,0xc0,0xff, 0xff,0x0f,0x00,0x00,0x30,0xc0,0xff,0xff,0x0f,0x00,0x00,0x30,0x80,0xff,0xff, 0x07,0x00,0x00,0x30,0x80,0xff,0xff,0x07,0x00,0x00,0x30,0x80,0xff,0xff,0x1f, 0x00,0x00,0x30,0xc0,0xff,0xff,0xff,0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0x03, 0x00,0x00,0xfe,0xff,0xff,0xff,0x1f,0x00,0xc0,0xff,0xff}; sendfile-2.1b/contrib/xhoppel/Mailbox.c0000600000175100001440000004513506352236560017720 0ustar framstagusers/* $XConsortium: Mailbox.c,v 1.64 94/04/17 20:43:26 rws Exp $ */ /* Copyright (c) 1988 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ #include /* for toolkit stuff */ #include /* for useful atom names */ #include /* for cursor constants */ #include /* for X_NOT_POSIX def */ #ifdef WIN32 #include #include #else #include /* for getting username */ #endif #include /* for stat() ** needs types.h ***/ #include /* for printing error messages */ #ifndef X_NOT_POSIX #ifdef _POSIX_SOURCE # include #else #define _POSIX_SOURCE # include #undef _POSIX_SOURCE #endif # define waitCode(w) WEXITSTATUS(w) # define waitSig(w) WIFSIGNALED(w) typedef int waitType; # define INTWAITTYPE #else /* ! X_NOT_POSIX */ #ifdef SYSV # define waitCode(w) (((w) >> 8) & 0x7f) # define waitSig(w) ((w) & 0xff) typedef int waitType; # define INTWAITTYPE #else #ifdef WIN32 #include # define INTWAITTYPE typedef int waitType; # define waitCode(w) (w) # define waitSig(w) (0) #else # include # define waitCode(w) ((w).w_T.w_Retcode) # define waitSig(w) ((w).w_T.w_Termsig) typedef union wait waitType; #endif /* WIN32 else */ #endif /* SYSV else */ #endif /* ! X_NOT_POSIX else */ #include "hoppelda.xbm" /* for flag up (mail present) bits */ #include "nohoppel.xbm" /* for flag down (mail not here) */ #include #include "MailboxP.h" /* for implementation mailbox stuff */ #include #include /* * The default user interface is to have the mailbox turn itself off whenever * the user presses a button in it. Expert users might want to make this * happen on EnterWindow. It might be nice to provide support for some sort of * exit callback so that you can do things like press q to quit. */ static char defaultTranslations[] = ": unset()"; static void Check(), Set(), Unset(); static XtActionsRec actionsList[] = { { "check", Check }, { "unset", Unset }, { "set", Set }, }; /* Initialization of defaults */ #define offset(field) XtOffsetOf(MailboxRec, mailbox.field) #define goffset(field) XtOffsetOf(WidgetRec, core.field) static Dimension defDim = 48; static Pixmap nopix = None; static XtResource resources[] = { { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension), goffset (width), XtRDimension, (XtPointer)&defDim }, { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension), goffset (height), XtRDimension, (XtPointer)&defDim }, { XtNupdate, XtCInterval, XtRInt, sizeof (int), offset (update), XtRString, "30" }, { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), offset (foreground_pixel), XtRString, XtDefaultForeground }, { XtNfile, XtCFile, XtRString, sizeof (String), offset (filename), XtRString, NULL }, { XtNcheckCommand, XtCCheckCommand, XtRString, sizeof(char*), offset (check_command), XtRString, NULL}, { XtNvolume, XtCVolume, XtRInt, sizeof(int), offset (volume), XtRString, "33"}, { XtNonceOnly, XtCBoolean, XtRBoolean, sizeof(Boolean), offset (once_only), XtRImmediate, (XtPointer)False }, { XtNfullPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), offset (full.bitmap), XtRString, "hoppelda" }, { XtNfullPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), offset (full.mask), XtRBitmap, (XtPointer) &nopix }, { XtNemptyPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), offset (empty.bitmap), XtRString, "nohoppel" }, { XtNemptyPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), offset (empty.mask), XtRBitmap, (XtPointer) &nopix }, { XtNflip, XtCFlip, XtRBoolean, sizeof(Boolean), offset (flipit), XtRString, "true" }, { XtNshapeWindow, XtCShapeWindow, XtRBoolean, sizeof(Boolean), offset (shapeit), XtRString, "false" }, }; #undef offset #undef goffset static void GetMailFile(), CloseDown(); static void check_mailbox(), redraw_mailbox(), beep(); static void Initialize(), Realize(), Destroy(), Redisplay(); static Boolean SetValues(); MailboxClassRec mailboxClassRec = { { /* core fields */ /* superclass */ (WidgetClass) &simpleClassRec, /* class_name */ "Mailbox", /* widget_size */ sizeof(MailboxRec), /* class_initialize */ XawInitializeWidgetSet, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ actionsList, /* num_actions */ XtNumber(actionsList), /* resources */ resources, /* resource_count */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ NULL, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, { /* simple fields */ /* change_sensitive */ XtInheritChangeSensitive }, { /* mailbox fields */ /* ignore */ 0 } }; WidgetClass mailboxWidgetClass = (WidgetClass) &mailboxClassRec; /* * widget initialization */ static GC get_mailbox_gc (w) MailboxWidget w; { XtGCMask valuemask; XGCValues xgcv; valuemask = GCForeground | GCBackground | GCFunction | GCGraphicsExposures; xgcv.foreground = w->mailbox.foreground_pixel; xgcv.background = w->core.background_pixel; xgcv.function = GXcopy; xgcv.graphics_exposures = False; /* this is Bool, not Boolean */ return (XtGetGC ((Widget) w, valuemask, &xgcv)); } /* ARGSUSED */ static void Initialize (request, new, args, num_args) Widget request, new; ArgList args; Cardinal *num_args; { MailboxWidget w = (MailboxWidget) new; int shape_event_base, shape_error_base; if (w->core.width <= 0) w->core.width = 1; if (w->core.height <= 0) w->core.height = 1; if (w->mailbox.shapeit && !XShapeQueryExtension (XtDisplay (w), &shape_event_base, &shape_error_base)) w->mailbox.shapeit = False; w->mailbox.shape_cache.mask = None; w->mailbox.gc = get_mailbox_gc (w); w->mailbox.interval_id = (XtIntervalId) 0; w->mailbox.full.pixmap = None; w->mailbox.empty.pixmap = None; w->mailbox.flag_up = FALSE; w->mailbox.last_size = 0; if (!w->mailbox.filename) GetMailFile (w); return; } /* * action procedures */ /* * pretend there is new mail; put widget in flagup state */ /* ARGSUSED */ static void Set (gw, event, params, nparams) Widget gw; XEvent *event; String *params; Cardinal *nparams; { MailboxWidget w = (MailboxWidget) gw; w->mailbox.last_size = -1; check_mailbox (w, TRUE, FALSE); /* redraw, no reset */ return; } /* * ack the existing mail; put widget in flagdown state */ /* ARGSUSED */ static void Unset (gw, event, params, nparams) Widget gw; XEvent *event; String *params; Cardinal *nparams; { MailboxWidget w = (MailboxWidget) gw; check_mailbox (w, TRUE, TRUE); /* redraw, reset */ return; } /* * look to see if there is new mail; if so, Set, else Unset */ /* ARGSUSED */ static void Check (gw, event, params, nparams) Widget gw; XEvent *event; String *params; Cardinal *nparams; { MailboxWidget w = (MailboxWidget) gw; check_mailbox (w, TRUE, FALSE); /* redraw, no reset */ return; } /* ARGSUSED */ static void clock_tic (client_data, id) XtPointer client_data; XtIntervalId *id; { MailboxWidget w = (MailboxWidget) client_data; check_mailbox (w, FALSE, FALSE); /* no redraw, no reset */ /* * and reset the timer */ w->mailbox.interval_id = XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) w), w->mailbox.update * 1000, clock_tic, client_data); return; } static Pixmap make_pixmap (dpy, w, bitmap, depth, flip, widthp, heightp) Display *dpy; MailboxWidget w; Pixmap bitmap; Boolean flip; int depth; int *widthp, *heightp; { Window root; int x, y; unsigned int width, height, bw, dep; unsigned long fore, back; if (!XGetGeometry (dpy, bitmap, &root, &x, &y, &width, &height, &bw, &dep)) return None; *widthp = (int) width; *heightp = (int) height; if (flip) { fore = w->core.background_pixel; back = w->mailbox.foreground_pixel; } else { fore = w->mailbox.foreground_pixel; back = w->core.background_pixel; } return XmuCreatePixmapFromBitmap (dpy, w->core.window, bitmap, width, height, depth, fore, back); } static void Realize (gw, valuemaskp, attr) Widget gw; XtValueMask *valuemaskp; XSetWindowAttributes *attr; { MailboxWidget w = (MailboxWidget) gw; register Display *dpy = XtDisplay (w); int depth = w->core.depth; *valuemaskp |= (CWBitGravity | CWCursor); attr->bit_gravity = ForgetGravity; attr->cursor = XCreateFontCursor (dpy, XC_top_left_arrow); (*mailboxWidgetClass->core_class.superclass->core_class.realize) (gw, valuemaskp, attr); /* * build up the pixmaps that we'll put into the image */ if (w->mailbox.full.bitmap == None) { w->mailbox.full.bitmap = XCreateBitmapFromData (dpy, w->core.window, (char *) hoppelda_bits, hoppelda_width, hoppelda_height); } if (w->mailbox.empty.bitmap == None) { w->mailbox.empty.bitmap = XCreateBitmapFromData (dpy, w->core.window, (char *) nohoppel_bits, nohoppel_width, nohoppel_height); } w->mailbox.empty.pixmap = make_pixmap (dpy, w, w->mailbox.empty.bitmap, depth, False, &w->mailbox.empty.width, &w->mailbox.empty.height); w->mailbox.full.pixmap = make_pixmap (dpy, w, w->mailbox.full.bitmap, depth, w->mailbox.flipit, &w->mailbox.full.width, &w->mailbox.full.height); if (w->mailbox.empty.mask == None && w->mailbox.full.mask == None) w->mailbox.shapeit = False; w->mailbox.interval_id = XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) w), w->mailbox.update * 1000, clock_tic, (XtPointer) w); w->mailbox.shape_cache.mask = None; check_mailbox (w, TRUE, FALSE); return; } static void Destroy (gw) Widget gw; { MailboxWidget w = (MailboxWidget) gw; Display *dpy = XtDisplay (gw); XtFree (w->mailbox.filename); if (w->mailbox.interval_id) XtRemoveTimeOut (w->mailbox.interval_id); XtReleaseGC(gw, w->mailbox.gc); #define freepix(p) if (p) XFreePixmap (dpy, p) freepix (w->mailbox.full.bitmap); /* until cvter does ref cnt */ freepix (w->mailbox.full.mask); /* until cvter does ref cnt */ freepix (w->mailbox.full.pixmap); freepix (w->mailbox.empty.bitmap); /* until cvter does ref cnt */ freepix (w->mailbox.empty.mask); /* until cvter does ref cnt */ freepix (w->mailbox.empty.pixmap); freepix (w->mailbox.shape_cache.mask); #undef freepix return; } static void Redisplay (gw, event, region) Widget gw; XEvent *event; Region region; { MailboxWidget w = (MailboxWidget) gw; check_mailbox (w, TRUE, FALSE); } static void check_mailbox (w, force_redraw, reset) MailboxWidget w; Boolean force_redraw, reset; { long mailboxsize = 0; Boolean readSinceLastWrite = FALSE; if (w->mailbox.check_command != NULL) { waitType wait_status; int check_status; #ifdef INTWAITTYPE wait_status = system(w->mailbox.check_command); #else wait_status.w_status = system(w->mailbox.check_command); #endif check_status = waitCode(wait_status); /* error in sh checkCommand execution */ if (waitSig(wait_status)) check_status = 2; /* act as if there is no mail */ switch (check_status) { case 0: mailboxsize = w->mailbox.last_size + 1; break; case 2: mailboxsize = 0; break; default: /* treat everything else as no change */ /* case 1 is no change */ mailboxsize = w->mailbox.last_size; } } else { struct stat st; if (stat (w->mailbox.filename, &st) == 0) { mailboxsize = st.st_size; readSinceLastWrite = (st.st_atime > st.st_mtime); } } /* * Now check for changes. If reset is set then we want to pretent that * there is no mail. If the mailbox is empty then we want to turn off * the flag. Otherwise if the mailbox has changed size then we want to * put the flag up, unless the mailbox has been read since the last * write. * * The cases are: * o forced reset by user DOWN * o no mailbox or empty (zero-sized) mailbox DOWN * o if read after most recent write DOWN * o same size as last time no change * o bigger than last time UP * o smaller than last time but non-zero UP * * The last two cases can be expressed as different from last * time and non-zero. */ if (reset) { /* forced reset */ w->mailbox.flag_up = FALSE; force_redraw = TRUE; } else if (mailboxsize == 0) { /* no mailbox or empty */ w->mailbox.flag_up = FALSE; if (w->mailbox.last_size > 0) force_redraw = TRUE; /* if change */ } else if (readSinceLastWrite) { /* only when checkCommand is NULL */ /* mailbox has been read after most recent write */ if (w->mailbox.flag_up) { w->mailbox.flag_up = FALSE; force_redraw = TRUE; } } else if (mailboxsize != w->mailbox.last_size) { /* different size */ if (!w->mailbox.once_only || !w->mailbox.flag_up) beep(w); if (!w->mailbox.flag_up) force_redraw = w->mailbox.flag_up = TRUE; } w->mailbox.last_size = mailboxsize; if (force_redraw) redraw_mailbox (w); return; } /* * get user name for building mailbox */ static void GetMailFile (w) MailboxWidget w; { char *username; #ifdef WIN32 if (!(username = getenv("USERNAME"))) { fprintf (stderr, "%s: unable to find a username for you.\n", "Mailbox widget"); CloseDown (w, 1); } #else char *getlogin(); username = getlogin (); if (!username) { struct passwd *pw = getpwuid (getuid ()); if (!pw) { fprintf (stderr, "%s: unable to find a username for you.\n", "Mailbox widget"); CloseDown (w, 1); } username = pw->pw_name; } #endif w->mailbox.filename = (String) XtMalloc (strlen (MAILBOX_DIRECTORY) + 1 + strlen (username) + 5); sprintf (w->mailbox.filename, "%s/%s/log", MAILBOX_DIRECTORY, username); return; } static void CloseDown (w, status) MailboxWidget w; int status; { Display *dpy = XtDisplay (w); XtDestroyWidget ((Widget)w); XCloseDisplay (dpy); exit (status); } /* ARGSUSED */ static Boolean SetValues (gcurrent, grequest, gnew, args, num_args) Widget gcurrent, grequest, gnew; ArgList args; Cardinal *num_args; { MailboxWidget current = (MailboxWidget) gcurrent; MailboxWidget new = (MailboxWidget) gnew; Boolean redisplay = FALSE; if (current->mailbox.update != new->mailbox.update) { if (current->mailbox.interval_id) XtRemoveTimeOut (current->mailbox.interval_id); new->mailbox.interval_id = XtAppAddTimeOut (XtWidgetToApplicationContext(gnew), new->mailbox.update * 1000, clock_tic, (XtPointer) gnew); } if (current->mailbox.foreground_pixel != new->mailbox.foreground_pixel || current->core.background_pixel != new->core.background_pixel) { XtReleaseGC (gcurrent, current->mailbox.gc); new->mailbox.gc = get_mailbox_gc (new); redisplay = TRUE; } return (redisplay); } /* * drawing code */ static void redraw_mailbox (w) MailboxWidget w; { register Display *dpy = XtDisplay (w); register Window win = XtWindow (w); register int x, y; GC gc = w->mailbox.gc; Pixel back = w->core.background_pixel; struct _mbimage *im; /* center the picture in the window */ if (w->mailbox.flag_up) { /* paint the "up" position */ im = &w->mailbox.full; if (w->mailbox.flipit) back = w->mailbox.foreground_pixel; } else { /* paint the "down" position */ im = &w->mailbox.empty; } x = (((int)w->core.width) - im->width) / 2; y = (((int)w->core.height) - im->height) / 2; XSetWindowBackground (dpy, win, back); XClearWindow (dpy, win); XCopyArea (dpy, im->pixmap, win, gc, 0, 0, im->width, im->height, x, y); /* * XXX - temporary hack; walk up widget tree to find top most parent (which * will be a shell) and mash it to have our shape. This will be replaced * by a special shell widget. */ if (w->mailbox.shapeit) { Widget parent; for (parent = (Widget) w; XtParent(parent); parent = XtParent(parent)) { x += parent->core.x + parent->core.border_width; y += parent->core.y + parent->core.border_width; } if (im->mask != w->mailbox.shape_cache.mask || x != w->mailbox.shape_cache.x || y != w->mailbox.shape_cache.y) { XShapeCombineMask (XtDisplay(parent), XtWindow(parent), ShapeBounding, x, y, im->mask, ShapeSet); w->mailbox.shape_cache.mask = im->mask; w->mailbox.shape_cache.x = x; w->mailbox.shape_cache.y = y; } } return; } static void beep (w) MailboxWidget w; { XBell (XtDisplay (w), w->mailbox.volume); return; } sendfile-2.1b/contrib/xhoppel/MailboxP.h0000600000175100001440000000646406352236560020047 0ustar framstagusers/* $XConsortium: MailboxP.h,v 1.22 94/04/17 20:43:27 rws Exp $ */ /* $XFree86: contrib/programs/xbiff/MailboxP.h,v 3.1 1995/04/24 12:19:48 dawes Exp $ */ /* Copyright (c) 1988 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ #ifndef _XawMailboxP_h #define _XawMailboxP_h #include "Mailbox.h" #include #ifdef SYSV #define MAILBOX_DIRECTORY "/usr/mail" #endif #ifdef SVR4 #define MAILBOX_DIRECTORY "/var/mail" #endif #ifdef CSRG_BASED #include #ifdef _PATH_MAILDIR #define MAILBOX_DIRECTORY _PATH_MAILDIR #endif #endif #ifndef MAILBOX_DIRECTORY #define MAILBOX_DIRECTORY "/usr/spool/sendfile" #endif typedef struct { /* new fields for mailbox widget */ /* resources */ int update; /* seconds between updates */ Pixel foreground_pixel; /* color index of normal state fg */ String filename; /* filename to watch */ String check_command; /* command to exec for mail check */ Boolean flipit; /* do flip of full pixmap */ int volume; /* bell volume */ Boolean once_only; /* ring bell only once on new mail */ /* local state */ GC gc; /* normal GC to use */ long last_size; /* size in bytes of mailboxname */ XtIntervalId interval_id; /* time between checks */ Boolean flag_up; /* is the flag up? */ struct _mbimage { Pixmap bitmap, mask; /* depth 1, describing shape */ Pixmap pixmap; /* full depth pixmap */ int width, height; /* geometry of pixmaps */ } full, empty; Boolean shapeit; /* do shape extension */ struct { Pixmap mask; int x, y; } shape_cache; /* last set of info */ } MailboxPart; typedef struct _MailboxRec { /* full instance record */ CorePart core; SimplePart simple; MailboxPart mailbox; } MailboxRec; typedef struct { /* new fields for mailbox class */ int dummy; /* stupid C compiler */ } MailboxClassPart; typedef struct _MailboxClassRec { /* full class record declaration */ CoreClassPart core_class; SimpleClassPart simple_class; MailboxClassPart mailbox_class; } MailboxClassRec; extern MailboxClassRec mailboxClassRec; /* class pointer */ #endif /* _XawMailboxP_h */ sendfile-2.1b/contrib/xhoppel/xbiff.man0000600000175100001440000001633106304126052017737 0ustar framstagusers.\" $XConsortium: xbiff.man,v 1.22 94/04/17 20:43:28 gildea Exp $ .\" Copyright (c) 1988 X Consortium .\" .\" Permission is hereby granted, free of charge, to any person obtaining .\" a copy of this software and associated documentation files (the .\" "Software"), to deal in the Software without restriction, including .\" without limitation the rights to use, copy, modify, merge, publish, .\" distribute, sublicense, and/or sell copies of the Software, and to .\" permit persons to whom the Software is furnished to do so, subject to .\" the following conditions: .\" .\" The above copyright notice and this permission notice shall be included .\" in all copies or substantial portions of the Software. .\" .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS .\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF .\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. .\" IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR .\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, .\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR .\" OTHER DEALINGS IN THE SOFTWARE. .\" .\" Except as contained in this notice, the name of the X Consortium shall .\" not be used in advertising or otherwise to promote the sale, use or .\" other dealings in this Software without prior written authorization .\" from the X Consortium. .TH XBIFF 1 "Release 6" "X Version 11" .SH NAME xbiff \- mailbox flag for X .SH SYNOPSIS .B xbiff [ \-\fItoolkitoption\fP ... ] [ \fI\-option\fP ... ] .SH DESCRIPTION The .I xbiff program displays a little image of a mailbox. When there is no mail, the flag on the mailbox is down. When mail arrives, the flag goes up and the mailbox beeps. By default, pressing any mouse button in the image forces \fIxbiff\fP to remember the current size of the mail file as being the ``empty'' size and to lower the flag. .SH OPTIONS .I Xbiff accepts all of the standard X Toolkit command line options along with the additional options listed below: .TP 8 .B \-help This option indicates that a brief summary of the allowed options should be printed on the standard error. .TP 8 .B \-update \fIseconds\fP This option specifies the frequency in seconds at which \fIxbiff\fP should update its display. If the mailbox is obscured and then exposed, it will be updated immediately. The default is 30 seconds. .TP 8 .B \-file \fIfilename\fP This option specifies the name of the file which should be monitored. By default, it watches /usr/spool/mail/\fIusername\fP, where \fIusername\fP is your login name. .TP 8 .B \-volume \fIpercentage\fP This option specifies how loud the bell should be rung when new mail comes in. .TP 8 .B \-shape This option indicates that the mailbox window should be shaped if masks for the empty or full images are given. .PP The following standard X Toolkit command line arguments are commonly used with .I xbiff: .TP 8 .B \-display \fIdisplay\fP This option specifies the X server to contact. .TP 8 .B \-geometry \fIgeometry\fP This option specifies the preferred size and position of the mailbox window. The mailbox is 48 pixels wide and 48 pixels high and will be centered in the window. .TP 8 .B \-bg \fIcolor\fP This option specifies the color to use for the background of the window. .TP 8 .B \-bd \fIcolor\fP This option specifies the color to use for the border of the window. .TP 8 .B \-bw \fInumber\fP This option specifies the width in pixels of the border surrounding the window. .TP 8 .B \-fg \fIcolor\fP This option specifies the color to use for the foreground of the window. .TP 8 .B \-rv This option indicates that reverse video should be simulated by swapping the foreground and background colors. .TP 8 .B \-xrm \fIresourcestring\fP This option specifies a resource string to be used. This is especially useful for setting resources that do not have separate command line options. .SH X DEFAULTS The application class name is XBiff. This program uses the .I Mailbox widget. It understands all of the core resource names and classes as well as: .PP .TP 8 .B checkCommand (\fPclass\fB CheckCommand) Specifies a shell command to be executed to check for new mail rather than examining the size of \fBfile\fP. The specified string value is used as the argument to a \fIsystem\fP(3) call and may therefore contain i/o redirection. An exit status of 0 indicates that new mail is waiting, 1 indicates that there has been no change in size, and 2 indicates that the mail has been cleared. By default, no shell command is provided. .TP 8 .B file (\fPclass\fB File) Specifies the name of the file to monitor. The default is to watch /usr/spool/mail/\fIusername\fP, where \fIusername\fP is your login name. .TP 8 .B onceOnly (\fPclass\fB Boolean) Specifies that the bell is only rung the first time new mail is found and is not rung again until at least one interval has passed with no mail waiting. The window will continue to indicate the presence of new mail until it has been retrieved. The default is false. .TP 8 .B width (\fPclass\fB Width) Specifies the width of the mailbox. .TP 8 .B height (\fPclass\fB Height) Specifies the height of the mailbox. .TP 8 .B update (\fPclass\fB Interval) Specifies the frequency in seconds at which the mail should be checked. The default is 30. .TP 8 .B volume (\fPclass\fB Volume) Specifies how loud the bell should be rung. The default is 33 percent. .TP 8 .B foreground (\fPclass\fB Foreground) Specifies the color for the foreground. .TP 8 .B reverseVideo (\fPclass\fB ReverseVideo) Specifies that the foreground and background should be reversed. .TP 8 .B flip (\fPclass\fB Flip) Specifies whether or not the image that is shown when mail has arrived should be inverted. The default is ``true.'' .TP 8 .B fullPixmap (\fPclass\fB Pixmap) Specifies a bitmap to be shown when new mail has arrived. The default is flagup. .TP 8 .B emptyPixmap (\fPclass\fB Pixmap) Specifies a bitmap to be shown when no new mail is present. The default is flagdown. .TP 8 .B shapeWindow (\fPclass\fB ShapeWindow) Specifies whether or not the mailbox window should be shaped to the given fullPixmapMask and emptyPixmapMask. The default is false. .TP 8 .B fullPixmapMask (\fPclass\fB PixmapMask) Specifies a mask for the bitmap to be shown when new mail has arrived. The default is none. .TP 8 .B emptyPixmapMask (\fPclass\fB PixmapMask) Specifies a mask for the bitmap to be shown when no new mail is present. The default is none. .SH ACTIONS The \fIMailbox\fP widget provides the following actions for use in event translations: .TP 8 .B check() This action causes the widget to check for new mail and display the flag appropriately. .TP 8 .B unset() This action causes the widget to lower the flag until new mail comes in. .TP 8 .B set() This action causes the widget to raise the flag until the user resets it. .PP The default translation is .sp .nf : unset() .fi .sp .SH ENVIRONMENT .PP .TP 8 .B DISPLAY to get the default host and display number. .TP 8 .B XENVIRONMENT to get the name of a resource file that overrides the global resources stored in the RESOURCE_MANAGER property. .SH "SEE ALSO" X(1), xrdb(1), stat(2) .SH BUGS The mailbox bitmaps are ugly. .SH AUTHOR Jim Fulton, MIT X Consortium .br Additional hacks by Ralph Swick, DEC/MIT Project Athena sendfile-2.1b/contrib/xhoppel/nohoppel.gif0000700000175100001440000000340006304126052020451 0ustar framstagusersGIF87aL€ðÿÿÿ,L€þŒ©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·Ü®÷ ‹Çä²ùŒN«×ì¶û ËçôºýŽÏë÷ü¾ÿ(8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù *:JZjzŠšªºÊÚêú +;K[k{‹›«»ËÛëû ,N^n~Žž®¾ÎÞîþ/?O_oŸ¯¿Ïßïÿ0 À <ˆ0¡Â… :|1¢Ä‰+Z¼ˆ1£Æþ;zü2¤È‘$Kš<‰2¥Ê•,[º| 3¦Ì™4kÚ¼™€Î<{úü 4hЇB‹=Š4©Î}J›:} u)»¨T«ZU îªÖ­\Në 6¬Ø¡ÇÆš=‹v§¯´lÛ¢­å6®Ü´­æÚ½köÞ½|Å~ê›Wౘ{íaøð£Ä<©0V»ÈðÉ„ú±ìoŸ»zæò\§­$·—éfbËæm(Õf£:;Ùï+×\dà »7/°Xx ëê˜k2áOˆ33®D+µ­I”_s^Ī·«C¤{áœÅúª½û u{x)ÞÇ7¡º}ñòÀ“›·ñ¾9{ÔGâË€ê~¾f"öþ]௯eBü÷Õ8߀NÁð> ¶° ‚^¡xX©Pa~ØbMq¸¡† ž(Uz#ž°¢(¾øŠI™Ð"0ÞØ“%†°£Œ8þ˜"=z0d@¢3òˆ”‹H>$|KÙ¤ˆP^iä”h©Ã•^FI—T©ã—^f©Ø˜ivi¦™hÅ™l¶é¦’Fi ç›t~©'PxÞYæžmÚ çk*h7* >&ª¨”BaàèœЍŸ0*饘.Z(•Zê)Ÿ™Æ(j¨¤–z橨6:i ¬š j¬°’%ë¬Xºšd£ö©ë“Àæ8Á¯¼ûþã°½B`l­ÈB©,d·jšë³É®Jì´?9i-’¾Ê¬ªßv ã¸Ë>Ь³äÞˆm¶¾ŠkîºÆ+í»¶Z)/Šô‚é@ºÇæ«_µîÚ‹+¾Chð¶©Þ›ðÁïËo¿ð ìðc ƒîÄWÌ·«ñÆÛåñÇÚ*ìáÈR|îÉ—¬2v0£l§Çlš‰ /òÍ8Û¦3µ”ÚìóÏÌYØ3Á;ht{H/]3ÑA7­ÞÓPoš§T÷7µÐ[f­õÖb¦ ¶šR3-öËV_=tÙH¤1Úþš}vØ?Ÿ76•n/1òzyë½7ÞÏNQ# …WQª‡^ä´*¾8ã‘çþâ’8y‰•1¡—ÏÁøy=28º<\{žz;U×ðº:±«›yV³ÿ;77¡Ï\ûs»K¨Ý6ÔE7¼ï¿Û}ü3GçWüqÐ Þ¼1ÈAát0¾!^½.ºewýmÙS¾½+„‰Ûkã·Æš'é£A_a9»AÚbñƒ"rí!sûe¶WiýW62l. ¢^€°®=ÞÁ§7v10‚'rõ5Á Î+ƒL #:¸A‚ða"! HfAšì(,¡AÖÂȨ0CJ«Ÿ )ȳûÝ0‚9´¡ UØÃùAp†A͉CÐüЄElߘD.q„M|þ‘XC>‘‰.3âAE)n‘Š]t⡘E!ž‘‹iôâÁXF+Úm4ãÙXG9~‹yÔ#éˆ®Ž½±ƒaTâñÈÿ­‘Œ}ôã fHÃŒídþÉBŠ“|L¤"9 H‰ ”¡l`YION²Œ¤*/ùÇR2à””L¥(GKY. €{ÌdÕ(ˆVºò–Ÿ|d+5iHcú²‘v „0‘™L@s˜¦ä¥2—iÉbJó™¿æ¦ ÍMnó˜Ýô&¦IÍY®ì›à,§ÙÉMf¾“ñ̦67ÓNy6óœù´ç=;ƒÎ*F §8 ÚO¡õTèBåñ€Î¸ír€ø,¨;ç©¿ˆ t Õ¨A9šˆ¦S¨G?ªÅŒžô¢û éJõ‰Q:ˆ´^}(ýfºQŠn¦#hIïÀÓž*À;*Å)J*S£²´¥I}é+ÿYTrµ|×ìdM9N]’T§Á´êS™ÊJD^5|ò#äR£7š~u}–¸ 1cz ú4¥êKÛP‘ú—­!€«  šø:Š öN/‚M+ K3\ ÖzJýMB‹¡UȪUvÍÆÝ¦Ã1räKvÈ‚Gâìñ@}‹ /jÈ+òSŽÐ%ËÉk_ ÛØÊö";sendfile-2.1b/contrib/xhoppel/Makefile0000600000175100001440000000055007064434202017603 0ustar framstagusersCC=gcc -O2 -I/usr/X386/include -D_POSIX_SOURCE -c LINK=gcc LIBS=-L/usr/X11/lib -lXaw -lXmu -lXt -lXext -lX11 -lsocket -lnsl xhoppel: Mailbox.o xhoppel.o $(LINK) -o xhoppel Mailbox.o xhoppel.o $(LIBS) strip xhoppel Mailbox.o: Mailbox.c nohoppel.xbm hoppelda.xbm $(CC) Mailbox.c xhoppel.o: xhoppel.c $(CC) xhoppel.c clean: rm -f core *~ *.o xhoppel sendfile-2.1b/contrib/xhoppel/nohoppel.xbm0000600000175100001440000000277606304126052020510 0ustar framstagusers#define nohoppel_width 44 #define nohoppel_height 47 static char nohoppel_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xf8,0x03,0xe0,0x0f,0x00,0x00,0x1f,0x00,0x00,0x7c,0x00,0x80,0x03,0x00, 0x00,0xe0,0x01,0xe0,0x00,0xfc,0x3f,0x00,0x03,0x18,0xe0,0xff,0xff,0x07,0x0c, 0x08,0xe0,0xff,0xff,0x0f,0x08,0x08,0xf8,0xff,0xff,0x0f,0x08,0x08,0xe0,0xff, 0xff,0x0f,0x08,0x08,0xe0,0xff,0xff,0x07,0x08,0x18,0x80,0xff,0xff,0x01,0x0c, 0x70,0x00,0xf0,0x0f,0x00,0x06,0xe0,0x00,0x00,0x00,0x80,0x03,0x80,0x07,0x00, 0x00,0xf0,0x01,0x00,0x3e,0x00,0x00,0x3e,0x00,0x00,0xf8,0xff,0xff,0x1f,0x00, 0x00,0xf8,0xff,0x8f,0x1f,0x00,0x00,0xf8,0xff,0x8f,0x1f,0x00,0x00,0xf8,0xff, 0x8f,0x1f,0x00,0x00,0xf8,0xff,0x8f,0x1f,0x00,0x00,0xf8,0xff,0x8f,0x1f,0x00, 0x00,0xf8,0xff,0x8f,0x1f,0x00,0x00,0xf8,0xff,0x8f,0x3f,0x00,0x00,0xfc,0xff, 0x8f,0x3f,0x00,0x00,0xfc,0xff,0x8f,0x3f,0x00,0x00,0xf8,0xff,0x8f,0x1f,0x00, 0x00,0xe0,0xff,0xdf,0x0f,0x00,0x00,0x80,0xff,0xff,0x01,0x00}; sendfile-2.1b/contrib/xhoppel/hoppelda.gif0000700000175100001440000000641706304126052020434 0ustar framstagusersGIF87aL€ðÿÿÿ,L€þŒ©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öç: ôý ‡<ŸñGL*—ÌÆñ‰lJ§3(`iµR·\TÖGüj»äòF| ¢Çæ¶²6îâì·ýNOßòлÿͧGØ÷gØE(7˜¨xèØÄØ)øh9D 6™)yé‰Ã©é*úiZCz5ºvÀzú*“¥B‡à ‹[$f§»k‹–+LûË[›·p;̲Ðëõl\Ülݬ]’Ì} ®ñpLÒí=®>‘<ýñîþµN/ÑN~’^]ï?ïA9ûøü‡°U?e9Äcx0ῇòf(èäžÄþp!v¤€1£Åà>j ’¢Ç,$ë™<©R`L˜[^› p¤½—ëØ´Æ“¦N™A…úü9¬hΡ=YbÀ‰ÔT£NÙM¥Z)j.¥+«F@¹“©V©b‰½ÚôÉXa\»M[èLÙµ†Úºë-ܬt/ÙÝËw©W¹5û’-|Q¥^‘ƒ ?ú ¸ÖÀâæ:n9ò,Áx Z¾ŒèsXÄÔc šJfƦ›}›ê¯÷V³îÛŽmͪÎ ;w™Ýw³º†ó[8¦ä´k׬\7säÅŽS7Ës襃{&]õôël¶—^ûø×cÌŸï>4xx»Ü¿‡_üüï,þíOFŸ$ë±§–œQ ˜†á– ûÑ 2 FØÂ…yUhá„ÎááiŒƒÝ‡Ë•è ‡Ò h"ÞÆG‡,¶¨ƒƒnc‚4¦¢C#®8ãŽ{¼È[>ö(dDÞ‡dbM&¹É“O%B¢‘PƲäYØÉ•5ny#XZée”dVFˆŒÞ•‰Š”üx‚Žl¢yæ”i¹æœXºYœÜÈ©ç›`v‡£9ƒjg‚ޙ㡈.ªhŸTÆé裒òi£†Vji¦‘¦4馟vú'˜*Ž(© ŽÚœ¦G¼óž?ÍoÐæ4ÐF 4ÑKçà4y?=äÔßfBµ ²àImÖ¾²l3Ö^Ã\2ÓÈŽ}ìÙJŠ‹v± ›Hۢƨ`ÙrïÛPÝqßM/Àd¿Í7“Æ’±wànâ†Ûë·Ö….£µ<þ.7݇X9º:»yæê¦Zuã?~èÄ’îåF£îIÞ|»~ ìhË»èÑÒþŠê!ë~¹í½òîðû>œéz <ñ–"ÿ˜òˆ:Ÿ¸ñ^B_¼äWR½õIb_ýĤrŸ}Ѫ‚ß½øJ>Çå’Ÿ>Ís•­)ì›x–ú²yèLèÛyõæúòÄ|ã1o™XŠ`‚­d%üìCL)H³ZAª¦5…¹¥mJȘú( ±h?9ñ1 —lT´WÉ+¦ê‘j '7ëuÅoú”ú á ÏYÊÓ—›$¨™¹L„ÊÑ ˜Éçþí99BöÓ&À„&ùK†ªÃŸÐ8¢Èê0Þ„£xÌ'Þ@Ú·}¦’c(å'Ô 9M˜FÔ¤ÿTiGu„ÑdŠr†GéJ1漜6“¦%éPÍÒ5ýð¤æ+§7“ÚÔ˜ˆtíO™zÕ’jtƒS­ãAeÚO›$kQ=¹Ð–b•¨2<X?‰Ö¯Zt¦ø3+]íÚÇlºsôÛRáæÑ^òunƒ­`¾þZÖvZ¢=-¬ÙÈ…Ø*ªm¬8 ; µ¦”±‚ÅëOQºñhv­œÖdºHiÙf´-mkÙzÖ¸öS¬5m /Õ£‚v¶&ªæè™Ö­Z6µ¼•§Qƒþ©×½Î³ŠÅEf^ÅÖä6«Mds…ëJý죃*ãKQã[=îvº¹rãwët\äÞ–¼]5¯jÑ Ï‚Z·Oº}‘ XŸâ±žIãŸz{_ü&V¿é­îÿ»ÝÏvñ½øŒ¯|½jà{EÂØå.v ¬UI"˜Â†pɄ᛺7Â.E‰¡«\;¸¦Hë°+âzbý7¶N(‡IŒ#ÐÆ¶›E*.cOƒ˜;Î-\mzÜ"7±-äe#W¬£êÆåciläx^xÅ.öq2ãbÈ;÷MB®±\ËbeæwµÔË1® ª ?V¬!,œšìÀ û°Ì%ºsWþ;þç ×y f£g_‹’B‹Øµ‹Uô~¹4g¤¾êtòç ]Õ´±tp–¥A*[=ŠwÑYæžõŒZàv$Ôce㨅\RÉ:šÄ6¾×>¢äñ:ý1ÝbæG0BÇ#×–&u@,çkÈïÅÛ€±/kìƒ4›S4Þ7íìg‡sÂ.5r)‹êÖòyÜ¿Õ6l:w3G ¯¶Á„µœËmnIgø>‡Ä-Š;Q­ÂûËñö3F®}¨È:Ë–Uy‡ìú}DƒW§»hø3—<Å ¡µYxV]n ‹B# œ8Åcö ßa|ßÁUÇ™âñV|"wøƒïåœ|>)_áÊÛcþy“æZNâªkζ›3ºç2>5×Hš™]ƒB¯l«Y›iÛª­éKwÕߊi§Ú?L^HÕ‰ ò¡?™çFo꘣-‰¯×ðê.O³Ö¥:r¤ó*ب;±Ü]‡sSW§[÷9«Ë¾šg÷=‚§}î¿×«Ÿ7ÚÛc{ÌG¬ž ç|ïYç—’ZâÉSžè™•<ç¬yÆ?ëð>ðýŒhÑëýWNs¥÷3G½ñ®®‹ÏvbñŠöõ¥«ýèÚ¹Þ]ìŸ/6àÃ{|ëhX‘y7üì…`üÊ“¾uî´€ |Õ·Qºå;ûï‹ÎD]Ÿû£C|,£;ó§îï·¢ä$‰[BßþÃÂôÓ[>PèO?üÒôDxïøýÞE÷å ™· (Ä6~—ýÆN5‡Ajn´gˆØbè!¨¹!‚%hÊa‚)È~¤‚-H~Tä‚1(|(ƒ5ø|4dƒH€ ˜ƒ§{â÷€=84Îw‚A(„þ'}òÇ‚G8‚üf}È„M8|܃Q8_„Uh…ð÷r\h„[è~œç…$†cøiêG†e¨„Sø‚—¡†a˜„+¸€o(‡?X‡PH‡YXzh¸„yH…{¨‡nè‡è×e(ˆƒØ†…˜ˆ†ˆ†¨ˆOˆƒè}€HˆŒ(‰Íg‡|¨…—XþxhÇ}ȉˆ€ÑŠœ¥€(XŠNwŠ_˜ŠÞ´ŠiØŠ®8Ѝ‹²èƒ X‹õs‹›˜‹–ñŠ¸Ø‹VÒz´Œ¾ø‹‡XŒÆ8‹À˜ŒŽÇkfh‰ÍøNLj‡Ò.ËÖ茞8„̨^Ægиß(ŒØ8‡ä¸7Æ‹èèg™‡ÈÈŽàøŒâ8ñ¨RXöØŽˆH¡Â…ÑøD˜`ðh‰„ùxbX‘øûŽEÈE)Ü(€H‘9‰‘‰ IƒÉ 9Žù‘$Ù‘"9’Ÿè©‘I$á’/i‘Ý’*‡,Ù3I“ž7‘.ùx6ù“&y’:ú)“3”BIF<™” ¹”HÙ”F¹}PY”R8•@•R™€i ¢ŽÙ©MNÉÅ÷™ß)žãIžåižç‰žé);sendfile-2.1b/contrib/xhoppel/README0000644000175100001440000000114206305565577017052 0ustar framstagusersUnicode::Utf7 ============= 1997-02-28 Stefan Scholl Sorry, no automatic install and no manuals! Make a directory "Unicode" in your @INC (watch "perl -V") and copy Utf7.pm into it. Unicode::Utf7.pm provides you with the two functions isotoutf7() and utf7toiso(). The following is a Perl-version of utf7encode: #! /usr/bin/perl -w use Unicode::Utf7; while (<>) { chomp; print isotoutf7($_),"\n"; } And the same for utf7decode: #! /usr/bin/perl -w use Unicode::Utf7; while(<>) { print deutf7($_); } sendfile-2.1b/contrib/xhoppel/xhoppel.c0000600000175100001440000001000306304126052017755 0ustar framstagusers/* $XConsortium: xbiff.c,v 1.19 94/04/17 20:43:28 rws Exp $ */ /* Copyright (c) 1988 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ #include #include #include #include #include "Mailbox.h" #include extern void exit(); static void quit(); char *ProgramName; static XrmOptionDescRec options[] = { { "-update", "*mailbox.update", XrmoptionSepArg, (caddr_t) NULL }, { "-file", "*mailbox.file", XrmoptionSepArg, (caddr_t) NULL }, { "-volume", "*mailbox.volume", XrmoptionSepArg, (caddr_t) NULL }, { "-shape", "*mailbox.shapeWindow", XrmoptionNoArg, (caddr_t) "on" }, }; static XtActionsRec xhoppel_actions[] = { { "quit", quit }, }; static Atom wm_delete_window; static void Usage () { static char *help_message[] = { "where options include:", " -display host:dpy X server to contact", " -geometry geom size of mailbox", " -file file file to watch", " -update seconds how often to check for mail", " -volume percentage how loud to ring the bell", " -bg color background color", " -fg color foreground color", " -rv reverse video", " -shape shape the window", NULL}; char **cpp; fprintf (stderr, "usage: %s [-options ...]\n", ProgramName); for (cpp = help_message; *cpp; cpp++) { fprintf (stderr, "%s\n", *cpp); } fprintf (stderr, "\n"); exit (1); } void main (argc, argv) int argc; char **argv; { XtAppContext xtcontext; Widget toplevel, w; ProgramName = argv[0]; toplevel = XtAppInitialize(&xtcontext, "XHoppel", options, XtNumber (options), &argc, argv, NULL, NULL, 0); if (argc != 1) Usage (); /* * This is a hack so that f.delete will do something useful in this * single-window application. */ XtAppAddActions (xtcontext, xhoppel_actions, XtNumber(xhoppel_actions)); XtOverrideTranslations(toplevel, XtParseTranslationTable ("WM_PROTOCOLS: quit()")); w = XtCreateManagedWidget ("mailbox", mailboxWidgetClass, toplevel, NULL, 0); XtRealizeWidget (toplevel); wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", False); (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), &wm_delete_window, 1); XtAppMainLoop (xtcontext); } static void quit (w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { if (event->type == ClientMessage && event->xclient.data.l[0] != wm_delete_window) { XBell (XtDisplay(w), 0); return; } XCloseDisplay (XtDisplay(w)); exit (0); } sendfile-2.1b/contrib/java/0000755000175100001440000000000011025466700015415 5ustar framstaguserssendfile-2.1b/contrib/java/SaftVersion.class0000755000175100001440000000263206322006535020715 0ustar framstagusersÊþº¾-cJbQZ5ç9>:@EaK7\0AOH= ( % . - $ / & + * , ) ' # & R6 TD ^] _G _C F[ NV 3; B` W4 _L _M U]java/io/PrintStream ConstantValueSaftVersion.javagetInputStream(Ljava/lang/String;)Z(USAGE: java SaftVersion.class (Ljava/lang/String;)V SaftVersion Exceptions Can't find 's SAFT:()Ljava/io/InputStream; SourceFilejava/lang/SystemError connecting to mainquitjava/io/IOExceptiongetOutputStream(Ljava/lang/String;I)V(I)Ljava/lang/String;java/io/DataInputStreamappend()Vjava/lang/StringSAFTPORT221java/net/Socket(Ljava/io/OutputStream;)V(Ljava/io/InputStream;)Voutjava/net/UnknownHostException([Ljava/lang/String;)V215printlnI substringtoStringLjava/io/PrintStream; startsWithCodeLocalVariablesNo Version found!?,(Ljava/lang/String;)Ljava/lang/StringBuffer;java/lang/StringBuffer()Ljava/lang/String;readLine()Ljava/io/OutputStream;java/lang/Objectversion IS1 ?PXêÎ*¾žÃM» Y*2ç· N» Y-¶·:»Y-¶·:¶! ¶!¶L+¶™ +¶M+¶™ÿå,Æ&²»Y·*2¶ ¶¶¶!²,¶!±²¶!±W²»Y·¶*2¶¶¶!±W²»Y·¶*2¶¶¶!±²¶!±Š‹Ѝ_GX*·"±<2sendfile-2.1b/contrib/java/SaftVersion.java0000644000175100001440000000255306322006430020522 0ustar framstagusers/** * Diese Klasse testet die verwendete sendfiled-Version eines * angegebenen Servers. *

* Sollte man vielleicht nicht zu oft aufrufen. Einige beobachten * ihre Logfiles sehr genau. * * @author Stefan Scholl * @version $Id$ */ import java.net.*; import java.io.*; public class SaftVersion { static final int SAFTPORT = 487; public static void main( String argv[] ) { if( argv.length > 0 ) { try { String line, version = null; Socket sock = new Socket( argv[0], SAFTPORT); DataInputStream sdin = new DataInputStream(sock.getInputStream()); PrintStream spout = new PrintStream(sock.getOutputStream()); spout.println("version"); spout.println("quit"); do { line = sdin.readLine(); if( line.startsWith("215") ) version = line.substring(4); } while ( !line.startsWith("221")); if( version != null ) { System.out.println(argv[0] + "'s SAFT:"); System.out.println(version); } else { System.out.println("No Version found!?"); } } catch ( UnknownHostException e ) { System.out.println("Can't find " + argv[0]); } catch ( IOException e ) { System.out.println("Error connecting to " + argv[0]); } } else { System.out.println("USAGE: java SaftVersion.class "); } } } sendfile-2.1b/contrib/perl/0000755000175100001440000000000011025466700015436 5ustar framstaguserssendfile-2.1b/contrib/perl/distr.pl0000755000175100001440000000505006317720344017130 0ustar framstagusers#! /usr/bin/perl # distr.pl 199703062030 # Example of a sendfiled post processing filter # ======= # # Insert the following line to /usr/local/etc/sendfile.aliases: # # distrtest | /distr.pl # # # Use the right strings instead of and . Modify the # distribution list in the global section of this source. # # History # # * 1997-03-31T13:30+02 Stefan Scholl # - Some minor code cleanup # - read() instead in read-loop # * 1997-03-03T20:26+01 Stefan Scholl # - Use the module Unicode::Utf7 # - Insert comment (and forward the old one, too) # * 1997-02-01T16:45+01 Stefan Scholl # - First Version use Unicode::Utf7 qw( utf7toiso ); #-globals--------------------------------------------------- # SAFT-Urls for all receivers @distlist = qw( saft://parsec.inka.de/stesch saft://bofh.belwue.de/framstag ); $tempdir = $ENV{'TMPDIR'} or $tempdir = '/tmp'; $gzippath = '/usr/local/bin/gzip'; $sendfilepath = '/usr/local/bin/sendfile'; $PACKET = 512; #----------------------------------------------------------- # Sideeffect: result is in %shead sub readsafthead { my $l; while($l = ) { my ($key, $val); $l =~ tr/\r\n//d; # get rid of CRs and LFs. ($key, $val) = split(/\s+/, $l, 2); return if uc($key) eq 'DATA'; $shead{uc($key)} = utf7toiso($val); } } #----------------------------------------------------------- #-main------------------------------------------------------ # Reading the header into %shead. Following data on STDIN is # the transfered file. &readsafthead; # Comment if(defined($shead{'COMMENT'})) { # There's allready a comment $comment = "forward from $shead{FROM}\r\n$shead{'COMMENT'}"; } else { $comment = "forward from $shead{FROM}"; } if($shead{'TYPE'} =~ /COMPRESSED/i) { $outf = "|$gzippath -dc >$shead{FILE}"; } else { $outf = ">$shead{FILE}"; } chdir($tempdir); if(open(OUT, $outf)) { my $data; while(read(STDIN, $data, $PACKET)) { print OUT $data; } close(OUT); # Now we have the received file in $tempdir. # Time to distribute it. foreach $receiver (@distlist) { system("$sendfilepath $shead{FILE} -c '$comment' $receiver"); } # get rid of it! unlink($shead{FILE}); } else { # right place for error logging. :-) } #----------------------------------------------------------- sendfile-2.1b/contrib/perl/psendmsg.pl0000755000175100001440000000244506305570363017631 0ustar framstagusers#!/usr/bin/perl -w require 5.002; use Socket; use Unicode::Utf7; use Getopt::Std; # Init and globals my $proto = getprotobyname('tcp'); my $port = getservbyname('saft', 'tcp'); my $CRLF = "\x0d\x0a"; my $host; my $user; my $message; my $whoami = $ENV{'USER'} . ' ' . isotoutf7((getpwnam($ENV{'USER'}))[6]); getopts('h:u:m:'); $host = !defined($opt_h) ? 'localhost' : $opt_h; if(!defined($opt_u)) { print <<"EOT"; MISSING username! USAGE: psendmsg.pl [-h host] -u user EOT exit 1; } else { $user = $opt_u; } if(defined($opt_m)) { $message = $opt_m; } else { my $line; $message = ''; print "Enter your message, terminated with single '.':\n\n--->\n"; $line = ; while($line !~ /^\.$/) { $message = $message . $line; $line = ; } print "<---\n\n"; } my $hisiaddr = inet_aton($host) || die "unknown host"; my $hispaddr = sockaddr_in($port, $hisiaddr); socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; connect(SOCKET, $hispaddr) || die "bind: $!"; select(SOCKET); $|=1; select(STDOUT); print SOCKET "from $whoami$CRLF"; print SOCKET "to ", isotoutf7($user),$CRLF; print SOCKET "msg ", isotoutf7($message), $CRLF; print SOCKET "quit",$CRLF; while() { print; } close(SOCKET); sendfile-2.1b/contrib/perl/Utf7.pm0000644000175100001440000000350106306504101016612 0ustar framstaguserspackage Unicode::Utf7; require 5.000; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(isotoutf7 utf7toiso); # converts ISO-8859-1 to utf7 sub isotoutf7 { my $l = shift; $l =~ s/\+/\+-/gs; $l =~ s/([^\x21-\x7e]+)/'+' . enb64($1) . '-'/ges; return $l; } # converts utf7 to ISO-8859-1. # # ATTENTION: All Unicodes > 255 are replaced with _. sub utf7toiso { my $l = shift; $l =~ s/\+-/+ACs-/g; # arghl! $l =~ s/\+(.*?)-/deb64($1)/ge; return $l; } ################################################################# # decode base64 # # algorithm by Randal Schwartz # code by bad@ora.de (Christoph Badura) # modified by Stefan Scholl sub deb64 { my $l = shift; $l =~ tr#A-Za-z0-9+/##cd; # remove non-base64 chars $l =~ tr#A-Za-z0-9+/# -_#; # convert to uuencoded format $len = pack("c", 32 + 0.75*length($l)); # compute length byte $l = unpack("u", $len . $l); # uudecode $l =~ s/(.)(.)/$1 ne "\000" ? '_' : $2/ges; return $l; } # encode base64 # # algorithm based on an idea by Randal Schwartz # code by bad@ora.de (Christoph Badura) # modified by Stefan Scholl sub enb64 { my $l = shift; my ($p, $r); my $len; $l =~ s/(.)/\x00$1/gs; $len = length($l); $l .= "\0" x (3 - ($len % 3)) if $len % 3; # pad with nul bytes $l = pack("u", $l); # uuencode $r = ''; foreach $p (split(/\n/, $l)) { $p = substr($p, 1); # strip length byte $p =~ s/\n//gs; # deletes newline $p =~ tr#` -_#AA-Za-z0-9+/#; # convert to base64 format $p =~ s/A$// if ($len % 3) == 2; # fix base64 pad chars $p =~ s/AA$// if ($len % 3) == 1; $r = $r . $p; } return $r; } sendfile-2.1b/contrib/perl/perlmodule_unicode_utf7.tar.gz0000644000175100001440000000230606305571560023417 0ustar framstagusers‹pó3íWÛnÛFõkùI…È8¼I¢[qb5õƒrAlE«Ö]“+‰0µËì.-+Eúí%©›c#E'(º‚d.g†3g.Ÿ«qßËg;‰0öz=ØûQ°ù[¢!À^7ˆ¢½^Ôëãí°Ûëî@ð ^Õ(¤"`G**ãéýrŸ»ÿENâ+2¡pÎÒ˜'ôàà b` ú¾H…È ‚`}y|“s¡¨XÖÑÉéáýÜ^:ëèøç·oÞUç©äŠhô—âx"–Õ„˜³k*”„“Ó7îӧѾ‚⥘%‹KXkþié ™- •¡Q9MÇ Mè3}ðH´‹ןÈÁÖ±ýëNèŽnúô·]Çoï¶ÁÊ.÷zv+tðï¶Ûö'TÖæU…`¨>°>n¹XºÎ­]õ¬& ÏÎŽ_Ÿ¼y}Ã,[ò'á9t¢’%hž‘˜&0OÕ.¼2´w‡¦n…çú»Ã—#ÀšøˆÉ4{tKØö¿p\?¡uœá†Ñí 1Ì/…f*¡:p¸$’îõJjH6ácžÁåÞ– Nãéœõ¡¤V‹/P#9â‚xxe¿œŠT*žOá’‚8(7ãI:N‘?”=UtL˜¶Â‘ìgU3É+é¥ìJ›x^²[ÆýÙ¢Q¢9t!î‡ÀÝßõ›Í8Ù¢¹tƯ)0ÎÜ*.ˆ§DÈûm€{Ѽ•Ÿº‚ÊÂ.(ÓQ'0æbFTm‡2tO7 ÝˆO Û]¼~ôïLÔÔneŽ3(-ÍòBQ¨Ž‘EWž@Á* Z(Mzøã JŠ¢JÎvgx~üVŒBc„ýÝ€оhô:UKÜQ,M¨b¸'Ñx˜g€IJJ¾jæËÔ—­}Sá‘ÝÊ‘"=¦V2”Ýš&š™ÑM´Â‰Ræi“Õ ñ5 ¸» .Ú×’ßC×q ÃòJg0'õ`EVæo]J°™>g»·êiYD3B z»]ùƒ•EI<…V¶Ì³TÙþˆù¥Q§¦¥ÔÉ5/Å¥T¢ä#¼û‘M@4ÿ¤ä–&ÊiÃ|MÒý'4£*ÖÙðq©Qç«z£4_Há_¦Ì¯<Ÿ¯'w!?Ù¸W÷ʯù4ÍðåøìùæìFêgõ,ÒȆ½Þ•íÖ…ó¤1bå´B 1®$3‚(ý¬v‚ƒ禵vï–w•;kêÐ¥'ßºÈ þGøwÚÉT(sendfile-2.1b/contrib/perl/distrX.pl0000755000175100001440000000715406317717720017273 0ustar framstagusers#! /usr/bin/perl # distrX.pl 199703062030 # Example of a sendfiled post processing filter # ======= # using the extended header feature of sendfile # # # Insert the following line to /usr/local/etc/sendfile.aliases: # # distrXtest | /distrX.pl # # # Use the right strings instead of and . Modify the # distribution list, $sender and $realname in the global section. # # History # # * 1997-03-31T13:25+02 Stefan Scholl # - First version with extended header feature # - POSIX::tmpnam() # * 1997-03-06T21:30+01 Stefan Scholl # - Some minor code cleanup # - read() instead in read-loop # * 1997-03-03T20:26+01 Stefan Scholl # - Use the module Unicode::Utf7 # - Insert comment (and forward the old one, too) # * 1997-02-01T16:45+01 Stefan Scholl # - First version use Unicode::Utf7 qw( isotoutf7 utf7toiso ); use POSIX; #-globals--------------------------------------------------- # SAFT-Urls for all receivers @distlist = qw( saft://parsec.inka.de/stesch saft://bofh.belwue.de/framstag ); # Don't forget to set the right from $sender = 'Distributor'; $realname = 'Test Testerson'; $sendfilepath = '/usr/local/bin/sendfile'; $PACKET = 512; $CRLF = "\x0d\x0a"; #----------------------------------------------------------- # Sideeffect: result is in %shead sub readsaftheadraw { my $l; while($l = ) { my ($key, $val); $l =~ tr/\r\n//d; # get rid of CRs and LFs. ($key, $val) = split(/\s+/, $l, 2); return if uc($key) eq 'DATA'; $shead{uc($key)} = $val; } } #----------------------------------------------------------- #-main------------------------------------------------------ # Reading the header into %shead. Following data on STDIN is # the transfered file. &readsaftheadraw; foreach $k (keys %shead) { print ">$k< : >$shead{$k}<\n"; } # Comment if(defined($shead{'COMMENT'})) { # There's allready a comment $comment = isotoutf7('forward from ' . utf7toiso($shead{FROM})) . isotoutf7($CRLF) . $shead{'COMMENT'}; } else { $comment = isotoutf7('forward from ') . $shead{FROM}; } # FROM if(defined($realname)) { $from = isotoutf7($sender) . ' ' . isotoutf7($realname); } else { $from = isotoutf7($sender); } # Name of tempfile $outf = tmpnam(0); if(open(OUT, ">$outf")) { my $data; while(read(STDIN, $data, $PACKET)) { print OUT $data; } close(OUT); # Now we have the data of the received file in $outf. # No matter if it's compressed or not. It's the raw data. # Time to distribute it. foreach $receiver (@distlist) { my($host, $to) = ($receiver =~ /^saft:\/\/(.*?)\/(.*)/); open(DF, $outf) || die "Can't open $outf\n"; if(open(SF, "|$sendfilepath -X $host")) { my $data; print SF "FROM $from" . $CRLF; print SF "TO " . isotoutf7($to) . $CRLF; print SF "COMMENT $comment" . $CRLF; foreach $key (keys %shead) { next if $key eq 'FROM'; next if $key eq 'TO'; next if $key eq 'COMMENT'; print SF "$key $shead{$key}" . $CRLF; } print SF "DATA" . $CRLF; while(read(DF, $data, $PACKET)) { print SF $data; } close(SF); } else { # Errors suck! } close(DF); } # get rid of it! unlink($outf); } else { # right place for error logging. :-) } #----------------------------------------------------------- sendfile-2.1b/LIESMICH0000777000175100001440000000000011025466700016036 2doc/LIESMICHustar framstaguserssendfile-2.1b/doc/0000755000175100001440000000000011025466700013601 5ustar framstaguserssendfile-2.1b/doc/sendfiled.80000644000175100001440000000502410251132201015612 0ustar framstagusers.\" Personal .TH SENDFILED 8 .UC L .SH NAME sendfiled - Simple Asynchronous File Transfer server .SH SYNOPSIS .B sendfiled [ .B \-4 | .B \-6 ] [ .B \-d ] [ .B \-f ] [ .B \-q ] [ .B \-Q ] [ .B \-c configfile ] .SH DESCRIPTION .B sendfiled is a server process (daemon) for the Simple Asynchrnous File Transfer (SAFT) protocol. The server is normally called by inetd (8) and receives files or messages sent by SAFT-clients to the. Files are stored in the recipient's spool and messages are written to the recipient's terminals. .PP The .B \-4 and .B \-6 options explicitly force IPv4 or IPv6 connections. By default, the program will try to resolve the name given, and choose the appropriate protocol automatically. If resolving a host name returns both IPv4 and IPv6 addresses, sendfiled will try to use the adresses in the order they are returned by the resolver. .PP If the .B \-d option is specified, debugging information is written to /var/log/sendfiled.dbg. .PP If the .B \-f option is specified, .B sendfiled prints the free disk space on /var/spool/sendfile and terminates. .PP If the .B \-q option is specified, .B sendfiled processes once the outgoing spool and terminates. .PP If the .B \-Q option is specified, .B sendfiled starts an outgoing spool daemon, which runs in an endless loop in the background. .PP On startup .B sendfiled reads its configuration file /usr/local/etc/sendfile.cf, but you can specify with .B \-c configfile an alternate configuration file. .PP .B sendfiled is also an O-SAFT server, which means authenticated clients can fetch files. See fetchfile (4) for details. .PP .B sfdconf is the .B sendfiled configuration helper program. It has its own usage help, just type .B sfdconf -h .SH FILES .TP 6 .I /usr/local/etc/sendfile.deny Users which are not allowed to receive files or messages. .TP .I /usr/local/etc/sendfile.allow Users which are ONLY allowed to receive files or messages. If this file has at least one entry, then .I /usr/local/etc/sendfile.deny will be ignored. .TP .I /usr/local/etc/sendfile.aliases Alias names for local users. Format is: .ES alias realname .EE .TP .I /var/spool/sendfile/LOG/in Log file for incoming files. .TP .I /var/spool/sendfile/LOG/out Log file for outgoing files. .TP .I /usr/local/etc/sendfile.cf The system configuration file. See .B sfdconf -i config for a complete description and default values. .SH SEE ALSO .BR sfdconf .BR sendfile (1) .BR receive (1) .BR sendmsg (1) .BR fetchfile (1) .BR fetchfile (4) .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de sendfile-2.1b/doc/NEWS0000644000175100001440000002302410251132201014263 0ustar framstagusersIn diesem File werden neue Feature beschrieben, die noch nicht im (veralteten) doku.ps enthalten sind. Irgendwann demnaechst wird die ganze Doku ueberarbeitet, dann verschwindet auch dieses File wieder. Die Behebung von Bugs wird in ChangeLog beschrieben. - Neue Option -m LIMIT fuer sendfile um den maximalen Durchsatz auf LIMIT KB/s zu beschraenken. - Neue sendfile.cf Option lanspeed: damit kann festgelegt werden, bis zu welchem Durchsatz in KB/s andere Hosts als lokal definiert werden, was zur Folge hat, dass an diese Hosts nicht komprimiert verschickt wird. - Unterstuetzte regular expressions: ? matches any single character * matches any string [abc] matches 'a' or 'b' or 'c' within [] the characters '?', '*' and '[' are no wildcards [^abc] matches every character but not 'a' or 'b' or 'c' [a-d] matches 'a' or 'b' or 'c' or 'd' (range) this is equal to [abcd] [^a-d] matches every character but not 'a' or 'b' or 'c' or 'd' (range) this is equal to [^abcd] \? test for "true" '?' alternative: [?] \* test for "true" '*' alternative: [*] \[ test for "true" '[' alternative: [[] \a Bell \b BackSpace \f FormFeed \n NewLine \r Return \t Tab \v FormFeed \\ Backslash - sendfile-2.1 hat jetzt bzip2 Support. bzip2 ist ein neues lizenzfreies Komprimierungsprogramm und ist etwa 10-30% effizienter als gzip (http://www.muraroa.demon.co.uk/) - Neue Hilfsprogramme zum Konfigurieren: fuer den User: sfconf fuer den Admin: sfdconf - Protokoll-Erweiterung O-SAFT mit neuem Client fetchfile: siehe LIESMICH.fetchfile - Die Syntax der sendfile Option "-a archive-name" wurde geaendert zu "-a=archive-name" um eine Fehlbedienung zu minimieren. Aus Orthogonalitaetsgruenden ist jetzt auch "-c='comment'" neben "-c 'comment'" zulaessig. - Neue receive Option "-S keyring" erzwingt einen Signaturcheck. Nur wenn dieser positiv ist, wird das File empfangen. Wichtig fuer Batch-Betrieb. - Wird ein File erkannt, das nicht komprimierbar erscheint (typische File- Extension oder Erkenntnis durch file(1)-Programm), dann wird unkomprimiert verschickt. Mit der Option -C kann Komprimierung erzwungen werden. - Messages koennen in /var/spool/sendfile/$USER/msglog geloggt werden, wenn die Option msglog = on im /var/spool/sendfile/$USER/config/config oder sendfile.cf gesetzt ist. - Das Verhalten des tty Tests von sendmsg wurde geaendert. Jetzt gilt: Die erste message, die ankommt wird vom sendfiled auf allen ttys ausgegeben, die fuer group schreibberechtigt sind. Dasselbe wird erreicht durch: sendmsg -M Wird eine message abgeschickt und ist kein tty als aktiv markiert, so wird das aktuelle tty als aktiv markiert. Das bedeutet dass ab sofort einkommende messages nur noch auf dieses tty ausgegeben werden. Wird versucht auf einem tty eine message zu verschicken, das schreibgeschuetzt ist oder waerend ein anderes tty als aktiv markiert ist, so kommt es zu einer Fehlermeldung. Um trotzdem messages abschicken zu koennen gibt es die Option: sendmsg -f Mit sendmsg -m markiert man das aktuelle tty als aktiv. Das bedeutet, dass messages nur noch hier ausgegeben werden. - Fuer Benchmarktests stehen 2 neue Moeglichkeiten zur Verfuegung: sendfile test /dev/null # testet die Lesegeschwindigkeit sendfile test /dev/null@host # testet zusaetzlich die Uebertragungsgeschwindigkeit In keinem Fall wird das (test) File auf Platte geschrieben. - Protokollaenderung: das TYPE-Kommando erlaubt jetzt auch das Attribut MIME - Protokollaenderung: das CHARSET-Kommando wurde in das TYPE-Kommando integriert: CHARSET charset --> TYPE TEXT=charset (Dies hat keine Kompatibilitaetsauswirkungen, da sendfile bisher die einzige SAFT-Implementierung ist und das TEXT bzw CHARSET Attribut vorerst ignoriert werden koennen.) - Mit der Option -P gibt receive ein File auf stdout aus (kann dann via Pipe weiterverarbeitet werden). Beispiel: receive -kP readme | more (Die Option -k verhindert, dass das File aus dem spool geloescht wird) - Mit der Option -P kann sendfile von stdin (bzw aus einer Pipe) lesen. Beispiel: ls -l | sendfile -P my_dir framstag@bofh.belwue.de Dabei handelt es sich nicht um synchrones Piping im klassischen (Unix-) Sinn, sondern der data stream von stdin wird in ein tmp-File geschrieben (transparent fuer den User) und erst wenn ein EOF von stdin kommt, wird dieses Zwischenfile abgeschickt. Dasselbe Prinzip verwendet zB der lpd bzw lpschedul. - sendfiled hat die runtime option "-c " bekommen, welches anstelle dem eincompilierten CONFIG Wert auf das sendfile-config- file zeigt. Beispieleintrag in /etc/inetd.conf : saft stream tcp nowait root /usr/local/sbin/sendfiled sendfiled -c /local/etc/sendfile.cf - Existiert /var/spool/sendfile/.nosendfile, so werden vom sendfiled keine Files mehr angenommen und auch laufende Transfers werden abgebrochen. - In config.h kam das neue Macro ALIASES hinzu. Existiert das dazugehoerende File (wird von root verwaltet), dann setzt der sendfiled die Adressen entsprechend um. Beispiel fuer so ein sendfile.aliases: frams framstag # lokaler Username Umsetzung delta zrzs0111 # lokaler Username Umsetzung blubb bla@gaga.banane.net # forward Adresse auf anderen Host - forwards koennen jetzt geschachtel werden, maximaler hopcount ist 10 - sendfile 1.5 hat jetzt pgp Support eingebaut: Files koennen verschluesselt und/oder mit digitaler Signatur uebertragen werden, vorausgesetzt, sowohl auf Empfaenger-, als auch auf Sendersystem ist pgp installiert. Neue Optionen fuer sendfile (Argumente in [] sind optional): -pe[=to_user] pgp Verschluesselung -pc pgp IDEA Verschluesselung (symmetrisch) -ps[=my_ID] pgp Signierung Beispiel fuer das Verschicken eines verschluesselten Archivs: sendfile -pe -a geheim *.gif hoppel@juhu.lake.de Der pgp public key fuer hoppel muss latuernich vorhanden sein. - Die neue Option "-f from_user" erlaubt es bei receive anzugeben auf welche Files von welchem Sender die Aktion gilt, zB: receive -L -f framstag # listet nur die Files von mir receive -daf microsoft.com # loescht alle files, die von Winzigweich gekommen sind. - Die neue Option "-s" bei receive gibt eine "short file list" aus (ohne Kommentare, Signaturen, etc). - Die neue Option "-o" (overwrite) erlaubt es, bei sendfile ein File zu schicken und ein File gleichen Namens zuvor zu loeschen (falls es sich noch im Empfaengerspool befindet). sendfile -o blubb heiko ist gleichbedeutend mit: sendfile -d blubb heiko sendfile blubb heiko - Bei receive kann jetzt nicht nur zwischen Ueberschreiben oder Uebergehen ausgewaehlt werden, wenn ein File gleichen Namens schon existiert, sondern es kann gleich ein neuer Name angegeben werden. - Ein neues Fileattribute COMMENT wurde eingefuehrt. Damit kann zu einem File ein kurzer Kommentar angegeben werden, der dann in der receive- Liste erscheint. Automatisch wird ein Kommentar beim bouncing und forwarding erzeugt. Beim Versenden kann ein Kommentar zB angegeben werden mit: sendfile -c "ein ganz niedlicher Hase!" rabbit.gif beate@juhu.lake.de - Um das Logfile, das ja UTF-7 codiert ist, korrekt lesen zu koennen, wurden die Programme utf7decode bzw utf7encode erstellt, mit denen man Textfiles von bzw nach UTF-7 wandeln kann. - Die Supportprogramme gzip, tar, pgp und recode koennen nun mit Pfad in config.h definiert werden. Durch Setzen der Environment-Variablen SF_TAR, SF_GZIP, SF_PGP und SF_RECODE koennen diese Werte wiederum geaendert werden. - Ist eine forward-Adresse (vom User oder vom Admin) gesetzt, dann folgt sendfile diesem Hinweis und sendet seine Files dorthin. Eine Verschachtelung von forwards ist nicht erlaubt. - Ein User kann sich in /var/spool/sendfile/$USER/config/config mit der Option "forward = user@host" eine forward Adresse fuer sich setzen. Der Admin kann Userforwarding global unterbinden, indem er in sendfile.cf die Option "forwarding = off" setzt. - Mit receive kann ein File aus dem Spool gleich weitergeschickt werden ("bouncing") mit: receive -b file_name other_user@other.host - sendmsg, sendfile und receive haben die Option -q bzw -Q hinzubekommen fuer einen "quiet" Modus: es werden keine Meldungen mehr ausgegeben oder Fragen gestellt. - receive faengt jetzt gefaehrliche Filenamen ab; dies sind Files, die mit "." beginnen oder relative oder absolute Pfade in tar-Files. - Bei nicht komprimierbaren Files (Erkennung ueber /etc/magic) erfolgt keine automatische Komprimierung mehr. - Ein besseres Transaktions Ausgabeformat wurde eingefuehrt. - Das Attribute "ATTR EXE" wurde fuer Unix und VMS eingefuehrt. Bei ausfuehrbaren Files (Programmen) wird das execute-Flag im Filesystem entsprechend gesetzt nach dem receive. - User der ksh oder bash koennen sich folgende Variablen setzen (am besten in ~/.profile), um von der Shell ueber neue Files im Spool informiert zu werden: $ export MAILPATH=/var/spool/mail/$LOGNAME:\ /var/spool/sendfile/$LOGNAME/log%'new file in spool!' $ export MAILCHECK=0 Dazu empfiehlt es sich in /var/spool/sendfile/$LOGNAME/config/config die Option: notification = none zu setzen. sendfile-2.1b/doc/THANKS0000644000175100001440000000236010251132201014477 0ustar framstagusersThanks goes to: Lorenz Adena: for features requesting and beta testing Rainer Bawidamann: for code contributions Thomas Beisel: for C consulting, postscript magics and beta testing Uwe Berger: for discussions on principles and design helps Martin Buck: for code contributions Olaf Erb: for code contributions Christoph Goern: for transforming to GNU autoconfigure Beate Herrmann: for basic ideas, psychologic care and beta testing Olaf Hopp: for HP-UX support Bruce C. Law: for help on the english documentation Andreas Ley: for many helps on obscure C problems and for the peername function Annette Maier: for help on the english documentation Shannon Miller: for help on the english documentation Uwe Obermüller: for many suggestions and beta testing Bernd Onasch: for C consulting Andreas Ott: for translation of the SAFT/sendfile WWW pages Christian Recktenwald: for code contributions and Convex support Jörg Scheurich: for monster-bug hunting Heiko Schlichting: for code contributions and code reviewing Stefan Scholl: for SAFT missioning and Perl support code Martin Schulze: for the wlock and utf7encode man pages Thomas Tissen: for code contributions and beta testing Hanno Wagner: for the sendfile/SAFT FAQ sendfile-2.1b/doc/LIESMICH.spool0000644000175100001440000000555610251132201016051 0ustar framstagusersMit sendfile 1.6-19970708 ist echtes asynchrones Verschicken ueber einen Outgoing Spool verfuegbar. Eigentlich war der Code schon seit fast 1 Jahr drin und wartete nur darauf, dass ich ihn endlich mal debuggte und fertig stellte. Nun isses so weit :-) sendfile hat dafuer 2 neue Optionen zur Verfuegung: -S sendet nicht direkt, sondern legt das File im Outgoing Spool ab -l listet Files im Outgoing Spool Beispiel: moep:~/sendfile/sendfile-1.6> sendfile -S Makefile framstag@bofh.belwue.de %sendfile-I, 'Makefile' spooled moep:~/sendfile/sendfile-1.6> sendfile -l Files in outgoing spool: framstag@bofh.belwue.de : Makefile Oder etwas ausfuehrlicher: moep:~/sendfile/sendfile-1.6> sendfile -Suv makeconfig framstag@bofh.belwue.de %sendfile-I, makeconfig is of type: Bourne shell script text %sendfile-I, 'makeconfig' spooled 220 moep.bb.bawue.de SAFT server (sendfiled 1.6 on Linux) ready. -> START SPOOLDAEMON 200 Command ok. Wie man sieht, nimmt sendfile am Ende noch schnell Kontakt zum eigenen sendfiled auf und sagt ihm, er solle den spooldaemon starten. Der sendfile spool daemon ist im normalen sendfiled enthalten und wird von diesem via fork gestartet. Fuer jeden Zielhost, den er im Outgoing Spool findet, wird erneut ein sfsd geforkt, der dann versucht zu diesem host eine Verbindung aufzubauen. Dies habe ich gemacht, um zu verhindern, dass sich die tcp-timeouts zu sehr addieren. Alternativ kann ueber die sendfile.cf Option parallel=off auch erzwungen werden, dass nur ein sfsd laeuft, der alles hintereinander abarbeitet. Ist ein Host nicht erreichbar, so wird fuer X Minuten gewartet, um es erneut zu versuchen. Kommt es nach Y Tagen zu keiner erfplgreichen Uebertragung, so wird das betreffende File an den Absender zurueckgeschickt; genauer gesagt: es landet in dessen Incomming Spool. X und Y sind in sendfile.cf konfigurierbar ueber die Optionen retry und bounce. Der Absender kann aber auch Files aus dem Outgoing Spool loeschen, Beispiel: moep:~> sendfile -Sd Makefile framstag@bofh.belwue.de %sendfile-I, deleted from outgoing spool: 'Makefile' for framstag@bofh.belwue.de Die Abarbeitung der Outgoing Queue kann aber auch von root direkt angestossen werden mit: sendfiled -q Dabei wird nur einmal versucht auszuliefern und nicht in einer Endlosschleife. Es ist trotzdem zu empfehlen in das System Bootscript folgende Zeile aufzunehmen: /usr/local/sbin/sendfiled -Q Damit wird sichergestellt, dass liegengebliebene Files im outgoing spool gleich weiterverarbeitet werden und nicht erst wenn der naechste User es mit sendfile anstoesst. Anmerkung: der sendfile spool daemon arbeitet mit locking und kommt daher nicht durcheinander wenn versucht wird ihn mehrfach zu starten. Spaeter gestartete sendfile spool daemon terminieren einfach, wenn sie merken, dass die queue bereits abgearbeitet wird. Nur "sendfiled -q" arbeitet die outgoing spool queue in jedem Fall einmal ab. sendfile-2.1b/doc/sendfile.10000644000175100001440000001267210251132201015446 0ustar framstagusers.\" Personal .TH SENDFILE 1 .UC L .SH NAME sendfile - send file(s) via Internet .SH SYNOPSIS .B sendfile [ .B \-stMgduzvolSPiqQV ] [ .B \-c=" comment" ] [ .B \-C=program ] [ .B \-ps=[my_ID] ] [ .B \-pe=[to_user] ] [ .B \-m LIMIT ] .I file [...] .I user[@host] .PP .B sendfile .BI \-a=" archive" [ .B \-uviqQ ] [ .B \-c=" comment" ] [ .B \-C=program ] [ .B \-ps[=my_ID] ] [ .B \-pe[=to_user] ] .I file_or_directory [...] .I recipient .SH DESCRIPTION .B sendfile sends files to the specified recipient. .PP On the receiving site there must be a SAFT-server (Simple Asynchronous File Transfer) installed like .B \%sendfiled which stores incoming files into the recipients spool-directory. .PP SAFT knows about 4 file types: .TP 8 .B BINARY Byte-stream file which will not be modified. .TP 8 .B SOURCE Record oriented program source file. Only EOL will be translated. .TP 8 .B TEXT Human readable text files. EOL and the character set (like German umlauts) will be translated. .TP 8 .B MIME Multipurpose Internet Mail Extension file as defined by RFC 2045-2049. .PP Files can be sent compressed or pgp-encrypted and/or pgp-signed. As an extension to SAFT, .B sendfile is able to send multiple binary files in one archive file. .PP Default mode for .B sendfile is sending compressed binary files. Compression will be disabled for hosts which are inside your LAN and for files which cannot be compressed. .PP With the helper program .B sfconf you can easily configure sendfile. .SH ARGUMENTS You have to specify at least one file name and the recipient's address. An address can be specified as: .TP 4 .B user a local user or a sendfile alias (see below), e.g.: framstag .TP .B user@host an user on a remote host, e.g.: framstag@bofh.belwue.de .TP .B saft://host/user like above, but in URL-syntax, e.g.: saft://bofh.belwue.de/framstag .TP .B saft://host:port/user like above, but with alternate SAFT-port, e.g.: saft://bofh.belwue.de:4870/framstag .SH OPTIONS .TP 8 .B -4, -6 Explicitly force IPv4 or IPv6 connections. By default, the program will try to resolve the name given, and choose the appropriate protocol automatically. If resolving a host name returns both IPv4 and IPv6 addresses, sendfile will try to use the adresses in the order they are returned by the resolver. .TP .B -s Send in source mode (not needed if sending to a unix host). .TP .B -t Send in text mode (not needed if sending to a unix host). .TP .B -M Send MIME file (must be external composed before!). .TP .B -g Send in guessed mode: sendfile tries to guess the correct mode (source, text or binary). This will not work in every case and not on all platforms! .TP .B -i Print more transaction information. .TP .B -v Verbose mode: show SAFT protocol messages. .TP .B -V Show version information and exit. .TP .B -u Send uncompressed. .TP .B -z Send compressed. .TP .B -a Send files or whole directories as one archive (binary mode only). You have to specify an archive name. .TP .B -d Delete previous sent file. No wildcards allowed. .TP .B -o Overwrite already sent file(s) with same name. .TP .B -P Read file from stdin. You must specify a file name, too. .TP .B -S Spool file into outgoing queue for later processing. You must run a sendfiled which supports this mode. .TP .B -l List files in the outgoing spool. .TP .B -q Quiet mode 1: print no transfer messages. .TP .B -Q Quiet mode 2: print no transfer, information or warning messages. .TP .B -c Add a short comment to a single file. .TP .B -C Force usage of specified compression program (gzip or bzip2). .TP .B -pc Encrypt file(s) with pgp (IDEA symmetric). .TP .B -pe Encrypt file(s) with pgp (public key). .TP .B -ps Add pgp signature(s) to the file(s). .TP .B -m Limit the maximum thruput (in KB/s). .SH ARGUMENTS .TP 8 .I user Recipient user name. Can be an alias, too. See below. .TP .I file File name to be sent. Only when using the .BI \-a=" archive" option you may specify any file or directory. .SH EXAMPLES sendfile -t project.txt chief@bigvax.somewhere.net .br .br sendfile -a=jokes -c 'from Gary Larson' *.gif framstag .SH FILES .TP 6 .I /usr/local/etc/sendfile.deny Users which are not allowed to receive files or messages (set by root). .TP .I /var/spool/sendfile/$USER/config/config Your configuration file. Valid entries are (the | symbol means " or"): .ES bell = on|off .EE add a bell when a file or message arrives. .ES deleting = on|off .EE allow remote users to delete their files after transmission .ES msglog = on|off .EE log incoming messages in /var/spool/sendfile/$USER/msglog .ES notification = none|both|mail [user@host]|message [user@host] .EE send a notification when a file has been arrived via mail or message or none or both mechanism. .ES forward = user@host .EE set a forward address. .TP .I /var/spool/sendfile/$USER/config/restrictions List of addresses from where you don't want messages or files. The format is: .ES user@host [mfb] .EE m stands for messages, f for files and b for both. Wildcards * and ? are allowed. Examples: .ES gates@microsoft.com b *aol.com m .EE You may also specify the addresses in URL-syntax. .TP .I /var/spool/sendfile/$USER/config/aliases The sendfile alias file. Format: .ES alias address [sendfile-options] .EE Example: .ES chief grmblfz@bigvax.somewhere.net ccc chaoscomputerclub@saft.ccc.de -pe -ps .EE You may also specify the addresses in URL-syntax. .SH SEE ALSO .BR sfconf .BR receive (1) .BR sendmsg (1) .BR fetchfile (1) .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de sendfile-2.1b/doc/sendmsg.10000644000175100001440000000433310251132201015310 0ustar framstagusers.\" Personal .TH SENDMSG 1 .UC L .SH NAME sendmsg - send a message via Internet .SH SYNOPSIS .B sendmsg [ .B \-46vfrmM ] [ .B \-s 'message' ] .I recipient .SH DESCRIPTION .B sendmsg sends a one line text message to the terminal(s) of the specified recipient. .PP On the receiving site there must be a SAFT-server (Simple Asynchronous File Transfer) installed, like the .B sendfiled and the recipients terminal must be writeable. The .BI recipient address can be specified as: .TP 4 .B user a local user or a sendfile alias (see below), e.g.: framstag .TP .B user@host an user on a remote host, e.g.: framstag@bofh.belwue.de .TP .B saft://host/user like above, but in URL-syntax, e.g.: saft://bofh.belwue.de/framstag .TP .B saft://host:port/user like above, but with alternate SAFT-port, e.g.: saft://bofh.belwue.de:4870/framstag .SH OPTIONS .TP 8 .B -4, -6 Explicitly force IPv4 or IPv6 connections. By default, the program will try to resolve the name given, and choose the appropriate protocol automatically. If resolving a host name returns both IPv4 and IPv6 addresses, sendmsg will try to use the adresses in the order they are returned by the resolver. .TP .B -v Verbose mode: show SAFT protocol messages .TP .B -f Force sending of messages and ignore tty (re)settings. .TP .B -r Reply to last received message. .TP .B -m Receive messages only on this tty. This is the default. .TP .B -M Allow receiving messages on other ttys. .TP .B -s 'message' Send directly .B message .SH EXAMPLES .B sendmsg neg@linux.rus.uni-stuttgart.de .br message: .I how about lunch? .SH FILES .TP 6 .I /usr/local/etc/sendfile.deny Users which are not allowed to receive files or messages (set by root). .TP .I /var/spool/sendfile/$LOGNAME/config/restrictions List of addresses from where you don't want messages or files. The format is: .ES user@host [mfb] .EE m stands for messages, f for files and b for both. Wildcards * and ? are allowed. Examples: .ES gates@microsoft.com b *aol.com m .EE .TP .I /var/spool/sendfile/$LOGNAME/config/aliases The sendfile alias file. Format: .ES alias address .EE Example: .ES chief grmblfz@bigvax.somewhere.net .EE .SH SEE ALSO .BR sendfile (1). .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de sendfile-2.1b/doc/Makefile0000644000175100001440000001150210251132201015222 0ustar framstagusers# Generated automatically from Makefile.in by configure. # Makefile.in generated automatically by automake 1.1l from Makefile.am # Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. SHELL = /bin/sh srcdir = . top_srcdir = .. prefix = /usr/local exec_prefix = ${prefix} bindir = /usr/local/bin sbindir = ${exec_prefix}/sbin libexecdir = /usr/local/sbin datadir = ${prefix}/share sysconfdir = /usr/local/etc sharedstatedir = ${prefix}/com localstatedir = ${prefix}/var libdir = ${exec_prefix}/lib infodir = ${prefix}/info mandir = /usr/local/man includedir = ${prefix}/include oldincludedir = /usr/include pkgdatadir = $(datadir)/sendfile pkglibdir = $(libdir)/sendfile pkgincludedir = $(includedir)/sendfile top_builddir = .. INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} transform = s,x,x, target_alias = i486-pc-linux-gnu build_alias = i486-pc-linux-gnu host_triplet = i486-pc-linux-gnu target_triplet = i486-pc-linux-gnu build_triplet = i486-pc-linux-gnu host_alias = i486-pc-linux-gnu INSTALL_SCRIPT = ${INSTALL_PROGRAM} PACKAGE = sendfile SYSTEM = i486-pc-linux-gnu CC = gcc VERSION = 1.6 REVISION = 19970327 AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 man_MANS = sendfile.1 sendmsg.1 receive.1 EXTRA_DIST = LIESMICH LIESMICH.auch LIESMICH.neu LIESMICH.goern doc.txt \ doku.ps doku.txt mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = .././src/config.h CONFIG_CLEAN_FILES = MANS = sendfile.1 sendmsg.1 receive.1 NROFF = nroff DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ $(TEXINFOS) $(MANS) $(EXTRA_DIST) TAR = tar default: all .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL) cd $(top_srcdir) && automake --gnits doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-man: $(MANS) $(NORMAL_INSTALL) $(mkinstalldirs) $(mandir)/man1 sect=1; \ inst=`echo "sendfile" | sed '$(transform)'`.1; \ if test -f $(srcdir)/sendfile.1; then file=$(srcdir)/sendfile.1; \ else file=sendfile.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst sect=1; \ inst=`echo "sendmsg" | sed '$(transform)'`.1; \ if test -f $(srcdir)/sendmsg.1; then file=$(srcdir)/sendmsg.1; \ else file=sendmsg.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst sect=1; \ inst=`echo "receive" | sed '$(transform)'`.1; \ if test -f $(srcdir)/receive.1; then file=$(srcdir)/receive.1; \ else file=receive.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst uninstall-man: inst=`echo "sendfile" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst inst=`echo "sendmsg" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst inst=`echo "receive" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = doc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done info: dvi: check: all $(MAKE) installcheck: install-exec: $(NORMAL_INSTALL) install-data: install-man $(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-man all: $(MANS) Makefile install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install installdirs: $(mkinstalldirs) $(mandir)/man1 mostlyclean-generic: test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: rm -f Makefile $(DISTCLEANFILES) rm -f config.cache config.log stamp-h test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-generic clean: clean-generic mostlyclean distclean: distclean-generic clean rm -f config.status maintainer-clean: maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default install-man uninstall-man tags distdir info dvi \ installcheck install-exec install-data install uninstall all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sendfile-2.1b/doc/COPYING0000644000175100001440000004307610251132201014630 0ustar framstagusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. sendfile-2.1b/doc/Makefile.am0000644000175100001440000000040110251132201015612 0ustar framstagusers## Process this file with automake to generate Makefile.in AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 man_MANS = sendfile.1 sendmsg.1 receive.1 EXTRA_DIST = LIESMICH LIESMICH.auch LIESMICH.neu LIESMICH.goern doc.txt \ doku.ps doku.txt sendfile-2.1b/doc/README0000644000175100001440000001172610251133450014461 0ustar framstagusersThis is the quick installation guide for sendfile. With sendfile you can transfer files asynchronously from any user A to another user B without B being active in any way. In contrast to ftp one does not have to log on to the recipient's account. For a more detailed description read the file README.too in the doc directory (LIESMICH* is the same in German). The sendfile package contains 5 main programs: sendfiled - the sendfile daemon which will be started by inetd sendfile - the sendfile client for sending files sendmsg - the send-message client for sending one-line text messages receive - the receive client for picking up already received files fetchfile - the O-SAFT client to obtain files from a remote SAFT server sendfile, sendmsg, receive and fetchfile run in user mode, sendfiled has to be installed by root. 1) Adjusting the paths: If you want you may change some default values in "makeconfig" (and ONLY there!). 2) create the Makefiles and configuration files: $ make config 3) compile everything: $ make all There should be no error messages. On some systems with buggy system include files there might be compiler warnings which can be ignored as long as the binaries will be produced. So far, sendfile is tested on AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, Mac-OSX (Darwin) NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris 2) and Ultrix with gcc. 4) install everything automatically (has to be done by root!): $ make install OR install manually: - set correct file protection mask: $ umask 022 - install sendfiled, wherever it makes sense: $ cp src/sendfiled /usr/local/sbin/ - create the spool directories (as described in config.h!): $ mkdir /var/spool/sendfile $ mkdir /var/spool/sendfile/LOG $ mkdir /var/spool/sendfile/OUTGOING $ chmod 700 /var/spool/sendfile/LOG $ chmod 1777 /var/spool/sendfile/OUTGOING Check with "df /var/spool/sendfile" if there is enough free disk space for the spool partition. The minimum free space is defined by the minfree option in sendfile.cf. - add to /etc/services (respectively "niload services ." on NeXT): saft 487/tcp # simple asynchronous file transfer - add to /etc/inetd.conf: saft stream tcp nowait root /path/to/sendfiled sendfiled or if you have tcpd installed (default on Linux): saft stream tcp nowait root /usr/sbin/tcpd /path/to/sendfiled - add to /etc/inetd.sec (only if this file exists!): saft allow - If you want to use the outgoing spooling feature, then add to your system bootup file (/etc/rc.local or /etc/rc.d/rc.local): /usr/local/sbin/sendfiled -Q - restart inetd: $ kill $ /usr/sbin/inetd # (or wherever inetd is located) - activate the user restriction: $ cp etc/sendfile.deny /usr/local/etc/ - install the configuration file (contents is self-descriptive): $ cp etc/sendfile.cf /usr/local/etc/ - install the man pages: $ ( cd doc; cp sendmsg.1 sendfile.1 receive.1 fetchfile.1 /usr/local/man/man1 ) (call makewhatis if you want) - install the notify script: $ cp etc/check_sendfile /usr/local/bin add "/usr/local/bin/check_sendfile" to /etc/profile - install the clients: $ ( cd src; cp sendfile sendmsg receive fetchfile utf7encode wlock \ /usr/local/bin ) $ ( cd etc; cp sfconf sfdconf /usr/local/bin ) $ ( cd /usr/local/bin/; ln -s utf7encode utf7decode ) 5) testing: $ sendfile README `whoami` $ receive $ receive -n 1 6) As an addon you can find xhoppel (idea and graphics by beate@juhu.lake.de), which is a program for X to inform the user that new files has been received, like xbiff for mail. Xhoppel has not been tested on all plattforms and will not be automaticly installed. If you want it, you should do: $ cd xhoppel $ make $ cp xhoppel /usr/local/bin and add to your .xsession (or .xinitrc, etc): xhoppel & 7) I'm very interested in comments and bug reports in respect to sendfile/SAFT as well as in spelling corrections of the documentation (as you may guess, english is not my native language). Send gifts via postal services. :-) 8) If you tell me the address of your new installed SAFT server, I will send you a nice gif as a reward. :-) 9) There is a mailing list which I maintain manually and in which I post announcements of updates and bug fixes from time to time. If you want to be on this list just send me a mail. -- \ Ulli 'Framstag' Horlacher \ BelWue-Koordination \ framstag@belwue.de \ \ Universitaet Stuttgart \ Allmandring 30 \ D-70550 Stuttgart \ Germany \ \ SAFT://saft.belwue.de/framstag \ HTTP://www.belwue.de/saft/index.html \ \ "X.500: Security through Complexity" - Juergen G. \ sendfile-2.1b/doc/doc.txt0000644000175100001440000004347510251132201015106 0ustar framstagusersA Definition of a Protocol for asynchronous File Transfer for the Internet -------------------------------------------------------------------------- and a UNIX Reference Implementation ----------------------------------- Ulli Horlacher Allmandring 30 Rechenzentrum Universität Stuttgart framstag@rus.uni-stuttgart.de Abstract -------- SAFT (Simple Asynchronous File Transfer) is a proposed new Internet protocol for sending files and messages asynchronously. This allows the sender to transfer files without to log on to the receiving site. You simply tell the sendfile program a file name and where to send it: "sendfile your_file user@somedomain" (Of course there are options). The package includes: A sendfile client (which sends files), a sendmsg client (which sends messages), a receive client (which copies files from the local sendfile spool to the recipient's current directory) and a sendfiled server (which receives files and messages and stores them in the local sendfile spool). This pre-RFC is partially influenced by RFCftp. The meanings of "should" ... are defined in RFC... Also considered were RFCtelnet RFCutf7, RFC1440, ..., see also Rationale: ---------- More information about asynchronous file transfer and comparison with --------------------------------------------------------------------- existing services ----------------- With asynchronous file transfer, files are transmitted from a sender to a recipient, without the latter having to take an active part. Among familiar Internet services, e-mail is an asynchronous service, while ftp represents a synchronous service. Asynchronous file transfer effectively has not existed until now on the Internet. If a user A wanted to send a file to a user B, he has been forced to use the following less than ideal procedures: - ftp [13] to the recipient's account To do this, A must know the password of B's account. If A and B are not identical, this method is out of question for obvious security reasons. Even if A and B are the same person, doing a transfer this way requires the password to be sent unencrypted via the Internet, which will be readable by the "bad guys". - ftp via anonymous ftp To do this, A must "put" the file to the anonymous ftp server. Then he must inform B via e-mail, that there is a file to pick up. This can only be done if the ftp server allows anonymous write access, in which case received files can be read or modified by other anonymous users prior to pickup. Also, using this method requires most files to be transferred twice. - sending via e-mail To do this, A must send B the file as an e-mail. However, according to RFC 822 an e-mail may only contain characters from the NVT-ASCII character set (a printable subset of the regular 7 bit ASCII character set). Thus the file transfer is restricted to English text documents ("Foreign" language texts contain 8 or even 16 bit wide characters, like German umlauts). To send more interesting documents, you have to encode the file appropriately, so that it will contain only NVT-ASCII characters during transmission. For encoding you can use uuencode or MIME [16], but these are complicated to use, and do not support all file attributes. They also inevitably enlarge the file size, which isn't helpful, since many mailing systems limit e-mails to as little as 100 kilobytes. In addition e-mail has no resend option: an interrupted transfer has to be begin at byte #1, again. File Transfer in Bitnet ----------------------- In Bitnet there is an asynchronous file transfer service, which was the model for our new Internet service. We are making improvements though. If you look closely at the Bitnet services, you will find that they are all based on asynchronous file transfers; however, Bitnet allows only file names to contain 8 Bytes, with another 8 Bytes for file name extensions (IBM-internal restrictions). Records must be not longer that 80 Bytes and the character set is EBCDIC or 7 bit ASCII. The SIFT/UFT Protocol --------------------- There is an "experimental" Internet protocol for asynchronous file sending. However, SIFT/UFT (Sender-Initiated/Unsolicited File Transfer) protocol, RFC 1440 [15] has serious problems and inconsistencies. The deficiencies of RFC 1440 are: - the character set of the protocol is not defined - the character sets of the files are not defined - only VM file types are supported - the date format is not defined - a string "EOF" in the file terminates the transfer - the return codes from the server are not defined - there aren't many SIFT/UFT servers on the Internet The SAFT Protocol ----------------- The protocol we propose is named Simple Asynchronous File Transfer, or SAFT. Essential attributes are: - Independence SAFT should be available on all operating systems in the Internet and not be bound to a particular operating system. - Simplicity SAFT should be an easily comprehensible protocol on an ASCII basis which can be debugged via telnet to the server port. - Extensibility There should not be limits on later extension. A bad example perhaps is the 7 bit limitation of smtp / RFC 822. Sending short asynchronous messages has been added to SAFT as a by-product. Such messages are defined as one line text strings, which normally would be written to the recipient's terminal. An example use might be, "Frams, The file I sent you called sendfile_tricks is a .dvi file." SAFT is a client/server protocol. The SAFT client (typically as a user program) sends files or messages via Internet to a SAFT server which accepts them and delivers them to a local recipient, or saves them in a special spool area. The one line messages, however, will not be spooled but will either be immediately displayed or dismissed. Recipients can pick up the received files when convenient with the SAFT receive client. This works similarly to Internet mail, so users will be immediately comfortable with it. Actually, the receive client and the spool mechanism are not part of the SAFT protocol but are mentioned here as an example how to deal with incoming files. SAFT only defines the pure transfer protocol. SAFT supports the following file attributes: - File name in Unicode [19] of any length - Time stamp Specification by ISO-8601 [7] (UTC full date & time) - File type binary Byte stream without any format - File type source File consists of lines of any length with CR/LF (ASCII 13, ASCII 10) as an end of line (EOL) mark - File type text Like file type source but the sub-attribute CHARSET (see below) is evaluated - File type MIME File is a MIME message as described in [16] - Name of the character set Specification by RFC 1345 [14] - Operating system specific attributes These attributes can be freely introduced by the author of the first SAFT implementation for a specific operating system, but should be announced to the maintainer of the SAFT protocol (see author's address at the front page of this document). Compatibility is principally guaranteed only among client and server of the same operating system, of course. SAFT can transfer files in compressed mode using the gzip algorithm. This does not represent a file attribute but a transfer attribute. This happens transparently for the sender and the recipient, so they don't have to deal with it. The compression has been introduced to save net bandwidth. As a rule, the bottle neck of a file transfer is the capacity of the network and not the performance of the local CPU. SAFT uses tcp as transport layer and tcp port 487, which has been registered by the IANA [21]. The SAFT client connects to this port at the host of the SAFT server. The client/server communication is divided into two parts: the actual communication protocol and the file which has to be transfered as a structureless "data-stream" (stream of octetts = bytes of 8 bit). This is the only true restriction of SAFT: the smallest transfer unit is an octet and machines with other byte configurations are not supported. But, generally such machines belong to history. The communication protocol conforms to NVT (network virtual telnet) [13], using 7 bit ASCII without any control codes and CR/LF (ASCII 13, ASCII 10) as EOL (end of line) mark. HT (ASCII 9) is valid, too, but one should avoid it. A command from the client consists of a single text line, which contains a command token and on demand one or more parameters, each separated with a whitespace. A whitespace is a non-null string of SPACE (ASCII 32) or HT (ASCII 9) in any order. If possible a whitespace should be a single SPACE. The following commands are defined: - FROM [] Sender login name and optionally real name. - TO Recipient login name. - FILE Name of the file which is to be transferred. - DATE Time stamp of the file in UTC ISO-8601 format (YYYY:MM:DD hh:mm:ss). - TYPE BINARY|SOURCE|MIME|TEXT[= [COMPRESSED[=GZIP]|CRYPTED[=PGP]] File type and transfer encoding. So far, for compressing only the gzip algorithm is allowed and for encrypting only pgp. Therefore these keywords are optional. is the name of the character set of a text file as defined by RFC 1345 (&charset entry). Alias names are not allowed. If not specified, ISO_8859-1:1987 is assumed. - SIGN A digital signature corresponding to FILE. So far, only pgp armor signatures are supported. - ATTR Operating system specific file attribute extension (depends on the implementation). - MSG A one line text message, which shall be written directly onto the recipient's terminal. - DEL The file which has been transferred before will be deleted. - RESEND After a preceding link failure the file will be sent again. The first string (string delimiter is a whitespace) in the reply from the server contains the number of bytes which have already been transferred: - SIZE Size of the file in bytes. The first parameter is the number of bytes which really have to be transferred; the second parameter is the file size after decompressing. The last one is for information purposes for a receive client. - DATA After this command - bytes of the file are sent as a contiguous stream of octets. - QUIT End of session. The command tokens may be written in upper or lower case or even in mixed case. FROM, from or FrOm are equal. If possible the command tokens should be written in upper case. , , , and are strings encoded with UTF-7 [20]. If possible one should only use NVT-ASCII or ISO Latin-1 characters [14]. UTF-7 defines a reversible encoding of Unicode strings to strings of the mbase64 character set, which itself is a subset of NVT-ASCII. Unicode is *the* 16 bit character set which will be the successor of all current 8 bit character sets. For more details see [14]. To transfer a file, at least the commands FROM, TO, FILE and SIZE have to be specified. DATA then starts the actual transfer. The other commands are optional. In general, the order of the commands does not matter. Exceptions from this rule are ( Format: : ): - MSG : FROM, TO - DEL : FROM, TO, FILE - DATA : FROM, TO, FILE, SIZE - RESEND : FROM, TO, FILE, SIZE, DATE On every command from the client the server responds with a so called "reply-message", which has the following format (notation is in EBNF): reply-message = {reply-line} reply-end reply-line = reply-code "-" text reply-end = reply-code " " text reply-code = digit digit digit digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" text = char {char} CR LF char = CR is ASCII 13, LF is ASCII 10, all other terminal-symbols are ASCII characters. text should be encoded in ASCII or UTF-7. ASCII should be preferred. The first digit of the reply-codedetermines the category of the reply-message: - 2 stands for: command successfully executed - 3 stands for: more data/information is needed - 4 stands for: a fatal error has occurred and the connection will be terminated - 5 stands for: other error, which can be corrected with further commands The following "reply-messages" are defined: - 200 Command ok.. - 201 File has been correctly received. - 202 Command not implemented, superfluous at this site. - 205 Non-ASCII character in command line ignored. - 214 - 220 SAFT server (sendfiled on ) ready. - 221 Goodbye. - 230 Bytes already received. - 302 Header ok, send data. - 410 Spool directory does not exist. - 411 Can't create user spool directory. - 412 Can't write to user spool directory. - 415 TCP error: received too few data. - 421 Service not available. - 451 Requested action aborted: local error in processing. - 452 Insufficient storage space. - 453 Insufficient system resources. - 500 Syntax error, command unrecognized. - 501 Syntax error in parameters or arguments. - 502 Command not implemented. - 503 Bad sequence of commands. - 504 Command not implemented for that parameter. - 505 Missing argument. - 510 This SAFT-server can only receive messages. Send files to saft://xx/yy - 511 This SAFT-server can only receive files. - 520 User unknown. - 521 User is not allowed to receive files or messages. - 522 User cannot receive messages. - 523 You are not allowed to send to this user. - 530 User cannot receive messages. - 531 This file has been already received. - 599 Unknown error. Only the 3 digit reply-codes are reserved, the texts behind can be changed at your pleasure as long as they conform to the meaning of the message. Exceptions are the texts of the reply codes 220 and 230: 220 must contain the ASCII-string "SAFT" and 230 must follow one space and the number of bytes which have already been transferred as first string. number = digit {digit} Examples -------- Examples of SAFT sessions using a direct telnet connection to the server port: > telnet linux saft Trying 129.69.58.50... Connected to linux.rus.uni-stuttgart.de. Escape character is '^]'. 220 linux.rus.uni-stuttgart.de SAFT server (sendfiled 1.4 on Linux) ready. FROM gaga 200 Command ok. TO framstag 200 Command ok. FILE blubb 200 Command ok. SIZE 5 5 200 Command ok. DATA 302 Header ok, send data. ABC 201 File has been correctly received. QUIT 221 Goodbye. Connection closed by foreign host. > telnet linux saft Trying 129.69.58.50... Connected to linux.rus.uni-stuttgart.de. Escape character is '^]'. 220 linux.rus.uni-stuttgart.de SAFT server (sendfiled 1.4 on Linux) ready. HELP 214-The following commands are recognized: 214- FROM [] 214- TO 214- FILE 214- SIZE 214- TYPE BINARY|SOURCE|TEXT [COMPRESSED|CRYPTED] 214- SIGN 214- DATE 214- CHARSET 214- ATTR TAR|EXE|NONE 214- MSG 214- DEL 214- RESEND 214- DATA 214- QUIT 214-All argument strings have to be UTF-7 encoded. 214 You must specify at least FROM, TO, FILE, SIZE and DATA to send a file. FROM gaga 200 Command ok. TO dengibtsnicht 520 User unknown. TO framstag 200 Command ok. MSG huhu! 530 User cannot receive messages. TYPE TEXT 200 Command ok. FILE x1 200 Command ok. SIZE 6 6 200 Command ok. abcd 500 Syntax error, command unrecognized. DATA 302 Header ok, send data. abcd 201 File has been correctly received. FILE x2 200 Command ok. SIZE 3 3 200 Command ok. SIZE 5 5 200 Command ok. DATA 302 Header ok, send data. 123 201 File has been correctly received. QUIT 221 Goodbye. Connection closed by foreign host. (Note the difference between the number of bytes in the SIZE and DATA commands. Telnet transfers a line with CR LF as EOL mark. Such bytes count, too.) Information and literature list =============================== [1] Andrew Tanenbaum: Computer Networks [2] Bettina Reimer, Paul Müller: Kommunikationssysteme auf der Basis des ISO-Referenzmodells [3] Kernighan, Ritchie: Programmieren in C [4] Jürgen Gulbins: UNIX [5] W. R. Stevens: Advanced Programming in the UNIX Environment [6] W. R. Stevens: UNIX Network Programming [7] ISO-8601 - International Time and Date Representing [8] C-FAQ-list in news.answers [9] Umlaute-FAQ in de.comp.standards [10] internationalization/programming-faq in news.answers [11] mail/mime-faq in news.answers [12] http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt [13] RFC 859 - ftp [14] RFC 1345 - Character Mnemonics & Character Sets [15] RFC 1440 - SIFT/UFT: Sender-Initiated/Unsolicited File Transfer [16] RFC 2045-2049 - MIME [18] RFC 1543 - Instructions to RFC Authors [19] RFC 1641 - Using Unicode with MIME [20] RFC 1642 - UTF-7 [21] RFC 1700 - Assigned Numbers Still missing from this document: - rationale section - programmer's documentation of the programs of the sendfile package - a nice postscript version You can find that which is missing in the German version, doku.ps I'm translating the missing parts as fast as I can. sendfile-2.1b/doc/doku.txt0000644000175100001440000014076710251132201015305 0ustar framstagusers*ACHTUNG* !VERALTET! *ACHTUNG* Definition eines Protokolls für asynchronen Filetransfer im Internet und Referenzimplementierung für Unix Ulli Horlacher Allmandring 30 Rechenzentrum Universität Stuttgart framstag@rus.uni-stuttgart.de 5. März 1996 : Kurzbeschreibung SAFT (Simple Asynchronous File Transfer) ist ein neues Internet-Protokoll, das es erlaubt, Dateien und Nachrichten asynchron zu verschicken, d.h. ohne daß es notwendig ist, sich beim Empfängersystem einzuloggen. Als Referenzimplementation wurden ein sendfile-Client (ver- schickt Dateien), ein sendmsg-Client (verschickt einzeilige Nachrichten), ein receive-Client (empfängt Dateien aus dem sendfile-spool) und ein sendfiled-Server (empfängt Dateien und Nachrichten und verteilt sie weiter) geschrieben. INHALT 1 Definition des asynchronen Dateitransfers und Abgrenzung gegenüber existierenden Diensten 4 1.1 Filetransfer im Bitnet 4 1.2 Das SIFT/UFT Protokoll 5 1.3 Das SAFT Protokoll 5 1.3.1 Beispiele 10 1.3.2 Begründung des Protokolldesigns 12 2 sendfile: eine SAFT Referenzimplementation für Unix 14 2.1 Programmbeschreibung 14 2.1.1 sendfiled 14 2.1.2 sendfile 16 2.1.3 sendmsg 18 2.1.4 receive 18 2.2 Benutzerkonfigurationsdateien 20 2.3 Installation 21 2.4 Sourcen 23 2.4.1 Aufrufdiagramm 26 2.4.2 Datenstrukturen 27 3 Danksagungen 30 4 Informationsverzeichnis 31 5 Glossar 32 1 Definition des asynchronen Dateitransfers und Abgrenzung gegenüber existierenden Diensten Bei einem asynchronen Filetransfer werden Dateien von einem Sender an einen Empfän- ger geschickt, ohne daß letzterer aktiv an der Übertragung teilnehmen muß. E-mail ist z.B. ein asynchroner Dienst, während ftp einen synchronen Dienst darstellt. Asynchronen Filetransfer gab es bisher im Internet nicht. Wollte ein Benutzer A einem beliebigen Benutzer B eine Datei zukommen lassen, hatte er bisher nur folgende wenig brauchbare Möglichkeiten: · ftp [13] zum Empfängeraccount Dazu muß das Paßwort des Empfängeraccounts bekannt sein. Wenn A und B nicht physisch identisch sind, ist diese Methode sicherheitstechnisch indiskutabel. Aber auch wenn es sich bei A und B um dieselbe Person handelt, so wandert doch das Paß- wort als Klartext in einem tcp-Päckchen durchs Internet. · ftp über einen anonymous ftp Server Die Datei muß von A auf den anonymous ftp Server mittels ftp übertragen werden, A muß B mit einer e-mail informieren, daß dieser die Datei abholen kann und B muß dann ebenfalls ftp aufrufen. Als Nebenbedingung muß ein ftp Server gefunden wer- den, der von beiden gut erreicht werden kann und dieser Server muß ein allgemein schreibbares Verzeichnis aufweisen. Während die Datei auf dem anonymous ftp Ser- ver liegt, kann sie aber praktisch von jedermann gelesen, gelöscht oder verändert wer- den. · verschicken via e-mail Die Datei wird von A an B als e-mail geschickt. Nach RFC 822 darf eine e-mail nur Zeichen aus dem NVT-ASCII Zeichensatz enthalten, welcher eine Untermenge von 7 bit ASCII ist. Somit ist der Dateientransfer auf englische Textdokumente beschränkt, wenn man nicht die zu verschickende Datei entsprechend kodiert, so daß sie nur noch NVT-ASCII Zeichen enthält. Als Kodierung bieten sich an: uuencode oder MIME [16]. Beide sind aber umständlich zu handhaben, unterstützen nicht alle Dateiattribute und vergrößern zwangsläufig die zu übertragende Datenmenge. Zudem sind die real existierenden Mailsysteme nicht in der Lage, mit größeren Übertragungen fertig zu werden. 1.1 Filetransfer im Bitnet Im Bitnet gibt es einen asynchronen Filetransferdienst. Dieser wurde als Vorbild genom- men und auf das Internet abgebildet, wobei die Funktionalität wesentlich erweitert wurde. Tatsächlich basieren sämtliche Bitnetdienste auf asynchronen Filetransfers. Bitnet erlaubt aufgrund von IBM-internen Restriktionen nur Dateinamen mit 8 Byte und 8 Byte Extension, Zeilenlängen von maximal 80 Byte und EBCDIC bzw. 7 bit ASCII als Zeichensatz. 1.2 Das SIFT/UFT Protokoll In der Vorbereitungsphase wurde das SIFT/UFT (Sender-Initiated/Unsolicited File Transfer) Protokoll aka RFC 1440 gefunden [15] , welches ebenfalls einen asynchro- nen Filetransferdienst für das Internet beschreibt. Dieses Protokoll hat den ,Experi- mental" Status und enthält noch einige Fehler bzw. Inkonsistenzen. Außerdem ist es stark an IBMs VM Betriebssystem angelehnt, da es ausschliesslich dessen Dateitypen unterstützt. Es wurde versucht, mit dem Author (Rick Troth, troth@compassnet.com) e-mail Kon- takt aufzunehmen. Leider lagen seine Antwortzeiten im Schnitt bei ca. 2 Wochen, so daß eine sinnvolle Diskussion mit ihm nicht möglich war. SIFT/UFT weist folgende Mängel auf: · der Zeichensatz des Protokolls ist nicht spezifiziert · als Dateitypen sind nur propritäre VM-Files vorgesehen · das Datumformat ist nicht spezifiziert · die Zeichensätze der Dateien sind nicht spezifiziert · Designfehler in der DATA-Anweisung: ein String ,EOF" in der zu übertragenden Datei führt zum Abbruch der Übertragung · die Return Codes des Servers sind nicht spezifiziert · Rick Troth ist anscheinend der einzige, der SIFT/UFT real benutzt; es ist nur ein einziger Server bekannt (ua1vm.ua.edu), der nicht mal selber RFC 1440 konform ist Somit war eine Projektrealisation auf Basis von SIFT/UFT nicht möglich und es mußte ein eigenes Protokoll entwickelt werden. 1.3 Das SAFT Protokoll Als Grundlage für den asynchronen Filetransfer wurde das SAFT-Protokoll entwik- kelt: Simple Asynchronous File Transfer Wesentliche Merkmale sind: · Betriebssystemunabhängigkeit SAFT soll auf möglichst allen Computersystemen im Internet verfügbar sein. · Einfachheit ,keep it simple": ein überschaubares Protokoll auf ASCII-Basis, so daß es leicht mit telnet auf den Serverport zu debuggen ist. · Erweiterbarkeit spätere Erweiterungen sollen keine künstlichen Grenzen behindern. Als abschrecken- des Beispiel sei die 7 Bit Beschränkung von smtp / RFC 822 genannt. Quasi als ,Abfallprodukt" wurden noch asynchrone Nachrichten (,messages") als weite- rer Internetdienst integriert. Bei solch einer Nachricht handelt es sich um einen einzeiligen Text, der normalerweise direkt auf das Terminal des Empfängers geschrieben wird. SAFT ist ein Client/Server-Protokoll. Der SAFT-Client, typischerweise ein Userpro- gramm, verschickt Dateien oder Nachrichten via Internet an den SAFT-Server, welcher sie entgegennimmt und an den lokalen Adressaten direkt ausliefert oder in einem Spoolbe- reich zwischenlagert, wo sie dann der Adressat mittels eines Receive-Clients abholen kann. Die Funktionsweise ist ähnlich wie bei normaler Internet-mail. Der Spooling-Mechanismus und der Receive-Client werden nicht von SAFT beschrieben, sondern bleiben der jeweiligen Implementation überlassen. SAFT definiert nur das reine Übertragungsprotokoll. SAFT unterstützt folgende Dateiattribute: · Dateiname in Unicode [19] mit beliebiger Länge · Zeitstempel Spezifikation nach ISO-8601 [7] (UTC full date & time) · BINARY unstrukturierter Bytestrom · SOURCE Datei besteht aus einzelnen Zeilen jeweils beliebiger Länge mit CR/LF als EOL Mar- kierung · TEXT wie Source, nur daß zusätzlich das Attribut CHARSET (siehe unten) ausgewertet wird · Name des Zeichensatzes Spezifikation nach RFC 1345 [14] · Betriebssystemspezifische Attribute Diese können bei der ersten SAFT-Implementation für das jeweilige Betriebssystem vom Autor beliebig verwendet werden. Kompatibilität ist dabei aus prinzipiellen Gründen nur zwischen Client und Server desselben Betriebssystems gewährleistet. SAFT kann Dateien mittels gzip Algorithmus komprimiert übertragen. Dieses stellt kein Dateiattribut sondern ein Übertragungsmerkmal dar. Für den Sender und Empfänger geschieht dies völlig transparent. Diese Komprimierung wurde eingeführt, um Netzband- breite zu schonen. Der Flaschenhals eines Filetransfers stellt in der Regel das Netz dar und nicht die Leistungsfähigkeit der lokalen CPU. SAFT benutzt tcp als Transportmedium und den tcp-Port 487. Der SAFT-Client stellt eine Verbindung zu diesem Port auf dem Host des SAFT-Servers her. Die Client/Server Kommunikation ist zweigeteilt, sie setzt sich aus dem eigentlichen Kommunikationsprotokoll und der zu übertragenden Datei als ,data-stream" zusam- men. Das Kommunikationsprotokoll ist NVT-konform, also 7 bit ASCII ohne Steuerzeichen und CR/LF (ASCII 13 und ASCII 10) als EOL Markierung. HT (ASCII 9) ist zwar zulässig, sollte aber vermieden werden. Ein Kommando vom Client besteht aus einer Zeile, die ein Befehlswort und je nach Bedarf ein oder mehrere Parameter enthält, getrennt durch Whitespace. Ein White- space ist eine nicht-Null Zeichenfolge aus SPACE (ASCII 32) oder HT (ASCII 9) in beliebiger Reihenfolge. Nach Möglichkeit sollte immer ein einzelnes SPACE als Whitespace verwendet werden. Als Kommandos sind definiert: · FROM [] Absender Loginname und optional echter Name und pgp Signatur. · TO Empfänger Loginname · FILE Name der zu übertragenden Datei · DATE Zeitstempel der Datei in UTC ISO-8601 Format (YYYY:MM:DD hh:mm:ss) · TYPE BINARY|SOURCE|TEXT [COMPRESSED] Typ der Datei. · CHARSET Name des Zeichensatzes einer Textdatei nach RFC 1345 (&charset Eintrag) . Ali- ase sind nicht erlaubt. Wenn möglich sollte ISO_8859-1:1987 verwendet werden. · ATTR Betriebssystemspezifische Dateiattributerweiterung, implementationsabhängig. · MSG Einzeilige Nachricht, die direkt auf das Terminal des Empfängers ausgegeben werden soll. · DEL Datei, die zuvor übertragen wurde, wird gelöscht. · RESEND Die Datei soll nach vorhergehenden Übertragungsabbruch erneut geschickt werden. Die Serverantwort enthält als erster String die Anzahl der bereits übertragenen Bytes: · SIZE Größe der zu übertragenden Datei in Bytes: die erste Zahl stellt die tatsächlich zu übertragenden Bytes dar, die zweite die Größe der Datei nach der Dekomprimierung. · DATA Ab hier folgen - Bytes der Datei als aufeinanderfolgender Strom von 8-bit Bytes. · QUIT Ende der Verbindung Die Befehlswörter können in Groß- oder Kleinbuchstaben oder sogar gemischt geschrie- ben werden. FROM, from oder FrOm sind gleichbedeutend. Nach Möglichkeit sollten alle Befehlswörter aber einheitlich in Großbuchstaben geschrieben werden. , , , und sind UTF-7 [20] kodierte Strings. Nach Möglichkeit sollten hier nur NVT-ASCII oder ISO Latin-1 Zeichen [14] enthalten sein. Zur Übertragung einer Datei müssen mindestens die Kommandos FROM, TO, FILE und SIZE angegeben werden. DATA startet dann den eigentlichen Transfer. Die anderen Kommandos sind optional. Die Reihenfolge der Kommandos spielt im Allgemeinen keine Rolle. Ausnahme sind (Format: Kommando (Kommandos, die vorhergehen müssen)): · DATA ( FROM, TO, FILE , SIZE ) · MSG ( FROM , TO ) · RESEND ( FROM, TO, FILE ) · DEL ( FROM, TO, FILE, DATE, SIZE ) Jedes dieser Kommandos wird vom Server mit einer sogenannten ,reply-message" beant- wortet, die folgendermaßen aufgebaut ist: Antwort = {reply-line} reply-end reply-line = reply-code "-" text reply-end = reply-code " " text reply-code = number number number number = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" text = char {char} CR LF char = CR ist ASCII 13, LF ist ASCII 10. Die erste Ziffer (number) des reply-code gibt Aus- kunft über die Kategorie der Antwort: · 2 steht für: korrekte Kommandodurchführung · 3 steht für: weitere Daten/Informationen werden benötigt · 4 steht für: fataler Fehler mit anschliessendem Verbindungsabbruch · 5 steht für: sonstiger Fehler, der aber durch weitere Kommandos wieder behebbar ist Definiert sind folgende ,reply-messages": · 200 Command o.k.. · 201 File has been correctly received. · 202 Command not implemented, superfluous at this site. · 205 Non-ASCII character in command line ignored. · 214 · 220 SAFT server (sendfiled on ) ready. · 221 Goodbye. · 230 Bytes already received. · 302 Header ok, send data. · 410 Spool directory does not exist. · 411 Can`t create user spool directory. · 412 Can`t write to user spool directory. · 415 TCP error: received too few data. · 421 Service not available. · 451 Requested action aborted: local error in processing. · 452 Insufficient storage space. · 453 Insufficient system resources. · 500 Syntax error, command unrecognized. · 501 Syntax error in parameters or arguments. · 502 Command not implemented. · 503 Bad sequence of commands. · 504 Command not implemented for that parameter. · 505 Missing argument. · 510 This SAFT-server can only receive messages. Send files to xx@yy · 511 This SAFT-server can only receive files. · 520 User unkown. · 521 User is not allowed to receive files or messages. · 522 User cannot receive messages. · 523 You are not allowed to send to this user. · 530 User cannot receive messages. · 531 This file has been already received. · 599 Unknown error. Nur die aus 3 Ziffern bestehende Replycodes sind fest vergeben, die Texte dahinter kön- nen beliebig verändert werden, solange sie weiterhin dem Sinn der Meldung entsprechen. Ausnahmen hiervon sind die Texte zu den Replycodes 220 und 230: bei 220 muß der String , SAFT " enthalten sein und bei 230 muß das erste Wort im Text die Anzahl der bereits übertragenen Bytes sein. 1.3.1 Beispiele Beispiele einer SAFT-Session anhand eines direkten telnet Zugriffs auf den Serverport (fett gedruckte Textteile sind Benutzereingaben): > telnet linux saft Trying 129.69.58.50... Connected to linux.rus.uni-stuttgart.de. Escape character is '^]'. 220 linux SAFT server (sendfiled 1.4 on Linux) ready. FROM gaga 200 Command ok. TO framstag 200 Command ok. FILE blubb 200 Command ok. SIZE 5 5 200 Command ok. DATA 302 Header ok, send data. ABC 201 File has been correctly received. QUIT 221 Goodbye. Connection closed by foreign host. > telnet linux saft Trying 129.69.58.50... Connected to linux.rus.uni-stuttgart.de. Escape character is '^]'. 220 linux SAFT server (sendfiled 1.4 on Linux) ready. HELP 214-The following commands are recognized: 214- FROM [] [] 214- TO 214- FILE 214- SIZE 214- TYPE BINARY|SOURCE|TEXT [COMPRESSED] 214- DATE 214- CHARSET 214- ATTR TAR|EXE|NONE 214- MSG 214- DEL 214- RESEND 214- DATA 214- QUIT 214-All argument strings have to be UTF-7 encoded. 214 You must specify at least FROM, TO, FILE, SIZE and DATA to send a file. FROM gaga 200 Command ok. TO dengibtsnicht 520 User unkown. TO framstag 200 Command ok. MSG huhu! 530 User cannot receive messages. TYPE TEXT 200 Command ok. FILE x1 200 Command ok. SIZE 6 6 200 Command ok. abcd 500 Syntax error, command unrecognized. DATA 302 Header ok, send data. abcd 201 File has been correctly received. FILE x2 200 Command ok. SIZE 3 3 200 Command ok. SIZE 5 5 200 Command ok. DATA 302 Header ok, send data. 123 201 File has been correctly received. QUIT 221 Goodbye. Connection closed by foreign host. Eine Anmerkung zur anscheinenden Diskrepanz bei SIZE und DATA: telnet überträgt eine Zeile mit CR LF als EOL-Markierung. Diese Bytes zählen natürlich mit. 1.3.2 Begründung des Protokolldesigns Die Ablehnung von SIFT/UFT wurde bereits weiter oben besprochen. Als weitere bereits existierende Alternativen wurden untersucht: · http Das Hyper Text Transfer Protocol [12] ist zu sehr spezialisiert auf Dokumente mit ,festem Platz". Es geht davon aus, daß Dateien immer unter derselben Adresse anzu- finden sind. Außerdem kann man mit der derzeitigen http Spezifikation Dateien nur holen, nicht aber verschicken. · fsp Das File Service Protocol kennt nur einen anonymous User und keine realen Benutzer als Adressaten. Zudem benutzt es udp als Transportmedium, was es zwar sehr sicher gegenüber Netzproblemen aber auch recht langsam macht. · smtp mit MIME Das Simple Mail Transport Protocol mit Multipurpose Internet Mail Extensions [11] [16] [17] ist zwar das flexibelste Transportprotokoll für Dokumente aller Art, aber lei- der auch eins der ineffektivsten was den Datendurchsatz angeht und Aufgrund der 7 bit Restriktion von smtp am schwersten zu implementieren. Dies verdeutlicht die Tat- sache, daß es selbst Jahre nach der Einführung von MIME noch keinen brauchbaren freien MUA für Unix oder VMS gibt. Als große Probleme stellten sich die Wahl des Zeichensatzes für Textdateien und das For- mat der Dateinamen heraus. Für beide liessen sich keine gemeinsame Basis finden, die allen Betriebssystemen im Internet gerecht werden würde. Der einzige Zeichensatz, der eine echte Obermenge aller anderen Zeichensätze ist, ist ISO-10646 aka Unicode [9] [10] [19]. Unicode basiert aber auf 16 bit breiten Zeichen und hat noch keine nennenswerte Verbreitung gefunden. Deshalb erlaubt SAFT die Verwen- dung eines beliebigen in RFC 1345 definierten Zeichensatzes und überläßt die korrekte Konvertierung der Empfängerseite. Empfohlen wird jedoch die Verwendung von ISO- 8859-1 aka ISO Latin 1 [14], da dies von der Anzahl der Benutzer und installierten Systeme her führend ist. Beim Format des Dateinamens stellt sich ein ähnliches Dilemma. Stellvertretend seien hier einige verbreitete Betriebssysteme bzw. Filesysteme genannt: · DOS 8+3 Zeichen; alle Zeichen bis auf . und \ · VM und MVS 8+8 Zeichen; A..Z 0..9 · VMS/RMS 39+39 Zeichen; A..Z 0..9 $ _ - ; $ - nicht am Anfang; Versionsnummern · Unix < SysV 4.0 14 Zeichen; alle Zeichen bis auf ASCII(0) und / · Unix >= SysV 4.0 und BSD 255 Zeichen; alle Zeichen bis auf ASCII(0) und / · Windows NT 255 Zeichen; alle Unicodezeichen (?) Ein kleinster gemeinsamer Nenner ließ sich hier nicht bilden. Deshalb erlaubt SAFT bei Dateinamen die Verwendung von Unicodezeichen und beliebige Länge. Der Client kann aber nicht sicher sein, daß der Dateiname auf dem Empfängersystem verarbeitet werden kann. Deshalb sollten bei Unkenntnis der Möglichkeiten des Empfängersy- stems eher konservative Werte benutzt werden. Der Flaschenhals bei praktisch jeder Kommunikation im Internet stellt die zur Verfü- gung stehende Bandbreite dar. Deshalb kann SAFT Dateien mittels gzip Algorithmus komprimiert übertragen. gzip wurde ausgewählt, weil es · lizenzfrei ist (GNU Copyleft) · sehr gute Kompressionsraten liefert · auf praktisch allen Betriebssystemen verfügbar ist · einen Quasistandard im Internet darstellt Viele Betriebssysteme bieten weitere Dateiattribute, als die von SAFT abgedeckten an. Diese Attribute sind aber Filesystem-proprietär und nicht zwischen verschiedenen Betriebssystemen konvertierbar. VMS/RMS kann z.B. nichts mit dem Hidden-bit von DOS/FAT anfangen, während wiederum auf allen anderen Betriebssystemen die FDL von VMS/RMS keinen Sinn macht. Deshalb wurde das ATTR Kommando eingeführt, welches nur für das jeweilige Betriebssystem von Relevanz ist. Jeder Autor einer neuen SAFT Implementation kann das ATTR Kommando für sein Betriebssystem erweitern, indem er neue Parameter einführt (siehe Kapitel sendfile weiter unten). Er sollte dies jedoch dokumentieren und dem Autor von SAFT zwecks Koordination melden. Die Verwendung von MIME [16] [17] zur Spezifizierung von Dateiattributen wurde verworfen, weil MIME Dokumente beschreibt, die visualisiert werden sollen. Hierbei wird der Inhalt einer Datei meist einer nicht reversiblen Transformation unterworfen, was in Hinblick auf die eigentliche Aufgabenstellung nicht wünschenswert ist. 2 sendfile: eine SAFT Referenzimplementation für Unix Das sendfile Paket ist eine Umsetzung des SAFT Protokolls für Unix-Systeme und umfaßt die Teile: · sendfiled der sendfile daemon, ein SAFT-Server · sendfile ein SAFT-Client zum Verschicken von Dateien · sendmsg ein SAFT-Client zum Verschicken von Nachrichten · receive ein Client, der bereits empfangene Dateien aus dem lokalen Spool abholt · Utilities: - check_sendfile: informiert beim login auf files im sendfile-Spool - sf_cleanup: räumt alte Files aus dem Spool · Dokumentation: - man-pages: Hilfetexte im Standard-Unix-Format - LIESMICHe bzw. READMEs: Kurze Hilfetext für schnelle Information - doku.ps bzw. doc.ps: dieses Dokument Der sendfile-Client ist ein Userprogramm, das Dateien an den sendfiled verschickt, wel- cher sich auf demselben Host befinden kann oder sonst irgendwo im Internet. Der sendfi- led nimmt die Dateien entgegen, legt sie im Spoolbereich ab und informiert den Empfänger mit einer Nachricht, die direkt auf sein Terminal geschrieben wird. Der Emp- fänger kann sich dann die Dateien mittels des receive-Clients in sein Directory kopieren, wobei das Original im Spool gelöscht wird. Der sendmsg-Client ist ein Userprogramm, das einzeilige Textnachrichten an den sendfiled verschickt, welcher sie dann direkt auf das Terminal des Empfängers schreibt. Das sendfile-Paket setzt voraus, daß die Programme gzip, tar und GNU-recode (letzteres optional) bereits installiert sind und zur Installation der gcc-Compiler vorhanden ist. Ver- wendete Programmierstandards sind ANSI-C, POSIX 1003.1 und BSD sockets. 2.1 Programmbeschreibung 2.1.1 sendfiled Der sendfiled muß nur einmal installiert werden (siehe weiter unten) und läuft dann ohne weitere direkte Benutzeraktion, da er automatisch vom inetd gestartet wird. Er verhält sich damit analog zu einem ftpd. sendfiled legt ankommende Dateien im Spool-Directory des Empfängers ab und gibt ankommende Nachrichten (messages) auf den tty des Empfängers aus, sofern dies nicht durch die Konfigurationsdateien verboten wurde (siehe weiter unten). Das Spoolverzeichnis ist normalerweise /var/spool/sendfile/username (sofoern beim installieren nicht anders spezifiziert). Zum sendfiled gehören zwei Konfigurationsdateien: nosendfile und sendfile.cf, die normalerweise in /usr/local/etc/ liegen. In nosendfile können lokale Benutzer eingetragen werden, die keine Dateien oder Nachrichten erhalten sollen, also vom SAFT-Service ausgeschlossen werden sollen. dies sind normalerweise Pseudo-User wie ftp, news, admin, root, nobody, lpd, etc. Steht in nosendfile in der ersten Zeile allow-only,bewirkt dies, daß jetzt nur noch die nachfolgend aufgeführten Benutzer Dateien oder Nachrichten empfangen können. In sendfile.cf stehen Optionen, die das genau Verhalten des sendfiled steuern und die jederzeit geändert werden können. Die Bezeichnungen sind im wesentlichen Selbster- klärend. Hier ein Beispiel: # sendfile configuration file # ring the gong when a message arrives (on/off) bell = on # maximum allowed files to receive per user maxfiles = 200 # maximum total disk space quota for spool in MB # (WARNING! Defining this option will sendfile slow down!) # maxspool = 100 # minimum free disk space for spool partition in MB minfree = 10 # accept only messages or files # acceptonly = messages # address of your generic SAFT-server (for NFS) # saftserver = saft.banana.net # notify by message, mail, both or none notification = message # keep spool files at least xx days, then delete them (0=infinity) keep = 0 # delete aborted or corrupted spool files after xx days (0=never) deljunk = 10 maxspool beschränkt die maximale Anzahl an belegten MBs im Spool (total), wärend minfree ein Minimum an freien MBs in der Spool Partition garantiert. Die Unterschei- dung ist deshalb sinnvoll, weil der Spool nicht in einer eigenen Partition sein muß, son- dern nur ein Directory-Baum innerhalb einer Partition sein kann, die auch noch anderen Zwecken dient. Die Optionen keep und deljunk werden durch den Aufruf von receive oder durch ankommende Files über sendfiled getriggert. Um sicher zu gehen, daß auch alte Files von allen Usern gelöscht werden, gibt es das Programm sf_cleanup. Dies kann bei Bedarf gestartet werden (einmal pro Woche oder so). Mit NFS tut sich sendfile etwas schwer, weil NFS keinerlei Locking-Mechanismus besitzt und es so zu Race Conditions und Datenkorruption kommen kann, wenn auf den sendfile- spool via NFS zugegriffen wird (wenn /var/spool/sendfile via NFS gemountet wird). Mit folgendem Workaround funktioniert sendfile aber auch in einer NFS-Umgebung: · Auf NFS-Clients in sendfile.cf eintragen: acceptonly = messages saftserver = nfs.server.host.name · Auf dem NFS-Server in sendfile.cf eintragen: notification = mail Wenn jetzt versucht wird, an einen NFS-Client ein File zu schicken, kommt folgende Feh- lermeldung (Beispiel): $ sendfile LIESMICH framstag@moep.bb.bawue.de %sendfile-F, server error: For sending files use: framstag@syssrv.bb.bawue.de Messages können trotzdem weiterhin verschickt werden. In beiden Konfigurationsdateien dient ein # als Kommentarzeichen, d.h. alles inklusive diesem Zeichen bis Zeilenende wird ignoriert. Als Unix-betriebssystemspezifische Erweiterung des SAFT-Protokolls wurden die Attri- but TAR und EXE eingeführt. TAR erlaubt alle Unix-Fileattribute mit zu übertragen. Hat eine Datei das tar-Attribut, so handelt es sich um ein tar-Archiv nach POSIX 1003 und diese wird vom receive-Client dann entsprechend behandelt. EXE sagt aus, daß die über- tragene Datei ein ausführbares Programm (z.B. executable oder Shell-Script) ist. Der receive-Client setzt dann die korrekte Protection. Alle POSIX kompatiblen Betriebssy- steme, wie z.B. VMS und Windows NT, können auch diese erweiterte Attribute überneh- men, sollte für diese Systeme eine SAFT-Implementation realisiert werden. 2.1.2 sendfile Der sendfile-Client ist ein Userprogramm, das Dateien an den Empfänger verschickt. Der Aufruf von sendfile -h ergibt die Ausgabe: usage: sendfile [-stuvd] file-name [...] user[@host] or: sendfile [-uva] archive-name file/directory-name [...] user[@host] -s send file(s) in source mode -t send file(s) in text mode -u send file(s) uncompressed -v verbose mode -a send file(s) as one archive -d delete previous sent file(s) ( default mode: send file(s) in binary mode and compressed ) example: sendfile rabbit.gif beate@juhu.lake.de Im einfachsten Fall reicht die Zeile (Beispiel) sendfile bdsm.txt andrea um die Datei bdsm.txt an den lokalen Benutzer andrea zu schicken. sendfile verschickt dann die Datei binär, d.h. ohne jede Veränderung, und komprimiert (Falls es sich um eine komprimierbare Datei handelt).. Die Anzahl der übertragenen Bytes wird immer angezeigt. Es können aber auch die folgenden Optionen angegeben werden: -s behandelt die zu verschickende Datei als Programm Sourcecode. Dies ist nur notwendig, wenn das Empfängersystem kein Unix ist. -t behandelt die zu verschickende Datei als Text. Beim Textmodus werden Umlaute und andere Sonderzeichen korrekt gewandelt. Dies ist nur notwendig, wenn das Empfängersystem kein Unix ist. -u verschickt unkomprimiert. Default ist komprimierte Übertragung. Dies sollte nur dann verwendet werden, wenn sich Sender und Empfänger auf dem selben Host befinden. Komprimierte Übertragung ist ein wesentliches Mittel zur Reduk- tion von Netzlast. -v gibt alle SAFT-Meldungen mit aus (verbose mode). Dies dient zur Lokalisa- tion von Protokollfehlern oder zur Befriedigung der Neugier (,Was geht denn da ab?"). -a schickt mehrere Dateien oder ganze Verzeichnisbäume als ein Archiv. Das erste Argument nach -a gibt den Namen des Archivs an. Diese Option ist nur gül- tig, wenn das Empfängersystem ebenfalls ein Unix ist. -d löscht eine vorher verschickte Datei auf dem Serversystem, vorausgesetzt, es befindet sich dort noch im Spool. Die Optionen -s -t, -d und -a schließen sich jeweils gegenseitig aus. Als user-Name darf auch ein elm-Alias verwendet werden, wenn kein sendfile-Alias (siehe weiter unten) gleichen Namens vorhanden ist und der elm-Alias auf eine echte Internet-Adresse zeigt. Weitere Beispiele: sendfile -s *.pas uranus@bigvax.inka.de sendfile -va C-Projekt sendfile doku.ps uwe 2.1.3 sendmsg Der sendmsg-Client ist ein Userprogramm, das einzeilige Textnachrichten an den sendfi- led verschickt, welcher sie dann direkt auf das Terminal des Empfängers schreibt. Der Aufruf von sendmsg -h ergibt den Output: usage: sendmsg [-v] user@host or: sendmsg [-mM] options: -v verbose mode -m receive messages only on this tty (default) -M receive messages on other ttys, too example: sendmsg orakel@main01.bb.bawue.de sendmsg verlangt nach Aufruf, die zu übertragende Nachricht einzugeben. Als user-Name darf auch ein elm-Alias verwendet werden. Beispiel: sendmsg framstag@moep.bb.bawue.de message: geiles Programm, das sendfile! Ankommende Nachrichten werden normalerweise (sofern via Konfigurationsdatei nicht anders geregelt) auf allen ttys des Empfängers ausgegeben. Wird der Empfänger selbst zum Sender, indem er sendmsg aufruft (z.B. mit sendmsg -m), so werden ab sofort Messa- ges nur noch auf diesem tty ausgegeben. 2.1.4 receive Der Empfänger kann sich die Dateien mittels des receive-Clients in sein Directory kopie- ren, wobei das Original im Spool gelöscht wird. Der Aufruf von receive -h ergibt den Output: usage: receive [-d] file-name or: receive -n [-dr] file-number or: receive [-l] [-L] or: receive -a [-dr] options: -l short list of files -L full list of files -n specify a file number -a specify all files -d delete -r rename file when receiving examples: receive -a ! receive all files receive -n 1 ! receive file with number 1 receive blubb ! receive file with name blubb Im einfachsten Fall gibt der Benutzer an (Beispiel): receive blubb.txt %receive-I, blubb.txt received Dies kopiert die Datei blubb.txt ins aktuelle Directory und löscht sie aus dem Spool. Weitere Optionen sind: -d löscht die Datei ohne sie vorher zu kopieren -n anstelle des Dateinamens wird seine Spoolnummer verwendet -a alle Dateien abholen bzw. löschen -l auflisten der Dateien -L auflisten der Dateien und Inhalt der Archive mit ausgeben -r umbenennen der Datei beim abholen Weitere Beispiele: receive -l From zrxh0370@baracke.rus.uni-stuttgart.de (Ulli Horlacher) 1) 10-Aug-1995 15:41:24 3 KB LIESMICH 2) 10-Aug-1995 15:41:37 30 KB doku.txt 3) 11-Aug-1995 16:12:09 113 KB Sourcen (archive) receive -n 1 LIESMICH already exists. Overwrite it (yYnN)? y %receive-I, LIESMICH received receive -d Sourcen %receive-I, Sourcen deleted Existiert eine Datei gleichen Namens bereits, so fragt receive nach, ob es sie über- schreiben soll. Ist die Eingabe Y oder N oder so werden bei anderen Dateien keine weiteren Fragen gestellt, sondern diese einfach überschrieben bzw. übergangen. Bei y oder n wird jedesmal neu nachgefragt. Der Dateiname darf auch * oder ? als Wildcard-Zeichen enthalten, allerdings ist durch Einschliessung in '' Quote-Zeichen dafür zu sorgen, daß die Shell die Metazeichen * und ? nicht vorher selber interpretiert. Enthält eine Datei besondere Zeichen, wie Unicodezeichen, Controlcodes oder Shell- metazeichen, so frägt receive nach, in welchem Format der Dateiname abgespeichert werden soll. Beispiel: receive 'gaga*' The next file name contains characters which may cause problems with your shell or may do strange things with your terminal. These characters have been substituted with '_'. (c)omplete file name with control code characters is not displayable (n)ormal file name: >gaga blubb< (s)hell file name: >gaga_blubb< Select one of c n s (or C N S for no more questions): n gaga blubb already exists. Overwrite it (yYnN)? y %receive-I, gaga blubb received Wenn Dateien bereits aus dem Spool gelöscht worden sind, besteht trotzdem noch eine Möglichkeit herauszubekommen, wer was geschickt hatte. Mit more /var/spool/sendfile/$LOGNAME/log läßt sich die sendfile-Protokolldatei anschauen. 2.2 Benutzerkonfigurationsdateien Sowohl sendfile als auch sendmsg greifen auf diverse benutzerspezifische Konfigurations- dateien zurück, die alle unter /var/spool/sendfile/username/config/ liegen. Diese Dateien werden per default vom sendfiled angelegt, sobald der entsprechende Benutzer zum ersten mal etwas empfangen sollen. Ihre Erzeugung kann also z.B. mit: sendmsg $LOGNAME erzwungen werden. Es handelt sich bei diesen Konfigurationsdateien um: · config Hier können die globale Konfigurationsoptionen bell und notification (aus /usr/local/ etc/sendfile.cf) überschrieben werden: bell = on # Bimmel an bell = off # Bimmel aus notification = none # keine Benachrichtigung fuer Files notification = message # Benachrichtigung via msg notification = mail # Benachrichtigung via mail notification = both # Benachrichtigung via mail und msg notification = mail blubber@blah # Benachrichtigung via mail an ... · aliases Hierbei handelt es sich um ein Aliasfile, in dem oft benutzte Adressen abgekürzt wer- den können. Das Format ist: alias address Beispiel: chief grmblfz@bigvax.somewhere.net beate beate@juhu.lake.de · restrictions Hier drin stehen Adressen, von denen man keine Dateien oder Nachrichten bekom- men möchte. Das Format ist: user@host [mfb] Dabei steht m für Message, f für File und b für both. Beispiele: gates@microsoft.com b *aol.com m · msg Hier drin steht der Name des tty auf das ankommende Nachrichten ausgegeben werden sollen. Wird automatisch von sendmsg gesetzt. 2.3 Installation Es wird vorausgesetzt, daß grundlegende Kenntnisse der Administration einer vernet- zen Unix-Workstation vorhanden sind. Diese hier zu erklären, würden bei weitem den Rahmen der Dokumentation sprengen. 1. Pfade anpassen: Bei Bedarf können in config.h (und NUR da!) Default-Werte für bestimmte Pfade geändert werden. Dies sind: #define BINDIR "/usr/local/bin" #define MANDIR "/usr/local/man/man1" #define SERVERDIR "/usr/local/sbin" #define SPOOL "/var/spool/sendfile" #define NOSENDFILE "/usr/local/etc/nosendfile" #define CONFIG "/usr/local/etc/sendfile.cf" Bei den ersten drei Werten handelt es sich Verzeichnis, in die sendfile installiert wird, bei den letzten drei um den Ort des Spool bzw. der Systemkonfigurationsda- teien. 2. Laufzeit-Konfiguration anpassen: Der sendfiled wertet zur Laufzeit die Systemkonfigurationsdatei sendfile.cf aus (wird normalerweise nach /usr/local/etc/ kopiert, siehe oben). Dies kann entweder jetzt oder zu jedem späteren Zeitpunkt geändert werden, falls Bedarf besteht. 3. alles compilieren: make Es dürfen keine Fehlermeldungen auftreten. Auf manchen Systemen mit fehlerhaf- ten System-Include-Files kann es zu Warnings kommen, die aber ignoriert werden können. Sendfile wurde bisher getestet unter AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris 2) und Ultrix mit gcc 2.5.8. Ultrix-ACHTUNG! Bei Ultrix muss vor ,make all" noch ,sh5 genmake" einge- geben werden (weil Ultrix-sh buggy ist)! 4. alles automatisch installieren (muss root machen!): make install oder von Hand installieren: - korrekte Fileprotection einstellen: umask 022 - sendfiled hinkopieren, wo es Sinn macht, zB /usr/local/sbin, /usr/etc : cp sendfiled /usr/local/sbin/ - spool-directory anlegen (wie in config.h angegeben!): mkdir /var/spool/sendfile chmod 755 /var/spool/sendfile - Eintragung in /etc/services (bzw mit ,niload services ." bei NeXT): saft 487/tcp # simple asychronous file transfer - Eintragung in /etc/inetd.conf: saft stream tcp nowait root /wo/auch/immer/sendfiled - inetd neu starten: kill -HUP /usr/sbin/inetd #(oder wo auch immer der inetd liegt) - Userbeschränkung aktivieren (wie in config.h angegeben!): cp nosendfile /etc - man-pages installieren: cp sendmsg.1 sendfile.1 receive.1 /usr/man/man1 - notify-script installieren: $ cp check_sendfile /usr/local/bin /usr/local/bin/check_sendfile in /etc/profile aufnehmen - Clients installieren: cp sendfile sendmsg receive /usr/local/bin 5. testen: sendfile LIESMICH $LOGNAME receive -l receive -n 1 6. Ich bin sehr an Kommentaren und Bugreports interessiert. Geschenke via Post schicken. :-) 7. Wer mir die Adresse seines neu installierten SAFT-Servers mitteilt, bekommt zur Belohnung ein schönes gif zugeschickt. :-) 8. Es gibt eine Mailingliste, die ich von Hand führe und in der Ankündigungen zu updates und bugfixes geposted werden. Wer da aufgenommen werden möchte, sende mail an mich. 2.4 Sourcen Das sendfile Paket besteht aus (Module und darin enthaltene Funktionen): · sendfile.c - Das sendfile Hauptmodul. usage : print short help usage text whereis : search for program name in PATH send_data : send file data clean_up: delete tmp-file · sendfiled.c - Das sendfiled Hauptmodul. getline : get a command line writeheader : write one line to header spool file msg2tty : write a message to all ttys of the user mail2user : send a mail to the recipient spoolid : get the next spool id number restricted : check killfile wlock_file : write-lock a file tlock_file : test the lock status of a file · sendmsg.c - Das sendmsg Hauptmodul. usage : print short help usage text · receive.c - Das receive Hauptmodul. usage : print short help usage text receive_sf : receive a spool file list : list all spool files crlf2lf : translate NVT format file to Unix text format file fcopy : copy a file spawn : spawn a subprocess and direct output to a file · spool.c spool.h - Funktionen zum lesen und schreiben von Spoolfiles out : send string conforming to NVT standard scanspool : scan the spool directory and create structure lists delete_sf : delete a spool file · reply.c reply.h - reply-codes für sendfiled. reply: send string conforming to NVT standard · string.c string.h - Erweiterte Stringfunktionen. str_trim : trim white spaces str_toupper : transform string to upper case str_tolower : transform string to lower case strins : insert one string in another simplematch : match a simple pattern · utf7.c utf7.h - UTF-7 und Unicode Kodierungsroutinen. utf2iso : UTF-7 to ISO Latin-1 decoding iso2utf : ISO Latin-1 to UTF-7 encoding iso2uni : transform ISO Latin-1 to Unicode add_char : add a char depending on its range decode_mbase64 : decode mbase64 string to Unicode encode_mbase64 : encode Unicode pstring to mbase64 · pstring.c pstring.h - Routinen zum Umgang mit Pascalähnliche Strings. pstr_create : create a pstring pstr_delete : delete a pstring pstr_addchar : add a char to a pstring pstr_assign : assign one pstring to another pstr_addstring : add a string to a pstring pstr_print : print a pstring · message.c message.h - VMS-like Informations und Fehlermeldungsroutine. message : print information, warning and error messages on stderr · peername.c peername.h - Funktion zur Erkennung des aufrufenden Host über stdin. peername : returns the peername of the connecting host on stdin · io.c io.h - Socket read und write Funktionen. readn : read n bytes from network socket writen : write n bytes to network socket · net.c net.h - Verschiedener Netzwerkkram. open_connection : open socket and connect to client sock_getline : get a line from the network socket sock_putline : send a line to the network socket getreply : get the reply on a command from the server sendheader : send a headerline and check the reply code · destination.c destination.h - Bestimmung des Empfängers destination: parsen von elm-aliasen und hostname-Daten. · config.h - Verschiedene Preprozessordefinitionen. · bsd.h - Das blöde AIX hat keine eigenen include-Files für sockets. · genmake - Shellscript zur Bestimmung des Betriebsystems und zur Generierung des Makefiles. · check_sendfile - Shellscript um zu überprüfen, ob Dateien im Spool vorliegen. Sollte von /etc/profile aufgerufen werden. · sf_cleanup - Shellscript zum löschen alter Files aus dem Spool. · install - automagic install-script · nosendfile - Liste aller Benutzer, die vom SAFT-Dienst ausgeschlossen sind. · sendfile.cf - sendfile-Systemkonfigurationsfile. · LIESMICH - Eine deutsche Installationsschnellhilfe. · LIESMICH.auch - Kurzbeschreibung von sendfile/SAFT · README - a quick installation guide · README.too - a short description of sendfile/SAFT · HISTORY - last changes · sendmsg.1 - Man-page für sendmsg. · sendfile.1 - Man-page für sendfile. · receive.1 - Man-page für receive. · doku.ps - Diese Dokumentation hier. · doc.ps - this documentation 2.4.1 Aufrufdiagramm Modulübersicht 2.4.2 Datenstrukturen Von den Programm-Datenstrukturen, die implementiert wurden, sind 3 von Interesse (bei den restlichen handelt es sich um Standard C Typen wie int, char *, etc): · pstring - Strings mit Längeninformationen (von Pascal abgeleitet). Die pstrings sind notwendig, um Unicode-Strings zu verarbeiten, welche ASCII(0) Zeichen enthalten können. Die normalen C-Strings vom Typ char* behandeln ASCII(0) als Ende des Strings und sind somit für Unicode unbrauchbar. In Anlehnung an Pascal wurden die pstrings implementiert, deren Länge nicht durch ein Terminalzeichen definiert wird, sondern über extra Struktureinträge. Die pstrings haben folgende Struktur: struct { int size; /* absolute Länge */ int length; /* belegte string-Länge */ char *string; /* der String selber ohne Terminierungssymbol */ } size ist dabei die Speicherkapazität des pstrings, während length die tatsäch- lich belegte Länge ist. In *string steht der eigentlich Textstring. Per Definition beginnt der Inhalt des pstring mit string[1] und nicht wie sonst üblich in C mit string[0]. Dies hat zwar zur Folge, daß pro pstring ein Byte ver- schwendet wird, aber es hat gleichzeitig den Vorteil, leichter mit den Längenange- ben rechnen zu können. In string.c sind die pstring-Funktionen definiert, die im Zusammenhang mit den Unicode-Strings im sendfile-Paket benötigt werden. · filelist - Eine einfach verkettete Liste zum Speichern der Dateiattribute und deren Absender. Pro Absender existiert eine Liste, pro Datei wird ein Listenelement angelegt, wobei die Liste nach dem Empfangsdatum aufwärts geordnet ist, d.h. die zuerst empfangene Datei wird als erstes Listenelement gespeichert. Ein filelist-Element hat folgende Struktur: struct filelist { int id, /* id number */ osize, /* original size */ csize, /* compressed size */ tsize, /* transfered size */ flags; /* binary,source,text,compress and tar flag */ char rdate[30], /* receiving date */ date[30], /* file date */ charset[30], /* character set name */ fname[MAXLEN]; /* UTF-7 file name */ struct filelist *next; /* next list element */ }; id ist die eindeutige Dateinummer im Spool. Siehe dazu weiter unten. osize ist die Originalgröße der Datei ohne Kompression. csize ist die Größe der Datei, wie sie (komprimiert) übertragen wird. tsize ist die tatsächlich Anzahl der übertragenen Bytes. flags sind die Dateiattribute für SOURCE, TEXT, COMPRESS und TAR. rdate ist das Empfangsdatum. date ist das Originaldatum der Datei, wie sie der Sender mit angibt. charset ist der Name des Zeichensatzattributs. fname ist der Dateiname, UTF-7 codiert. *next ist der Zeiger um die Liste zu verketten. Die Definition von filelist und den Flags befindet sich in spool.h. · senderlist - Eine einfach verkettete Liste zum Speichern der Absender und der filelists. Im Gegensatz zu den filelists existiert nur eine senderlist. Pro Absender wird ein Listenelement angelegt. Ein senderlist-Element hat folgende Struktur: struct senderlist { char from[MAXLEN], /* sender */ sig[MAXLEN]; /* authentification signature */ struct filelist *flist; /* list of files */ struct senderlist *next; /* next list element */ }; from ist der Name des Absenders, UTF-7 codiert. *flist ist der Zeiger auf die dazugehörige filelist. *next ist der Zeiger auf das nächste Listenelement. Die senderlist und filelists ergeben also zusammen folgende Struktur:: Diese Datenstruktur wird jedesmal neu erzeugt, wenn Informationen über Spoolfi- les benötigt werden. Diese verketteten Listen können in einem C Programm wesentlich einfacher ausgewertet werden, als daß für jede Information das betref- fende Spoolheaderfile explizit ausgelesen wird Der Spool selber wird in /var/spool/sendfile angelegt, wo jeder Empfän- ger bei Bedarf, d.h. wenn zum ersten mal eine Datei für ihn empfangen wird, auto- matisch ein eigenes Spoolverzeichnis bekommt (im Source als userspool bezeichnet). Im userspool befinden sich für jede empfangene Datei zwei Spoolfiles: das Spoolheaderfile und das Spooldatafile. Im Spoolheaderfile sind alle Dateiattribute eingetragen, die der Sender übermittelt hat, im Spooldatafile ist die Datei selbst als Bytestrom abgelegt, so wie sie übertragen wurde.Weiterhin befindet sich in die- sem Directory das sogenannte log-File, in dem alle Übertragungen protokolliert werden. Beispiel eines userspool: baracke:~/sendfile> ll /var/spool/sendfile/zrxh0370/ -rw------- 1 zrxh0370 system 1176 Sep 13 18:03 1.d -rw------- 1 zrxh0370 system 137 Sep 13 18:03 1.h -rw------- 1 zrxh0370 system 994 Sep 13 18:03 2.d -rw------- 1 zrxh0370 system 136 Sep 13 18:03 2.h -rw------- 1 zrxh0370 system 5178 Sep 13 18:03 log baracke:~/sendfile> cat /var/spool/sendfile/zrxh0370/1.h FROM gaga@linux.rus.uni-stuttgart.de FILE blubb.txt TYPE TEXT SIZE 5 5 DATE 1995-09-14 12:38:06 CHARSET ISO_8859-1:1987 3 Danksagungen Mein besonderer Dank geht an: · Lorenz Adena - für Featurewünsche und Betatesting · Thomas Beisel - für C Beratung, Postscripthexerei und Betatesting · Uwe Berger - für Grundsatzdiskussion und Designhilfen · Beate Herrmann - für grundlegende Ideen, psychologische Betreuung und Betatesting · Andreas Ley - für jede Menge Hilfe bei obskuren C Problemen und für die peername Funktion · Shannon Miller - for his corrections to my english documentation · Uwe Obermüller - für viele Vorschläge und Betatesting · Bernd Onasch - für C Beratung · Ingo Wilken - für die simplematch Funktion ohne deren Hilfe die Realisation dieses Projekts unmöglich gewesen wäre. 4 Informationsverzeichnis [1] Andrew Tanenbaum: Computer Networks [2] Bettina Reimer, Paul Müller: Kommunikationssysteme auf der Basis des ISO- Referenzmodells [3] Kernighan, Ritchie: Programmieren in C [4] Jürgen Gulbins: UNIX [5] W. R. Stevens: Advanced Programming in the UNIX Environment [6] W. R. Stevens: UNIX Network Programming [7] ISO-8601 - International Time and Date Representing [8] C-FAQ-list in news.answers [9] Umlaute-FAQ in de.comp.standards [10] internationalization/programming-faq in news.answers [11] mail/mime-faq in news.answers [12] http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt [13] RFC 859 - ftp [14] RFC 1345 - Character Mnemonics & Character Sets [15] RFC 1440 - SIFT/UFT: Sender-Initiated/Unsolicited File Transfer [16] RFC 1521 - MIME [17] RFC 1522 - MIME [18] RFC 1543 - Instructions to RFC Authors [19] RFC 1641 - Using Unicode with MIME [20] RFC 1642 - UTF-7 [21] RFC 1700 - Assigned Numbers Die RFCs sind zu finden unter ftp://ftp.uni-stuttgart.de:/pub/doc/standards/rfc/ Die FAQs sind zu finden unter ftp://ftp.uni-stuttgart.de:/pub/doc/faq/ 5 Glossar · ASCII - American Standard Code of Information Interchange 7 bit Zeichensatzkodierung der wichtigsten im amerikanischen Sprachraum vorkom- menden Zeichen. Siehe RFC 1345. · Bitnet - Because It`s Time Network Aussterbendes weltweites Forschungsnetzwerk auf IBM RSCS Technologie. In vielen Belangen der Vorgänger zum Internet. · DOS - Diskette Operating System Primitiver Diskettenmonitor und Interrupthandler für i8088 PCs · EBCDIC - Extended Binary Coded Decimals Interchange Code IBMs Zeichensatz für ihre Großrechner. · EOL - End Of Line · FAT - File Availibility Table Filesystem für DOS. · FDL - File Definition Languange Filesystembeschreibungssprache für RMS. · ftp - file transfer protocol/program Standardmethode um Dateien zu transferieren (synchron). Siehe RFC 959. · GNU - GNU`s not Unix Ein fortlaufendes Projekt der Free Software Foundation um qualitativ hochwertige und lizenzfreie Software im Sourcecode der Internetgemeinde zur Verfügung zu stel- len. · MIME - Multipurpose Internet Mail Extensions Multimediaerweiterungen für Mail. Siehe RFC 1341. · MUA - mail user agent Der Mailclient, den der Benutzer direkt verwendet. · MTA - mail transfer agent Der Mailserver (daemon), der vom MUA kontaktiert wird. · NVT - Network Virtual Terminal Remote login im Internet: telnet. Siehe RFC 854. · RFC - Request for Comment Internet Standard und Protokoll Beschreibungen. · RMS - Record Management System Das native Filesystem von VMS. · tcp/ip - transmission control protocol / internet protocol Netzwerk- und Transport-Ebene (ISO Level 3+4) des Internets. Siehe RFC 791/793. · VMS - Virtual Memory System Das beste Betriebssystem der Welt von DEC :-) sendfile-2.1b/doc/fetchfile.10000644000175100001440000000537610251132201015611 0ustar framstagusers.\" Personal .TH SENDFILE 1 .UC L .SH NAME fetchfile - fetch file(s) via O-SAFT protocol .SH SYNOPSIS .B fetchfile [ .B \-46lakdPriqQvVI ] [ .B \-f user ] [ .B \-s [user@]server ] [ .B \-C[wr]=conffile ] .I filename .B fetchfile [ .B \-lakdPriqQvVI ] [ .B \-f user ] [ .B \-s [user@]server ] [ .B \-C[wr]=conffile ] .I -n filenumber .SH DESCRIPTION .B fetchfile fetches files from a SAFT server to the local user spool. .PP In the SAFT server spool there must lay your sendfile public key to identify yourself. This key can be generated by the .I fetchfile -I command and has to be transfered to the SAFT server at the very first time. This prevents other people to steal your files. .PP You may list or fetch your files from the server. But remember, they are stored first in your local sendfile spool. You have to call .I receive to really receive them to your current directory. .SH OPTIONS .TP 8 .B -4, -6 Explicitly force IPv4 or IPv6 connections. By default, the program will try to resolve the name given, and choose the appropriate protocol automatically. If resolving a host name returns both IPv4 and IPv6 addresses, fetchfile will try to use the adresses in the order they are returned by the resolver. .TP .B -l Only list the files on the server. .TP .B -a Fetch all files. .TP .B -k Keep files on server after fetching. .TP .B -d Delete files without receiving. .TP .B -n Specify the file number instead of the file name. .TP .B -r Call receive automaticly afterwards. .TP .B -f user Restrict file selection to this specifc user. .TP .B -V Show version information and exit. .TP .B -v Be verbose and show SAFT protocol messages. .TP .B -P Send files to stdout directly. .TP .B -i Ignore testing whether file has been already fetched. .TP .B -q Quiet mode 1: print no transfer messages. .TP .B -Q Quiet mode 2: print no transfer, information or warning messages. .TP .B -I Initialize fetchfile and the pgp key pair. .TP .B -s [user@]host Specify an alternate saft server and/or alternate user. .TP .B -Cr=conffile Read configuration file "config" or "restrictions" from server. .TP .B -Cw=conffile Write configuration file "config" or "restrictions" to server. .SH ARGUMENTS .TP 8 .I filename or filenumber Specify the name of the file or its number (with option -n). .SH EXAMPLES fetchfile -l .br fetchfile -a .br fetchfile -Cr=config -s saft.belwue.de .SH FILES .TP 6 .I /var/spool/sendfile/$USER/ Your local spool directory. .TP .I $HOME/.sfspool/ Your local private spool directory if /var/spool/sendfile/$USER/ does not exist. .TP .I config, restrictions Your configuration files for the server. See sendfile(1) for a description. .SH SEE ALSO .BR receive (1), .BR sendfile (1), .BR fetchfile (7), .BR sendfiled (8). .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de sendfile-2.1b/doc/install-with-configure.old0000644000175100001440000001534510251132201020671 0ustar framstagusersBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing this file and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. 6. Now you got to make some changes to the /etc/inetd.conf and /etc/services, or the proper files for your system: 6.a) add a line to /etc/services like: saft 487/tcp # simple asynchrounos file transfer 6.b) If you use the tcp-wrappers, add a line to /etc/inetd.conf: saft stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/sendfiled Adjust /usr/local/sbin/sendfiled to whereever you installed the sendfiled, usually it is in $(prefix)/sbin/sendfiled, see below. 7. Restart inetd. See your system manual how this works, often you can send inetd a SIGHUP to restart it. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Using a Different Build Directory ================================= You can compile the package in a different directory from the one containing the source code. Doing so allows you to compile it on more than one kind of computer at the same time. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Save the results of the tests in FILE instead of `config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. sendfile-2.1b/doc/LIESMICH.entwickler0000644000175100001440000002360710251132201017061 0ustar framstagusersDiese Datei ist fuer sendfile Entwickler/Portierer. --------------------------------------------------------------------------- Erst mal eine Erklaerung, was die ganzen Versionsnummern zu bedeuten haben: Urspruenglich hatte ich gar keine Versionsnummer drin. Da haben einige Leute aber zurecht gemeckert und ich hab dann mit sendfile 1.0 angefangen, das ziemlich schnell von 1.2, und 1.3 abgeloest wurde. 1.3 war dann auch die erste Version, die auf unseren ftp-Server kam. Mit 1.4 wurde das Installationsskript wesentlich verbessert und sendfile.cf wurde eingefuehrt. Damit konnte man zum ersten mal sendfile zur Laufzeit konfigurieren (wer's sich noch nicht angeschaut hat, moege bitte JETZT einen Blick in sendfile.cf werfen :-) ). Im Mai 1996 war ich 1 Monat arbeitslos und waerend der Zeit hatte ich genug Zeit den pgp-Support und einige andere neue Features einzubauen (viele Tips und Vorschlaege dazu sind von Heiko Schlichting und Lorenz Adena eingeflossen). Das Resultat war sendfile 1.5. Leider ist die Postscript-Doku immer noch auf Stand von 1.4, weil ich ausserhalb der Uni keinen Zugriff auf Framemaker hab. Deshalb will ich jetzt die gesamte Doku umstellen. Ich evaluiere gerade SGML-Tools, YODL und UDO. Letzteres scheint mir am vielversprechendsten zu sein, auch wenn es Shareware ist. Dann kam stesch und hat sich als Missionar im Namen des SAFTs betaetigt, hauptsaechlich via #Linuxger auf irc. In Folge wurde ich von Anfragen ueberrannt und ich habe die Mailingliste saft@listserv.uni-stuttgart.de aufgemacht. Bis dahin war 1.5 immer noch aktuell und ziemlich ausgereift und stabil. Als GNUish mich fragte, warum ich so ein komisches heimgebrautes Konfigurationscript genmake benutze und nicht die Standardmethode mittels GNU autoconf hab ich geantwortet "1.5 ist stabil und ich hab auch keine Zeit den Code auf autoconf komplett umzustellen. Mach doch du, wenn du willst :-)". Der hat das dann doch tatsaechlich ernst genommen. :-) 1.5.1 war geboren und nur 2 Leuten zugaenglich: GNUish und mir. Das war auch besser so, denn diese Version compilierte grad eben so unter Linux. Mit vielen Verbesserungen wurde daraus 1.5.2, die ausschliesslich an interessierte Entwickler ging, denn auch diese Version compilierte immer noch nicht gut auf den bisher unterstuetzten Plattformen (AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris) und Ultrix). Das GNU autoconf/automake System ist ein wahres Monster an Shellscripten, m4 und Makefiles. Wir haben es nie hingebracht, dass es auch auf Systemen funktionierte, die nicht alle GNU Tools bereits installiert hatten. Als ich mich dann wieder zu sehr darueber aufgeregt hatte, dass ich selber nicht verstehe wer was wo aufruft beim Konfigurationsschritt, hab ich alles weggeworfen, was nicht portabel oder zu kompliziert war. In 1.5.3 ist vom GNU autoconf nur noch uebrig geblieben: das configure-Script, das herausfindet, welche Besonderheiten das jeweilige UNIX hat und das config.guess-Script, das die UNIX-Variante erraet. Diese 2 Scripte sind unabhaengig voneinander und brauchen keine weitere Zusatztools, sind also prima handhabbar. Die eigentliche Codebasis blieb zwischen 1.5 und 1.5.3 fast dieselbe (abzueglich ein paar Goodies, die ich fuer stesch eingebaut habe und die er bald mal vorstellen darf :-) ). Nur die Konfiguration und die bedingte Compilation hat sich geandert. In 1.5.4 wurden einige Bugs gefixt und die Doku verbessert. Nachdem das einige Wochen stabil lief, hab ichs in sendfile 1.6 umbenannt. In sendfile 2.0 kam der O-SAFT Support hinzu: man kann mittels des fetchfile Clients jetzt seine Files von einem O-SAFT Server abholen. Dazu musste das SAFT-Protokoll erweitert werden, eben um den O-Teil, der fuer "Offer" steht. Nachdem sich bzip2 als neues und besseres Kompressionsprogramm verbreitet hat, bietet nun auch sendfile 2.1 (automatischen) bzip2 Support an. Kann der Empfaenger damit nichts anfangen, kommt es zu einem Fallback auf gzip. Was frueher (<=1.5) genmake hiess wurde jetzt zu makeconfig und ist auch vom toplevel Makefile aufrufbar. Es ergibt sich jetzt folgende Struktur: Ausgangspunkt ist das makeconfig-Script. In dem kann man bestimmte Dinge wie Compiler, Flags, Pfade, etc vorher festlegen. Fuer alle Werte hab ich aber (hoffentlich) sinnvolle Defaults eingesetzt. Das Festlegen erfolgt wie folgt: 1. Existiert die Environment-Variable SF_DEVELENV, wird die Datei gelesen auf die diese Variable zeigt, oder 2. es wird ./.develenv benutzt, oder 3. es wird $HOME/.develenv gelesen und die Variablen werden aus dieser Datei uebernommen, oder 4. die default-Werte aus makeconfig werden benutzt. In diesen Konfigurationsdateien werden einfach die entsprechenden Variablen als environment-Variablen gesetzt. Es existieren folgende Variablen: - CC, CFLAGS, LINK, LDFLAGS beeinfluessen das Kompilieren und Linken, - BINDIR, SERVERDIR, MANDIR fuer die Installationsverzeichnisse, - CONFIG ist fuer das Konfigurationsverzeichnis, - SPOOL fuer das Spool-Verzeichnis, - TAR, GZIP, PGP, RECODE, SENDMAIL fuer die externen Programme. makeconfig startet dann das configure-Script welches das config.h File erzeugt, in dem die Systembesonderheiten des jeweiligen UNIX stehen. Eigentlich erzeugt es auch noch die Makefiles, aber die sind so schlecht und undurchsichtig (siehe oben), dass ich sie im weiteren Verlauf von makeconfig gleich wieder durch meine eigenen Makefiles ersetz :-) Diese Makefiles haben den Vorteil, dass sie klein, ueberschaubar und ueberall lauffaehig sind. Weiterhin wird globals.h erzeugt, das Konfigurationen enthaelt, die zur compile-Zeit festliegen, wie Pfade und Konstanten fuer C. Deshalb duerfen Makefile, config.h und globals.h niemals von Hand editiert werden, weil die beim naechsten makeconfig Aufruf wieder ueberschrieben werden! Zur Erleichterung fuer den normal-User liefer ich noch ein proto-Makefile mit, das eigentlich nur die Aufgabe hat makeconfig zu starten. Es wird dann auch gleich darauf ueberschrieben. In 1.5 hab ich das mit genmake aehnlich gemacht. Speziell jetzt fuer die wagemutigen non-UNIX-Portierer (huhu Hen3ry!) gilt: makeconfig und damit config.guess und configure werden nicht auf diesen Systemen laufen. Ich rate dazu System-spezifische Makefiles, globals.h und config.h zu erzeugen, das sich ja dort nicht mehr aendern muss, und makeconfig&Co zu ignorieren. Im Code selber kann dann mit #ifdef gearbeitet werden, also zB #ifdef OS2 Als Ausgangsbasis fuer Makefiles, globals.h und config.h empfehle ich die Version, die makeconfig fuer Linux erzeugt (kann ich auf Wunsch saften oder mailen). Ich habe die Erfahrung gemacht, dass der Code fuer Linux am geeignesten ist um portiert zu werden - zumindest mein Code fuer Linux :-) --------------------------------------------------------------------------- Ports: OS/2 (Stefan Bauch, bauch@lizard.RoBIN.de): config.h kann fuer OS/2 leer sein, bis auf die Zeilen: #define PACKAGE "sendfile" #define VERSION "1.5.3" #define REVISION "19970217" #define SYSTEM "OS/2 4.0" /* heisst doch so, oder? */ #include "globals.h" --------------------------------------------------------------------------- post processing =============== Im File sendfile.aliases (wenn man die Konfiguration nicht geändert hat als /usr/local/etc/sendfile.aliases zu finden) kann man nicht nur die gewohnten Aliases unterbringen. Verwendet man das Pipe-Symbol ('|'), dann kann man ein empfangenes File zusammen mit dem Header in ein Programm pipen. Aufbau ist wie gewohnt: | muß ein lokaler Username sein. ist das Programm, welches mit dem Header und dem empfangenen File auf STDIN versorgt wird. Alternativ kann ein User auch in seiner lokalen Konfiguration ein "forward=|" einfügen. Der Headeraufbau ist einfach eine Sammlung von SAFT-Protokoll-Kommandos, wie sie beim lokalen Server ankommen. Am besten schaut man sich dazu im lokalen SAFT-Spool die Dateien mit der Endung ".h" an. Die Dateien mit ".d" sind die Datenfiles. Das Postprocessingprogramm bekommt nun beide Dateien (Header und Daten) hintereinander auf STDIN vorgesetzt. Die eigentlichen Daten folgen nach der Headerzeile "DATA". Zu beachtet ist, daß der Header in utf7 kodiert ist. - Stefan Scholl --------------------------------------------------------------------------- extended headers ================ sendfile hat die Option "-X" für extended Header. Mit dieser Option ist es möglich das zu übertragene File inklusive dem benötigten Header (siehe "post processing") in sendfile "reinzupipen". Einzig benötigter (und einzig zulässiger) Parameter beim sendfile-Aufruf ist der Empfängerhostname. Es läuft praktisch fast so ab, als würde man mit telnet zum Server connecten, dort den Dialog ablaufen lassen und dann nach "DATA" das File schicken. Man könnte es vielleicht grob mit BSMTP vergleichen. Wie bei BSMTP gibt es hier keine Onlinephase und auch keinen Dialog. Und BSMTP ist von SMTP abgeleitet. Sinn und Zweck kann sich jeder selbst suchen. Sehr praktisch ist dieses Feature jedenfalls, wenn man Unicode-Zeichen erhalten will, die vielleicht als Parameter beim Aufruf von sendfile (vielleicht wegen der Shell) verloren gehen würden. - Stefan Scholl --------------------------------------------------------------------------- GANZ WICHTIGE ANMERKUNG zu snprintf: snprintf(MAXS(string),...) darf nur verwendet werden, wenn string als Array deklariert und bekannt ist, NICHT jedoch wenn string nur ein pointer ist, zB bei einem Funktionsaufruf! Bei letzterem muss verwendet werden: snprintf(string,Laenge_des_strings-1,...) Begruendung: in string.h ist definiert: #define MAXS(s) s,sizeof(s)-1 Dies funktioniert nur auf Arrays, nicht jedoch auf Pointer! --------------------------------------------------------------------------- Um den sendfiled zu debuggen kann mit fprintf(dbf,...) in das File DBF = "/var/log/sendfiled.dbg" geschrieben werden. Der filedescriptor dbf ist global definiert und immer offen. sendfile-2.1b/doc/LIESMICH.neu0000644000175100001440000002302410251132201015472 0ustar framstagusersIn diesem File werden neue Feature beschrieben, die noch nicht im (veralteten) doku.ps enthalten sind. Irgendwann demnaechst wird die ganze Doku ueberarbeitet, dann verschwindet auch dieses File wieder. Die Behebung von Bugs wird in ChangeLog beschrieben. - Neue Option -m LIMIT fuer sendfile um den maximalen Durchsatz auf LIMIT KB/s zu beschraenken. - Neue sendfile.cf Option lanspeed: damit kann festgelegt werden, bis zu welchem Durchsatz in KB/s andere Hosts als lokal definiert werden, was zur Folge hat, dass an diese Hosts nicht komprimiert verschickt wird. - Unterstuetzte regular expressions: ? matches any single character * matches any string [abc] matches 'a' or 'b' or 'c' within [] the characters '?', '*' and '[' are no wildcards [^abc] matches every character but not 'a' or 'b' or 'c' [a-d] matches 'a' or 'b' or 'c' or 'd' (range) this is equal to [abcd] [^a-d] matches every character but not 'a' or 'b' or 'c' or 'd' (range) this is equal to [^abcd] \? test for "true" '?' alternative: [?] \* test for "true" '*' alternative: [*] \[ test for "true" '[' alternative: [[] \a Bell \b BackSpace \f FormFeed \n NewLine \r Return \t Tab \v FormFeed \\ Backslash - sendfile-2.1 hat jetzt bzip2 Support. bzip2 ist ein neues lizenzfreies Komprimierungsprogramm und ist etwa 10-30% effizienter als gzip (http://www.muraroa.demon.co.uk/) - Neue Hilfsprogramme zum Konfigurieren: fuer den User: sfconf fuer den Admin: sfdconf - Protokoll-Erweiterung O-SAFT mit neuem Client fetchfile: siehe LIESMICH.fetchfile - Die Syntax der sendfile Option "-a archive-name" wurde geaendert zu "-a=archive-name" um eine Fehlbedienung zu minimieren. Aus Orthogonalitaetsgruenden ist jetzt auch "-c='comment'" neben "-c 'comment'" zulaessig. - Neue receive Option "-S keyring" erzwingt einen Signaturcheck. Nur wenn dieser positiv ist, wird das File empfangen. Wichtig fuer Batch-Betrieb. - Wird ein File erkannt, das nicht komprimierbar erscheint (typische File- Extension oder Erkenntnis durch file(1)-Programm), dann wird unkomprimiert verschickt. Mit der Option -C kann Komprimierung erzwungen werden. - Messages koennen in /var/spool/sendfile/$USER/msglog geloggt werden, wenn die Option msglog = on im /var/spool/sendfile/$USER/config/config oder sendfile.cf gesetzt ist. - Das Verhalten des tty Tests von sendmsg wurde geaendert. Jetzt gilt: Die erste message, die ankommt wird vom sendfiled auf allen ttys ausgegeben, die fuer group schreibberechtigt sind. Dasselbe wird erreicht durch: sendmsg -M Wird eine message abgeschickt und ist kein tty als aktiv markiert, so wird das aktuelle tty als aktiv markiert. Das bedeutet dass ab sofort einkommende messages nur noch auf dieses tty ausgegeben werden. Wird versucht auf einem tty eine message zu verschicken, das schreibgeschuetzt ist oder waerend ein anderes tty als aktiv markiert ist, so kommt es zu einer Fehlermeldung. Um trotzdem messages abschicken zu koennen gibt es die Option: sendmsg -f Mit sendmsg -m markiert man das aktuelle tty als aktiv. Das bedeutet, dass messages nur noch hier ausgegeben werden. - Fuer Benchmarktests stehen 2 neue Moeglichkeiten zur Verfuegung: sendfile test /dev/null # testet die Lesegeschwindigkeit sendfile test /dev/null@host # testet zusaetzlich die Uebertragungsgeschwindigkeit In keinem Fall wird das (test) File auf Platte geschrieben. - Protokollaenderung: das TYPE-Kommando erlaubt jetzt auch das Attribut MIME - Protokollaenderung: das CHARSET-Kommando wurde in das TYPE-Kommando integriert: CHARSET charset --> TYPE TEXT=charset (Dies hat keine Kompatibilitaetsauswirkungen, da sendfile bisher die einzige SAFT-Implementierung ist und das TEXT bzw CHARSET Attribut vorerst ignoriert werden koennen.) - Mit der Option -P gibt receive ein File auf stdout aus (kann dann via Pipe weiterverarbeitet werden). Beispiel: receive -kP readme | more (Die Option -k verhindert, dass das File aus dem spool geloescht wird) - Mit der Option -P kann sendfile von stdin (bzw aus einer Pipe) lesen. Beispiel: ls -l | sendfile -P my_dir framstag@bofh.belwue.de Dabei handelt es sich nicht um synchrones Piping im klassischen (Unix-) Sinn, sondern der data stream von stdin wird in ein tmp-File geschrieben (transparent fuer den User) und erst wenn ein EOF von stdin kommt, wird dieses Zwischenfile abgeschickt. Dasselbe Prinzip verwendet zB der lpd bzw lpschedul. - sendfiled hat die runtime option "-c " bekommen, welches anstelle dem eincompilierten CONFIG Wert auf das sendfile-config- file zeigt. Beispieleintrag in /etc/inetd.conf : saft stream tcp nowait root /usr/local/sbin/sendfiled sendfiled -c /local/etc/sendfile.cf - Existiert /var/spool/sendfile/.nosendfile, so werden vom sendfiled keine Files mehr angenommen und auch laufende Transfers werden abgebrochen. - In config.h kam das neue Macro ALIASES hinzu. Existiert das dazugehoerende File (wird von root verwaltet), dann setzt der sendfiled die Adressen entsprechend um. Beispiel fuer so ein sendfile.aliases: frams framstag # lokaler Username Umsetzung delta zrzs0111 # lokaler Username Umsetzung blubb bla@gaga.banane.net # forward Adresse auf anderen Host - forwards koennen jetzt geschachtel werden, maximaler hopcount ist 10 - sendfile 1.5 hat jetzt pgp Support eingebaut: Files koennen verschluesselt und/oder mit digitaler Signatur uebertragen werden, vorausgesetzt, sowohl auf Empfaenger-, als auch auf Sendersystem ist pgp installiert. Neue Optionen fuer sendfile (Argumente in [] sind optional): -pe[=to_user] pgp Verschluesselung -pc pgp IDEA Verschluesselung (symmetrisch) -ps[=my_ID] pgp Signierung Beispiel fuer das Verschicken eines verschluesselten Archivs: sendfile -pe -a geheim *.gif hoppel@juhu.lake.de Der pgp public key fuer hoppel muss latuernich vorhanden sein. - Die neue Option "-f from_user" erlaubt es bei receive anzugeben auf welche Files von welchem Sender die Aktion gilt, zB: receive -L -f framstag # listet nur die Files von mir receive -daf microsoft.com # loescht alle files, die von Winzigweich gekommen sind. - Die neue Option "-s" bei receive gibt eine "short file list" aus (ohne Kommentare, Signaturen, etc). - Die neue Option "-o" (overwrite) erlaubt es, bei sendfile ein File zu schicken und ein File gleichen Namens zuvor zu loeschen (falls es sich noch im Empfaengerspool befindet). sendfile -o blubb heiko ist gleichbedeutend mit: sendfile -d blubb heiko sendfile blubb heiko - Bei receive kann jetzt nicht nur zwischen Ueberschreiben oder Uebergehen ausgewaehlt werden, wenn ein File gleichen Namens schon existiert, sondern es kann gleich ein neuer Name angegeben werden. - Ein neues Fileattribute COMMENT wurde eingefuehrt. Damit kann zu einem File ein kurzer Kommentar angegeben werden, der dann in der receive- Liste erscheint. Automatisch wird ein Kommentar beim bouncing und forwarding erzeugt. Beim Versenden kann ein Kommentar zB angegeben werden mit: sendfile -c "ein ganz niedlicher Hase!" rabbit.gif beate@juhu.lake.de - Um das Logfile, das ja UTF-7 codiert ist, korrekt lesen zu koennen, wurden die Programme utf7decode bzw utf7encode erstellt, mit denen man Textfiles von bzw nach UTF-7 wandeln kann. - Die Supportprogramme gzip, tar, pgp und recode koennen nun mit Pfad in config.h definiert werden. Durch Setzen der Environment-Variablen SF_TAR, SF_GZIP, SF_PGP und SF_RECODE koennen diese Werte wiederum geaendert werden. - Ist eine forward-Adresse (vom User oder vom Admin) gesetzt, dann folgt sendfile diesem Hinweis und sendet seine Files dorthin. Eine Verschachtelung von forwards ist nicht erlaubt. - Ein User kann sich in /var/spool/sendfile/$USER/config/config mit der Option "forward = user@host" eine forward Adresse fuer sich setzen. Der Admin kann Userforwarding global unterbinden, indem er in sendfile.cf die Option "forwarding = off" setzt. - Mit receive kann ein File aus dem Spool gleich weitergeschickt werden ("bouncing") mit: receive -b file_name other_user@other.host - sendmsg, sendfile und receive haben die Option -q bzw -Q hinzubekommen fuer einen "quiet" Modus: es werden keine Meldungen mehr ausgegeben oder Fragen gestellt. - receive faengt jetzt gefaehrliche Filenamen ab; dies sind Files, die mit "." beginnen oder relative oder absolute Pfade in tar-Files. - Bei nicht komprimierbaren Files (Erkennung ueber /etc/magic) erfolgt keine automatische Komprimierung mehr. - Ein besseres Transaktions Ausgabeformat wurde eingefuehrt. - Das Attribute "ATTR EXE" wurde fuer Unix und VMS eingefuehrt. Bei ausfuehrbaren Files (Programmen) wird das execute-Flag im Filesystem entsprechend gesetzt nach dem receive. - User der ksh oder bash koennen sich folgende Variablen setzen (am besten in ~/.profile), um von der Shell ueber neue Files im Spool informiert zu werden: $ export MAILPATH=/var/spool/mail/$LOGNAME:\ /var/spool/sendfile/$LOGNAME/log%'new file in spool!' $ export MAILCHECK=0 Dazu empfiehlt es sich in /var/spool/sendfile/$LOGNAME/config/config die Option: notification = none zu setzen. sendfile-2.1b/doc/AUTHORS0000644000175100001440000000163511025466672014666 0ustar framstagusersMain author: Ulli Horlacher Contributions: Martin Buck Heiko Schlichting Christian Recktenwald Rainer Bawidamann Beate Herrmann Christoph 'GNUish' Goern Thomas Tissen Olaf Erb Michael Neumayer (eumel@42.org) Madeleine Freudenberg Kilian Krause Martin Schulze Ulf Fischer Support code: Steven M. Bellovin Richard Salz Jim Berets Andreas Ley Harald Hanche-Olsen Ingo Wilken Jürgen Hägg sendfile-2.1b/doc/README.fetchfile0000644000175100001440000001231710251132201016377 0ustar framstagusers O-SAFT/fetchfile ================== With the server protocol extension O-SAFT (Offer Simple Asynchronous File Transfer) and the matching client fetchfile there is an easy method of retrieving files from a SAFT server. This is a direct analogy to the SMTP and POP or APOP protocol suite in the world of e-mail transfer. Overview: - How does O-SAFT/fetchfile work? - What to do on the client side? - What to do on the server side? - How about security issues? How does O-SAFT/fetchfile work? --------------------------------- O-SAFT is an extension to the existing SAFT protocol and allows athenticated clients to retrieve files from a (remote) server. The implemention is the server sendfiled and the client fetchfile. O-SAFT uses a dedicated pgp key pair to authenticate the fetchfile session. The private key will be kept on the client side, the public key must tbe present at the server side. For security reasons this will NOT be your regular e-mail pgp key pair, but a separate pair of pgp keys, uniquely assigned for fetchfile transfers. You will have to create a pair of pgp keys for this purpose befor using the fetchfile client for the first time (see below). Fetchfile can provide a directory listing of available files from the server, retrieve files or delete files. After retrieving a file, it will be placed in the regular spool directory, not in the current directory! You will have to use the receive command to transfer the files from the spool directory to your current directory afterwards. If there already exists a regular sendfile spool directory /var/spool/sendfile on the client side it will be used, otherwise a $HOME/.sfspool will be created. Fetchfile will be running without using root permissions on the client side. What to do on the client side? --------------------------------- You must have pgp installed and the binaries must be available through your $PATH environment variable. First, and ONLY ONCE before using fetchfile the very first time, you have to create a fetchfile pgp key pair: fetchfile -I Please only hit 'ENTER' when being asked for a pass phrase! This will create a special non-passphrase protected key pair for O-SAFT. After this initialization you will have a file /var/spool/sendfile/$USER/config/public.pgp resp. $HOME/.sfspool/public.pgp Please send this file to root@SAFT-server, who has to save this public key file into the appropiate user configuration directory. Example: sendfile -c "my O-SAFT puplic key" /var/spool/sendfile/$USER/config/public.pgp \ root@bofh.belwue.de (This prelimary action will enable you to use the SAFT server and will prevent othes from abusing your name or SAFT-account on the server.) After preparing the pgp keys an both sides, you can invoke fetchfile on a regular basis: fetchfile -l list files on the server fetchfile -a retrieve all files from server fetchfile -daf *aol.com delete all files from the AOL domain There is a detailed description of all capabilities in the man page, which can be read using 'man fetchfile'. For configuring the server SAFT account there are two options: fetchfile -Cw=config fetchfile -Cw=restrictions Using this the two local configuration files will be transfered from the local current directory to the SAFT server. The details of the configuration can be found with the 'man sendfile' command. With using fetchfile -Cr=config fetchfile -Cr=restrictions the files will be retrieved back and will be displayed to STDOUT. What to do on the server side? --------------------------------- pgp must be installed. The system adminsitrator needs to run sfdconf -e config and set the following lines: # allow O-SAFT extension (on/off) fetchfile = on The system administrator must create a user account (if it does not yet exist). This account does not need an interactive login shell and does not need a valid password; the login shell could be /bin/false. The only purpose is to enable the sendfiled to check out the user and to create a local spool directory (this method is well known for creating POP mail accounts). The client user will create the initial pgp key pair and the public key (public.pgp) will be sent to the system administrator of the server. This key has to be placed into the config directory for the particular user. Assuming the user name is bozo, the system administrator will have to type the following (under root permissions): receive -f bozo@* -b bozo public.pgp su bozo cd /var/spool/sendfile/bozo/config receive public.pgp (the first receive resends the file public.pgp from the sender bozo@* to the local user bozo) How about security issues? ------------------------------ O-SAFT uses a tcp challenge/response authentication with a pgp signature. This opens the possibility that the session can be attacked through tcp hijacking. We are well aware of this, but tcp hijacking is not easy and only possible if the attacker has direct access to the transport media (e.g. listening on the same ethernet cable/segment) and has access to a set of pretty nice cracker tools. With regular operating system supplied software it is not possible to attack a session. translated by andreas@citecs.de, Thu Dec 18 13:50:31 PST 1997 sendfile-2.1b/doc/LIESMICH.ups0000644000175100001440000000570210251132201015515 0ustar framstagusersFrom moep.bb.bawue.de!news Wed Apr 16 22:40:31 1997 Path: moep.bb.bawue.de!news From: framstag@moep.bb.bawue.de (Ulli Horlacher) Newsgroups: de.comm.chatsystems Subject: Re: SAFT im IRC Date: 9 Apr 1997 23:49:18 +0200 Organization: Maichinger Rechenzentrum Lines: 73 Message-ID: <5ih2su$26e@moep.bb.bawue.de> References: <5i58ac$djj@parsec.inka.de> <33490C8C.BC6@materna.de> <5iblfe$7vl@parsec.inka.de> <5ie3u7$1sr@blackbox.free.de> NNTP-Posting-Host: moep.bb.bawue.de Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-Newsreader: TIN [UNIX 1.3 unoff BETA 970321; i486 Linux 2.0.27] Xref: moep.bb.bawue.de de.comm.chatsystems:822 Mark Nowiasz wrote: > Dazu eine offtopic-Frage: wo besteht der Unterschied zwischen SAFT und ups? - ups benutzt einen illegalen tcp-Port, der laut RFC 1700 bereits anderweitig vergeben ist, SAFT hat von der IANA offiziell Port 487 reserviert bekommen. - ups kann nur regulaere Einzel-Files uebertragen, SAFT notfalls ganze Verzeichnisbaeume inklusive Devices - bei ups sind die Fileattribute nicht genau spezifiziert - ups kann nur ASCII Filenamen, SAFT kann Unicode - SAFT beherrscht die automatische Wandlung von allen im Internet verwendeten Zeichensätzen (Umlaute, etc) - SAFT beherrscht automatische Kompression - SAFT hat integrierte pgp Verschlüsslung und Signierung - SAFT kann nach Verbindungsabbruch am letzten uebertragenen Byte wiederaufsetzen - bereits verschickte Files koennen mit SAFT nachtraeglich storniert werden (Cancel) - Files können mit SAFT mit Kommentaren versehen werden - ups gibts es nur fuer BSD-UNIX, SAFT ist nicht an ein bestimmtes Betriebsystem gebunden - SAFT definiert zusaetzlich zum Filetransfer einen "Message Transfer", mit dem kurze Textzeilen direkt aufs Empfaengerterminal geschrieben werden koennen. - ups wird seit ca 5 Jahren nicht mehr supported, an SAFT/sendfile arbeiten etwa ein dutzend Leute - SAFT wird es bald als RFC geben sendfile, die Referenzimplementation von SAFT beherrscht weiterhin: - bouncing und forwarding sind moeglich - Gefährliche Filenamen (.rhosts) werden abgefangen - "Killfiles" für den Admin und den User - Der Admin kann eigene User vom SAFT-Service ausschließen - Begrenzung des sendfile-spools verhindert Überlaufen der Platte - Der Admin kann ein Expire auf Spool-Files setzen - NFS-Support (nur ein SAFT-Server pro NFS-Cluster) - Verfügbarkeit auf AIX, AmigaOS, BSDI, Convex-OS, Digital Unix, FreeBSD,HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris-2) und Ultrix (Implementationen für Windows NT, OS/2 und VMS sind in Vorbereitung) Reicht das vorerst? :-) Weitere Infos gibts unter http://www.belwue.de/saft -- \ Ulli Horlacher \ Sindelfinger Strasse 116 \ D-71069 Maichingen \ Germany \ \ framstag@moep.bb.bawue.de \ SAFT://bofh.belwue.de/framstag \ \ "Ich vertippe mich weit seltener als ich mich vermause" - Chris Blum \ sendfile-2.1b/doc/README.too0000644000175100001440000001152210251132201015244 0ustar framstagusers Sendfile / SAFT Sendfile is an asynchronous file transfer service for the Internet, like the sendfile facility in Bitnet: Any user A can send files to another user B without B being active in any way. The existing standard file transfer (ftp) is a synchronous service: The user must have access to an account on the sending and on the receiving site, too. A user based data exchange via anonymous ftp server is complicated and in respect to security out of question. Sending of files with e-mail is an asynchronous process but complicated too (binary data have to be specially encoded before sending and decoded after receiving). You can not transfer large files this way because many mail systems limit the maximum size of mails. With both procedures you also loose nearly all file attributes. Sendfile for UNIX, which is an implementation of the SAFT protocol (Simple Asynchronous File Transfer) now offers you a true asynchronous file transfer service for the Internet. Virtually any form of file can be sent, including encrypted ones. The SAFT protocol will be submitted as an RFC in the near future. Sendfile is a client/server application and contains: - sendfiled : the server (daemon) - sendfile : a client for sending files - sendmsg : a client for sending one-line messages - receive : a client for picking up already received files - documentation: README-files for a quick overview, Unix man pages and a 40 page description of the protocol and the programs. The sendfile client is a user program which sends files to the sendfiled server of the destination system. The sendfiled receives the files, saves them in the local spool area and informs the recipient who is now able to copy the files in his directory with the receive client. The original files in the spool will be deleted then. Examples for the sendfile client: $ sendfile doc.ps zrxh0370 $ sendfile -a Sources *.f90 Makefile uranus@bigvax.inka.de Sendfile automatically compresses the files before sending in order to save net bandwith. It is also possible to send several files or whole directories as one archive file (see second example above). With the integrated pgp support you can encrypt files and/or add a sigital signature. The sendmsg client is a user program which sends one-line text messages to the sendfiled which itself directly writes them onto the recipient's terminal. Example for the sendmsg client: $ sendmsg framstag@linux message: Pizza is ready! The addresses you specify with sendfile and sendmsg have to be real existing Internet accounts and must not be generic mail addresses (so called mx records). To pick up files from the spool one uses the receive client. Example: $ receive -l From zrxh0370@baracke.rus.uni-stuttgart.de (Ulli Horlacher) ----------------------------------------------------------- 1) 1995-Aug-10 15:41:24 3 KB README 2) 1995-Aug-10 15:41:37 30 KB doc.txt 3) 1995-Aug-10 15:42:09 113 KB Sources (archive) $ receive README %receive-I, README received So far, sendfile runs on AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris) and Ultrix. An implementation for Windows NT and OS/2 is in preparation. Sendfile needs the gcc compiler at compile time and gzip at run time. GNU recode is not needed now, but it will be when SAFT implementations appear on non-ISO coding systems, like MS-DOS. Sendfile needs the gcc compiler at compile time and gzip at run time. GNU recode is optional if once there will be a SAFT implementation on non-ISO coding systems like MS-DOS. If you have pgp on your system, you'll be glad to know that sendfile has built-in support for it. The sendfiled server has to be installed by root because it is a privileged Internet daemon. The clients may run as normal user programs. The installation is either be done with an automatic script (no questions, no answers) or manually with the help of a detailed description file. Sendfile does not cause any security problems because the clients run in user mode and the server is only called under control of the inetd. The sendfiled only writes in the user spool directory and only under the recipient's UID. The administrator may create a file containing the names of those users who are not allowed to use the sendfile/sendmsg service and he may limit the size of the spool (disk quota). The user himself may create a file containing a list of addresses from which he does not want any submissions. SAFT uses the tcp port 487, which has been reserved by the IANA (Internet Assigned Numbers Authority): ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers SAFT/sendfile has been written by Ulli Horlacher (framstag@rus.uni-stuttgart.de). URLs: ftp://ftp.uni-stuttgart.de/pub/unix/comm/sendfile/sendfile.tar.gz http://www.belwue.de/belwue/software/saft/index.html sendfile-2.1b/doc/vorteile0000644000175100001440000000464010251132201015343 0ustar framstagusers- Mit sendfile kann jede beliebige Datei beliebiger Groesse zuverlaessig, sicher und effizient von einem Benutzer A zu einem Benutzer B geschickt werden. - sendfile benutzt eine gzip bzw bzip2 komprimierte Übertragung. - sendfile kann automatisch den Dateityp (binary, source, text) erkennen und passt dann automatisch die EOL Marke und den Zeichensatz (zB Umlaute) an. - sendfile kann nach einem vorherigen Verbindungsabbruch an dem letzten versendeten Byte wieder aufsetzen. - sendfile kann ganze Verzeichnisbaeume versenden. - sendfile hat integrierte pgp Unterstuetzung fuer Signierung und Verschluesselung. - sendfile kann bereits versendete Dateien nachtraeglich loeschen (cancel). - sendfile kann echt asynchron senden, eine permanente Internetverbindung ist nicht notwendig. Ein besonderer sendfile spool daemon versucht dann alle xx Minuten die Dateien auszuliefern. - Mit der fetchfile/O-SAFT Erweiterung kann man Dateien von einem anderen Server abholen. Dies funktioniert aehnlich wie bei POP-mail, nur dass hier eine sichere pgp Authentfizierung stattfindet. - Man kann Dateien mit Kommentaren versehen. - Mit dem Zusatzprogramm sendmsg kann man einzeilige Textnachrichten direkt auf das Terminal des Empfaengers schreiben. - Dateien aus dem lokalen Spool kann man direkt weiterschicken (bounce). - Man kann eine "forward" Adresse setzen. Anders als bei mail wird hierbei die Datei erst gar nicht empfangen sondern direkt umgeleitet. - Das receive Programm warnt vor gefaehrlichen Dateinamen wie .rhosts. - Der sendfile daemon hat diverse Konfigurationsmoeglichkeiten um einen "denial of service attack" zu verhindern: max Anzahl an Dateien, min freier Partitionsplatz, "kill files", automatisches Loeschen zu alter Dateien, Protokollierung aller Transaktionen, Abweisung nicht-signierter Dateien, usw. - Der Administrator kann bestimmte lokale Benutzer vom SAFT Service ausschliessen oder das Gegenteil veranlassen: nur auserwaehlte Benutzer zulassen. - sendfile unterstuetzt NFS und AFS. - SAFT benutzt Unicode. - sendfile lauft bisher auf AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris-2) und Ultrix. Implementationen fuer Windows NT und OS/2 werden bald folgen. - SAFT benutzt den tcp Port 487, welcher bei der IANA (Internet Assigned Numbers Authority) dafuer registriert wurde. Ein SAFT-RFC ist in Vorbereitung. sendfile-2.1b/doc/utf7encode.10000644000175100001440000000257210251132201015716 0ustar framstagusers.\" utf7encode - Filter to encode UTF-7 .\" Copyright (c) 1998 Martin Schulze .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .TH UTF7ENCODE 1 "19 March 1998" "" "System Administration" .SH NAME utf7encode, utf7decode \- Filter to encode UTF-7 .SH SYNOPSIS .B utf7encode .RB [ " \-d" ] .I textfile .br .B utf7decode .I textfile .SH DESCRIPTION This program is used to encode or decode a textfile line by line with UTF-7. If the program is called as .B utf7decode the given file will be decoded. .SH OPTIONS These options are accepted. .TP .B "\-d" Don't encode but decode the file. .SH AUTHOR .B utf7encode has been written by Ulli Horlacher (framstag@belwue.de>. .SH "SEE ALSO" .BR sendfile (1). sendfile-2.1b/doc/LIESMICH0000644000175100001440000001251010251132201014702 0ustar framstagusersDies ist die Schnellinstallationshilfe fuer sendfile. Sendfile erlaubt es, Files asynchron zu verschicken, die dann im Empfaengersystem im sendfile-spool abgelegt werden. Im Gegensatz zu ftp muss man sich auf Empfaengerseite nicht einloggen. Es funktioniert also so aehnlich wie mail. Nur eben mit Files. Sendfile benutzt das SAFT-Protokoll: Simple Asynchronous File Transfer (Ist in RFC Vorbereitung). Eine etwas ausfuehrlichere Beschreibung zu sendfile befindet sich in LIESMICH.auch, eine 30-seitige Komplettbeschreibung von sendfile und SAFT ist in doku.ps. Das sendfile Paket umfasst 5 Hauptprogramme: sendfiled - der sendfile daemon, der vom inetd gestartet wird sendfile - der sendfile Client, die die Files verschickt sendmsg - der send-message Client, der einzeilige Text-messages verschickt receive - der receive Client, mit dem man empfangene Files abholen kann fetchfile - der O-SAFT Client, mit dem man Files von einem anderen SAFT-Server abholen kan, sendfile, sendmsg, receive und fetchfile laufen als normale User Programme, sendfiled muss von root installiert werden. 1) Pfade anpassen: Bei Bedarf koennen in "makeconfig" (und NUR da!) default-Werte fuer bestimmte Pfade geaendert werden. 2) erzeugen der Konfiguration und der Makefiles: $ make config 3) alles compilieren: $ make all Es duerfen keine Fehlermeldungen auftreten. Auf manchen Systemen mit fehlerhaften System-Include-Files kann es zu Warnings kommen, die aber ignoriert werden koennen. Sendfile wurde bisher getestet unter AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris 2) und Ultrix jeweils mit gcc 2.5.8. 4) alles automatisch installieren (muss root machen!): $ make install ODER von Hand installieren: - korrekte Fileprotection einstellen: $ umask 022 - sendfiled hinkopieren, wo es Sinn macht, zB /usr/local/sbin, /usr/etc : $ cp src/sendfiled /usr/local/sbin/ - Spool-Verzeichnisse anlegen (wie in config.h angegeben!): $ mkdir /var/spool/sendfile $ mkdir /var/spool/sendfile/LOG $ mkdir /var/spool/sendfile/OUTGOING $ chmod 700 /var/spool/sendfile/LOG $ chmod 1777 /var/spool/sendfile/OUTGOING Mit "df /var/spool/sendfile" ueberpruefen, ob genug Platz in der Spool Partition ist. Der minimale freie Platz wird mit der Option minfree in sendfile.cf definiert. - Eintragung in /etc/services (bzw mit "niload services ." bei NeXT): saft 487/tcp # simple asynchronous file transfer - Eintragung in /etc/inetd.conf: saft stream tcp nowait root /wo/auch/immer/sendfiled sendfiled oder wenn der tcpd installiert ist (default bei Linux): saft stream tcp nowait root /usr/sbin/tcpd /wo/auch/immer/sendfiled - Eintragung in /etc/inetd.sec (nur wenn dieses File vorhanden!!): saft allow - Eintragung ins System Bootfile (/etc/rc.local oder /etc/rc.d/rc.local) falls outgoing spooling benutzt werden soll: /usr/local/sbin/sendfiled -Q - inetd neu starten: $ kill $ /usr/sbin/inetd # (oder wo auch immer der inetd liegt) ( Ein "kill -HUP " funktioniert zumindest bei IRIX und OSF/1 nicht. ) - Userbeschraenkung aktivieren: $ cp etc/sendfile.deny /usr/local/etc/ - Konfigurationsfile installieren (Inhalt ist selbsterklaerend): $ cp etc/sendfile.cf /usr/local/etc/ - man-pages installieren: $ ( cd doc; cp sendmsg.1 sendfile.1 receive.1 fetchfile.1 /usr/local/man/man1 ) (eventuell makewhatis neu aufrufen) - notify-script installieren: $ cp etc/check_sendfile /usr/local/bin /usr/local/bin/check_sendfile in /etc/profile aufnehmen - Clients installieren: $ ( cd src; cp sendfile sendmsg receive fetchfile utf7encode /usr/local/bin ) $ ( cd etc; cp sfconf sfdconf /usr/local/bin ) $ ( cd /usr/local/bin/; ln -s utf7encode utf7decode ) 5) testen: $ sendfile LIESMICH `whoami` $ receive $ receive -n 1 6) Als Zusatzprogramm liegt xhoppel bei (Idee und Grafik von beate@juhu.lake.de). Dabei handelt es sich um ein Programm, das unter X anzeigt, wenn neue Files eingetroffen sind, aehnlich xbiff fuer mail. Dieses ist nicht auf allen Plattformen getestet und wird nicht automatisch installiert. Wer es haben will: $ cd xhoppel $ make $ cp xhoppel /usr/local/bin und in sein .xsession (oder .xinitrc, etc) schreiben: xhoppel & 7) Ich bin sehr an Kommentaren und Bugreports interessiert. Geschenke via Post schicken. :-) 8) Wer mir die Adresse seines neu installierten SAFT-Servers mitteilt, bekommt zur Belohnung ein schoenes gif zugeschickt. :-) 9) Es gibt eine Mailingliste, die ich von Hand fuehre und in der Ankuendigungen zu updates und bugfixes geposted werden. Wer da aufgenommen werden moechte, sende mail an mich. -- \ Ulli 'Framstag' Horlacher \ BelWue-Koordination \ framstag@belwue.de \ \ Universitaet Stuttgart \ Allmandring 30 \ D-70550 Stuttgart \ Germany \ \ SAFT://saft.belwue.de/framstag \ HTTP://www.belwue.de/saft/index.html \ \ "X.500: Security through Complexity" - Juergen G. \ sendfile-2.1b/doc/features0000644000175100001440000000437410251132201015334 0ustar framstagusers- sendfile can send any file at any size reliable, secure and effecient from any user A to any user B on the Internet. - sendfile uses a (gzip or bzip2) compressed link for transfers. - sendfile can automaticly guess the correct file type (binary, source, text) and will translate EOL markers and the character set, e.g. German Umlauts. - sendfile has an integrated resend facility: if a transfer has been interrupted by any reason, the next transfer will continue at the last sent byte. - sendfile can transfer whole directory trees. - sendfile has integrated pgp support for signing and encryption. - sendfile can delete previous sent files (as long as they are in the recipient's spool) - sendfile can truly send asynchronous, you don't need a permanent internet connection. A special sendfile spool daemon will retry every xx minutes to deliver the files. - With the fetchfile/O-SAFT extension you can retrieve files from a remote host. This is similar to POP-mail, but with secure pgp authentification. - You can annotate the files you send with a comment. - With the addon program sendmsg you can send short messages directly to the recipients terminal, this works like write(1), but net-wide. - You can bounce (forward) files directly from the spool. - You can set up a forward address. Unless like mail, this means that new files will not sent first to you, but directly to the forward address. - The receive program warns you for dangerous files, like .rhosts. - The sendfile daemon has various configuration possibilities to prevent a denial of service attack: max # of files, min free disk space, "kill files", expire dates, log all transactions, refuse all non-signed files etc. - The administrator can deny SAFT services for certain users or do the inverse: allow it only for special users. - sendfile has NFS and AFS support. - SAFT supports Unicode. - sendfile runs so far on AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris-2) and Ultrix. Implementations for Windows NT and OS/2 will be released in the next future. - SAFT uses the tcp port 487, which has been reserved by the IANA (Internet Assigned Numbers Authority). An SAFT-RFC is in preparation phase. sendfile-2.1b/doc/receive.10000644000175100001440000000440210441752151015304 0ustar framstagusers.\" Personal .TH RECEIVE 1 .UC L .SH NAME receive - receive files from the sendfile spool .SH SYNOPSIS .B receive [ .B \-d ] [ .B \-r ] [ .B \-k ] [ .B \-P ] [ .B \-S ] [ .B \-Z spool ] [ .B \-q ] [ .BI \-f from ] .BI file [...] .br .B receive \-n [ .B \-d ] [ .B \-r ] [ .B \-k ] [ .B \-P ] [ .B \-S ] [ .B \-Z spool ] [ .B \-q ] .I file\-number [...] .br .B receive [ .B \-s ] [ .B \-l ] [ .B \-L ] [ .B \-R ] [ .BI \-f from ] .br .B receive \-b .I user[@host] [ .BI \-k ] [ .BI \-f" from" ] file [...] .br .B receive \-b .I user[@host] [ .BI \-k ] [ .BI \-f" from" ] .BI -n .I file-number [...] .br .B receive \-b .I user[@host] [ .BI \-k ] .BI -a .SH DESCRIPTION .B receive files from the sendfile spool which has been sent to you. .PP If there is already a file with the same name you will be prompted for overwriting or renaming. .PP Allowed wildcards in file names are: * ? [abc] [^abc] .br CAUTION: you have to put wildcards and other special characters in \'\' quotes to hide them for interpretation by your shell. .SH OPTIONS .TP 8 .B -n receive file number(s) .TP .B -d delete instead of receive .TP .B -a receive (or delete or bounce) all files .TP .B -r rename before receiving .TP .B -k keep files in spool after receiving .TP .B -P pipe files to stdout .TP .B -S receive only pgp-signed files .TP .B -s list files in short format .TP .B -l list files .TP .B -L list files and look inside archives, too .TP .B -R renumber files in spool .TP .B -b bounce (forward) files to another recipient .TP .B -q quiet mode: no questions asked .TP .BI -f user all actions refer only to files from this user .TP .B -Z spool specify an alternate spool directory .SH EXAMPLES .I receive -L .br list all files in long format. .B receive 'blubb*' .br receive all files starting with string "blubb". .B receive -daf microsoft.com .br delete all files from microsoft.com sites. .B receive -b framstag@bofh '*.jpg' .br bounce all *.jpg-files to framstag@bofh. .SH FILES .TP 22 .I /var/spool/sendfile The sendfile spool directory. .TP .I /var/spool/sendfile/$USER/log A log of the last transfers. .TP .I /usr/local/etc/sendfile.deny Users which are not allowed to receive files or messages (set by root). .SH SEE ALSO .BR sendfile (1). .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de sendfile-2.1b/doc/fetchfile.70000644000175100001440000001251010251132201015603 0ustar framstagusers.\" Personal .TH FETCHFILE 7 .UC L .SH NAME O-SAFT / fetchfile .SH DESCRIPTION .SS Introduction With the server protocol extension O-SAFT (Offer Simple Asynchronous File Transfer) and the matching client fetchfile there is an easy method of retrieving files from a SAFT server. This is a direct analogy to the SMTP and POP or APOP protocol suite in the world of e-mail transfer. .PP Overview: .RS .sp \- How does O-SAFT/fetchfile work? .B \- What to do on the client side? .B \- What to do on the server side? .B \- How about security issues? .B .sp .RE .SS How does O-SAFT/fetchfile work? O-SAFT is an extension to the existing SAFT protocol and allows athenticated clients to retrieve files from a (remote) server. The implemention is the server sendfiled and the client fetchfile. .PP O-SAFT uses a dedicated pgp key pair to authenticate the fetchfile session. The private key will be kept on the client side, the public key must tbe present at the server side. For security reasons this will NOT be your regular e-mail pgp key pair, but a separate pair of pgp keys, uniquely assigned for fetchfile transfers. You will have to create a pair of pgp keys for this purpose befor using the fetchfile client for the first time (see below). .PP Fetchfile can provide a directory listing of available files from the server, retrieve files or delete files. After retrieving a file, it will be placed in the regular spool directory, not in the current directory! You will have to use the receive command to transfer the files from the spool directory to your current directory afterwards. .PP If there already exists a regular sendfile spool directory /var/spool/sendfile on the client side it will be used, otherwise a $HOME/.sfspool will be created. Fetchfile will be running without using root permissions on the client side. .SS What to do on the client side? You must have pgp-2.6.x installed and the binaries must be available through your $PATH environment variable. .PP First, and ONLY ONCE before using fetchfile the very first time, you have to create a fetchfile pgp key pair (only pgp-2.6.x is supported!): .PP .TP 4 .B fetchfile -I .PP Please only hit 'ENTER' when being asked for a pass phrase! This will create a special non-passphrase protected key pair for O-SAFT. .PP After this initialization you will have a file /var/spool/sendfile/$USER/config/public.pgp resp. $HOME/.sfspool/public.pgp .PP Please send this file to root@SAFT-server, who has to save this public key file into the appropiate user configuration directory. .PP Example: .PP .B sendfile -c 'my O-SAFT puplic key' .B /var/spool/sendfile/$USER/config/public.pgp root@bofh.belwue.de .PP (This prelimary action will enable you to use the SAFT server and will prevent othes from abusing your name or SAFT-account on the server.) .PP After preparing the pgp keys an both sides, you can invoke fetchfile on a regular basis: .TP 8 .TP .B fetchfile -l list files on the server .TP .B fetchfile -a retrieve all files from server .TP .B fetchfile -daf *aol.com delete all files from the AOL domain .PP There is a detailed description of all capabilities in the fetchfile(1) man page. For configuring the server SAFT account by the client user there are two options: .nf fetchfile -Cw=config fetchfile -Cw=restrictions .fi .PP Using this the two local configuration files will be transfered from the local current directory to the SAFT server. The details of the configuration can be found in the sendfile(1) man page. With using .nf fetchfile -Cr=config fetchfile -Cr=restrictions .fi .PP the files will be retrieved back and will be displayed to STDOUT. .SS What to do on the server side? pgp-2.6.x must be installed. The system adminsitrator needs to run .B sfdconf -e config add set the following option: .PP .TP 8 .TP fetchfile = on .PP The system administrator must create a user account (if it does not yet exist). This account does not need an interactive login shell and does not need a valid password; the login shell could be /bin/false. The only purpose is to enable the sendfiled to check out the user and to create a local spool directory (this method is well known for creating POP mail accounts). .PP The client user will create the initial pgp key pair and the public key (public.pgp) will be sent to the system administrator of the server. This key has to be placed into the config directory for the particular user. Assuming the user name is bozo, the system administrator will have to type the following (under root permissions): .PP .nf receive -f bozo@* -b bozo public.pgp su bozo cd /var/spool/sendfile/bozo/config receive public.pgp .fi .PP (the first receive resends the file public.pgp from the sender bozo@* to the local user bozo) .SS How about security issues? O-SAFT uses a tcp challenge/response authentication with a pgp signature. This opens the possibility that the session can be attacked through tcp hijacking. We are well aware of this, but tcp hijacking is not easy and only possible if the attacker has direct access to the transport media (e.g. listening on the same ethernet cable/segment) and has access to a set of pretty nice cracker tools. With regular operating system supplied software it is not possible to attack a session. .SH SEE ALSO .BR sendfile (1), .BR fetchfile (1), .BR sendfiled (8). .SH AUTHOR Ulli Horlacher - framstag@rus.uni-stuttgart.de .PP translated by andreas@citecs.de sendfile-2.1b/doc/ChangeLog0000644000175100001440000003702410765536673015402 0ustar framstagusers2008-03-11 sendmsg: reconnect and resend after server timeout 2007-01-05 receive: fixed verbose mode flag bug. 2006-11-27 sendmsg: correct exit code on error. 2006-09-20 Added moep to contrib directory. 2006-06-08 Fixed wrong description of bouncing in receive man-page. 2006-06-07 Added -L/usr/lib/termcap for readline-support on more systems. 2005-11-13 Fixed shell quoting bug (call to file). 2005-06-10 Better Darwin support. 2005-06-07 Fixed bug in receive: vanishing spool for root. 2005-06-06 Added preliminary patch for ipv6 for Linux. 2005-06-02 Added Mac-OSX (Darwin) support. 2001-06-01 New config.guess and config.sub (http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config) 2005-05-31 Added largefile support. 2005-05-30 Fixed some compile warnings (system includes and data types). Fixed timeout bug when preprocessing huge files. Added support for xinetd. Deactivated buggy check for symbolic links in archive files, needs to be fixed by replacing external tar program with tarlib! 2001-08-14 New config.guess and config.sub (ftp://ftp.gnu.org/pub/gnu/config/) 2001-02-06 Added timeout function in sendfiled. 2000-12-28 Release of sendfile-2.1a (security bugfixes) 2000-01-02 receive: Y2K bug in getdate.c (chatila@faxmate.com). 1999-08-18 PUSSY now with documentation and notification feature. 1999-08-03 gzip is default compression, back again (bzip2 is way too slow). 1999-02-19 receive-option -L with selecting arguments, e.g: receive -L sources 1999-02-15 Added check for dangerous symbolic links in archive files. 1998-12-15 Default compression methode is now gzip again (bzip2 is way too slow!). 1998-11-05 Do not compress files less than 1 KB. 1998-10-29 Fixed iso2utf space encoding bug (O-SAFT). Added utf7encode -S option. 1998-09-29 New program added: ewl (edit with locking) 1998-08-21 Added -m option to sendfile to limit the maximum thruput. 1998-07-21 More liberal utf7-encoding: allow middle single spaces. 1998-07-17 Added -q quiet option to sendmsg. 1998-07-13 Finally changed standard date format to ISO 8601. 1998-07-12 Added -r reply option to sendmsg (and reply msg support to sendfiled). 1998-07-11 The aliases file may now contain optional CLI arguments, eg: willy willy@host.de -pe -ps -S With "notification = program" in the user config file the program notify (in the user config directory) will be called for delivery notification. 1998-07-10 sendfile spool daemon pid is now in OUTGOING/.lock 1998-05-10 Added -R option to receive to renumber the spool files. 1998-04-06 Added -s message option for sendmsg. 1998-03-19 New man-pages for wlock and utf7encode. 1998-03-12 New user SAFT server pussy. 1998-03-11 New option userconfighome for sendfile.cf allows the user configuration directory to be in $HOME. All client-programs will now check $HOME/.sendfile Added -H option to receive to display the headers. 1998-03-08 Added "reinstall" option for make. 1998-03-06 Better detection of correct man page sections. 1998-03-01 New null-recipient :NULL: for link speed testing. 1998-02-27 Added "reinstall" option for install. More verbose transfer statistics. 1998-01-18 Added manpages fetchfile.7 and sendfiled.8 Release of final sendfile-2.1 1998-01-17 New address types: user@host:port and saft://host:port/user (:port is optional and :487 is default) The outgoing spool daemon will no longer terminate on empty spool. Added wlock to the distribution. 1998-01-13 Small corrections in usage-helps. 1998-01-05 Reactivated outgoing logging. Heavy bug in str_trim() fixed, which may caused several troubles so far. 1998-01-04 Added forward dection for outgoing spooling. Added -r option to sfdconf. Added usage-help for sendfiled. 1997-12-20 New regular expressions types: [a-z] [^abc] [^a-z] 1997-12-19 Added -W option for sendfile to find internal files and directories. Added pgp enforcing option to sendfiled. fetchfile now uses 1024 bit pgp keys. 1997-12-15 Added LAN speed detection for auto-compression on/off switching. 1997-12-14 Renamed getline() to getpromptline() to avoid name collision with glibc function. 1997-12-11 Fixed fetchfile pgp handling bug. Added bzip2 support. Release of sendfile-2.1 1997-12-07 Better locking checking in sendfiled. 1997-12-05 Fixed sendfile file type handling bug (crypted archives). 1997-11-27 Accept also saft.*/user pseudo URLs (idea by Eumel, thanx!). 1997-11-23 Moved nosendfile to sendfile.allow and senfile.deny. New sfdconf configuration helper program for sendfiled. 1997-11-22 Added better SAFT URL checking (saft2rfc822()). New sfconf configuration helper program. 1997-11-15 Too big junk files will be deleted, too (not only too small ones). 1997-10-04 Added -r receive option to fetchfile. 1997-09-30 Patches for glibc-2 from Joerg Plate Better (own) spool free-space check for install. 1997-09-29 BETA-release of sendfile-2.0. 1997-09-28 O-SAFT and fetchfile finished. Better sendfile man page. 1997-09-23 Fixed prompting bug when there is no readline. 1997-08-21 Better handling of reply code 202 (command not implemented). 1997-08-20 Changed syntax of sendfile option "-a archive-name" to "-a=archive-name". 1997-07-31 Added -S secure option (signature check) for receive. 1997-07-10 Fixed bugs in utf7 routines (corrupt strings). 1997-07-04 Auto dection of pgp ID for encryption: sendfile -pe file user@host 1997-06-30 Fixed bug in transfer statistics output. Better file type guessing. Added -C force compress option for sendfile. 1997-06-23 Own user log file for messages: msglog Added GNU readline support. 1997-06-19 Changed tty active/receiving bevaviour. xhoppel checks now default /var/spool/sendfile/$USER/log instead of /var/spool/mail/$USER (patch by Joerg de la Haye ). New option msglog=on|off for sendfile.cf logs messages to the user log file, too. 1997-06-16 Added file transfer test mode. 1997-06-15 Added file reading test mode. Fixed transfer speed bug (was way too slow!). Fixed transfer statistics output bug. 1997-06-10 More reliable retransmit operation for sendfiled on very slow links. 1997-06-04 Added SF_TMPDIR environment variable testing. 1997-05-15 Added -c usage help for sendfile. Fixed configure bug. 1997-05-05 Better IRIX support (blksize determination). 1997-05-01 Clean up of directory structure, better makeconfig. 1997-03-27 Added DEBUG command to sendfiled. Fixed minfree checking bug in sendfiled. 1997-03-24 Fixed buffering bug with -X option. 1997-03-20 Introduced Amiga support in makeconfig and install. 1997-03-19 Fixed TYPE=TEXT parsing bug in receive. 1997-03-18 Better URL parsing. 1997-02-24 Substituted all sprintf() with snprintf(). 1997-02-23 Better (consistent) extended string functions naming with str_*. Added MIME support (New SAFT attribute: TYPE=MIME). Release of sendfile-1.5.4. 1997-02-17 New global configuration with makeconfig. Release of sendfile-1.5.3. 1997-02-10 Fixed various (security) bugs (see sendfiled.c). 1997-02-02 More reliable fcopy-function for receive (NFS-trouble?). 1997-02-01 Set default quiet mode 1 on dump ttys for sendfile. 1997-01-31 More consistent transfer statistics with quiet modes. 1997-01-30 More reliable TYPE and SIZE command parsing. 1997-01-25 Added -X option (extended headers), better usage text and better pgp parsing for sendfile. 1997-01-22 Added spool file post processing. Added connect-test to generic SAFT address (saft.DO.MAIN). 1997-01-20 Revisited all files to use globals.h. -- GNUish 1997-01-20 Fixed bug with TEXT=charset attribute. 1997-01-19 Fixed resend bug. Added "resuming at ..." output. 1997-01-04 sendmsg will now follow forward information. 1996-12-29 New domain variable in sendfile.cf 1996-12-02 Better domainname determination in sendfiled. 1996-12-01 Better file name questioning in receive.c when checking files with dangerous file names. 1996-11-27 Corrected bug when receiving a (binary) file and the destination file is is not writable. 1996-11-26 Added sendmsg -n option for keeping the message receiving mode. 1996-11-19 Fix for broken AIX 4.1 include-files. 1996-11-13 Faster mesg/tty handling in sendmsg. 1996-10-24 Added xhoppel. 1996-10-23 Defined missing O_SYNC for BSD. 1996-10-11 Corrected redirection comment bug. 1996-09-24 Protocol-change: CHARSET charset --> TYPE TEXT=charset Better host.domain-name determination for the sendfiled welcome message. 1996-09-13 Fixed du bug for BSD systems. Better install script. 1996-09-04 Fixed some code for smoother compilation for IRIX. 1996-08-03 Corrected thruput value for sendfile (net.c). 1996-06-24 Fixed bug when FROM contains no real name. Added -P option to receive: can now receive to stdout. 1996-06-23 Nicer format for global and user log files. 1996-06-22 Better default date setting: when DATE is not specified by the client, sendfiled uses the current date just before writing the file to the spool. 1996-06-21 Added global log files for incoming and outgoing file transfers. 1996-06-20 user@ip-address now works again (replaced gethostbyaddr() with gethostbyname() in net.c). 1996-05-26 Fixed bug with overwriting links in receive. Fixed forking bug in receive. 1996-05-24 sendmsg no longer tries to configure the tty when there is none (sending via pipe: echo blubb | sendmsg user). 1996-05-23 Added check if tmp-files are writeable for sendfile and receive. Added -P option for sendfile (read from stdin, eg: ls -l | sendfile -P directory framstag@bofh.belwue.de). 1996-05-22 Added "-c configfile" option to sendfiled. 1996-05-21 Corrected bug when sending archive. Better Solaris-2 support. 1996-05-12 If there is a SPOOL/.nosendfile receiving of files will be disabled. 1996-05-10 Added global alias file. Allowed multiple forwards (with hopcount). 1996-05-09 sendfiled now tells its full name (on some systems). 1996-05-08 Corrected bug when bouncing. 1996-05-07 Replaced strneq() with strbeq() 1996-05-03 Fixed stupid programming bug in sendmsg, now it will work again :-) Better tar error checking in receive. Corrected (umask) bug when receiving binary files. 1996-04-30 Checking the elm alias file is now configurable (default: off). 1996-04-20 Added pgp IDEA encryption. Added preserve option to receive (for pgp and tar files). Added keep option to receive. More efficient scanspool algorithm. 1996-04-18 Some minor bug fixes in the pgp support code. 1996-04-14 Beta release of sendfile 1.5 1996-04-13 Added "-f from" und "-s" options to receive. 1996-04-12 Added pgp support. 1996-04-08 Changed signature command. Better dangerous file name checking. Added overwrite option for sendfile. Better checking whether a file has been already sent. Added question for renaming to receive. 1996-04-06 Changed transaction message format. 1996-04-04 Fixed memory leak in utf7.c Added check for dangerous file names in tar files. Allowed COMPRESSED=GZIP for TYPE command, too. Better HP-UX support. 1996-04-03 Replaced call to mail with sendmail. 1996-04-02 FROM is now in UTF-7 in the spool header files. Added forward address to COMMENT string when bouncing. 1996-04-01 Corrected some programming bugs. Added multiline mode to sendmsg. 1996-03-28 Extended search for support programs. 1995-03-27 Finally fixed security bug with links. Added quiet mode to receive. 1995-03-24 New uft7encode program. 1995-03-23 Added percentage output to sendfile. 1996-03-22 Code is now strictly ANSI (replaced some unsigned char with char). 1995-03-17 Replaced uname() with gethostname(). Some bug fixes in receive. Security bug (?) in sendfiled fixed: no chown on links. Set umask correctly in sendfile. 1996-03-16 Recognize file size 0 correctly. 1995-03-08 Fixed signal handling in sendfile.c 1995-03-06 Finally fixed bug when setting time stamps by using code from GNU fileutils (getdate.c). 1995-02-29 Some code beautifying. New version labeling. 1995-02-28 Several spelling corrections by Andreas Borchert. Bug fixes and code cleanup for peername. 1995-02-27 Added quiet options. 1996-02-23 Mail-notification now contains output of "receive -l", too. 1996-02-22 Replaced string "localhost" with the real name of the local host. Added bounce (=forwarding of files) feature to sendfile and receive. 1996-02-21 Better Solaris-2 support. Bug fix with maxfiles config option. Better notification check. 1996-02-20 Follow forward address for sending files (if given). Changed /config/msg to /config/tty@ and /config/msgfifo to /tmp/msg. for better NFS support. 1996-02-19 Fixed problems with NFS and MSG. Fixed (?) statfs-problem with Solaris-2 (wrong block size). Enhanced msg2tty with non-blocking write. 1996-02-07 Better Convex-OS support. Files which are already compressed won't be compressed by sendfile once more. 1996-02-06 Added ATTR EXE. Fixed bug in attribute handling. 1996-02-05 Added notification=both option. Faster str_trim function. 1996-01-31 Added maxspool and minfree config option. 1996-01-25 Added keep and deljunk option in sendfile.cf. New sf_cleanup program. 1996-01-24 New (received) DATEFORMAT. 1996-01-11 Added global and user config files for a lot new options. 1996-01-04 Added allow-only flag to NOSENDFILE. 1995-12-21 New default for nosendfile: /usr/local/etc/ Added Convex-OS support. Some C code formating changes. Simplified sock_getline and getreply. Improved message function. Better server connect testing. Changed SAFT multi-line reply format. 1995-12-18 Some improvements in the install script. 1995-12-13 Corrected bugs concerning alias files and NeXT support. 1995-12-12 Added Solaris-1 support. 1995-12-02 Added rename option to receive. 1995-11-27 Fixed tty handling in sendfiled, again. 1995-11-25 Better installation routine. Fixed man pages. Changed C-bracket source format once again. :-) 1995-11-21 Fixed tty handling in sendfiled. 1995-11-17 Fixed tty handling in sendmsg. 1995-11-15 Fixed memory leak in sendfiled. Added chat support. Added killfile (see man-page). Added sendfile alias file (see man-page). sendfile-2.1b/doc/LIESMICH.fetchfile0000644000175100001440000001155210251132201016637 0ustar framstagusers O-SAFT/fetchfile ================== Mit der Protokollerweiterung O-SAFT (Offer Simple Asynchronous File Transfer) und dem passenden Client fetchfile existiert nun eine Moeglichkeit Files von einem SAFT-Server abzuholen. Im Mailbereich gibt es einen analogen Mechanismus mit smtp und POP bzw APOP. Uebersicht: - Wie funktioniert O-SAFT/fetchfile? - Was ist auf Clientseite zu tun? - Was ist auf Serverseite zu tun? - Wie stehts mit der Security? Wie funktioniert O-SAFT/fetchfile? ----------------------------------- O-SAFT ist eine Erweiterung des SAFT Protokolls und erlaubt es authentifizierten Clients Files von einem (remote) Server abzuholen. Die Implementierung dazu ist sendfiled (Server) und fetchfile (Client). O-SAFT benutzt ein spezielles pgp Schluesselpaar zur Authentifizierung der fetchfile-Session. Dazu braucht der Client den Secret Key und der Server den Public Key. Dabei handelt es sich aus Sicherheitsgruenden NICHT um den normalen E-mail pgp key, sondern um einen extra Schluessel, exklusiv fuer fetchfile. Dieser muss einmal am Anfang erzeugt werden (siehe weiter unten). fetchfile kann vom Server Files anzeigen lassen, abholen oder nur loeschen. Nach dem Abholen durch fetchfile befinden sich die Files im lokalen Spool, nicht jedoch bereits im aktuellen Directory! Nach dem fetchfile Aufruf muss deshalb ganz normal receive gestartet werden, um die Files regulaer zu empfangen. Ist auf Client-Seite bereits ein lokales Spool /var/spool/sendfile vorhanden, so wird dieses benutzt, andernfalls $HOME/.sfspool angelegt. Dementsprechend laeuft fetchfile auf Clientseite voellig ohne root-Rechte ab. Was ist auf Clientseite zu tun? --------------------------------- pgp muss installiert und in $PATH enthalten sein. Zuallererst ist EINMAL das fetchfile pgp Schluesselpaar zu erzeugen mit: fetchfile -I Bitte unbedingt darauf achten, dass bei der Frage nach der Pass Phrase nur ENTER eingegeben wird! (Damit wird ein exklusives, nicht-Passphrase geschuetztes pgp-Schluesselpaar fuer O-SAFT erzeugt.) Nach erfolgreicher Initialisierung ist das File /var/spool/sendfile/$USER/config/public.pgp bzw $HOME/.sfspool/public.pgp vorhanden. Dieses ist an root@SAFT-Server zu schicken, damit dieser es in dem entsprechenden User Config-Directory ablegt. Beispiel: sendfile -c "mein O-SAFT puplic key" /var/spool/sendfile/$USER/config/public.pgp \ root@bofh.belwue.de (Dieser Schritt ist noetig, um den Empfaenger zu authentisieren und um vor Missbrauch zu schuetzen.) Danach kann fetchfile ganz normal benutzt werden, zB: fetchfile -l listet die Files auf dem Server fetchfile -a holt alle Files ab fetchfile -daf *aol.com loescht alle Files, die von aol gekommen sind Die weiteren Optionen koennen mittels "man fetchfile" nachgelesen werden. Mit zwei speziellen Optionen kann der Server-SAFT-Account konfiguriert werden: fetchfile -Cw=config fetchfile -Cw=restrictions Damit werden die betreffende Configfiles aus dem aktuellen Directory an den Server transferiert. Dessen Inhalt und Beudeutung koennen mit "man sendfile" nachgelesen werden. Mittels fetchfile -Cr=config fetchfile -Cr=restrictions koennen diese Files auch wieder ausgelesen werden (nach stdout). Was ist auf Serverseite zu tun? --------------------------------- pgp muss installiert sein. In /usr/local/etc/sendfile.cf muessen die folgenden Zeilen rein: # allow O-SAFT extension (on/off) fetchfile = on # where is the pgp programm? (for fetchfile) pgp = /usr/local/bin/pgp Der Administrator muss dann einen Account fuer den betreffenden User generieren (falls nicht schon vorhanden). Dieser Account muss nicht unbedingt interaktiv zugaenglich sein, dh, er braucht kein gueltiges Passwort zu haben und die login-Shell darf /bin/false sein. Sinn und Zweck ist es, dem sendfiled die Moeglichkeit zu geben den User zu ueberpruefen und ein Spooldirectory fuer ihn anzulegen (bei POP funktioniert das ebenso). Vom Client-User bekommt der Admin dann den fetchfile public key (public.pgp). Diesen muss er in das Config Directory des Users ablegen. Angenommen dieser User heisst gaga, dann tippt der Admin als root: receive -f gaga@* -b gaga public.pgp su gaga cd /var/spool/sendfile/gaga/config receive public.pgp (Das erste receive macht folgendes: es schickt das File public.pgp vom Absender gaga@* weiter an den lokalen User gaga) Wie stehts mit der Security? ------------------------------ O-SAFT benutzt eine tcp challenge/response Authentifizierung mittels pgp-Signatur. Dies bedeutet, dass die Session u.U. durch tcp hijacking uebernommen werden kann. Dieses ist aber relativ aufwendig und nur moeglich, wenn der Angreifer direkten Zugang zum Transportmedium hat, zB am selben Ethernetstrang sitzt und ueber hochwertige Hackertools verfuegt. Mit normalen Betriebssystemkomponenten ist so ein Angriff nicht moeglich. sendfile-2.1b/doc/Makefile.in0000644000175100001440000001133710251132201015635 0ustar framstagusers# Makefile.in generated automatically by automake 1.1l from Makefile.am # Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ target_alias = @target_alias@ build_alias = @build_alias@ host_triplet = @host@ target_triplet = @target@ build_triplet = @build@ host_alias = @host_alias@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE = @PACKAGE@ SYSTEM = @SYSTEM@ CC = @CC@ VERSION = @VERSION@ REVISION = @REVISION@ AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 man_MANS = sendfile.1 sendmsg.1 receive.1 EXTRA_DIST = LIESMICH LIESMICH.auch LIESMICH.neu LIESMICH.goern doc.txt \ doku.ps doku.txt mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = .././src/config.h CONFIG_CLEAN_FILES = MANS = sendfile.1 sendmsg.1 receive.1 NROFF = nroff DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ $(TEXINFOS) $(MANS) $(EXTRA_DIST) TAR = tar default: all .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL) cd $(top_srcdir) && automake --gnits doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status install-man: $(MANS) $(NORMAL_INSTALL) $(mkinstalldirs) $(mandir)/man1 sect=1; \ inst=`echo "sendfile" | sed '$(transform)'`.1; \ if test -f $(srcdir)/sendfile.1; then file=$(srcdir)/sendfile.1; \ else file=sendfile.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst sect=1; \ inst=`echo "sendmsg" | sed '$(transform)'`.1; \ if test -f $(srcdir)/sendmsg.1; then file=$(srcdir)/sendmsg.1; \ else file=sendmsg.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst sect=1; \ inst=`echo "receive" | sed '$(transform)'`.1; \ if test -f $(srcdir)/receive.1; then file=$(srcdir)/receive.1; \ else file=receive.1; fi; \ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst uninstall-man: inst=`echo "sendfile" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst inst=`echo "sendmsg" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst inst=`echo "receive" | sed '$(transform)'`.1; \ rm -f $(mandir)/man1/$$inst tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = doc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done info: dvi: check: all $(MAKE) installcheck: install-exec: $(NORMAL_INSTALL) install-data: install-man $(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-man all: $(MANS) Makefile install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install installdirs: $(mkinstalldirs) $(mandir)/man1 mostlyclean-generic: test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: rm -f Makefile $(DISTCLEANFILES) rm -f config.cache config.log stamp-h test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-generic clean: clean-generic mostlyclean distclean: distclean-generic clean rm -f config.status maintainer-clean: maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default install-man uninstall-man tags distdir info dvi \ installcheck install-exec install-data install uninstall all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sendfile-2.1b/doc/wlock.10000644000175100001440000000422610251132201014770 0ustar framstagusers.\" wlock - Tests or sets a file with POSIX-fcntl() write-locks .\" Copyright (c) 1998 Martin Schulze .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .TH WLOCK 1 "19 March 1998" "" "System Administration" .SH NAME wlock \- Tests or sets a file with POSIX-fcntl() write-locks .SH SYNOPSIS .B wlock .RB [ " \-s " [ "\-a \fIseconds\fR " ]] .RB [ " \-t" ] .RB [ " \-v" ] .RB [ " \-b \fIbegin\fR " ] .RB [ " \-l \fIlength\fR " ] .I file .br or .br .B wlock .RB [ " \-s " ] .RB [ " \-v" ] .RB [ " \-b \fIbegin\fR " ] .RB [ " \-l \fIlength\fR " ] .IR "file program " "[ " arguments " ]" .SH DESCRIPTION .B This program sets or tests advisory locks conforming to POSIX fcntl() call. You may specify optionaly a program to start it within the lock context. .SH OPTIONS These options are accepted. If a program is provided as argument .B wlock will start it. .TP .B "\-s" Sets the lock. .TP .B "\-t" Test the lock (default). .TP .B "\-v" Verbose output. .TP .BI "\-b " begin The lock starts at byte .RI # begin . .TP .BI "\-l " length The lock will be .I length bytes long. .TP .BI "\-a " seconds The lock is active for .I seconds (default=86400). .PP .SH "RETURN VALUES" .TP .B 0 In test mode this means that the file is locked. In set mode it indicates the succesful creation of the lockfile .TP .B 1 The file is not locked. Only available in testmode. .TP .B 2 Some error has occurred. .SH AUTHOR .B wlock has been written by Ulli Horlacher (framstag@belwue.de>. .SH "SEE ALSO" .BR sendfile (1). sendfile-2.1b/doc/LIESMICH.auch0000644000175100001440000001127410251132201015627 0ustar framstagusers Sendfile / SAFT Sendfile stellt einen asynchronen Filetransfer-Service fuer das Internet dar, wie es ihn beispielsweise im Bitnet gibt: Ein Benutzer A kann einem beliebigen Benutzer B Dateien zuschicken, ohne dass B dabei aktiv werden muss. Der bereits vorhandene Standard-Filetransfer, das ftp, ist ein synchroner Dienst: Der Benutzer muss sowohl auf Sender- als auch auf Empfaengerseite ueber einen Account verfuegen. Ein benutzerbezogener Datenaustausch ueber anonymous ftp-Server ist umstaendlich und sicherheitstechnisch indiskutabel. Das Versenden von Files via Mail erfolgt zwar asynchron, ist aber ebenfalls umstaendlich (Binaerdateien muessen vor dem Versenden speziell codiert und nach dem Empfangen entsprechend decodiert werden) und fuer die Uebertragung groesserer Datenmengen ungeeignet. Bei beiden Verfahren gehen ueberdies fast alle Fileattribute verloren. Sendfile fuer Unix, eine Implementation des SAFT-Protokolls (Simple Asynchronous File Transfer), bietet jetzt auch im Internet einen vollwertigen asynchroner Filetransfer-Service. Das SAFT-Protokoll wird in naechster Zukunft als RFC eingereicht. Sendfile ist eine Client/Server Applikation und umfasst die Teile: - sendfiled : der Server (Daemon) - sendfile : ein Client zum Verschicken von Dateien - sendmsg : ein Client zum Verschicken von einzeiligen Nachrichten - receive : ein Client zum Abholen von empfangenen Dateien - Dokumentation : LIESMICH-Files fuer schnelle Uebersicht, Unix-man-pages und eine ausfuehrliche Protokoll- und Programmbeschreibung. Der sendfile-Client ist ein Userprogramm, das Dateien an den sendfiled- Server des Empfaengersystems verschickt. Der sendfiled nimmt die Dateien entgegen, legt sie im lokalen Spoolbereich ab und informiert den Empfaenger. Der Empfaenger kann sich dann die Dateien mittels des receive-Clients in sein Directory kopieren, wobei das Original aus dem Spool geloescht wird. Beispiele fuer den sendfile-Client: $ sendfile doku.ps zrxh0370 $ sendfile -a Sourcen *.f90 Makefile uranus@bigvax.inka.de Sendfile komprimiert automatisch vor dem Versenden und spart so Netzbandbreite. Ausserdem ist es moeglich, Directories oder mehrere Files als ein Archivfile zu verschicken (siehe zweites Beispiel oben). Eine Verschluesselung und/oder Signierung (digital signature) der Files ist durch integrierten pgp-Support moeglich. Der sendmsg-Client ist ein Userprogramm, das einzeilige Textnachrichten an den sendfiled verschickt, welcher sie dann direkt auf das Terminal des Empfaengers schreibt. Beispiele fuer den sendmsg-Client: $ sendmsg framstag@linux message: Pizza ist fertig! Essen kommen! Die Adressen bei sendfile und sendmsg muessen real existierende Internet- Accounts darstellen und duerfen keine generischen Mail-Adressen (sogenannte mx-Records) sein. Zum Abholen aus dem Spool benutzt man den receive-Client. Beispiel: $ receive -l From zrxh0370@baracke.rus.uni-stuttgart.de (Ulli Horlacher) ----------------------------------------------------------- 1) 1995-Aug-10 15:41:24 3 KB LIESMICH 2) 1995-Aug-10 15:41:37 30 KB doku.txt 3) 1995-Aug-10 15:42:09 113 KB Sourcen (archive) $ receive LIESMICH %receive-I, LIESMICH received Sendfile laeuft bisher auf AIX, BSDI, Convex-OS, Digital Unix, FreeBSD, HP-UX, IRIX, Linux, NeXTstep/Mach, OSF/1, SunOS 4, SunOS 5 (Solaris) und Ultrix. Portierungen fuer Windows NT und OS/2 sind in Vorbereitung. Sendfile benoetigt den gcc-Compiler zum Uebersetzen und gzip zur Laufzeit, sowie optional GNU recode und pgp. Der sendfiled Server muss von root installiert werden, weil er ein privilegierter Internetdaemon ist, die Clients koennen als normale qUserprogramme betrieben werden. Die Installation kann entweder ueber ein automatisches Skript (no questions, no answers) oder manuell anhand einer ausfuehrlichen Anleitung erfolgen. Sicherheitstechnisch ist sendfile unbedenklich, da die Clients als normale Userprogramme laufen und der Server nur vom inetd kontrolliert aufgerufen wird. Der sendfiled schreibt ausschliesslich in das Userspool-Directory und dies auch nur mit der UID des Empfaengers. Der Administrator kann eine Datei anlegen mit lokalen Usern, die vom sendfile-Service ausgeschlossen sind und auch die Groesse des Spool beschraenken. Der User selbst kann eine Datei anlegen von Absendern, von denen er nichts empfangen moechte. Die Kommunikation erfolgt ueber den tcp-Port 487. Dieser ist von der IANA (Internet Assigned Numbers Authority) fuer SAFT reserviert worden: ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers Autor ist Ulli Horlacher (framstag@rus.uni-stuttgart.de). URLs: ftp://ftp.uni-stuttgart.de/pub/unix/comm/sendfile/sendfile.tar.gz http://www.belwue.de/saft/index.html sendfile-2.1b/src/0000755000175100001440000000000011025466700013623 5ustar framstaguserssendfile-2.1b/src/reply.c0000640000175100001440000002726210251136250015121 0ustar framstagusers/* * File: reply.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 10 Sep 95 Framstag initial version * 21 Dec 95 Framstag changed multi-line format * 17 Mar 95 Framstag replaced uname() with gethostname() * 8 Apr 96 Framstag changed signature command * 10 May 96 Framstag uname() is used back again * 13 May 96 Framstag uname() and gethostname() * 24 Sep 96 Framstag better host.domain-name determination * 2 Dec 96 Framstag even better domain-name determination * 29 Dec 96 Framstag included get_domainname * 21 Jan 97 Framstag added reply 414 * 23 Feb 97 Framstag extended with TYPE=MIME * 24 Feb 97 Framstag sprintf() -> snprintf() * 7 Dec 97 Framstag added reply 532 * 19 Dec 97 Framstag added reply 540 and 541 * 12 Mar 98 Framstag reply 523 -> 430 (same text) * 2001-02-06 Framstag added reply 429 * * Send the appropiate reply code and reply text conforming to NVT telnet * standard. Inspired by RFC-959 (ftp). * * Copyright © 1995-2001 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #include #include #include #include "io.h" /* socket and file IO extensions */ #ifdef ULTRIX struct utsname { char sysname[32]; char nodename[32]; char release[32]; char version[32]; char machine[32]; }; int uname (struct utsname *); #else #include #endif #if defined(SOLARIS2) int gethostname(char *, int); #endif #if defined(LINUX) int gethostname(char *, size_t); #endif #include "string.h" /* extended string functions */ /* * get_domainname - add domainname to host-string * * INPUT: host - hostname * * OUTPUT: host - hostname.domainname or hostname (if no domain was found) * * This is an ugly hack: we determin the domain by looking at /etc/resolf.conf * if not set in sendfile.cf */ void get_domainname(char *host) { char line[MAXLEN]; char *cp; extern char domain[FLEN]; FILE *inf; /* global variable domain set (in sendfiled.c)? */ if (*domain) { if ((cp=strchr(host,'.'))) *(++cp)=0; } else { /* if host-name contains already a '.', we are ready */ if (strchr(host,'.')) return; /* look in resolver config-file */ inf=rfopen("/etc/resolv.conf","r"); if (!inf) return; while (fgetl(line,inf)) { str_trim(line); /* is there the domain or search option set? */ if (str_beq(line,"domain") || str_beq(line,"search")) { /* isolate the domain name */ if ((cp=strchr(line,' '))) { strcpy(domain,++cp); if ((cp=strchr(domain,' '))) *cp=0; break; } } } fclose(inf); } strcat(host,"."); strcat(host,domain); } /* * reply - send string conforming to NVT telnet standard * * INPUT: rc - reply code * * terminates program on fatal error */ void reply(int rc) { char *text, /* reply code and reply text */ host[FLEN+1]; /* hostname */ #ifndef NEXT struct utsname sysname; #endif switch (rc) { case 200: text="200 Command ok."; break; case 201: text="201 File has been received correctly."; break; case 202: text="202 Command not implemented, superfluous at this site."; break; case 203: text="203 *schnuffel* *schnuffel* =:3"; break; case 205: text="205 Non-ASCII character in command line ignored."; break; case 214: text="214-The following commands are recognized:\r\n" "214- FROM []\r\n" "214- TO \r\n" "214- FILE \r\n" "214- SIZE \r\n" "214- TYPE BINARY|SOURCE|MIME|TEXT= [COMPRESSED|CRYPTED]\r\n" "214- DATE \r\n" "214- SIGN \r\n" "214- ATTR TAR|EXE|NONE\r\n" "214- MSG \r\n" "214- DEL\r\n" "214- RESEND\r\n" "214- DATA\r\n" "214- QUIT\r\n" "214-All arguments have to be UTF-7 encoded.\r\n" "214 You must specify at least FROM, TO, FILE, SIZE and " "DATA to send a file."; break; case 215: text="215 sendfiled "VERSION"-"REVISION" for "SYSTEM; break; case 220: text=(char *) malloc(MAXLEN); if (gethostname(host,FLEN)<0) strcpy(host,"UNKNOWN"); else get_domainname(host); #ifdef NEXT snprintf(text,MAXLEN-1, "220 %s "PROTOCOL" server (sendfiled "VERSION " on NeXTstep/Mach) ready.",host); #else if (uname(&sysname)<0) snprintf(text,MAXLEN-1,"220 %s "PROTOCOL" server (sendfiled " VERSION") ready.",host); else snprintf(text,MAXLEN-1,"220 %s "PROTOCOL" server (sendfiled " VERSION" on %s) ready.",host,sysname.sysname); #endif break; case 221: text="221 Goodbye."; break; case 230: text="230 "; break; case 231: text="231 "; break; case 250: text="250 End of transfer."; break; case 260: text="260 DEBUG-OUTPUT"; break; case 302: text="302 Header ok, send data."; break; case 331: text="331 "; break; case 401: text="401 Got unexpected EOF."; break; case 410: text="410 No access to spool directory (permission problems?)."; break; case 411: text="411 Can't create user spool directory."; break; case 412: text="412 Can't write to user spool directory."; break; case 413: text="413 User spool file quota exceeded."; break; case 414: text="414 Can't start spool postprocessing."; break; case 415: text="415 TCP error: received too few data."; break; case 421: text="421 Service currently not available."; break; case 429: text="429 Timeout."; break; case 430: text="430 You are not allowed to send to this user."; break; case 451: text="451 Requested action aborted: server error."; break; case 452: text="452 Insufficient storage space."; break; case 453: text="453 Insufficient system resources."; break; case 460: text="460 Authentication error."; break; case 490: text="490 Internal error."; break; case 500: text="500 Syntax error, command unrecognized."; break; case 501: text="501 Syntax error in parameters or arguments."; break; case 502: text="502 Command not implemented."; break; case 503: text="503 Bad sequence of commands."; break; case 504: text="504 Command not implemented for that parameter."; break; case 505: text="505 Missing argument."; break; case 506: text="506 Command line too long."; break; case 507: text="507 Bad argument."; break; case 510: text="510 User has set a forward to xxx@yyy"; text="510-This SAFT-server can only receive messages.\r\n" "510 Send files to xxx@yyy"; break; case 511: text="511 This SAFT-server can only receive files.\r\n"; break; case 512: text="512 This SAFT-server can only receive messages.\r\n"; break; case 520: text="520 User unknown."; break; case 521: text="521 User is not allowed to receive files or messages."; break; case 522: text="522 User cannot receive messages."; break; case 530: text="530 Authorization failed."; break; case 531: text="531 This file has been already received."; break; case 532: text="532 This file is currently transfered by you " "within another process."; break; case 540: text="540 Secure mode enforced: you have to sign your files"; break; case 541: text="541 Secure mode enforced: you have to encrypt your files"; break; case 550: text="550 File not found."; break; default: text="599 Unknown error."; } /* send string conforming to NVT standard */ printf("%s\r\n",text); fflush(stdout); /* if a fatal and non recoverable error occured terminate the program */ if (text[0]=='4') exit(1); } /* * from RFC-959 (ftp): * * 110 Restart marker reply. * In this case, the text is exact and not left to the * particular implementation, it must read: * MARK yyyy=mmmm * Where yyyy is User-process data stream marker, and mmmm * server's equivalent marker (note the spaces between markers * and "="). * 120 Service ready in nnn minutes. * 125 Data connection already open, transfer starting. * 150 File status okay, about to open data connection. * * 200 Command okay. * 202 Command not implemented, superfluous at this site. * 211 System status, or system help reply. * 212 Directory status. * 213 File status. * 214 Help message. * On how to use the server or the meaning of a particular * non-standard command. This reply is useful only to the * human user. * 215 NAME system type. * Where NAME is an official system name from the list in the * Assigned Numbers document. * 220 Service ready for new user. * 221 Service closing control connection. * Logged out if appropriate. * 225 Data connection open, no transfer in progress. * 226 Closing data connection. * Requested file action successful (for example, file * transfer or file abort). * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). * 230 User logged in, proceed. * 250 Requested file action okay, completed. * 257 "PATHNAME" created. * * 331 User name okay, need password. * 332 Need account for login. * 350 Requested file action pending further information. * * 421 Service not available, closing control connection. * This may be a reply to any command if the service knows it * must shut down. * 425 Can't open data connection. * 426 Connection closed, transfer aborted. * 450 Requested file action not taken. * File unavailable (e.g., file busy). * 451 Requested action aborted: local error in processing. * 452 Requested action not taken. * Insufficient storage space in system. * 500 Syntax error, command unrecognized. * This may include errors such as command line too long. * 501 Syntax error in parameters or arguments. * 502 Command not implemented. * 503 Bad sequence of commands. * 504 Command not implemented for that parameter. * 530 Not logged in. * 532 Need account for storing files. * 550 Requested action not taken. * File unavailable (e.g., file not found, no access). * 551 Requested action aborted: page type unknown. * 552 Requested file action aborted. * Exceeded storage allocation (for current directory or dataset). * 553 Requested action not taken. * File name not allowed. */ sendfile-2.1b/src/acconfig.h0000640000175100001440000000035110251136250015532 0ustar framstagusers/* local stuff for config.h.in */ /* generated by GNUish, Wed Feb 19 11:45 */ /* The package-name, version and revision */ #undef PACKAGE #undef VERSION #undef REVISION /* The system-name */ #undef SYSTEM /* end of acconfig.h */ sendfile-2.1b/src/bsd.h0000640000175100001440000000166610251136250014543 0ustar framstagusers/* * File: bsd.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: 11 Aug 95 Framstag initial version * 19 Nov 96 Framstag fix for broken AIX include-files * * missing prototype definitions in the AIX and Ultrix system include files * * Copyright © 1995,1996 Ulli Horlacher * This file is covered by the GNU General Public License */ #ifndef _BSD #define _BSD 43 #endif int socket(int, int, int); int connect(int, const struct sockaddr *, int); int shutdown(int, int); int getpeername(int, struct sockaddr *, int *); int getsockname(int, struct sockaddr *, int *); /* int getopt(int, char **, const char *); */ int chown(const char *, uid_t, gid_t); int chdir(const char *); time_t time(time_t *); #if !defined(HAVE_GETTIMEOFDAY) #if defined(ULTRIX) int gettimeofday(struct timeval *, struct timezone *); #endif #if defined(AIX) int gettimeofday(struct timeval *, void *); #endif #endif sendfile-2.1b/src/utf7encode.c0000640000175100001440000000466410765534352016051 0ustar framstagusers/* * File: utf7encode.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Christoph 'GNUish' Goern (goern@janus.beuel.rhein.de) * * History: * * 1995-03-24 Framstag initial version * 1997-01-20 GNUish modified to move to the gnu-style * 1997-02-23 Framstag modified str_* function names * 1998-10-29 Framstag new option -S * * Filter to encode or decode UTF-7. * * Copyright © 1995-1998 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" #include #include #include #include "message.h" /* information, warning and error messages */ #include "io.h" /* misc IO routines */ #include "utf7.h" /* UTF-7 coding */ #include "string.h" /* extended string functions */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #if defined(SOLARIS2) FILE *fdopen(int, const char *); #endif int usage(); int xonf=1, /* exit on fatalerror flag */ verbose=0; /* flag for verbose mode */ char *prg; /* program name */ int main(int argc, char *argv[]) { extern int optind; int withspace, opt; char *cp, line[MAXLEN], tmp[MAXLEN], utf_line[LEN_UTF], iso_line[LEN_ISO]; int decode; FILE *inf; withspace=1; decode=0; prg=argv[0]; if (str_eq(prg,"utf7decode")) decode=1; while ((opt=getopt(argc,argv,"Sh?d")) > 0) { switch (opt) { case ':': case 'h': case '?': exit(usage()); case 'S': withspace=0; break; case 'd': decode=1; break; } } if (argc-optind==0) inf=fdopen(0,"r"); else { inf=rfopen(argv[optind],"r"); if (inf==NULL) { sprintf(tmp,"cannot open %s",argv[optind]); message(prg,'F',tmp); } } while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; if (decode) { utf2iso(0,iso_line,tmp,tmp,line); printf("%s\n",iso_line); } else { iso2utf7(utf_line,line,withspace); printf("%s\n",utf_line); } } exit(0); } /* void function for message() */ void cleanup() { } /* * usage - print short help usage text */ int usage() { fprintf(stderr,"usage: %s [-S] [-d] [text-file]\n",prg); fprintf(stderr,"option: -S encode single spaces, too\n"); fprintf(stderr," -d decode\n"); return(2); } sendfile-2.1b/src/getline.h0000640000175100001440000000004210251136250015405 0ustar framstaguserschar *getpromptline(char *, int); sendfile-2.1b/src/peername.c0000640000175100001440000001234710251136250015560 0ustar framstagusers/* ** peername v1.1 ** ** Prints out the peername for stdin ** ** Copyright (c) 27.7.94 by Andreas Ley ** ** Permission to use, copy, modify, and distribute this software for any ** purpose and without fee is hereby granted, provided that the above ** copyright notice appears in all copies. This software is provided "as is" ** and without any express or implied warranties. ** ** This program has been tested on a HP9000/720 with HP-UX A.08.07 ** In this environment, neither lint -u nor gcc -Wall produce any messages. ** If you encounter any errors or need to make any changes to port it ** to another platform, please contact me. ** ** Version history ** ** Version 1.0 - 27.7.94 ** Initial version ** Version 1.0.1 - 20 Jul 95 framstag@rus.uni-stuttgart.de ** debugged for AIX, IRIX, Linux and Solaris ** Version 1.1 - 28 Feb 96 framstag@rus.uni-stuttgart.de ** Bug fixes and code cleanup ** Version 1.2 - 21 Nov 03 Madeleine Freudenberg ** added multiprotocol capabilities ** (ENABLE_MULTIPROTOCOL sections) */ #define __USE_BSD #include #include #include #include #include #ifndef IRIX #include #endif #include #include #include #include #include "peername.h" #include "string.h" #if defined(AIX3) || defined(ULTRIX) #include "bsd.h" #endif #ifdef IRIX extern char *strdup(const char *); int tolower(int); #endif /* #if defined(LINUX) || defined(SOLARIS2) char *strdup(const char *); #endif */ #ifndef ENABLE_MULTIPROTOCOL char *peername(int fd) { size_t len; struct sockaddr addr; struct in_addr *iaddr; struct hostent *hptr; char *remote_name; char **haddr=NULL; static char remote_host[256]; len=sizeof(struct sockaddr); remote_name="UNKNOWN_HOST"; *remote_host=0; if ((getpeername(fd,&addr,&len)) < 0) return(remote_name); iaddr=&(((struct sockaddr_in *)&addr)->sin_addr); hptr=gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET); if(hptr) { strncpy(remote_host,hptr->h_name,256); remote_name=str_tolower(remote_host); } /* Grrr. Check THAT name to make sure it's really the name of the addr. */ /* Code from Harald Hanche-Olsen */ if(*remote_host) { hptr=gethostbyname(remote_host); if (hptr) for(haddr=hptr->h_addr_list;*haddr;haddr++) if(((struct in_addr *)(*haddr))->s_addr == iaddr->s_addr) break; if((!hptr) || (!(*haddr))) *remote_host=0; } if(!(*remote_host)) remote_name=inet_ntoa(*iaddr); return(remote_name); } #else char *defaultName = "UNKNOWN_HOST"; char *peername(int fd) { size_t len; char addrbuf[1024]; struct sockaddr *addr; char service[1024]; struct addrinfo* addressInfo; struct addrinfo* aiptr; struct addrinfo hints; char peerHostName[1024]; len=sizeof(addrbuf); /* * Many thanks to Krupps for finding out that sizeof(struct sockaddr) * is less than sizeof(struct sockadd_in6) */ if ((getpeername(fd,&addrbuf,&len)) < 0) return(defaultName); addr = (struct sockaddr*)addrbuf; if (getnameinfo(addr, len, peerHostName, 1023, service, 1023, 0) < 0) { return defaultName; } str_tolower(peerHostName); hints.ai_flags = 0; hints.ai_family = addr->sa_family; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_addrlen = 0; hints.ai_addr = NULL; hints.ai_canonname = NULL; hints.ai_next = NULL; if (addr->sa_family == AF_INET6) { if (getaddrinfo(peerHostName, service, &hints, &addressInfo) == 0) { for (aiptr = addressInfo; aiptr != NULL; aiptr = aiptr->ai_next) { if (memcmp(&(((struct sockaddr_in6*)(aiptr->ai_addr))->sin6_addr), &(((struct sockaddr_in6*)addr)->sin6_addr), sizeof(struct in6_addr)) == 0) { freeaddrinfo(addressInfo); return strdup(peerHostName); } } freeaddrinfo(addressInfo); } } else if (addr->sa_family == AF_INET) { if (getaddrinfo(peerHostName, service, &hints, &addressInfo) == 0) { for (aiptr = addressInfo; aiptr != NULL; aiptr = aiptr->ai_next) { if (memcmp(&(((struct sockaddr_in*)(aiptr->ai_addr))->sin_addr), &(((struct sockaddr_in*)addr)->sin_addr), sizeof(struct in_addr)) == 0) { freeaddrinfo(addressInfo); return strdup(peerHostName); } } freeaddrinfo(addressInfo); } } if (getnameinfo(addr, len, peerHostName, 1023, service, 1023, NI_NUMERICHOST) < 0) { return defaultName; } else { return strdup(peerHostName); } } #endif /* ENABLE_MULTIPROTOCOL */ /* void usage(image) char *image; { (void)fprintf(stderr,"Usage: %s [-h] [-v] [filename...]\n",image); exit(1); } main(argc,argv) int argc; char *argv[]; { int c; extern char *optarg; extern int optind; char error[2*MAXPATHLEN+14]; FILE *src; char header[]="peername v1.0\n(c) 1994 by Andreas Ley\n"; while ((c=getopt(argc,argv,"vh?")) != EOF) switch ((char)c) { case 'v': (void)fprintf(stderr,header); exit(0); case 'h': (void)fprintf(stderr,header); case '?': usage(argv[0]); } printf("%s\n",peername(0)); return(0); } */ sendfile-2.1b/src/net.h0000640000175100001440000000266410251136250014560 0ustar framstagusers/* * File: net.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Heiko Schlichting (heiko@fu-berlin.de) * * History: * * 12 Aug 95 Framstag initial version * 14 May 96 Framstag included and modified send_data() * 24 Sep 96 Heiko added get_domainname() * 29 Dec 96 Framstag moved get_domainname to reply.c * 9 Dec 97 Framstag added sock_command() * 21 Aug 98 Framstag added maximum thruput option for send_data * * Network routines header-file for the the sendfile client of the * sendfile package. * * Copyright © 1995-1998 Ulli Horlacher * This file is covered by the GNU General Public License */ /* open socket and connect to client */ #ifdef ENABLE_MULTIPROTOCOL int open_connection(char *, char *); #else int open_connection(char *, int); #endif /* get a line from the network socket */ int sock_getline(int, char *); /* send a line to the network socket */ int sock_putline(int, const char *); /* send a command line to the network socket and get the answer */ char *sendcommand(int, const char *, char *); /* get the reply on a command from the server */ char *getreply(int); /* send a headerline and check the reply code */ int sendheader(int, char *); /* send file data */ int send_data(int, off_t, const char*, const char*, const char *, const char *, float, float *); #ifdef ENABLE_MULTIPROTOCOL /* default address family */ extern int addressFamily; #endif sendfile-2.1b/src/Makefile0000640000175100001440000000601011025466146015260 0ustar framstagusers# Do not edit this file! # It is autogenerated by "makeconfig" and will be overwritten next time! # If you want to change some values, so do it in "makeconfig". CC=gcc CFLAGS=-O2 -Wall -DLINUX LINK=gcc LDFLAGS=-s LIBS= -lnsl -lreadline -L/usr/lib/termcap -ltermcap PROJECT= sendfile sendmsg receive sendfiled utf7encode fetchfile wlock SENDFILE_OBJ= sendfile.o message.o utf7.o pstring.o string.o io.o net.o \ address.o spool.o FETCHFILE_OBJ= fetchfile.o message.o utf7.o pstring.o string.o io.o net.o \ address.o spool.o getline.o SENDMSG_OBJ= sendmsg.o message.o utf7.o pstring.o string.o io.o net.o \ address.o getline.o RECEIVE_OBJ= receive.o message.o utf7.o pstring.o string.o io.o spool.o \ getdate.o getline.o lock.o SENDFILED_OBJ= sendfiled.o message.o utf7.o pstring.o string.o io.o net.o \ spool.o peername.o reply.o address.o lock.o UTF7ENCODE_OBJ= utf7encode.o message.o utf7.o pstring.o string.o io.o all: $(PROJECT) @ls -l $(PROJECT) @echo @echo "and now type (as root): make install" @echo install: sendfile sendmsg receive sendfiled fetchfile utf7encode @cd ..;sh install LINUX sendfile: $(SENDFILE_OBJ) $(LINK) $(LDFLAGS) $(SENDFILE_OBJ) -o sendfile $(LIBS) fetchfile: $(FETCHFILE_OBJ) $(LINK) $(LDFLAGS) $(FETCHFILE_OBJ) -o fetchfile $(LIBS) sendmsg: $(SENDMSG_OBJ) $(LINK) $(LDFLAGS) $(SENDMSG_OBJ) -o sendmsg $(LIBS) receive: $(RECEIVE_OBJ) $(LINK) $(LDFLAGS) $(RECEIVE_OBJ) -o receive $(LIBS) sendfiled: $(SENDFILED_OBJ) $(LINK) $(LDFLAGS) $(SENDFILED_OBJ) -o sendfiled $(LIBS) utf7encode: $(UTF7ENCODE_OBJ) $(LINK) $(LDFLAGS) $(UTF7ENCODE_OBJ) -o utf7encode $(LIBS) @rm -f utf7decode ln -s utf7encode utf7decode wlock: wlock.o string.o $(LINK) $(LDFLAGS) wlock.o string.o -o wlock clean: rm -rf core *.o *~ a.out .deps \ sendfile sendfiled sendmsg receive fetchfile utf7??code wlock trimeol: perl -pi -e 's/[ \t]+$//' *.c *.h .c.o: $(CC) $(CFLAGS) -c $< sendfile.o: sendfile.c config.h globals.h utf7.h string.h io.h address.h fetchfile.o: fetchfile.c config.h globals.h utf7.h string.h io.h sendmsg.o: sendmsg.c config.h globals.h utf7.h string.h address.h receive.o: receive.c config.h globals.h utf7.h spool.h string.h io.h sendfiled.o: sendfiled.c reply.h config.h globals.h utf7.h spool.h string.h spoolid.o: spoolid.c config.h globals.h message.o: message.c message.h config.h globals.h utf7.o: utf7.c utf7.h config.h globals.h string.h base64.o: base64.c base64.h config.h globals.h pstring.o: pstring.c pstring.h config.h globals.h peername.o: peername.c peername.h string.h config.h globals.h net.o: net.c net.h io.h config.h globals.h io.o: io.c io.h config.h globals.h string.o: string.c string.h config.h globals.h address.o: address.c address.h config.h globals.h string.h spool.o: spool.c spool.h config.h globals.h string.h reply.o: reply.c reply.h config.h globals.h net.h getdate.o: getdate.c config.h getline.o: getline.c config.h lock.o: lock.c lock.h utf7encode.o: utf7encode.c config.h globals.h utf7.h sendfile-2.1b/src/pussy0000755000175100001440000004134510251132201014725 0ustar framstagusers#!/client/bin/perl -w # PUSSY - Perl User SAFT Server Yin ###################### user configuration section ########################### $spool = '~/.sfspool'; # local spool $maxfilesize = 100*2**20; # a single file may not exceed 100 MB $maxfiles = 2**10; # maximum number of files $compress = 'GZIP|BZIP2'; # accept gzip and bzip2 files $deleting = 1; # allow remote sender to delete his files $mailnotify = 1; # notify new files by mail (you may also # assign a string like 'framstag@belwue.de') $firstport = 48700; # first available port $lastport = 48999; # last available port $maxconnects = 5; # max # of concurrent connections ################### end of user configuration section ####################### $0 =~ s:.*/::; $HOME = $ENV{'HOME'}; $pussy = 'PUSSY-20030105'; $sendmail = '/usr/lib/sendmail -t'; $configdir = $HOME.'/.sendfile'; $userspool = $HOME.'/.sfspool'; use 5.003; use integer; use POSIX; use IO::Socket; use Getopt::Std; $SIG{CHLD} = sub {wait()}; # parse CLI arguments $opt_p = 0; $opt_I = $opt_h = $opt_V = $opt_v = $opt_x = ''; if (!getopts('IhVvxp:') || $opt_h) { print "usage: $0 [-I] [-v] [-x] [-p port]\n"; print "options: -I print instructions\n"; print " -v verbose mode\n"; print " -x do not write SAFTport to \$HOME/.plan\n"; print " -p port use this port to bind to\n"; exit 2; } if ($opt_V) { print $pussy,"\n"; exit; } &instructions if $opt_I; $firstport = $lastport = $opt_p if $opt_p; $base_socket = &init; # main-loop print "waiting for connection...\n" if $opt_v; for (;;) { if ($sock = $base_socket->accept()) { $peername = gethostbyaddr($sock->peeraddr(),AF_INET); print "\nnew connection from $peername:\n" if $opt_v; $pid = fork(); die "$0: cannot create subprocess: $!\n" unless defined $pid; if ($pid == 0) { select $sock; $| = 1; $notify = ''; &handle_connection; if ($notify) { warn "%$0-Info received files:\n".$notify; &sendmail if $mailnotify; } exit; } close $sock; } } exit; # # handle a SAFT connection (this is a subprocess!) # sub handle_connection { my @args; # SAFT command arguments my $i; # simple loop counter my $sn; # spool number my $size = -1; # file transfer size my $osize; # file original size my $type = 'BINARY'; # file type my $comment; # file comment my $transmitted; # bytes which have been already transmitted # SAFT welcome message &reply(220); while (<$sock>) { # trim command line s/\r//;s/\n//; warn ">$_<\n" if $opt_v; s/\s+/ /g;s/^ //;s/ $//; @args = split; if (/^HELP$/i) { &reply(214); next; } if (/^TO/i) { if ($args[1] eq ":NULL:") { $test = 1; } elsif ($args[1] ne $username) { &reply(520); exit; } &reply(200); next; } if (/^FROM/i) { if ($args[1]) { $from = $args[1].'@'.$peername.' ('.join(' ',@args[2..$#args]).')'; &reply(430) if &restricted($from); &reply(200); } else { &reply(505); } next; } if (/^FILE/i) { if ($args[1]) { $file = $args[1]; &reply(200); } else { &reply(505); } next; } if (/^SIZE/i) { if (!$args[2]) { &reply(505); next; } if ("$args[1]$args[2]" !~ /^\d+$/) { &reply(507); next; } $size = $args[1]; $osize = $args[2]; &reply(413) if $size > $maxfilesize; &reply(200); next; } if (/^TYPE/i) { if (!$args[1]) { &reply(505); next; } if (/^TYPE (BINARY|SOURCE|MIME|TEXT=[A-Z0-9_:-]+)( COMPRESSED(=($compress))?| CRYPTED(=PGP)?)?$/i) { s/TYPE //i; $type = uc $_; &reply(200); } else { &reply(507); } next; } if (/^DATE/i) { if (!$args[1]) { &reply(505); next; } if (/^DATE \d\d\d\d-\d\d-\d\d[ T]\d\d:\d\d:\d\d$/i) { s/DATE //i;s/T/ /i; $date = $_; &reply(200); } else { &reply(507); } next; } if (/^SIGN/i) { if (!$args[1]) { &reply(505); next; } $sign = $args[1]; &reply(200); next; } if (/^ATTR/i) { if (!$args[1]) { &reply(505); next; } if (/^ATTR (TAR|EXE|NONE)$/) { $attr = $args[1] if $args[1] !~ /^NONE$/i; &reply(200); } else { &reply(507); } next; } if (/^COMMENT/i) { if (!$args[1]) { &reply(505); next; } s/^COMMENT //i; $comment = $_; &reply(200); next; } if (/^DEL$/i) { if (!$deleting) { &reply(502); next; } if (!$from || !$file) { &reply(503); next; } $transmitted = 0; if (&delfile($from,$file)) { &reply(200); } else { &reply(550); } next; } if (/^RESEND$/i) { if (!$from || !$file || $size<0) { &reply(503); next; } if ($test) { $transmitted = 0; } else { ($transmitted,$sn) = &received($from,$file,$size,$type); } &reply(230,$transmitted); next; } if (/^DATA$/i) { if (!$from || !$file || $size<0) { &reply(503); next; } if ($transmitted==$size) { &reply(531); next; } &receive($from,$file,$type,"$size $osize", $date,$attr,$sign,$comment,$sn,$transmitted) or &reply(451); &reply(201); &logfile($from,$file,$date,$comment); $notify .= "$from : $file\n"; $size = -1; $sn = $transmitted = 0; $type = "BINARY"; $file = $sign = $comment = $attr = $date = ""; next; } if (/^MSG/i) { &reply(511); next; } if (/^QUIT$/i) { &reply(221); return; } &reply(500); } } # # bind this server to a free port # # RETURN: server-socket # sub init { my $warning = $^W; my $planfile = $HOME.'/.plan'; my $sock; my @plan; $username = getpwuid $< or die "$0: cannot determine own username : $!\n"; $hostname = &gethostname; $spool =~ s:^~/:$HOME/:; unless (-d $spool) { mkdir $spool,0700 or die "$0: cannot create $spool : $!\n"; } chdir $spool or die "$0: cannot cd to $spool : $!\n"; if ($spool ne $userspool && $spool ne (readlink $userspool or '')) { unlink $userspool; rmdir $userspool; symlink $spool,$userspool or die "$0: cannot create symlink $userspool : $!\n"; } $^W = 0; for ($port = $firstport; ;$port++) { die "$0: cannot bind to a free port: $!\n" if $port > $lastport; print "trying port $port\n" if $opt_v; $sock = new IO::Socket::INET( #LocalHost => 'localhost', LocalPort => $port, Listen => $maxconnects, Proto => 'tcp', Reuse => 1); last if $sock; } $^W = $warning; warn "%$0-Info successfully installed on port $port\n"; # if allowed, write SAFT-port to $HOME/.plan unless ($opt_x) { if (open F,$planfile) { @plan = ; close F; @plan = grep { s/^\s*SAFTport\s*=.*$/SAFTport=$port/i or $_ } @plan; } push @plan,"SAFTport=$port\n" unless grep /^SAFTport=/, @plan; open F,">$planfile" or die "$0: cannot write $planfile : $!\n"; print F @plan; close F; } %reply = ( 200 => "200 Command ok.", 201 => "201 File has been received correctly.", 202 => "202 Command not implemented, superfluous at this site.", 203 => "203 *schnuffel* *schnuffel* =:3", 205 => "205 Non-ASCII character in command line ignored.", 214 => "214-The following commands are recognized:\r\n". "214- FROM []\r\n". "214- TO \r\n". "214- FILE \r\n". "214- SIZE \r\n". "214- TYPE BINARY|SOURCE|MIME|TEXT= [COMPRESSED|CRYPTED]\r\n". "214- DATE \r\n". "214- SIGN \r\n". "214- ATTR TAR|EXE|NONE\r\n". "214- COMMENT \r\n". "214- DEL\r\n". "214- RESEND\r\n". "214- DATA\r\n". "214- QUIT\r\n". "214-All arguments have to be UTF-7 encoded.\r\n". "214 You must specify at least FROM, TO, FILE, SIZE and DATA to send a file.", 215 => "215 $pussy", 220 => "220 $username\@$hostname user SAFT server $pussy on port $port ready.", 221 => "221 Goodbye.", 230 => "230 %d bytes have already been transmitted.", 231 => "231 %d bytes will follow", 250 => "250 End of transfer.", 260 => "260 DEBUG-OUTPUT", 302 => "302 Header ok, send data.", 331 => "331 challenge: %s", 410 => "410 No access to spool directory (permission problems?).", 411 => "411 Can't create user spool directory.", 412 => "412 Can't write to user spool directory.", 413 => "413 File quota exceeded.", 414 => "414 Can't start spool postprocessing.", 415 => "415 TCP error: received too few data.", 421 => "421 Service currently not available.", 430 => "430 You are not allowed to send to this user.", 451 => "451 Requested action aborted: server error.", 452 => "452 Insufficient storage space.", 453 => "453 Insufficient system resources.", 460 => "460 Authentication error.", 490 => "490 Internal error.", 500 => "500 Syntax error, command unrecognized.", 501 => "501 Syntax error in parameters or arguments.", 502 => "502 Command not implemented.", 503 => "503 Bad sequence of commands.", 504 => "504 Command not implemented for that parameter.", 505 => "505 Missing argument.", 506 => "506 Command line too long.", 507 => "507 Bad argument.", #case 510: text="510 User has set a forward to xxx@yyy"; 511 => "511 This SAFT-server can only receive files.", 512 => "512 This SAFT-server can only receive messages.", 520 => "520 User unknown.", 521 => "521 User is not allowed to receive files or messages.", 522 => "522 User cannot receive messages.", 530 => "530 Authorization failed.", 531 => "531 This file has been already received.", 532 => "532 This file is currently transfered by you within another process.", 540 => "540 Secure mode enforced: you have to sign your files", 541 => "541 Secure mode enforced: you have to encrypt your files", 550 => "550 File not found.", ); return $sock; } # # send SAFT reply string # # INPUT: reply-code-# # printf-parameters # sub reply { my $rc = shift; my $text; $text = $reply{$rc}; $text = "599 Unknown error." unless $text; printf "$text\r\n",@_; # terminate on a fatal error exit 1 if $rc =~ /^4/; } # # delete a file from spool # # INPUT: sender in form: user@host # file name # # RETURN: number of deleted files # sub delfile { my $from = shift; my $file = shift; my $n; my $i; return 0 unless &scanspool; foreach $i (keys %spoolfiles) { if ($spoolfiles{$i}{"from"} eq $from && $spoolfiles{$i}{"file"} eq $file) { $n++; unlink "$i.h","$i.d"; } } return $n; } # # check restriction file # # RETURN: 1 on no access, 0 on access ok # sub restricted { my $from = shift; local $_; if (open F,"$configdir/restrictions") { while () { chomp; s/#.*//; s/\s+/ /g;s/^ //;s/ $//; next unless / [bf]$/i; s/ [bf]$//i; # transform simplematch pattern to perl regexp $_ = quotemeta; s/\\\\/\\/; s/\\\*/.*/; s/\\\?/./; s/\\\[\\\^/[^/; s/\\\[/[/; s/\\\]/]/; return 1 if $from =~ /^$_$/i; } } close F; return 0; } # # scan the spool header files # sub scanspool { my ($from,$file,$type,$size,$shf,$n); local $_; %spoolfiles = (); opendir SPOOL, '.' or return 0; while (defined($shf = readdir SPOOL)) { next if $shf !~ /^(\d+)\.h$/; $n = $1; next unless -f "$n.d"; $from = $file = $type = $size = ''; open F, $shf or next; while () { chomp; if (/^FROM\t(.*)/) { $from = $1; next; } if (/^FILE\t(.*)/) { $file = $1; next; } if (/^TYPE\t(.*)/) { $type = $1; next; } if (/^SIZE\t(\d+)/) { $size = $1; next; } } close F; if (length $from && length $file && $type && $size) { $spoolfiles{$n} = { from => $from, file => $file, type => $type, size => $size }; } } closedir SPOOL; return ($n>0); } # # find out how many bytes have been already transmitted # # INPUT: sender in form: user@host # file name # file size # file SAFT type # # RETURN: number of already received bytes, spool number # sub received { my $from = shift; my $file = shift; my $size = shift; my $type = shift; my $i; return (0,0) unless &scanspool; foreach $i (keys %spoolfiles) { if ($spoolfiles{$i}{"size"} eq $size && $spoolfiles{$i}{"file"} eq $file && $spoolfiles{$i}{"from"} eq $from && $spoolfiles{$i}{"type"} eq $type) { return ((stat "$i.d")[7],$i); } } return (0,0); } # # receive file data # sub receive { my $from = shift; my $file = shift; my $type = shift; my $sizes = shift; my $date = shift; my $attr = shift; my $sign = shift; my $comment = shift; my $sn = shift; my $transmitted = shift; my $size; my $bytes; my $bn; my $nblocks; my $n = 0; my $fd; my $buf; $size = $sizes; $size =~ s/ \d+//; unless ($test) { # known spool number: resume transfer if ($sn) { open D, ">>$sn.d" or return 0; } else { # find free spool file number for ($n=1; $n<=$maxfiles; $n++) { last if ($fd = POSIX::open("$n.h",O_CREAT|O_EXCL)); } return 0 if !defined($fd) || $n == $maxfiles; POSIX::close($fd); #$status = fcntl(LF,F_SETLK,pack('ss4l',F_WRLCK,SEEK_SET,0,0,0,0)); open H, ">$n.h" or return 0; open D, ">$n.d" or return 0; print H "FROM\t$from\n"; print H "FILE\t$file\n"; print H "TYPE\t$type\n"; print H "SIZE\t$sizes\n"; print H "DATE\t$date\n" if $date; print H "ATTR\t$attr\n" if $attr; print H "SIGN\t$sign\n" if $sign; print H "COMMENT\t$comment\n" if $comment; close H; } } &reply(302); $bytes = $size-$transmitted; $nblocks = $bytes/512; for ($bn=1; $bn<=$nblocks; $bn++) { &reply(415) if (read($sock,$buf,512) < 512); print D $buf unless $test; } if ($n = $bytes-$nblocks*512) { &reply(415) if (read($sock,$buf,$n) < $n); print D $buf unless $test; } close D unless $test; return 1; } # # log file transfer # sub logfile { my $from = shift; my $file = shift; my $date = shift; my $comment = shift; my $entry; if (open F,">>$spool/log") { $entry = "FROM\t$from\n". "FILE\t$file\n". "DATE\t$date\n"; $entry .= "COMMENT\t$comment\n" if $comment; print F $entry,"\n"; close F; } } # # determine own hostname (FQDN) # sub gethostname { my $hostname; my $domain; local $_; $hostname = `hostname 2>/dev/null`; chomp $hostname; return 'unknown' unless $hostname; if ($hostname !~ /\./ and open(F,'/etc/resolv.conf')) { while () { if (/^domain/ || /^search/) { $domain = (split)[1]; last; } } close F; $hostname .= '.'.$domain; } return $hostname; } sub sendmail { if (open P,'|'.$sendmail) { if ($mailnotify =~ /[a-z]/i) { print P "To: $mailnotify\n" } else { print P "To: $username\n" } print P "Subject: PUSSY receive report\n\n"; print P $notify,".\n"; close P; } } sub instructions { print < doesn't define. */ #undef gid_t /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if your struct stat has st_blksize. */ #undef HAVE_ST_BLKSIZE /* Define if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define if utime(file, NULL) sets file's timestamp to the present. */ #undef HAVE_UTIME_NULL /* Define to `int' if doesn't define. */ #undef mode_t /* Define to `int' if doesn't define. */ #undef pid_t /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define if your declares struct tm. */ #undef TM_IN_SYS_TIME /* Define to `int' if doesn't define. */ #undef uid_t /* The package-name, version and revision */ #undef PACKAGE #undef VERSION #undef REVISION /* The system-name */ #undef SYSTEM /* Define if you have the gethostname function. */ #undef HAVE_GETHOSTNAME /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY /* Define if you have the mkdir function. */ #undef HAVE_MKDIR /* Define if you have the snprintf function. */ #undef HAVE_SNPRINTF /* Define if you have the socket function. */ #undef HAVE_SOCKET /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the uname function. */ #undef HAVE_UNAME /* Define if you have the header file. */ #undef HAVE_DIRENT_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_GETOPT_H /* Define if you have the header file. */ #undef HAVE_NDIR_H /* Define if you have the header file. */ #undef HAVE_PATHS_H /* Define if you have the header file. */ #undef HAVE_STDARG_H /* Define if you have the header file. */ #undef HAVE_STDDEF_H /* Define if you have the header file. */ #undef HAVE_STDLIB_H /* Define if you have the header file. */ #undef HAVE_STRING_H /* Define if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the nsl library (-lnsl). */ #undef HAVE_LIBNSL /* Define if you have the socket library (-lsocket). */ #undef HAVE_LIBSOCKET /* Define if you have the readline library (-lreadline). */ #undef HAVE_LIBREADLINE /* Define if you have the header file. */ #undef HAVE_READLINE_READLINE_H /* Include the global settings */ #include "globals.h" sendfile-2.1b/src/snprintf.h0000644000175100001440000000165210251136250015635 0ustar framstagusers#ifndef _PORTABLE_SNPRINTF_H_ #define _PORTABLE_SNPRINTF_H_ #define PORTABLE_SNPRINTF_VERSION_MAJOR 2 #define PORTABLE_SNPRINTF_VERSION_MINOR 2 #ifdef HAVE_SNPRINTF #include #else extern int snprintf(char *, size_t, const char *, /*args*/ ...); extern int vsnprintf(char *, size_t, const char *, va_list); #endif #if defined(HAVE_SNPRINTF) && defined(PREFER_PORTABLE_SNPRINTF) extern int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); extern int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); #define snprintf portable_snprintf #define vsnprintf portable_vsnprintf #endif extern int asprintf (char **ptr, const char *fmt, /*args*/ ...); extern int vasprintf (char **ptr, const char *fmt, va_list ap); extern int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); extern int vasnprintf(char **ptr, size_t str_m, const char *fmt, va_list ap); #endif sendfile-2.1b/src/utf7.h0000640000175100001440000000251510251136250014652 0ustar framstagusers/* * File: utf7.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * 1995-08-12 Framstag initial version * 1998-10-29 Framstag iso2utf -> iso2utf7 * 1999-03-13 Framstag added uni2utf() and utf2uni() * * Header-file and size definitions of the UTF-7 and Unicode coding routines * for the sendfile package. * * Copyright © 1995,1998,1999 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "pstring.h" /* #define LEN_ISO 256 #define LEN_UNI 512 #define LEN_UTF 683 */ #ifndef MAXLEN #define MAXLEN 32768 #endif #define LEN_ISO MAXLEN #define LEN_UNI 2*MAXLEN #define LEN_UTF 3*MAXLEN /* UTF-7 to ISO Latin-1 decoding */ int utf2iso(int, char *, char *, char *, char *); /* ISO Latin-1 to UTF-7 encoding */ void iso2utf(char *, char *); /* ISO Latin-1 to UTF-7 encoding */ void iso2utf7(char *, char *, int); /* transform ISO Latin-1 to Unicode */ void iso2uni(pstr_t *, char *); /* Unicode to UTF-7 encoding */ void uni2utf(char *, pstr_t *); /* UTF-7 to Unicode decoding */ void utf2uni(pstr_t *, char *); /* add a char depending on its range */ void add_char(int, char *, char *, char *, char, int *); /* decode mbase64 string to Unicode */ void decode_mbase64(pstr_t *, char *); /* encode Unicode pstring to mbase64 */ void encode_mbase64(char *, pstr_t *); sendfile-2.1b/src/sendfiled.c0000644000175100001440000032001710765534266015744 0ustar framstagusers/* * File: sendfiled.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Thomas Tissen (tici@uni-paderborn.de) * Olaf Erb (erb@insu1.etec.uni-karlsruhe.de) * Rainer Bawidamann (widi@sol.wohnheim.uni-ulm.de) * Andreas "Ako" Koppenhöfer (koppenhoefer@belwue.de) * Chris Foote (chris@senet.com.au) * Daniel Kobras * Colin Phipps * * History: * * 1995-08-11 Framstag initial version * 1995-09-10 Framstag added delete and resend function * 1995-11-01 Framstag eliminated some security flaws * added pgp signature entry * 1995-11-05 Framstag added NeXT support * 1995-11-14 Framstag added user config files * 1995-11-21 Framstag added chat client support * 1996-01-04 Framstag added allow-only flag to NOSENDFILE * 1996-01-11 Framstag added global and user config files * 1996-01-27 Framstag added maxspool and minfree config option * 1996-01-31 Framstag bug fixes for mail2user * 1996-02-04 Olaf Erb added notification=both * 1996-02-05 Framstag some code cleanup * 1996-02-06 Framstag added ATTR EXE * bug fixes for attribute handling * 1996-02-19 Framstag fixed problems with NFS and MSG * fixed statfs-problem with Solaris-2 (?) * enhanced msg2tty with non-blocking write * 1996-02-20 Framstag changed msg-tty and msg-fifo files to support * NFS (msg2tty) * 1996-02-21 widi better Solaris-2 support * 1996-02-21 Framstag bug fix with maxfiles option * better notification check * 1996-02-22 Framstag replaced string "localhost" with the * real name of the local host * 1996-02-23 Framstag mail-notification now contains output * of "receive -l", too * 1996-03-17 Framstag security bug (?) fixed: * no more chown on symlinks * 1996-03-27 Framstag security bug fixed V2.0: * no more chown on any links * 1996-04-01 Framstag corrected logfile bug * swapped O_SYNC and O_NONBLOCK * 1996-04-02 Framstag fixed FROM line handling * added forwarding by user * 1996-04-04 Framstag allowed COMPRESSED=GZIP for TYPE option * 1996-04-08 Framstag changed signature command * better checking for same files * 1996-04-12 Framstag added pgp support * added own SIGN attribute * 1996-05-10 Framstag added global alias file support * 1996-05-12 Framstag added checking of SPOOL/.nosendfile * 1996-05-22 Framstag added -c configfile runtime option * 1996-06-21 Framstag added global log files * 1996-06-22 Framstag better default date setting * 1996-06-23 Framstag nicer log file formats * 1996-06-13 Framstag differ between SYSV and BSD du * 1996-09-24 Framstag protocol-change: * CHARSET charset --> TYPE TEXT=charset * 1996-10-23 Framstag define O_SYNC for BSD * 1996-12-29 Framstag added domain option in sendfile.cf * 1997-01-01 Framstag fixed mkdir bug * 1997-01-07 Framstag better spool file creation handling * added debug facility * 1997-01-19 Framstag fixed resend bug * 1997-01-20 Framstag fixed bug with TEXT=charset attribute * 1997-01-22 Framstag added file post-processing feature * 1997-01-25 Framstag fixed TYPE default declaration (binary) * 1997-01-30 Framstag better SIZE parsing * 1997-02-03 Framstag sprintf() -> snprintf() * 1997-02-09 Framstag new msg2tty interface (msgh,msg) * 1997-02-10 Framstag added setegid-call (security!) * 1997-02-12 Framstag better IRIX and HP-UX support * 1997-02-13 Framstag better OSF/1 support * 1997-02-23 Framstag modified str_* function names * extended with TYPE=MIME * 1997-03-27 Framstag added DEBUG command * fixed minfree checking bug * 1997-05-05 Framstag better IRIX support (blksize) * 1997-06-10 Ako more reliable retransmit operation * 1997-06-16 Framstag added pseudo-user /dev/null for * network speed testing * 1997-06-17 Framstag added packet_size config option * 1997-06-19 Framstag changed ruid and rgid to global variables * added message logging option * 1997-06-23 Framstag new own user log file for messages: msglog * 1997-07-07 Framstag activated outgoing spooling * 1997-07-09 Framstag added parallel option (sendfile.cf) * 1997-07-10 Framstag fixed date bug with messages * 1997-08-21 Framstag added config flag for allowing DEL command * 1997-09-12 Framstag allow empty date field on resend command * 1997-09-14 Framstag moved spoolid() from sendfiled.c to spool.c * 1997-09-30 Framstag added -f free_space option * 1997-11-22 Framstag better SAFT URL checking * 1997-11-23 Framstag moved NOSENDFILE to ALLOW and DENY files * 1997-12-07 Framstag better locking checking * 1997-12-10 Framstag allowed COMPRESSED=BZIP2 for TYPE option * added PATH variable in sendfiled.cf * 1997-12-12 Framstag fixed PATH bug * no more testing for gzip binary * 1997-12-19 Framstag added forcepgp option * 1998-01-04 Framstag added forward dection for outgoing spooling * added usage() * 1998-01-05 Framstag reactivated outgoing logging * 1998-01-15 Framstag save time stamp when bouncing file from outgoing spool * back to the user * 1998-01-16 Framstag added -Q option * 1998-01-20 Framstag fixed socket closing and delivery bugs in sfsd * 1998-01-21 Framstag fixed closedir bug in check_outspool() * 1998-01-25 Framstag fixed forwarding bug in sfsd() * 1998-03-01 Framstag changed /dev/null testing recipient to :NULL: * 1998-03-11 Framstag userconfig directory may now in $HOME * 1998-03-16 Framstag fixed sfsd-fork bug (too many sfsd running) * 1998-05-19 Framstag fixed maxfiles counting bug in spoolid() * 1998-07-04 Ako set tcp timeout option * 1998-07-10 Framstag pid is now in OUTGOING/.lock * 1998-07-11 Framstag notification my be USERSPOOL/config/notify * 1998-07-12 Framstag log last msg-sender in * USERSPOOL/config/msg@localhost * 1998-08-20 Framstag added maxthruput option * 1998-08-21 Chris Foote fixed free_space-bug with BIG partitions * 1998-08-21 Framstag fixed sfsd mismatch bug * 1998-10-29 Framstag fixed iso2utf space encoding bug (O-SAFT) * 1999-03-21 Framstag added +batchmode to pgp-call * 2000-06-22 Framstag fixed Linux glibc 2.1 incompatibilities * 2000-12-10 Daniel Kobras fixed notify security bug * 2000-12-26 Framstag fixed several security bugs as reported in * Bug#76048 of Debian Bug Tracking System * 2000-12-27 Framstag fixed bug: spaces in file names * 2000-12-28 Framstag fixed :NULL: recipient bug * 2001-01-10 Framstag fopen() ==> rfopen() * 2001-01-17 cph fixed auth/log security bug * 2001-01-17 Framstag mail2user() now runs in a subprocess * 2001-02-02 Framstag fixed openlog() bug * 2001-02-06 Framstag added timeout on waiting response from client * 2001-04-24 Framstag fixed statvfs.f_bsize bug (wrong spool free) * 2002-05-28 Framstag moved free disk space check from SIZE to DATA * command to respect RESEND * 2005-05-30 Framstag post-processing reactivated (lost why and when?) * 2005-05-31 Framstag added largefile support * 2005-06-01 Framstag correct free_space for symlinked userspool * 2005-06-02 Framstag added Mac-OSX (Darwin) support and better BSD support * 2005-06-06 Maide added multiprotocol cababilities * 2005-06-07 Framstag better AIX support * (send_file() --> send_file_stdout()) * 2005-06-10 Framstag openlog() --> openuserlog() * 2008-03-11 Framstag timeout now in sendfile.cf * * * The sendfile-daemon of the sendfile package. * sendfiled receives files for a specified recipient, stores them in the * sendfile spool directory and informs the recipient. * It also receives messages for a specified recipient and display them * on the recipients terminal. * sendfiled is spawned via the (x)inetd superserver. See the README file * for installing hints. * * Copyright © 1995-2008 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various definitions */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "reply.h" /* the 3 digit reply codes with text messages */ #include "peername.h" /* get the name of the calling host */ #include "string.h" /* extended string functions */ #include "message.h" /* information, warning and error messages */ #include "spool.h" /* operations on files in the sendfile spool */ #include "net.h" /* network stuff */ #include "io.h" /* socket read/write */ #include "utf7.h" /* UTF-7 coding */ #include "address.h" /* address routines */ #include "lock.h" /* file locking */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #if defined(SOLARIS2) int gethostname(char *, int); #endif /* #if defined(LINUX) int putenv(const char *); int gethostname(char *, size_t); int symlink(const char *, const char *); #endif */ #if defined(IRIX) || defined(IRIX64) #include #elif defined(AIX3) #include int statfs(char *, struct statfs *); #elif defined(OSF1) #include #include int statfs(char *p, struct statfs *, int); #elif defined(HAVE_SYS_STATVFS_H) #include #define statfs statvfs #elif defined(BSD) || defined(ULTRIX) #include #include #else #include #endif #ifdef SYSV #define DU "du -ks " #else #define DU "du -s " #endif /* stupid AIX comes with no include files for networking and other stuff */ #if defined(AIX3) || defined(ULTRIX) #include "bsd.h" #endif #ifndef AIX #ifndef CONVEXOS FILE *popen(const char *, const char *); #endif int pclose(FILE *); #endif #ifdef ULTRIX int statfs(char *, struct fs_data *); #endif #ifdef NEXT int statfs(char *, struct statfs *); #endif #ifdef BSD #ifndef O_SYNC #define O_SYNC O_FSYNC #endif #endif #if defined(HPUX) || defined(BSD) #define seteuid(a) setuid(a) #define setegid(a) setgid(a) #endif #ifndef _PATH_UTMP #define _PATH_UTMP "/etc/utmp" #endif #define DEBUG(a) if (dbf) fprintf(dbf,"%s\n",a) #define null_recipient(r) (str_eq(r,"/dev/null") || str_eq(r,":NULL:")) /* get a command line */ int getaline(char *); /* get next SAFT command from client */ int getcmd(char *, char *); /* write one line to header spool file */ void writeheader(int, const char *, const char *); /* notify recipient and send reply to client */ void notify_reply(int *, char *, const char *, const char *, const char *, int, int); /* write a message to all ttys of the user */ int msg2tty(const char *, const char *, char *, int); /* send a mail to the recipient */ void mail2user(const char *, const char *, const char *); /* check killfile */ int restricted(const char *, const char *, char); /* missed in in some systems */ int seteuid(uid_t); int setegid(gid_t); /* sendfile spool daemon for outgoing files */ int sfsd(int, int, int, int, float); /* send a file from the outgoing spool */ int send_spooldata(int, char *, char *, char *, char *, char *, float, int); /* send a status report via mail to the local user */ int mail_report(const char *); /* look for correct SAFT server and open connection */ int saftserver_connect(char *, char *); /* check outgoing spool if there are expired files */ void check_outspool(int); /* check if user is allowed to use sendfile and create the user spool directories */ int check_userspool(char *, int); /* bounce back a file from outgoing spool to the sender's incoming spool */ int bounce_file(char *, char *); /* copy a file to a pipe descriptor */ int copy2pipe(const char *, int); /* get the compressed and original file size */ int get_sizes(char *, off_t *, off_t *); /* write debug output */ void dbgout(const char *); /* simple interrupt handler for SIGCHLD */ void sigchld(); /* free disk space on spool directory */ off_t free_space(); /* send a file to stdout */ int send_file_stdout(int); /* open user log file */ int openuserlog(const char *); /* clean termination routine */ void cleanexit(); /* timeout termination routine */ void timeoutexit(); /* delete tmp-file */ void cleanup(); /* send a message to a remote SAFT server */ int send_msg(const char *, const char *, const char *); /* set effective uid and gid for recipient */ void setreugid(); /* emulate su(1) */ int sudo(const char *, const char *); /* print short help usage text */ int usage(); /* global variables */ char *prg, /* name of the game */ *config, /* config file name */ domain[FLEN], /* domain name for get_domainname() */ localhost[FLEN], /* name of the local host */ path[MAXLEN], /* $PATH for environment */ chfile[MAXLEN], /* challenge file name */ csfile[MAXLEN], /* challenge sign file name */ userspool[MAXLEN], /* user spool directory */ userconfig[MAXLEN]; /* user config directory */ int test=0, /* flag for test mode: receiving to /dev/null */ auth=0, /* flag for correct authentification */ xonf=1, /* exit on fatalerror flag */ quiet=3, /* no user messages to stdout */ client=0, /* flag to determine client or server */ timeout=300, /* timeout for clients in seconds */ verbose=0, /* flag for verbose mode */ packet_size=0; /* packet size */ uid_t ruid; /* recipient's user id */ gid_t rgid; /* recipient's group id */ FILE *dbf; /* debug file */ int main(int argc, char *argv[]) { int status, /* return status */ opt, /* arg-option to test for */ infd, /* input file descriptor */ outfd, /* input file descriptor */ shfd, /* spool header file descriptor */ sdfd, /* spool data file descriptor */ lfd, /* log file descriptor */ maxfiles, /* maximal number of allowed files per user */ bounce, /* days after files are bounced to sender */ parallel, /* flag for multple spool daemons */ retry, /* minutes to wait for retrying to deliver */ wconf, /* flag for writing config file (0=reading) */ notify, /* flag for sending a message */ bell, /* flag for tty bell */ sys_bell, /* system flag for tty bell */ fetchfile, /* flag for allowing SAFT fetchfile commands */ forwarding, /* flag for user file forwarding */ msglog, /* flag for logging incoming messages */ sys_msglog, /* system flag for logging incoming messages */ queue, /* flag for processing outgoing spool queue */ piping, /* flag for user file post-processing */ spooling, /* flag for outgoing spooling */ deleting, /* flag for allowing delete command */ userconfighome, /* flag for linking the user config to HOME */ sys_deleting, /* system flag for allowing delete command */ del_success, /* flag for successfull deleting a file */ flags, /* source, text, compress, tar and exe flag */ challenge, /* challenge for fetchfile authentification */ id, /* spool file id */ n; /* simple loop variable */ off_t bytes, /* number of bytes to be received */ nblocks, /* number of packet length blocks */ bn, /* block number to read */ minfree, /* minimum free spool disk space in MB */ maxspool, /* maximum spool disk space quota, total in MB */ spoolsize, /* current spool size in KB */ transmitted, /* bytes already transmitted */ size, /* size of the file */ osize; /* original size of the file (uncompressed) */ float mtp; /* maximum thruput for outgoing files */ char *cp, /* simple char pointer */ *argp, /* argument string pointer */ *peer, /* sender host name */ *realr, /* real recipient name */ *aliasr, /* alias recipient name */ log, /* type of global logging */ acceptonly, /* flag for accepting only files or messages */ sys_notification, /* system flag for notification */ notification[MAXLEN], /* notification type (message, mail or action) */ line[MAXLEN], /* incoming command line */ rpipe[MAXLEN], /* receiving pipe */ arg[MAXLEN], /* the argument(s) of the command line */ cmd[MAXLEN], /* the command itself */ type[MAXLEN], /* file type: binary, source or text */ otype[MAXLEN], /* original file type with charset info */ subtype[MAXLEN], /* COMPRESSED or CRYPTED subtype */ compress[FLEN], /* compression type */ sizes[FLEN], /* original and compressed file size */ charset[MAXLEN], /* name of the character set */ attribute[MAXLEN], /* tar or exe attribute */ sign[MAXLEN], /* pgp signature */ comment[MAXLEN], /* file comment in UTF-7 */ pgp_bin[MAXLEN], /* the pgp binary */ forcepgp[FLEN], /* force pgp option */ sys_forcepgp[FLEN], /* force pgp option default */ date[MAXLEN], /* date string of file */ currentdate[FLEN], /* current date */ shfile[MAXLEN], /* spool header file name */ sdfile[MAXLEN], /* spool data file name */ tmp[3*MAXLEN], /* temporary string */ real[MAXLEN], /* sender real name in UTF-7 */ forward[MAXLEN], /* user forward address */ sender[MAXLEN], /* user@senderhost (real name) */ utfsender[MAXLEN], /* sender in UTF-7 */ logsender[MAXLEN], /* sender for log file */ filename[MAXLEN], /* file name in UTF-7 */ recipient[MAXLEN], /* local user */ mailto[MAXLEN], /* notification mail recipient */ saftserver[MAXLEN], /* real saft server name */ packet[OVERSIZE], /* data packet to read */ msgh[MAXLEN], /* message header to user-tty */ msg[3*MAXLEN], /* message to user-tty */ logdata[OVERSIZE]; /* log file data */ unsigned char *ucp; /* simple unsigend char pointer */ struct stat finfo; /* information about a file */ struct filelist *flp; /* file list pointer */ struct senderlist *sls, /* sender list start */ *slp; /* sender list pointer */ time_t timetick,tt1,tt2; /* unix time (in seconds) */ FILE *inf, /* for various files */ *outf, /* output file */ *pp; /* pipe stream */ /* set default values */ id=0; lfd=0; mtp=0; bell=1; ruid=0; rgid=0; sdfd=0; shfd=0; auth=0; infd=0; flags=0; queue=0; retry=0; bounce=0; piping=1; notify=0; msglog=0; minfree=0; fetchfile=0; deleting=1; parallel=1; maxspool=0; spooling=2; sys_bell=1; maxfiles=200; forwarding=1; sys_msglog=0; acceptonly=0; transmitted=0; sys_deleting=1; userconfighome=0; log='b'; sys_notification='t'; *sign=0; *date=0; *chfile=0; *csfile=0; *mailto=0; *sender=0; *domain=0; *comment=0; *filename=0; *forcepgp=0; *userspool=0; *utfsender=0; *recipient=0; *attribute=0; *saftserver=0; *sys_forcepgp=0; config=CONFIG; prg=argv[0]; strcpy(notification,"t"); strcpy(charset,CHARSET); strcpy(type,"BINARY"); strcpy(otype,"BINARY"); dbf=NULL; sls=NULL; flp=NULL; inf=NULL; outf=NULL; realr=NULL; /* determine pgp program */ strcpy(pgp_bin,PGP); if ((cp=getenv("SF_PGP"))) strcpy(pgp_bin,cp); /* switch off buffering for STDIN */ setvbuf(stdout,NULL,_IONBF,0); /* setbuf(stdout,NULL); */ /* set tcp timeout option */ #ifdef SO_KEEPALIVE { int flag=1; setsockopt(fileno(stdin),SOL_SOCKET,SO_KEEPALIVE, (void *)&flag,sizeof(flag)); } #endif /* scan the command line */ #ifndef ENABLE_MULTIPROTOCOL while ((opt=getopt(argc, argv, "Vh?fvqQdc:")) > 0) { #else while ((opt=getopt(argc, argv, "Vh?fvqQdc:46")) > 0) { #endif switch (opt) { case ':': case 'h': case '?': exit(usage()); case 'c': config=optarg; break; case 'd': dbf=rfopen(DBF,"a"); break; case 'v': verbose=1; quiet=0; break; case 'q': queue=1; break; case 'Q': queue=2; break; case 'f': printf("%lld\n",free_space()); exit(0); case 'V': message(prg,'I',"version "VERSION" revision "REVISION); exit(0); #ifdef ENABLE_MULTIPROTOCOL case '4': addressFamily = PF_INET; break; case '6': addressFamily = PF_INET6; break; #endif } } #ifdef DBG if (!dbf) dbf=rfopen(DBF,"a"); #endif if (dbf) { timetick=time(0); strftime(tmp,20,"%Y-%m-%d %H:%M:%S",localtime(&timetick)); dbgout(tmp); } /* get the local host name */ if (gethostname(localhost,FLEN-1)<0) strcpy(localhost,"localhost"); /* parse the global config-file */ if ((inf=rfopen(config,"r"))) { while (fgetl(line,inf)) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; str_tolower(str_trim(line)); /* is there an option and an argument? */ if ((argp=strchr(line,' '))) { *argp=0; argp++; if (str_eq(line,"bell")) { if (str_eq(argp,"off")) sys_bell=0; continue; } if (str_eq(line,"userconfig")) { if (str_eq(argp,"home")) userconfighome=1; continue; } if (str_eq(line,"forwarding")) { if (str_eq(argp,"off")) forwarding=0; continue; } if (str_eq(line,"piping")) { if (str_eq(argp,"off")) piping=0; continue; } if (str_eq(line,"deleting")) { if (str_eq(argp,"off")) sys_deleting=0; continue; } if (str_eq(line,"fetchfile")) { if (str_eq(argp,"on")) fetchfile=1; continue; } if (str_eq(line,"path")) { if (*argp == '/') { snprintf(MAXS(path),"PATH=%s",argp); putenv(path); } continue; } if (str_eq(line,"pgp")) { if (*argp == '/') strcpy(pgp_bin,argp); continue; } if (str_eq(line,"forcepgp")) { snprintf(MAXS(sys_forcepgp),"%s",argp); continue; } if (str_eq(line,"spooling")) { if (str_eq(argp,"off")) spooling=0; if (str_eq(argp,"nostart")) spooling=1; if (str_eq(argp,"on")) spooling=2; continue; } if (str_eq(line,"parallel")) { if (str_eq(argp,"off")) parallel=0; continue; } if (str_eq(line,"maxthruput")) { mtp=atof(argp); if (mtp<0) mtp=0; continue; } if (str_eq(line,"msglog")) { if (str_eq(argp,"on")) sys_msglog=1; continue; } if (str_eq(line,"maxfiles")) { maxfiles=atoi(argp); continue; } if (str_eq(line,"maxspool")) { maxspool=atoi(argp); continue; } if (str_eq(line,"minfree")) { minfree=atoi(argp); continue; } if (str_eq(line,"packet")) { packet_size=atoi(argp); continue; } if (str_eq(line,"bounce")) { bounce=atoi(argp); continue; } if (str_eq(line,"retry")) { retry=atoi(argp); continue; } if (str_eq(line,"timeout")) { timeout=atoi(argp); continue; } if (str_eq(line,"acceptonly")) { acceptonly=*argp; continue; } if (str_eq(line,"saftserver")) { strcpy(saftserver,argp); continue; } if (str_eq(line,"domain")) { strcpy(domain,argp); continue; } if (str_eq(line,"notification")) { if (str_eq(argp,"mail")) sys_notification='m'; if (str_eq(argp,"both")) sys_notification='b'; if (str_eq(argp,"none")) sys_notification=0; continue; } if (str_eq(line,"log")) { if (str_eq(argp,"in")) log='i'; if (str_eq(argp,"out")) log='o'; if (str_eq(argp,"both")) log='b'; if (str_eq(argp,"none")) log=0; continue; } } } fclose(inf); } /* set tcp packet length */ if (packet_size<1) packet_size=PACKET; /* process outgoing spool queue? */ if (queue) { if (getuid()) { errno=0; message(prg,'F',"only root is allowed to process the outgoing spool"); } switch (sfsd(queue,parallel,bounce,retry,mtp)) { case -1: message(prg,'F',"cannot start spool daemon"); case 0: message(prg,'I',"spool daemon started"); break; case 1: message(prg,'W',"a sendfile spool daemon is already running"); } exit(0); } /* send the server ready message */ reply(220); /* main loop for command line parsing and getting data */ for (;;) { /* establish timeout signal handler */ signal(SIGALRM,timeoutexit); alarm(timeout); /* get next SAFT command and argument */ status=getcmd(cmd,arg); if (status<0) { notify_reply(¬ify,notification,sender,recipient,mailto,bell,221); exit(0); } /* HELP command? */ if (str_eq(cmd,"HELP") || str_eq(cmd,"?")) { reply(214); continue; } /* TO command? */ if (str_eq(cmd,"TO")) { /* is there an argument? */ if (*arg==0) { reply(505); continue; } /* is there a pending notification request? */ if (notify) notify_reply(¬ify,notification,sender,recipient, mailto,bell,0); /* convert recipient name from UTF-7 to ISO Latin 1 */ utf2iso(0,recipient,NULL,NULL,arg); realr=aliasr=NULL; *rpipe=0; /* is there a global alias file? */ if ((inf=rfopen(ALIASES,"r"))) { while (fgetl(line,inf)) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; str_trim(line); /* check alias and real recipient user name */ if ((realr=strchr(line,' '))) { *realr=0; realr++; aliasr=line; /* does the recipient name match the alias name? */ if (str_eq(aliasr,recipient)) { /* is it a forward to a pipe? */ if ((cp=strchr(realr,'|'))) { *cp=0; /* piping to a remote address is not allowed recipient must be a local user! */ if (strchr(realr,'@') || str_beq_nocase(realr,"saft://")) continue; /* save the pipe command */ snprintf(rpipe,MAXLEN,"%s",cp+1); /* an empty pipe is not allowed */ if (! *rpipe) continue; /* strip off trailing space */ str_trim(realr); } /* alias found, ok */ break; } else { realr = NULL; } } } fclose(inf); /* alias found? */ if (aliasr && str_eq(aliasr,recipient)) { /* convert SAFT to mail address */ if (str_beq_nocase(realr,"saft://")) saft2rfc822(realr); if (strchr(realr,'@')) { printf("510 Admin has set a forward to: %s\r\n",realr); fflush(stdout); *recipient=0; continue; } else { strcpy(recipient,realr); } } } /* for transfer benchmarks don't write to spool */ if (null_recipient(recipient)) { test=1; reply(200); continue; } else { test=0; } /* check the user's spool and get his uid/gid */ if (check_userspool(recipient,userconfighome)<0) continue; /* set global configs */ *forward=0; bell=sys_bell; msglog=sys_msglog; deleting=sys_deleting; sprintf(notification,"%c",sys_notification); strcpy(mailto,recipient); strcpy(forcepgp,sys_forcepgp); /* parse the user config-file */ snprintf(MAXS(tmp),"%s/config",userconfig); setreugid(); if ((inf=rfopen(tmp,"r"))) { while ((fgetl(line,inf))) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; else continue; str_trim(line); if (!*line) continue; str_tolower(line); /* is there an option and an argument? */ if ((argp=strchr(line,' ')) && strlen(argp)) { *argp=0; argp++; /* bell on or off? */ if (str_eq(line,"bell")) { if (str_eq(argp,"off")) bell=0; if (str_eq(argp,"on")) bell=1; continue; } /* allow sender to delete his files afterwards */ if (str_eq(line,"deleting")) { if (str_eq(argp,"off")) deleting=0; if (str_eq(argp,"on")) deleting=1; continue; } /* log messages? */ if (str_eq(line,"msglog")) { if (str_eq(argp,"off")) msglog=0; if (str_eq(argp,"on")) msglog=1; continue; } /* pgp force option */ if (str_eq(line,"forcepgp")) { snprintf(MAXS(forcepgp),"%s",argp); continue; } /* determine notification type */ if (str_eq(line,"notification")) { if (str_eq(argp,"none")) *notification=0; if (str_beq(argp,"message")) strcpy(notification,"t"); if (str_beq(argp,"mail")) strcpy(notification,"m"); if (str_eq(argp,"both")) strcpy(notification,"b"); if (str_eq(argp,"program")) snprintf(MAXS(notification),"%s/notify ",userconfig); else { /* mail address specified to send notifications to? */ if ((argp=strchr(argp,' '))) { argp++; /* convert SAFT to mail address */ if (str_beq_nocase(argp,"saft://")) saft2rfc822(argp); strcpy(mailto,argp); } } continue; } /* forwarding or post-processing? */ if (str_eq(line,"forward") && *argp) { /* convert SAFT to mail address */ if (str_beq_nocase(argp,"saft://")) saft2rfc822(argp); /* forwarding AND post-processing is not allowed */ if ((cp=strchr(argp,'@')) && strchr(cp,'|')) continue; /* post-processing by a pipe allowed and specified? */ if (piping && (cp=strchr(argp,'|'))) { snprintf(rpipe,MAXLEN,"%s",cp+1); *notification=0; continue; } strcpy(forward,argp); continue; } /* msg delivery: tty, file(fifo) or program? */ /* ### Baustelle! ### */ if (str_eq(line,"msgdelivery") && *argp) { /* post-processing by a pipe allowed and specified? */ if (piping && (cp=strchr(argp,'|'))) { snprintf(rpipe,MAXLEN,"%s",cp+1); *notification=0; continue; } strcpy(forward,argp); continue; } } } fclose(inf); } seteuid(0); setegid(0); /* user forward? */ if (forwarding && *forward && *filename && !*rpipe) { printf("510 User has set a forward to %s\r\n",forward); fflush(stdout); continue; } reply(200); continue; } /* FROM command? */ if (str_eq(cmd,"FROM")) { /* is there an argument? */ if (*arg==0) { reply(505); continue; } *real=0; /* is there a real name? */ if ((cp=strchr(arg,' '))) { strcpy(real,cp+1); *cp=0; } /* save sender@host and real name */ peer=peername(0); if (str_eq(peer,"localhost")) peer=localhost; if (strlen(arg)+strlen(peer)+strlen(real)+431 && *ucp<127) || *ucp>159) tmp[n++]=*ucp; tmp[n]=0; strcpy(msg,tmp); msg[MAXLEN-3]=0; /* fprintf(dbf,"msglog: %d\n",msglog); fprintf(dbf,"check_userspool: %d\n",check_userspool(recipient, userconfighome)); fprintf(dbf,"chdir: %d\n",chdir(userspool)); fprintf(dbf,"ruid: %d (%d)\n",ruid,geteuid()); fprintf(dbf,"rgid: %d (%d)\n",rgid,getegid()); fprintf(dbf,"setegid: %d\n",setegid(rgid)); fprintf(dbf,"seteuid: %d\n",seteuid(ruid)); */ /* convert back to UTF-7 and write to log file */ if (msglog && check_userspool(recipient,userconfighome)==0 && chdir(userspool)==0) { if ((lfd=openuserlog("msglog"))) { iso2utf(tmp,msg); timetick=time(0); strftime(currentdate,20,"%Y-%m-%d %H:%M:%S",localtime(&timetick)); writeheader(lfd,"FROM",logsender); writeheader(lfd,"MSG",tmp); writeheader(lfd,"DATE",currentdate); write(lfd,"\n",1); close(lfd); } } seteuid(0); setegid(0); timetick=time(0); if (bell) strcat(msg,"\007"); strftime(currentdate,9,"%H:%M",localtime(&timetick)); snprintf(MAXS(msgh),"Message from %s at %s :",sender,currentdate); /* try to send to recipient ttys */ if (msg2tty(recipient,msgh,msg,O_SYNC)<0) reply(522); else { /* log sender address */ if (rgid) setegid(rgid); if (ruid) seteuid(ruid); snprintf(MAXS(tmp),"%s/msg@%s",userconfig,localhost); if ((outf=rfopen(tmp,"w"))) { strcpy(tmp,sender); if ((cp=strchr(tmp,' '))) *cp=0; fprintf(outf,"%s\n",tmp); } fclose(outf); seteuid(0); setegid(0); reply(200); } continue; } /* DELETE command? */ if (str_eq(cmd,"DEL")) { /* DEL command not allowed? */ if (!deleting) { reply(502); continue; } del_success=-1; /* within authentication (O-SAFT) mode? */ if (auth) { /* need argument */ if (*arg==0) { reply(505); continue; } id=atoi(arg); if (id<1) { reply(507); continue; } if ((sls=scanspool(""))) { /* loop over sender list */ for (slp=sls; slp!=NULL && del_success<0; slp=slp->next) { /* loop over files list */ for (flp=slp->flist; flp!=NULL && del_success<0; flp=flp->next) if (id==flp->id) del_success=delete_sf(flp,0); } } } else { /* normal mode */ /* sender, recipient and filename already specified? */ if (*sender==0 || *recipient==0 || *filename==0) { reply(503); continue; } transmitted=0; /* are there any files in the spool directory from this user? */ if ((sls=scanspool(sender))) { /* loop over files list */ for (flp=sls->flist; flp!=NULL; flp=flp->next) { /* if file found try to delete spool file */ if (str_eq(filename,flp->fname)) del_success*=delete_sf(flp,0); } } } if (del_success!=0) reply(550); else reply(200); continue; } /* DATA command? */ if (str_eq(cmd,"DATA")) { /* sender, recipient, sizes and filename already specified? */ if (*sender==0 || *recipient==0 || *filename==0 || (*sizes==0 && transmitted==0)) { reply(503); continue; } /* sending not to /dev/null */ if (!test) { /* quota exceeded for sendfile? */ if (free_space() <= minfree+(size-transmitted)/1048576) notify_reply(¬ify,notification,sender,recipient, mailto,bell,452); /* spool quota limit set? */ if (maxspool) { pp=popen(DU SPOOL,"r"); if (pp && fgetl(tmp,pp)) { sscanf(tmp,"%lld",&spoolsize); /* too much spool usage? */ if (spoolsize+(size-transmitted)/1024>maxspool*1024) notify_reply(¬ify,notification,sender,recipient,mailto,bell, 452); } pclose(pp); } /* pgp signing enforced? */ if ((str_eq(forcepgp,"sign") || str_eq(forcepgp,"both")) && !*sign) { reply(540); continue; } /* pgp encryption enforced? */ if ((str_eq(forcepgp,"encrypt") || str_eq(forcepgp,"both")) && !strstr(type,"CRYPTED")) { reply(541); continue; } /* does the top level spool directory exist? */ if (stat(SPOOL,&finfo)<0 || (finfo.st_mode&S_IFMT)!=S_IFDIR) notify_reply(¬ify,notification,sender,recipient,mailto,bell,410); setreugid(); /* go to the user spool directory */ if (chdir(userspool)<0) notify_reply(¬ify,notification,sender,recipient,mailto,bell,410); /* check killfile */ if (restricted(sender,recipient,'f')) reply(430); /* resend option? */ if (transmitted && flp) { /* file already completly transferd? */ if (transmitted==flp->csize) { transmitted=0; reply(531); continue; } /* open spool data file for appending */ id=flp->id; snprintf(MAXS(sdfile),"%d.d",id); sdfd=open(sdfile,O_WRONLY|O_APPEND|O_LARGEFILE,S_IRUSR|S_IWUSR); if (sdfd<0) notify_reply(¬ify,notification,sender,recipient, mailto,bell,412); if (wlock_file(sdfd)<0) { reply(532); continue; } } else /* new file */ { /* check if the file has been already sent */ if ((sls=scanspool(sender))) { /* loop over files list */ for (flp=sls->flist; flp!=NULL; flp=flp->next) { /* is it the same file and complete? */ if (str_eq(filename,flp->fname) && flp->csize==flp->tsize && osize==flp->osize && (str_eq(date,flp->date) || !*date) && (flags|F_COMPRESS|F_CRYPT)==(flp->flags|F_COMPRESS|F_CRYPT)) { reply(531); *filename=0; break; } } /* return to main loop if file is already there */ if (*filename==0) continue; } /* get next spool id */ id=spoolid(maxfiles); if (id==0) notify_reply(¬ify,notification,sender,recipient,mailto,bell,412); if (id<0 || id>maxfiles) notify_reply(¬ify,notification,sender,recipient,mailto,bell,413); /* open spool header and data files */ snprintf(MAXS(shfile),"%d.h",id); snprintf(MAXS(sdfile),"%d.d",id); sdfd=open(sdfile,O_WRONLY|O_CREAT|O_LARGEFILE,S_IRUSR|S_IWUSR); shfd=open(shfile,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); if (shfd<0 || sdfd<0) notify_reply(¬ify,notification,sender, recipient,mailto,bell,412); /* lock the data file */ if (wlock_file(sdfd)<0) { reply(532); continue; } /* get the actual UTC time if date is not specified */ /* disabled to allow resending files without DATE field *//* if (!*date) { timetick=time(0); strftime(date,20,"%Y-%m-%d %H:%M:%S",gmtime(&timetick)); }*/ /* write the header lines */ writeheader(shfd,"FROM",utfsender); writeheader(shfd,"FILE",filename); writeheader(shfd,"TYPE",otype); writeheader(shfd,"SIZE",sizes); if (*date) writeheader(shfd,"DATE",date); if (*attribute) writeheader(shfd,"ATTR",attribute); if (*sign) writeheader(shfd,"SIGN",sign); if (*comment) writeheader(shfd,"COMMENT",comment); if (*rpipe) writeheader(shfd,"DATA",""); close(shfd); } } /* tell the client to send data */ reply(302); /* read the file data in packet_size blocks */ /* and write it to the spool file */ if (transmitted) { if (lseek(sdfd,transmitted,SEEK_SET)!=transmitted) reply(490); } bytes=size-transmitted; nblocks=bytes/packet_size; transmitted=0; tt1=time(0); for (bn=1; bn<=nblocks; bn++) { alarm(timeout); /* check every 3 seconds if receiving files is currently disabled? */ tt2=time(0); if (tt2-tt1>2) { tt1=tt2; if (stat(SPOOL"/.nosendfile",&finfo)==0) reply(421); } if (readn(0,packet,packet_size)flist; flp!=NULL; flp=flp->next) { /* is it the same file? */ if (str_eq(filename,flp->fname) && (str_eq(date,flp->date) || !*date) && flags==flp->flags) { /* with same sizes? */ snprintf(MAXS(tmp),"%lld %lld",flp->csize,flp->osize); if (str_eq(tmp,sizes)) { /* number of bytes already transmitted */ transmitted=flp->tsize; break; } } } } } /* emulate reply(230) */ printf("230 %lld bytes have already been transmitted.\r\n",transmitted); fflush(stdout); continue; } /* VERSION command? */ if (str_eq(cmd,"VERSION")) { reply(215); continue; } /* COMMENT command? */ if (str_eq(cmd,"COMMENT")) { /* is there an argument for "COMMENT" command? */ if (*arg==0) { reply(505); continue; } strcpy(comment,arg); reply(200); continue; } /* insider joke :-) */ if (str_eq(cmd,"HOPPEL")) { reply(203); continue; } /* AUTH before ID? */ if (str_eq(cmd,"AUTH")) { reply(503); continue; } /* ID command? */ if (str_eq(cmd,"ID")) { auth=0; if (!fetchfile) { reply(502); continue; } /* is there an argument? */ if (*arg==0) { reply(505); continue; } /* too many arguments? */ if (strchr(arg,' ')) { reply(504); continue; } /* is pgp available? */ if (!whereis(pgp_bin)) reply(421); /* check the user's spool and get his uid/gid */ if (check_userspool(arg,userconfighome)<0 || chdir(userspool)<0) reply(410); srand(time(0)); challenge=rand(); printf("331 challenge: %d\r\n",challenge); fflush(stdout); /* get the next command line from the client, must be "auth" */ status=getcmd(cmd,arg); if (status<0) { notify_reply(¬ify,notification,sender,recipient,mailto,bell,221); exit(0); } if (!str_eq(cmd,"AUTH")) { reply(503); continue; } if (*arg==0) { reply(505); continue; } /* enable simple interrupt handler */ signal(SIGTERM,cleanexit); signal(SIGABRT,cleanexit); signal(SIGQUIT,cleanexit); signal(SIGHUP,cleanexit); signal(SIGINT,cleanexit); /* change effective uid and gid to recipient */ setreugid(); /* write challenge file */ snprintf(MAXS(chfile),"tmp_challenge_%d",(int)getpid()); outf=rfopen(chfile,"w"); if (!outf) reply(410); fprintf(outf,"%d",challenge); fclose(outf); /* write challenge signature file */ snprintf(MAXS(csfile),"tmp_challenge_%d.asc",(int)getpid()); unlink(csfile); outf=rfopen(csfile,"w"); if (!outf) { unlink(chfile); reply(410); } utf2iso(0,tmp,NULL,NULL,arg); fprintf(outf,"%s",tmp); fclose(outf); /* * pgp -kg +pubring=public.pgp +secring=private.pgp 512 * pgp -sbaf +clearsig=on +secring=private.pgp +pubring=private.pgp */ snprintf(MAXS(tmp),"%s +pubring=config/public.pgp %s %s 2>/dev/null", pgp_bin,csfile,chfile); pp=popen(tmp,"r"); if (!pp) { unlink(chfile); unlink(csfile); reply(421); } while (fgetl(line,pp)) if (str_beq(line,"Good signature")) auth=1; pclose(pp); unlink(chfile); unlink(csfile); if (auth) reply(200); else reply(530); seteuid(0); setegid(0); continue; } /* CONF command? */ if (str_eq(cmd,"CONF")) { if (!fetchfile) { reply(502); continue; } if (!auth) { reply(503); continue; } if (ruid==0) reply(430); /* correct arguments? */ if (!(cp=strchr(arg,' '))) { reply(505); continue; } *cp=0; str_toupper(arg); if (str_eq(arg,"READ")) wconf=0; else wconf=1; strcpy(filename,cp+1); if (!(str_eq(filename,"config") || str_eq(filename,"restrictions"))) { reply(507); continue; } /* change to user config directory */ snprintf(MAXS(tmp),"%s/config",userspool); if (chdir(tmp)<0) reply(410); /* change effective uid and gid to recipient */ setreugid(); /* write config file */ if (wconf) { reply(302); /* open config file for writimg */ if ((outf=rfopen(filename,"w"))) { /* read config data until EOT */ while (fgetl(line,stdin)) { if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strchr(line,'\r'))) *cp=0; if (str_eq(line,"\004")) break; fprintf(outf,"%s\n",line); } fclose(outf); } else reply(412); reply(201); } else { /* read config file */ /* open config file for reading */ if ((inf=rfopen(filename,"r"))) { /* read config data */ while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strchr(line,'\r'))) *cp=0; iso2utf(tmp,line); printf("250-%s\r\n",tmp); } reply(250); fclose(outf); } else reply(550); } seteuid(0); setegid(0); continue; } /* LIST command? */ if (str_eq(cmd,"LIST")) { if (!fetchfile) { reply(502); continue; } if (!auth) { reply(503); continue; } sls=scanspool(""); /* loop over sender list */ for (slp=sls; slp!=NULL; slp=slp->next) { /* loop over files list */ for (flp=slp->flist; flp!=NULL; flp=flp->next) { /* not complete? */ if (flp->csize!=flp->tsize) continue; iso2utf7(tmp,slp->from,0); printf("250-%d %s %s %lld ",flp->id,flp->fname,tmp,flp->csize); strftime(tmp,FLEN,"%Y-%m-%d+ACA-%H:%M:%S",localtime(&flp->rtime)); printf("%s\r\n",tmp); } } reply(250); continue; } /* GET command? */ if (str_eq(cmd,"GET")) { if (!fetchfile) { reply(502); continue; } if (!auth) { reply(503); continue; } str_toupper(arg); /* too few arguments? */ if (!(cp=strchr(arg,' '))) { reply(505); continue; } /* split arguments */ transmitted=0; *cp=0; cp++; id=atoi(cp); if ((cp=strchr(cp,' '))) { *cp=0; cp++; transmitted=atol(cp); } /* header requested? */ if (str_eq(arg,"HEADER")) { /* change effective uid and gid to recipient */ setreugid(); /* open header file */ snprintf(MAXS(shfile),"%d.h",id); if (!(inf=rfopen(shfile,"r"))) reply(550); /* read and transfer header file */ while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; /* if ((cp=strchr(line,'\t'))) *cp=' '; */ printf("250-%s\r\n",line); } fclose(inf); reply(250); seteuid(0); setegid(0); continue; } if (str_eq(arg,"FILE")) { /* change effective uid and gid to recipient */ setreugid(); /* open spool data file */ snprintf(MAXS(sdfile),"%d.d",id); if (stat(sdfile,&finfo)<0 || (infd=open(sdfile,O_RDONLY|O_LARGEFILE))<0) reply(550); if (transmitted>finfo.st_size) { reply(507); continue; } size=finfo.st_size-transmitted; printf("231 %lld bytes will follow.\r\n",size); fflush(stdout); if (size) { if (transmitted && lseek(infd,transmitted,SEEK_SET)<0) reply(451); if (send_file_stdout(infd)!=finfo.st_size) reply(415); } fflush(stdout); close(infd); seteuid(0); setegid(0); continue; } reply(501); continue; } /* start outgoing spool daemon */ if (str_eq(cmd,"START")) { /* is there an argument? */ if (*arg==0) { reply(505); continue; } str_toupper(arg); /* wrong argument? */ if (!str_eq(arg,"SPOOLDAEMON")) { reply(501); continue; } /* start outgoing spool daemon if allowed */ if (spooling==2 && *saftserver==0) { if (queue>=0) if (sfsd(queue,parallel,bounce,retry,mtp)<0) reply(453); queue=-1; reply(200); } else if (*saftserver) { printf("510 Your SAFT-server is: %s\r\n",saftserver); fflush(stdout); } else reply(502); continue; } /* log command for outgoing files */ if (str_eq(cmd,"LOG")) { /* arguments correct? */ if (*arg && (cp=strchr(arg,' '))) { *cp=0; utf2iso(0,sender,NULL,NULL,arg); strcpy(filename,cp+1); /* throw away untrusty path in filename */ if ((cp=strrchr(filename,'/'))) { strcpy(tmp,cp+1); strcpy(filename,tmp); } } else { reply(505); continue; } /* saftserver defined? */ if (*saftserver) { printf("510 Your SAFT-server is: %s\r\n",saftserver); fflush(stdout); continue; } /* check sender spool and log filename */ if (check_userspool(sender,userconfighome)<0) continue; if (ruid==0) { reply(504); continue; } if (chdir(userspool)<0 || access(filename,R_OK)<0) { reply(550); continue; } /* open user tmp log and global log */ infd=open(filename,O_RDONLY); outfd=open(OUTLOG,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR); if (infd<0 || outfd<0) reply(421); /* try to the lock the logfile */ if (wlock_file(sdfd)<0) { sleep(1); if (wlock_file(sdfd)<0) { sleep(1); if (wlock_file(sdfd)<0) reply(421); } } /* add header to empty log file */ stat(OUTLOG,&finfo); if (finfo.st_size==0) { strcpy(tmp,"# use utf7decode to view this file\n\n"); write(lfd,tmp,strlen(tmp)); } /* append user tmp log file to global log */ if ((bytes=read(infd,logdata,OVERSIZE))<0) reply(421); if (write(outfd,logdata,bytes)!=bytes) reply(421); close(infd); close(outfd); reply(200); continue; } /* for debugging purposes? */ if (str_eq(cmd,"DEBUG")) { str_toupper(arg); if (str_eq(arg,"FREE")) { off_t f = free_space(); if (f<0) printf("260 %s\r\n",strerror(errno)); else printf("260 %lld MB free\r\n",f); continue; } reply(501); continue; } /* QUIT command? */ if (str_eq(cmd,"QUIT")) { /* is there a pending notification request? */ notify_reply(¬ify,notification,sender,recipient,mailto,bell,221); exit(0); } /* unknown command or syntax error */ reply(500); } } /* * getaline - get a command line until LF * * INPUT: ptr - empty string * * OUTPUT: ptr - string containing the command line * * RETURN: number of read bytes, -1 on error */ int getaline(char *ptr) { int c, /* one character */ n, /* number of read bytes */ ctrl=0; /* flag for non-ASCII character */ ptr[0]=0; /* get max MAXLEN characters */ for (n=0; n13 && c<32) || c>126) { ctrl=1; n--; } else { /* copy the char into the command line string */ ptr[n]=c; /* check for EOL */ if (c=='\n') break; if (c=='\r') n--; } } /* input line overrun? */ if (n==MAXLEN-1 && ptr[n]!='\n') { /* read to next lf */ while (c!='\n') c=getchar(); n=0; reply(506); } else if (ctrl) reply(205); ptr[n]=0; /* trim all white spaces */ if (n) str_trim(ptr); return(strlen(ptr)); } /* * getcmd - get next SAFT command from client * * OUTPUT: cmd - SAFT command * arg - argument of SAFT command * * RETURN: status from getaline() */ int getcmd(char *cmd, char *arg) { int status; /* return value */ char *cp, /* simple char pointer */ line[MAXLEN]; /* incoming command line */ *cmd=0; *arg=0; status=0; while (status==0) status=getaline(line); if (status>0) { /* extract the command name and the argument */ strcpy(cmd,line); cp=strchr(cmd,' '); if (cp) { *cp=0; strcpy(arg,cp+1); } str_toupper(cmd); } return(status); } /* * writeheader - write one line of header information to log file * * INPUT: fd - file descriptor * attribute - name of the header attribute * value - contents of the header attribute */ void writeheader(int fd, const char *attribute, const char *value) { int hsize; /* header string size */ char header[2*MAXLEN]; /* header string */ snprintf(MAXS(header),"%s\t%s\n",attribute,value); hsize=strlen(header); if (write(fd,header,hsize)>> INFO <<< SAFT-Daemon has a new file for you!" "\n\nFrom: %s ( saft://%s/%s )\n\nType \"receive\".\n", sender,localhost,recipient); #else snprintf(msgh,MAXLEN-3, "%s has sent a file to you (%s@%s). Type \"receive\".", sender,recipient,localhost); #endif switch (*notification) { case 'b': mail2user(mailto,sender,msgh); case 't': if (strchr(mailto,'@')) { snprintf(msgh,MAXLEN-1,"new file from %s",sender); send_msg(msgh,mailto,recipient); } else { if (bell) strcat(msgh,"\007"); msg2tty(recipient,msgh,"",O_NONBLOCK); } break; case 'm': mail2user(mailto,sender,msgh); break; case '/': strcat(notification,">/dev/null 2>&1 &"); sudo(recipient,notification); } /* reset time out */ signal(SIGALRM,SIG_IGN); } } *notify=0; /* send reply if given */ if (replycode) reply(replycode); } /* * msg2tty - send a one line message to the recipient (tty(s) or FIFO) * * INPUT: recipient - recipient of the message * msgh - the message header * msg - the message * mode - non-blocking or synchronous mode * * RETURN: 0 if successfull, -1 if failed */ int msg2tty(const char *recipient, const char *msgh, char *msg, int mode) { char *cp, /* simple character pointer */ tty[FLEN], /* name of tty */ user[9], /* username */ output[MAXLEN], /* msgh+msg */ msgcf[MAXLEN]; /* message control file */ int wall, /* force writing to all ttys */ utmpfd, /* file descriptor for utmp */ mfd, /* message file descriptor */ success; /* return code */ struct utmp uinfo; /* information about a user */ struct stat finfo; /* information about a file */ FILE *inf; /* input file */ wall=0; success=0; user[8]=0; if (test) return(0); /* change effective uid to recipient for security reasons */ setreugid(); snprintf(MAXS(msgcf),"%s/config/tty@%s",userspool,localhost); /* force writing to all ttys which are open? */ if (*msg && str_beq(msg,"wall!")) { wall=1; msg=strchr(msg,'!')+1; } if (*msg) snprintf(MAXS(output),"\r\n%s\n\r%s\r\n",msgh,msg); else snprintf(MAXS(output),"\r\n%s\n\r",msgh); /* is there a message control file? */ if (!wall && success<=0 && (inf=rfopen(msgcf,"r"))) { /* read the tty name */ fgetl(tty,inf); if ((cp=strchr(tty,'\n'))) *cp=0; fclose(inf); /* belongs the tty to the recipient and is it writable? */ if (stat(tty,&finfo)==0 && finfo.st_uid==ruid && ((finfo.st_mode&S_IWOTH) || (finfo.st_mode&S_IWGRP))) { /* write to dedicated tty */ mfd=open(tty,O_WRONLY|mode); success=write(mfd,output,strlen(output)); close(mfd); } } /* no write success so far? */ if (success<=0) { success=0; /* search the utmp file (not standarisized, grrrr) */ utmpfd=open(_PATH_UTMP,O_RDONLY); if (utmpfd<0) utmpfd=open("/var/adm/utmp",O_RDONLY); if (utmpfd<0) utmpfd=open("/var/run/utmp",O_RDONLY); if (utmpfd<0) { seteuid(0); setegid(0); return(-1); } /* scan through utmp (currently logged in users) */ while (read(utmpfd,(char *)&uinfo,sizeof(uinfo))>0) { #if defined(NEXT) || defined(BSD) || defined(ULTRIX) || defined(SOLARIS1) strncpy(user,uinfo.ut_name,8); if (str_eq(recipient,user)) { #ifdef JEDPARSE } #endif #else strncpy(user,uinfo.ut_user,8); if (uinfo.ut_type==USER_PROCESS && str_eq(recipient,user)) { #endif /* get the tty */ snprintf(MAXS(tty),"/dev/%s",uinfo.ut_line); /* is the tty writeable? */ if (stat(tty,&finfo)==0 && ((finfo.st_mode&S_IWOTH) || (finfo.st_mode&S_IWGRP))) { mfd=open(tty,O_WRONLY|mode); /* write message to tty */ success=success | write(mfd,output,strlen(output)); close(mfd); } } } close(utmpfd); } /* reset uid to root */ seteuid(0); setegid(0); if (success>0) return(0); else return(-1); } /* * mail2user - send the recipient a mail in a subprocess * * INPUT: recipient - recipient of the mail * sender - sender of the file * msg - the message */ void mail2user(const char *recipient, const char *sender, const char *msg) { char *cp, /* simple character pointer */ line[MAXLEN], /* one text line */ cmd[MAXLEN]; /* command for pipe */ FILE *pin, /* input pipe */ *pout; /* output pipe */ struct passwd *pwe; /* password entry struct */ pid_t pid; /* security check: disallow superuser/group */ pwe=getpwuid(ruid); if (pwe==NULL || ruid==0 || rgid==0) return; /* spawn subprocess */ signal(SIGCHLD,SIG_IGN); pid=fork(); if (pid) return; /* change user */ /* note: setuid does not work if euid>0 ! STUPID! */ chdir(pwe->pw_dir); seteuid(0); setegid(0); if (setgid(rgid)<0) exit(1); initgroups(pwe->pw_name,pwe->pw_gid); if (setuid(ruid)<0) exit(1); /* strip off bell */ if ((cp=strchr(msg,7))) *cp=0; /* delete ' in sendername */ while ((cp=strchr(sender,'\''))) *cp=' '; /* open pipe to sendmail */ snprintf(MAXS(cmd),SENDMAIL" %s",recipient); pout=popen(cmd,"w"); /* fill out mail message */ if (pout) { /* fprintf(pout,"From: %s\n",recipient); */ fprintf(pout,"To: %s\n",recipient); fprintf(pout,"Subject: new file from %s\n\n",sender); /* try to open receive pipe */ pin=popen(RECEIVE" -l","r"); if (fgetl(line,pin)==NULL) { pclose(pin); pin=popen("receive -l","r"); if (fgetl(line,pin)==NULL) { pclose(pin); pin=popen("/client/bin/receive -l","r"); if (fgetl(line,pin)==NULL) { pclose(pin); pin=NULL; } } } /* add output from receive command, too */ if (pin) { fprintf(pout,"\n"); while (fgetl(line,pin)) fprintf(pout," %s",line); pclose(pin); } /* fprintf(pout,"\n\n"); fprintf(pout,"To get your file(s), do: rlogin saft.uni-hildesheim.de\n"); fprintf(pout,"and then type: receive\n"); */ fprintf(pout,".\n"); pclose(pout); } exit(0); } /* * restricted - check killfile * * INPUT: sender - sender name * recipient - local recipient * type - type of restriction: m(essage) or f(ile) * * RETURN: 1 if not allowed to send, 0 if allowed */ int restricted(const char *sender, const char *recipient, char type) { int m; char *cp, killfile[MAXLEN], kfu[MAXLEN], kfm[MAXLEN], line[MAXLEN], from[MAXLEN]; FILE *inf; if (test) return(0); setreugid(); snprintf(MAXS(killfile),"%s/config/restrictions",userspool); *kfm=*kfu=0; /* open and check killfile */ inf=rfopen(killfile,"r"); if (inf==NULL) return(0); strcpy(from,sender); if ((cp=strchr(from,' '))) *cp=0; while (fgetl(line,inf)) { line[MAXLEN-1]=0; sscanf(line,"%s%s",kfu,kfm); if (kfm[0]==0) m='b'; else m=tolower(kfm[0]); kfm[1]=0; if (simplematch(from,kfu,1) && (m==type || m=='b')) { fclose(inf); return(1); } } fclose(inf); return(0); } /* * mkrdir - make recursive directory * * INPUT: pathname - directory name * mode - permission mode bits * * RETURN: 0 if ok, else errorcode from mkdir(2) */ int mkrdir(const char *pathname, mode_t mode) { return 0; } /* * free_space - free disk space on spool device or directory * * RETURN: MBs of free disk space, -1 on error */ off_t free_space() { char spool[MAXLEN]; /* spool directory */ #ifdef ULTRIX struct fs_data fsinfo; /* information about the file system */ #else struct statfs fsinfo; /* information about the file system */ #endif if (*userspool) snprintf(MAXS(spool),"%s/.",userspool); else snprintf(MAXS(spool),"%s/.",SPOOL); #if defined(IRIX) || defined(IRIX64) if (statfs(spool,&fsinfo,sizeof(struct statfs),0)==0) return ((long)(fsinfo.f_bsize/1048576.0L*fsinfo.f_bfree)); #elif defined(ULTRIX) if (statfs(spool,&fsinfo)==0) return (((struct fs_data_req *)&fsinfo)->bfreen/1024); #elif defined(OSF1) if (statfs(spool,&fsinfo,sizeof(struct statfs))==0) return ((long)(fsinfo.f_bsize/1048576.0L*fsinfo.f_bavail)); #else if (statfs(spool,&fsinfo)==0) { #ifdef HAVE_SYS_STATVFS_H return ((long)(fsinfo.f_frsize/1048576.0L*fsinfo.f_bavail)); #else return ((long)(fsinfo.f_bsize/1048576.0L*fsinfo.f_bavail)); #endif } #endif return(-1); } /* * get_sizes - get the compressed and original file size * * INPUT: string - the sizes in one string * * OUTPUT: size - the compressed size * osize - the original size * * RETURN: 0 on success, reply-code on error */ int get_sizes(char *string, off_t *size, off_t *osize) { char max[FLEN], /* maximum file size allowed */ s1[MAXLEN], *s2; #ifdef RLIMIT_FSIZE struct rlimit rl; #endif /* this is 2**15-1 = max_signed_int32 */ strcpy(max,"2147483646"); strcpy(s1,string); /* get maximum file size for this process */ #ifdef RLIMIT_FSIZE if (getrlimit(RLIMIT_FSIZE,&rl)==0) snprintf(MAXS(max),"%llu",rl.rlim_cur); #endif /* get compressed and original file size string */ s2=strchr(s1,' '); if (!s2) return(501); *s2=0; s2++; /* more than maximum file size specified? */ if (strlen(s1)>strlen(max) || strlen(s2)>strlen(max) || (strlen(s1)==strlen(max) && strcmp(s1,max)>0) || (strlen(s2)==strlen(max) && strcmp(s2,max)>0)) return(453); /* return numeric compressed and original file size */ sscanf(s1,"%lld",size); sscanf(s2,"%lld",osize); return(0); } /* * send_msg - send a SAFT message to a remote server * * INPUT: msg - the message * to - user@host recipient * * RETURN: 0 on success, -1 on failure */ int send_msg(const char *msg, const char *to, const char *recipient) { int sockfd; /* socket file descriptor */ char *cp, /* simple char pointer */ user[FLEN], /* user name */ host[MAXLEN], /* host name */ tmp[MAXLEN], line[MAXLEN]; /* one line of text */ cp=strchr(to,'@'); if (cp) { *cp=0; snprintf(MAXS(user),"%s",to); snprintf(MAXS(host),"%s",cp+1); } else { snprintf(MAXS(user),"%s",to); strcpy(host,localhost); } #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection(host,SAFT); #else sockfd=open_connection(host,SERVICE); #endif if (sockfd<0) return(-1); /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) return(-1); /* snprintf(MAXS(tmp),"connected to %s",host); dbgout(tmp); */ snprintf(MAXS(line),"FROM %s autogenerated+ACA-SAFT+ACA-message",recipient); snprintf(MAXS(line),"FROM %s",recipient); sock_putline(sockfd,line); if (!str_beq(getreply(sockfd),"200 ")) { close(sockfd); return(-1); } snprintf(MAXS(line),"TO %s",user); sock_putline(sockfd,line); if (!str_beq(getreply(sockfd),"200 ")) { close(sockfd); return(-1); } iso2utf(tmp,(char*)msg); snprintf(MAXS(line),"MSG %s",tmp); sock_putline(sockfd,line); if (!str_beq(getreply(sockfd),"200 ")) { close(sockfd); return(-1); } sock_putline(sockfd,"QUIT"); getreply(sockfd); close(sockfd); return(0); } /* * sfsd - sendfile spool daemon * * INPUT: queue - flag for processing the outgoing spool queue * parallel - flag for multple spool daemons sending parallel * bounce - days after files are bounced to sender * retry - minutes to wait for retrying to deliver * mtp - maximum thruput * * RETURN: 1 if spool daemon started, 0 if a spool daemon is already running */ int sfsd(int queue, int parallel, int bounce, int retry, float mtp) { int lockf, /* lock file descriptor */ error, /* error flag */ sockfd, /* socket file descriptor */ sockfd2; /* 2nd socket file descriptor for forwards */ char *cp, /* simple char pointer */ *rs, /* reply string from the remote server */ *lockfn, /* lock file name */ errmsg[MAXLEN], /* error text from SAFT-connect */ tmp[MAXLEN], /* tmp string */ ahost[MAXLEN], /* alternate host to connect */ line[MAXLEN], /* incoming command line */ arecipient[MAXLEN], /* alternate recipient */ lrecipient[MAXLEN]; /* last recipient */ pid_t pid; /* process id */ struct hostlist *hls, /* host list start */ *hlp; /* host list pointer */ struct outfilelist *oflp; /* outgoing file list pointer */ FILE *inf; /* input file */ pid=-1; error=0; *errmsg=0; rs=""; lockfn=OUTGOING"/.lock"; if (retry<0) retry=10; if (bounce<=0) bounce=5; /* test outgoing spool */ if (chdir(OUTGOING)<0) { if (queue==1) message(prg,'F',OUTGOING); snprintf(MAXS(tmp),OUTGOING" : %s",strerror(errno)); dbgout(tmp); exit(1); } /* respect lock file when not in interactive mode */ if (queue!=1) { /* try to create lock file */ if ((lockf=open(lockfn,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) reply(421); /* try to set a lock */ if (wlock_file(lockf)<0) { /* lock failed -> sfsd is already running) */ close(lockf); return(1); } /* ignore exit status from child process */ signal(SIGCHLD,SIG_IGN); /* spawn subprocess */ pid=fork(); /* error? */ if (pid<0) return(-1); /* child process has no lock any more - this is STUPID! */ /* the parent process has to wait and check if the child relocks */ if (pid) { close(lockf); sleep(1); if ((lockf=open(lockfn,O_WRONLY,S_IRUSR|S_IWUSR))<0 || tlock_file(lockf)!=1) return(-1); else return(0); } /* this is the spool daemon child process */ /* relock */ unlink(lockfn); if ((lockf=open(lockfn,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) { snprintf(MAXS(tmp),"cannot open %s : %s",lockfn,strerror(errno)); dbgout(tmp); exit(1); } if (wlock_file(lockf)<0) { snprintf(MAXS(tmp),"cannot lock %s : %s",lockfn,strerror(errno)); dbgout(tmp); exit(1); } snprintf(MAXS(tmp),"%d\n",(int)getpid()); write(lockf,tmp,strlen(tmp)); /* disconnect from client */ setsid(); } /* set process name (argv[0]) */ /* does not work on all plattforms if ((int n=strlen(prg))>5) { for (int i=0;iflist; hlp=hlp->next) { /* ignore exit status from child process */ signal(SIGCHLD,SIG_IGN); pid=-1; /* fork an extra spool daemon if parallel option is set */ if (parallel) pid=fork(); if (!parallel || pid==0) { /* initiate the connection to the server host */ sockfd=saftserver_connect(hlp->host,errmsg); if (sockfd<0) { if (*errmsg) dbgout(errmsg); if (parallel) exit(0); continue; } snprintf(MAXS(tmp),"connected to %s",hlp->host); if (queue==1) message(prg,'I',tmp); dbgout(tmp); *lrecipient=0; /* process all files for this host */ for (oflp=hlp->flist; oflp; oflp=oflp->next) { error=0; *arecipient=0; /* goto next spool file if this one is not accessible */ if (!(inf=rfopen(oflp->oshfn,"r"))) continue; /* read the spool header file */ while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; /* check the TO line */ if (str_beq(line,"TO")) { if ((cp=strchr(line,'@'))) *cp=0; /* is this recipient the same as the last one (without forwarding)? */ strcpy(ahost,hlp->host); strcpy(arecipient,line+3); if (str_eq(arecipient,lrecipient)) continue; /* is there a forward address for this recipient? */ sock_putline(sockfd,line); error=check_forward(sockfd,arecipient,ahost,errmsg); /* recipient is not available */ if (error==-1) { fclose(inf); bounce_file(oflp->oshfn,errmsg); break; } /* forward address found */ if (error==1) { /* same host? */ if (str_eq(hlp->host,ahost)) { snprintf(MAXS(line),"TO %s",arecipient); sock_putline(sockfd,line); rs=getreply(sockfd); if (!str_beq(rs,"200")) { fclose(inf); break; } error=0; continue; } error=2; fclose(inf); /* try to connect to forward address */ if (parallel) if (fork()!=0) break; sockfd2=saft_connect("file",arecipient,oflp->from,ahost,errmsg); /* no connection? */ if (sockfd2<0) { if (parallel) exit(1); break; } snprintf(MAXS(tmp),"connected to %s (forward redirection)", hlp->host); if (queue==1) message(prg,'I',tmp); dbgout(tmp); /* reread spool header file and send it to the forward address */ if (!(inf=rfopen(oflp->oshfn,"r"))) { if (parallel) exit(1); sendcommand(sockfd2,"QUIT",NULL); shutdown(sockfd2,2); break; } while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; if (str_beq(line,"TO")) continue; /* TO line has been already sent */ sock_putline(sockfd2,line); rs=getreply(sockfd2); if (!str_beq(rs,"200") && !str_beq(rs,"202")) { error=1; break; } } fclose(inf); /* on error bounce back file */ if (error==1) { sendcommand(sockfd2,"QUIT",NULL); shutdown(sockfd2,2); bounce_file(oflp->oshfn,rs+4); if (parallel) exit(1); break; } /* send the spool data file */ error=send_spooldata(sockfd2,oflp->oshfn,oflp->from, oflp->to,hlp->host,oflp->fname, mtp,queue==1); sendcommand(sockfd2,"QUIT",NULL); shutdown(sockfd2,2); /* send mail on successful delivery */ if (!error) mail_report(ahost); /* return to normal spool processing */ if (parallel) exit(error); if (!error) error=2; /* forward address found and delivered */ break; } /* last recipient with no forward address */ strcpy(lrecipient,arecipient); } else { /* send header line (this is not the TO line!) */ sock_putline(sockfd,line); rs=getreply(sockfd); if (!str_beq(rs,"200") && !str_beq(rs,"202")) { error=1; break; } } } fclose(inf); /* on error bounce back file */ if (error==1) bounce_file(oflp->oshfn,rs+4); /* send the spool data file if there are no errors so far */ if (!error) send_spooldata(sockfd,oflp->oshfn,oflp->from, oflp->to,hlp->host,oflp->fname, mtp,queue==1); } /* all files are now sent for this destination */ sendcommand(sockfd,"QUIT",NULL); shutdown(sockfd,2); mail_report(hlp->host); if (pid==0) exit(0); } } /* check for expired files */ check_outspool(bounce); /* started with option -q ? */ if (queue==1) exit(0); sleep(retry*60); #ifdef deadcode /* handle child process termination and wait for next queue run */ t0=time(0); while ((ssec=t0-time(0)+retry*60)>0) { sigchld(); signal(SIGCHLD,sigchld); snprintf(MAXS(tmp),"sleep %d s",ssec); dbgout(tmp); sleep(ssec); } #endif } } /* * send_spooldata - send a file from the outgoing spool * * INPUT: sockfd - socket file descriptor * oshfn - outgoing spool header file * from - sender name * to - recipient name * host - server host * fname - original file name * mtp - maximum thruput * queue - process interactivly * * RETURN: 0 if ok, -1 on failure */ int send_spooldata(int sockfd, char *oshfn, char *from, char *to, char *host, char *fname, float mtp, int queue) { int status; /* return status from send_data */ char osdfn[MAXLEN], /* outgoing spool data file */ isoname[MAXLEN], /* filename in ISO Latin-1 */ tmp[MAXLEN], /* tmp string */ line[MAXLEN]; /* one text line */ struct stat finfo; /* information about a file */ FILE *mailf; /* mail file */ time_t timetick; /* unix time (in seconds) */ /* status report */ if (queue) { utf2iso(0,isoname,NULL,NULL,fname); snprintf(MAXS(tmp),"sending %s to %s",isoname,to); message(prg,'I',tmp); } snprintf(MAXS(tmp),"sending %s to %s@%s",fname,to,host); dbgout(tmp); strcpy(osdfn,oshfn); osdfn[strlen(osdfn)-1]='d'; if (stat(osdfn,&finfo)<0) { snprintf(MAXS(tmp),"cannot access %s",osdfn); dbgout(tmp); return(-1); } /* send file data and check return status */ status=send_data(sockfd,finfo.st_size,osdfn,"",osdfn,"",mtp,NULL); /* error? */ if (status<0) return(status); /* delete this file from outgoing spool */ unlink(oshfn); unlink(osdfn); /* write status log */ mkdir(SPOOL"/LOG",S_IRUSR|S_IWUSR|S_IXUSR); snprintf(MAXS(tmp),SPOOL"/LOG/%s:%s",from,host); if ((mailf=rfopen(tmp,"a"))) { chmod(tmp,S_IRUSR|S_IWUSR); snprintf(MAXS(tmp),"'%s' to %s",fname,to); utf2iso(1,line,NULL,NULL,tmp); timetick=time(0); strftime(tmp,21,DATEFORMAT,localtime(&timetick)); fprintf(mailf,"sending %s@%s at %s : ",line,host,tmp); if (status) fprintf(mailf,"already transmitted\n"); else fprintf(mailf,"ok\n"); fclose(mailf); } return(0); } #ifndef ENABLE_MULTIPROTOCOL /* * saftserver_connect - look for correct SAFT server and open connection * * INPUT: host - host to connect * * OUTPUT: host - connected host (may be different because of forward) * error - error string * * RETURN: socket file descriptor; -1 on error */ int saftserver_connect(char *host, char *error) { int port, /* tcp port to connect to */ status, /* status code */ sockfd, /* socket file descriptor */ hopcount; /* count for forwarding addresses */ char *colon, tmp[MAXLEN], /* temporary string */ server[MAXLEN], /* generic saft server */ line[MAXLEN]; /* one line of text */ port=SAFT; hopcount=0; *error=0; if ((colon=strrchr(host,':'))) { *colon=0; port=atoi(colon+1); } /* try to connect to the recipient's server */ for (hopcount=1; hopcount<11; hopcount++) { /* tell where to send to */ snprintf(MAXS(tmp),"opening connection to %s:%d",host,port); dbgout(tmp); /* initiate the connection to the server */ sockfd=open_connection(host,port); if (sockfd==-3 && port==SAFT) { snprintf(MAXS(server),"saft.%s",host); snprintf(MAXS(tmp),"opening connection to %s:%d",server,SAFT); dbgout(tmp); sockfd=open_connection(server,SAFT); switch (sockfd) { case -1: strcpy(error,"cannot create a network socket"); case -2: snprintf(error,MAXLEN-1,"cannot open connection to %s",server); case -3: snprintf(error,MAXLEN-1,"%s has no internet-address",server); } } else { switch (sockfd) { case -1: strcpy(error,"cannot create a network socket"); case -2: snprintf(error,MAXLEN-1,"cannot open connection to %s",host); case -3: snprintf(error,MAXLEN-1,"%s has no internet-address",host); } } if (sockfd<0) { dbgout(error); if (port!=SAFT) { if (colon) *colon=':'; return(-1); } } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { snprintf(error,MAXLEN-1,"No SAFT server on port %d at %s",port,host); dbgout(error); if (colon) *colon=':'; return(-1); } /* is there a forward set? */ sock_putline(sockfd,"FILE test"); status=check_forward(sockfd,tmp,host,error); if (status==-1) return(-1); if (status==1) { snprintf(MAXS(tmp),"forward points to %s",host); dbgout(tmp); colon=NULL; port=487; continue; } /* connection is successfull */ snprintf(MAXS(tmp),"connected to %s:%d",host,port); *error=0; dbgout(tmp); return(sockfd); } snprintf(error,MAXLEN-1,"maximum hopcount reached (forward loop?)"); dbgout(error); return(-1); } #else /* ENABLE_MULTIPROTOCOL */ /* * saftserver_connect - look for correct SAFT server and open connection * * INPUT: host - host to connect * * OUTPUT: host - connected host (may be different because of forward) * error - error string * * RETURN: socket file descriptor; -1 on error */ int saftserver_connect(char *host, char *error) { int status, /* status code */ sockfd, /* socket file descriptor */ hopcount; /* count for forwarding addresses */ char *service, /* tcp service/port to connect to */ *colon, tmp[MAXLEN], /* temporary string */ server[MAXLEN], /* generic saft server */ line[MAXLEN]; /* one line of text */ service = SERVICE; hopcount=0; *error=0; if ((colon=strrchr(host,':'))) { *colon=0; service = colon + 1; } /* try to connect to the recipient's server */ for (hopcount=1; hopcount<11; hopcount++) { /* tell where to send to */ snprintf(MAXS(tmp),"opening connection to %s:%s",host,service); dbgout(tmp); /* initiate the connection to the server */ sockfd=open_connection(host,service); if (sockfd==-3 && (strcasecmp(service, SERVICE) == 0 || strcmp(service, PORT_STRING) == 0)) { snprintf(MAXS(server),"saft.%s",host); snprintf(MAXS(tmp),"opening connection to %s:%s",server,SERVICE); dbgout(tmp); sockfd=open_connection(server,SERVICE); switch (sockfd) { case -1: strcpy(error,"cannot create a network socket"); case -2: snprintf(error,MAXLEN-1,"cannot open connection to %s",server); case -3: snprintf(error,MAXLEN-1,"%s has no internet-address",server); case -4: snprintf(error,MAXLEN-1,"out of memory"); } } else { switch (sockfd) { case -1: strcpy(error,"cannot create a network socket"); case -2: snprintf(error,MAXLEN-1,"cannot open connection to %s",host); case -3: snprintf(error,MAXLEN-1,"%s has no internet-address",host); case -4: snprintf(error,MAXLEN-1,"out of memory"); } } if (sockfd<0) { dbgout(error); if (strcasecmp(service, SERVICE) != 0 && strcmp(service, PORT_STRING) != 0) { if (colon) *colon=':'; return(-1); } } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { snprintf(error,MAXLEN-1,"No SAFT server on port %s at %s",service,host); dbgout(error); if (colon) *colon=':'; return(-1); } /* is there a forward set? */ sock_putline(sockfd,"FILE test"); status=check_forward(sockfd,tmp,host,error); if (status==-1) return(-1); if (status==1) { snprintf(MAXS(tmp),"forward points to %s",host); dbgout(tmp); colon=NULL; service = SERVICE; continue; } /* connection is successfull */ snprintf(MAXS(tmp),"connected to %s:%s",host,service); *error=0; dbgout(tmp); return(sockfd); } snprintf(error,MAXLEN-1,"maximum hopcount reached (forward loop?)"); dbgout(error); return(-1); } #endif /* ENABLE_MULTIPROTOCOL */ /* * mail_report - send a status report via mail to the local user * * INPUT: host - recipient host name * * RETURN: 0 if ok; -1 in failure */ int mail_report(const char *host) { char *cp, mailfn[FLEN], /* status log mail file name */ line[MAXLEN], /* incoming command line */ sender[MAXLEN], /* sender name */ tmp[MAXLEN]; /* tmp string */ FILE *mailf, /* mail file */ *pp; /* output pipe */ #ifdef NEXT FILE *dp; /* directory pipe */ #else struct dirent *dire; /* directory entry */ DIR *dp; /* directory pointer */ #endif /* look for status log files to send via mail */ if (chdir(SPOOL"/LOG")<0) return(-1); #ifdef NEXT /* stupid NeXT has a broken readdir(); this is a dirty workaround */ /* open LOG dir */ snprintf(MAXS(cmd),"ls *:%s 2>/dev/null",host); if ((dp=popen(cmd,"r")) == NULL) { exit(0); if (parallel) continue; } /* scan through LOG directory */ while (fgetl(mailfn,dp)) { if ((cp=strrchr(mailfn,'\n'))) *cp=0; #ifdef JEDPARSE } #endif #else /* open LOG dir */ dp=opendir("."); /* scan through LOG directory */ while ((dire=readdir(dp))) { strcpy(mailfn,dire->d_name); snprintf(MAXS(tmp),"*:%s",host); if (simplematch(mailfn,tmp,0)<1) continue; #endif mailf=rfopen(mailfn,"r"); if (!mailf) continue; strcpy(sender,mailfn); cp=strchr(sender,':'); *cp=0; /* open pipe to sendmail */ pp=popen(SENDMAIL" -t","w"); if (!pp) continue; /* fill out mail message */ fprintf(pp,"From: root\n"); fprintf(pp,"To: %s\n",sender); fprintf(pp,"Subject: sendfile spool daemon status report for %s\n\n", host); while (fgetl(line,mailf)) fprintf(pp,"%s",line); fprintf(pp,"\n.\n"); pclose(pp); fclose(mailf); unlink(mailfn); } #ifdef NEXT pclose(dp); #else closedir(dp); #endif return(0); } /* * sigchld - simple interrupt handler for SIGCHLD */ /* replaced by: signal(SIGCHLD,SIG_IGN); void sigchld() { #ifdef NEXT int status; wait(&status); #else waitpid(-1,NULL,WNOHANG); #endif return; } */ /* * check_outspool - check outgoing spool if there are expired files and * bounce them to the sender's incoming spool * * INPUT: bounce - number of days after file is expired */ void check_outspool(int bounce) { char tmp[MAXLEN], /* temporary string */ oshfn[FLEN]; /* outgoing spool header file name */ time_t timetick; /* unix time (in seconds) */ struct stat finfo; /* information about a file */ #ifdef NEXT FILE *pp; /* pipe */ #else struct dirent *dire; /* directory entry */ DIR *dp; /* directory pointer */ #endif timetick=time(0); if (chdir(OUTGOING)<0) return; /* mega stupid NeXT has broken readdir() */ #ifdef NEXT /* open spool dir */ if ((pp=popen("ls *.h 2>/dev/null","r")) == NULL) return; /* scan through spool directory */ while (fgetl(oshfn,pp)) { if ((cp=strrchr(oshfn,'\n'))) *cp=0; #ifdef JEDPARSE } #endif #else /* open spool dir */ if (!(dp=opendir("."))) return; /* scan through outgoing spool directory */ while ((dire=readdir(dp))) { /* ignore non-header files */ snprintf(MAXS(oshfn),"%s",dire->d_name); if (!str_eq(&oshfn[strlen(oshfn)-2],".h")) continue; #endif /* hier noch hinzufuegen: ungueltige Files nach outgoing/BAD schieben */ if (stat(oshfn,&finfo)<0) continue; /* spool time expired? */ if (timetick>finfo.st_mtime+bounce*DAYSEC) { snprintf(MAXS(tmp),"no connection within %d days",bounce); bounce_file(oshfn,tmp); } } #ifdef NEXT pclose(pp); #else closedir(dp); #endif } /* * bounce_file - bounce back a file from outgoing spool to the * sender's incoming spool * * INPUT: file - outgoing spool header file name * comment - comment to add * * RETURN: 0 on success, -1 on failure */ int bounce_file(char *file, char *comment) { int id; /* spool file id */ char *cp, /* simple character pointer */ *arg, /* the argument(s) of the header line */ cwd[MAXLEN], /* current working directory */ hline[MAXLEN], /* header line */ tmp[MAXLEN], /* temporary string */ shfn[MAXLEN], /* spool header file name */ sdfn[MAXLEN], /* spool data file name */ oshfn[MAXLEN], /* outgoing spool header file name */ osdfn[MAXLEN]; /* outgoing spool data file name */ FILE *inf, /* input file */ *outf; /* output file */ struct stat finfo; /* information about a file */ struct passwd *pwe; /* password entry struct */ struct utimbuf utb; /* binary time */ if ((cp=strrchr(file,'/'))) cp++; else cp=file; snprintf(MAXS(oshfn),OUTGOING"/%s",cp); snprintf(MAXS(osdfn),OUTGOING"/%s",cp); osdfn[strlen(osdfn)-1]='d'; if (stat(oshfn,&finfo)<0) return(-1); if (!getcwd(MAXS(cwd))) return(-1); /* get user name and spool directory */ if (!(pwe=getpwuid(finfo.st_uid))) return(-1); snprintf(MAXS(userspool),SPOOL"/%s",pwe->pw_name); /* create user spool directory if necessary */ if (mkdir(userspool,S_IRUSR|S_IWUSR|S_IXUSR)==0) chown(userspool,pwe->pw_uid,pwe->pw_gid); /* change uid and get user name */ if (setegid(finfo.st_gid)<0) exit(1); if (seteuid(finfo.st_uid)<0) exit(1); if (!(inf=rfopen(oshfn,"r")) || chdir(userspool)<0) { fclose(inf); seteuid(0); setegid(0); chdir(cwd); return(-1); } /* get next spool id */ id=spoolid(MAXLEN); if (id<=0 || id>MAXLEN) { fclose(inf); seteuid(0); setegid(0); chdir(cwd); return(-1); } /* set file names */ snprintf(MAXS(shfn),"%d.h",id); snprintf(MAXS(sdfn),"%d.d",id); if (!(outf=rfopen(shfn,"w"))) { fclose(inf); seteuid(0); setegid(0); chdir(cwd); return(-1); } /* copy header file */ while (fgetl(hline,inf)) { /* prepare the header line */ if ((cp=strchr(hline,'\n'))) *cp=0; cp=strchr(hline,'\t'); if (!cp) continue; arg=cp+1; *cp=0; /* ignore old COMMENT */ if (str_eq(hline,"COMMENT")) continue; /* add new bounce COMMENT */ if (str_eq(hline,"TO")) { snprintf(MAXS(tmp),"cannot sent to %s : %s",arg,comment); iso2utf(arg,tmp); fprintf(outf,"COMMENT\t%s\n",arg); continue; } /* add other header lines */ fprintf(outf,"%s\t%s\n",hline,arg); } fclose(inf); fclose(outf); /* copy spool data file */ if (fcopy(osdfn,sdfn,S_IRUSR|S_IWUSR)<0) { /* on failure delete new spool file */ unlink(shfn); unlink(sdfn); } else { /* on success delete outgoing spool file */ unlink(oshfn); unlink(osdfn); } /* set old time stamps */ utb.actime=utb.modtime=finfo.st_mtime; utime(shfn,&utb); utime(sdfn,&utb); seteuid(0); setegid(0); chdir(cwd); return(0); } /* * check_userspool - check if user is allowed to use sendfile and create the * user spool directories * * INPUT: user - user login name * * RETURN: 0 if ok, -1 if failed */ int check_userspool(char *user, int userconfighome) { int allowfound; /* flag if the allow file is not empty */ char *cp, /* simple character pointer */ tmp[MAXLEN], /* temporary string */ luser[MAXLEN]; /* check local user */ FILE #ifdef NEXT *pp, /* pipe stream */ #endif *inf; /* for various files */ struct passwd *pwe; /* password entry struct */ struct stat finfo; /* information about a file */ allowfound=0; if (test) return(-3); /* look in the sendfile allow file */ if ((inf=rfopen(ALLOW,"r"))) { while (fgetl(luser,inf)) { if ((cp=strchr(luser,'#'))) *cp=0; str_trim(luser); if (*luser) { allowfound=1; if (str_eq(luser,user)) break; } } fclose(inf); /* is the user not in the allow list? */ if (allowfound && !str_eq(luser,user)) { reply(521); *user=0; return(-1); } } /* look in the sendfile disallow file if the allow file does not exist */ if (!allowfound && (inf=rfopen(DENY,"r"))) { while (fgetl(luser,inf)) { if ((cp=strchr(luser,'#'))) *cp=0; str_trim(luser); /* is the user in the deny list? */ if (str_eq(luser,user)) { reply(521); *user=0; return(-1); } } fclose(inf); } if (test) { ruid=rgid=auth=0; strcpy(userspool,"."); *userconfig=0; return(0); } /* get user information */ pwe=NULL; #ifdef NEXT /* stupid NeXT has a broken getpwnam(); this is a dirty workaround */ snprintf(MAXS(tmp),"( nidump passwd . ; nidump passwd / ) | " "awk -F: '$1==\"%s\"{print $3,$4;exit}'",user); pp=popen(tmp,"r"); if (fgetl(tmp,pp) && *tmp!='\n' && *tmp!=0) { pwe=(struct passwd *) malloc(sizeof(struct passwd)); sscanf(tmp,"%d %d",&ruid,&rgid); pwe->pw_uid=ruid; pwe->pw_gid=rgid; } pclose(pp); #else pwe=getpwnam(user); #endif /* no such user? */ if (pwe==NULL) { reply(520); *user=0; return(-1); } /* going to change ruid/rgid, so reset auth flag */ auth=0; ruid=pwe->pw_uid; rgid=pwe->pw_gid; /* build user spool string */ user[32]=0; snprintf(MAXS(userspool),SPOOL"/%s",user); snprintf(MAXS(userconfig),"%s/config",userspool); /* create user spool directory for user */ if (mkdir(userspool,S_IRUSR|S_IWUSR|S_IXUSR)==0) chown(userspool,ruid,rgid); setreugid(); /* create user config directory in $HOME? */ if (stat(userconfig,&finfo)<0) { if (userconfighome) { snprintf(tmp,MAXLEN-8,"%s/.sendfile",pwe->pw_dir); mkdir(tmp,S_IRUSR|S_IWUSR|S_IXUSR); symlink(tmp,userconfig); strcat(tmp,"/spool"); symlink(userspool,tmp); } else mkdir(userconfig,S_IRUSR|S_IWUSR|S_IXUSR); } seteuid(0); setegid(0); return(0); } /* * copy2pipe - copy a file to a pipe descriptor * * INPUT: from - input file name * * OUTPUT: pfd - pipe descriptor * * RETURN: 0 on success, -1 on failure */ int copy2pipe(const char *from, int pfd) { int fdin; /* input file descriptor */ int bytes; /* read bytes */ int status; /* error status */ unsigned long blksize;/* file system block size */ char *buf; /* copy buffer */ struct stat finfo; /* information about a file */ status=0; /* open source file */ fdin=open(from,O_RDONLY|O_LARGEFILE,0); if (fdin<0) return(-1); /* get file system block size for copy operation */ stat(from,&finfo); #ifdef HAVE_ST_BLKSIZE blksize=finfo.st_blksize; #else blksize=1024; #endif /* ANSI C can not dynamicly allocate with buf[blksize] */ buf=(char *)malloc(blksize); if (!buf) return(-1); /* read until EOF */ while ((bytes=read(fdin,buf,blksize)) > 0) { /* write to destination file */ if (write(pfd,buf,bytes)<0) { /* write error */ status=-1; break; } } close(fdin); free(buf); return(status); } /* * openuserlog - open user log file * * INPUT: log - name of log file * * RETURN: log file descriptor * * Be sure to call this function with correct seteuid/setegid settings! */ int openuserlog(const char *log) { int n, /* simple loop counter */ lfd; /* log file descriptor */ char tmp[MAXLEN]; /* temporary string */ struct stat finfo; /* information about a file */ /* security check */ if (rgid!=getegid()) { if (setegid(rgid)<0) return(0); } if (ruid!=geteuid()) { if (seteuid(ruid)<0) return(0); } /* create logfile if not there */ close(open(log,O_CREAT|O_EXCL,S_IRUSR|S_IWUSR)); /* try several times to lock-write the logfile */ lfd=open(log,O_WRONLY|O_APPEND); for (n=1; n<5; n++) { if (wlock_file(lfd) >= 0) { /* add header to empty log file */ stat(log,&finfo); if (finfo.st_size==0) { strcpy(tmp,"# use utf7decode to view this file\n\n"); write(lfd,tmp,strlen(tmp)); } } return(lfd); } return(0); } /* * send_file_stdout - send a file to stdout * * INPUT: fd - file descriptor * * RETURN: number of transfered bytes, -1 if transfer failed */ int send_file_stdout(int fd) { int bytes; /* number of read bytes */ unsigned long tbytes; /* total number of bytes which has been sent */ char packet[OVERSIZE]; /* data packet to send */ /* fallback */ if (packet_size<1) packet_size=512; /* send the file data in packets */ bytes=0; tbytes=0; while ((bytes=read(fd,packet,packet_size))>0) { alarm(timeout); write(fileno(stdout),packet,bytes); tbytes+=bytes; } if (bytes<0) return(bytes); else return(tbytes); } /* * dbgout - write debug output * * INPUT: line - one line of text */ void dbgout(const char *line) { if (dbf) { fprintf(dbf,"(%d) >%s<\n",(int)getpid(),line); fflush(dbf); } } /* * cleanexit - clean termination routine * * A very simple interrupt handler */ void cleanexit() { /* ignore all relevant signals */ signal(SIGTERM,SIG_IGN); signal(SIGABRT,SIG_IGN); signal(SIGQUIT,SIG_IGN); signal(SIGHUP,SIG_IGN); signal(SIGINT,SIG_IGN); cleanup(); exit(0); } /* * timeoutexit - clean up after timeout */ void timeoutexit() { reply(429); cleanexit(); } /* * cleanup - delete tmp files */ void cleanup() { #ifndef DEBUG if (*chfile) unlink(chfile); if (*csfile) unlink(csfile); #endif } /* * setreugid - set effective uid and gid for recipient * * RETURN: nothing, but terminates program on error */ void setreugid() { if (rgid && setegid(rgid)<0) { printf("490 Internal error on setegid(%u): %s\r\n", (unsigned int)rgid,strerror(errno)); exit(1); } if (ruid && seteuid(ruid)<0) { printf("490 Internal error on seteuid(%u): %s\r\n", (unsigned int)ruid,strerror(errno)); exit(1); } } /* * sudo - emulate the shell su command: * execute a command in an async subprocess owned by another user * * INPUT: user - login name * cmd - shell command to execute * * RETURN: 0 on success, <0 on failure */ int sudo(const char *user, const char *cmd) { pid_t pid; char tmp[MAXLEN]; /* the command itself */ struct passwd *pwe; /* password entry struct */ /* get user name */ if (!(pwe=getpwnam(user))) return(-3); /* security check: disallow superuser/group */ if (pwe->pw_uid==0 || pwe->pw_gid==0) return(-2); /* spawn subprocess */ signal(SIGCHLD,SIG_IGN); pid=fork(); if (pid<0) return(-1); if (pid) {sleep(1); return(0);} /* change user */ /* note: setuid does not work if euid>0 ! STUPID! */ chdir(pwe->pw_dir); seteuid(0); setegid(0); if (setgid(pwe->pw_gid)<0) exit(1); initgroups(user,pwe->pw_gid); if (setuid(pwe->pw_uid)<0) exit(1); /* set some usefull environment variables */ snprintf(MAXS(tmp),"HOME=%s",pwe->pw_dir); putenv(tmp); snprintf(MAXS(tmp),"SHELL=%s",pwe->pw_shell); putenv(tmp); snprintf(MAXS(tmp),"USER=%s",user); putenv(tmp); snprintf(MAXS(tmp),"LOGNAME=%s",user); putenv(tmp); putenv("TERM="); /* call external program */ dbgout(cmd); system(cmd); exit(0); return(0); } /* * usage - print short help usage text */ int usage() { fprintf(stderr,"\n"); fprintf(stderr,"usage: %s [OPTIONS] (normally %s is called by inetd!)\n",prg,prg); fprintf(stderr,"options: -d debug mode on, output goes to %s\n",DBF); fprintf(stderr," -f print free space in MB on spool partition, then exit\n"); fprintf(stderr," -q process outgoing spool queue one time\n"); fprintf(stderr," -Q run as outgoing spool daemon\n"); fprintf(stderr," -c file alternate configuration file\n"); #ifdef ENABLE_MULTIPROTOCOL fprintf(stderr," -4 explicitly force ipv4 connections\n"); fprintf(stderr," -6 explicitly force ipv6 connections\n"); #endif fprintf(stderr,"see also: sfdconf\n"); return(2); } sendfile-2.1b/src/receive.c0000640000175100001440000015027211025466672015424 0ustar framstagusers/* * File: receive.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Christian Recktenwald (chris@yeti.faveve.uni-stuttgart.de) * Rainer Bawidamann (widi@sol.wohnheim.uni-ulm.de) * Beate Herrmann (beate@juhu.lake.de) * Stefan Zehl (sec@42.org) * Martin Schulze * * History: * * 1995-08-11 Framstag initial version * 1995-08-14 Framstag corrected bug when receiving archives * 1995-09-10 Framstag extracted functions to spool.c * 1995-10-31 Framstag fixed security problems * 1995-11-05 Framstag added NeXT support * 1995-11-07 Framstag corrected bug when receiving to * a non-writable directory * 1995-12-02 Framstag added rename option * 1996-01-15 Framstag better error handling * 1996-02-06 Framstag added ATTRIBUTE=EXE * 1996-02-07 Chris better Convex-OS support * 1996-02-21 widi better Solaris-2 support * 1996-02-22 Framstag added bounce (forward) option * 1996-03-06 Framstag moved time stamp setting to get_date * 1996-03-17 Framstag some bug fixes * 1996-03-27 Framstag added quiet mode: no questions asked * 1996-03-28 Framstag extended search for support programs * 1996-04-01 Framstag corrected forking bug * 1996-04-02 Framstag added verbose bouncing * 1996-04-04 Framstag added check for dangerous file names in archives * 1996-04-05 Framstag correction: 1 KB is now 1024 bytes * 1996-04-08 Framstag added question for renaming better dangerous * file name checking * 1996-04-12 Framstag added pgp support * 1996-04-13 Framstag added -f from option * 1996-04-13 Beate added -s list option * 1996-04-18 Framstag delete empty file when pgp fails * 1996-04-20 Framstag added preserve option for pgp and tar * added -k keep option * 1996-04-22 Framstag some code cleanup * 1996-04-23 Framstag moved fcopy to io.c * 1996-04-24 Framstag changed bouncing option syntax * 1996-05-02 Framstag better tar error checking * 1996-05-12 Framstag better checking of not complete files * 1996-05-23 Framstag added check for writeable tmp-files * 1996-05-26 Framstag fixed bug with overwriting links * fixed bug with returning from fork * 1996-06-24 Framstag added -P to stdout option * 1996-09-13 Framstag added rename option to "."-file checking * 1996-11-26 Framstag substituted all gets() with fgets() * 1996-11-27 Framstag corrected bug when receiving file is not * writable * 1996-12-01 Framstag better file name questioning * 1996-12-20 Framstag don't ask for directory overwriting * 1997-01-20 GNUish modified to reflect the GNUs needs * 1997-02-12 Framstag fixed boolean bugs in receive_sf * 1997-02-20 GNUish renamed error to error_log to support glibc * 1997-02-23 Framstag modified str_* function names * extended with TYPE=MIME * 1997-02-24 Framstag sprintf() -> snprintf() * 1997-06-23 Framstag added readline support * 1997-08-01 Framstag added -S secure option (signature check) * 1997-08-07 Framstag no tar-file checking with quiet-mode * 1997-08-27 Framstag ignore symlink errors when extracting tar files * 1997-09-21 Framstag added multi-spool support and -Z option * 1997-09-30 Framstag corrected list bug * 1997-10-06 Framstag corrected bug with -n -b options together * 1997-11-14 Framstag better verbose mode for system() calls * 1997-12-02 Framstag fixed -b -a conjunction bug * 1997-12-11 Framstag added bzip2 support * 1997-12-16 Sec better xhoppel support for BSD * 1998-03-11 Framstag added -H option to display the headers * 1998-05-10 Framstag added -R option to renumber the spool files * 1999-02-15 Framstag added check for dangerous symbolic links in * archive files * 1999-02-19 Framstag option -L with selecting arguments * 2001-01-10 Framstag fopen() ==> rfopen() * 2001-02-04 Framstag added secure mktmpdir() * 2002-08-04 Framstag moved spawn() to io.c * 2005-05-30 Framstag deactivated buggy symbolic links archive check * 2005-06-06 Framstag more correct exit status * 2005-06-07 Framstag fixed bug vanishing spool for root * 2007-01-05 Framstag fixed verbose mode flag bug (verbose ==> opt_v) * 2008-06-16 Joey prevent buffer overflow for getopt-strings * The receive client of the sendfile package. * Receives, lists and deletes files from the sendfile spool. * * Copyright © 1995-2008 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #ifdef ULTRIX #define S_IFMT 0170000 /* type of file */ #define S_IFDIR 0040000 /* directory */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "message.h" /* information, warning and error messages */ #include "utf7.h" /* UTF-7 coding */ #include "io.h" /* read/write routines */ #include "string.h" /* extended string functions */ #include "spool.h" /* operations on files in the sendfile spool */ #include "getline.h" /* get a line of text from stdin */ #include "lock.h" /* file locking */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #ifndef AIX #ifndef CONVEXOS FILE *popen(const char *, const char *); #endif int pclose(FILE *); #endif /* global variables */ char *lll, /* last list line */ *prg, /* name of the game */ *pgpvm, /* pgp verbose mode string */ *opt_v, /* verbose mode string on bouncing files */ *tmpdir, /* directory for temporary files */ error_log[MAXLEN], /* error log file */ tartmp[MAXLEN], /* tar temporary file */ fileslist[MAXLEN], /* files list from tar */ userspool[MAXLEN], /* user spool directory */ pgp_bin[MAXLEN], /* the pgp binary */ tar_bin[MAXLEN], /* the tar binary */ gzip_bin[MAXLEN], /* the gzip binary */ bzip2_bin[MAXLEN], /* the bzip2 binary */ recode_bin[MAXLEN], /* the recode binary */ metamail_bin[MAXLEN]; /* the metamail binary */ int keep=0, /* flag for keeping files in spool */ pipeout=0, /* flag for receiving to stdout (via pipe) */ quiet=0, /* quiet mode: no questions asked */ xonf=1, /* exit on fatalerror flag */ client=1, /* flag to determine client or server */ ren=0, /* flag for renaming files */ verbose=0, /* verbose mode flag */ pgppass=0, /* flag if the pgp password is set as an env variable */ preserve=0, /* preserve pgp and tar attributes */ nometamail=0; /* metamail-usage flag */ mode_t cmask; /* umask value */ /* clean termination routine */ void cleanexit(); /* delete tmp-file */ void cleanup(); /* print short help usage text */ int usage(void); /* list all spool files */ int list(struct senderlist *, int, char *, char *, int, int, char **); /* receive a spool file */ void receive_sf(struct filelist *, char *, int); /* check what to do when file with same name already exists */ int checkfile(int, char *, char *, char *, char *); /* create detached pgp signature file */ int create_sigfile(const char *, const char *, const char *, char *); /* translate NVT format file to Unix text format file */ void crlf2lf(FILE *, FILE *, const char *, const char *); /* shameless plug from GNU fileutils (getdate.c) :-) */ time_t get_date(char *, void *); /* check or print pgp signature */ int check_signature(struct filelist *, char *, int); /* renumber spool files */ void renumber(struct senderlist *); int main(int argc, char *argv[]) { int i, /* simple loop count */ status, /* exit status */ number, /* flag for specifying a spool file number */ listformat, /* format of listing */ del, /* flag for deleting */ all, /* flag for receiving all */ header, /* flag for receiving only the header (to stdout) */ id, /* spool id */ found, /* flag for found spool id */ opt; /* option to test for */ char *cp, /* a simple string pointer */ bounce[FLEN], /* bounce address */ from[FLEN], /* from which sender */ pgpring[FLEN], /* flag for receiveing only signed files */ tmp[3*MAXLEN], /* temporary string */ fname[MAXLEN], /* displayble file name */ bouncelist[MAXLEN], /* list of spool files to bounce */ pattern[MAXLEN]; /* file name pattern to search for */ struct stat finfo; /* information about a file */ struct passwd *pwe; /* password entry */ struct filelist *flp; /* file list pointer */ struct senderlist *sls, /* sender list start */ *slp; /* sender list pointer */ FILE *inf; del=0; all=0; found=0; status=0; number=0; header=0; listformat=0; lll=""; opt_v=""; *bounce=0; *pgpring=0; *userspool=0; *bouncelist=0; strcpy(from,"*"); cmask=umask(0); umask(cmask); /* get program name */ prg=argv[0]; if ((cp=strrchr(prg,'/'))) prg=cp+1; /* get pgp password environment variable */ if (getenv("PGPPASS")) { pgppass=1; pgpvm="+verbose=0"; } else { pgppass=0; pgpvm="+verbose=1"; } /* get metamail usage environment variable */ if (getenv("NOMETAMAIL")) nometamail=1; /* scan the command line */ while ((opt=getopt(argc,argv,"h?lLsndarRVvqpkHPS:f:Z:b:")) > 0) { switch (opt) { case ':': case 'h': case '?': exit(usage()); case 's': listformat=1; break; case 'l': listformat=2; break; case 'L': listformat=3; break; case 'n': number=1; break; case 'r': ren=1; break; case 'R': ren=2; break; case 'd': del=1; break; case 'a': all=1; break; case 'P': pipeout=1; break; case 'k': keep=1; break; case 'q': quiet=1; break; case 'p': preserve=1; break; case 'H': header=1; break; case 'S': snprintf(MAXS(pgpring),"%s",optarg); break; case 'v': opt_v="-v"; verbose=1; break; case 'f': snprintf(MAXS(from),"%s",optarg); break; case 'b': snprintf(MAXS(bounce),"%s",optarg); break; case 'Z': snprintf(MAXS(userspool),"%s",optarg); break; case 'V': message(prg,'I',"version "VERSION" revision "REVISION""); exit(0); } } /* no arguments? */ if (optind==argc && !all && !listformat) { listformat=2; lll="Type \"receive -a\" to receive all files or \"receive -h\" " "for a short help.\n\n"; } /* too few arguments? */ if ((argc-optind==0 && !all && ren<2 && (ren || del || (!str_eq(from,"*") && !listformat))) || (argc-optind>0 && ((*bounce && all) || ren==2)) || (argc-optind<1 && *bounce && !all)) exit(usage()); /* get the own user name */ if ((pwe=getpwuid(getuid())) == NULL) message(prg,'F',"cannot determine own user name"); /* determine the spool directory */ if (!*userspool) { if ((cp=getenv("SF_SPOOL"))) { snprintf(MAXS(userspool),"%s",cp); } else { snprintf(MAXS(userspool),"%s/.sfspool",pwe->pw_dir); if (stat(userspool,&finfo)<0 || !(finfo.st_mode&S_IFDIR)) snprintf(MAXS(userspool),SPOOL"/%s",pwe->pw_name); } } if (*userspool=='Z') snprintf(MAXS(userspool),SPOOL"/%s",pwe->pw_name); /* does the spool directory exist? */ if (stat(userspool,&finfo)<0 || (finfo.st_mode&S_IFMT)!=S_IFDIR) { snprintf(MAXS(tmp),"spool directory %s does not exist",userspool); errno=0; message(prg,'E',tmp); exit(1); } /* correct permissions for the spool directory? */ if (!(finfo.st_mode&S_IRWXU) || finfo.st_uid!=getuid()) { snprintf(MAXS(tmp), "no access to spool directory %s (wrong permissions)", userspool); errno=0; message(prg,'F',tmp); exit(1); } /* are there any files to receive? */ sls=scanspool(from); if (sls==NULL) { snprintf(MAXS(tmp),"no files found in spool directory %s",userspool); message(prg,'W',tmp); exit(1); } if (ren==2) { renumber(sls); sls=scanspool(""); } /* set log file read status (st_atime) for xhoppel */ snprintf(MAXS(tmp),"%s/log",userspool); inf=rfopen(tmp,"r"); if (inf) { fgetl(tmp,inf); fclose(inf); } /* incompatible options? */ if (*bounce) { if (listformat||ren||del||preserve) message(prg,'W',"you cannot use any other option " "when bouncing a file - ignored"); listformat=ren=del=0; } if (!str_eq(from,"*") && number) message(prg,'W',"ignoring -f option when specifying a spool number"); if (del&&keep) message(prg,'F',"you cannot delete and keep a file at the same time"); /* support programs defaults */ memset(pgp_bin,0,sizeof(pgp_bin)); memset(tar_bin,0,sizeof(tar_bin)); memset(gzip_bin,0,sizeof(gzip_bin)); memset(bzip2_bin,0,sizeof(bzip2_bin)); memset(recode_bin,0,sizeof(recode_bin)); memset(metamail_bin,0,sizeof(metamail_bin)); strcpy(pgp_bin,PGP); strcpy(tar_bin,TAR); strcpy(gzip_bin,GZIP); strcpy(bzip2_bin,BZIP2); strcpy(recode_bin,RECODE); strcpy(metamail_bin,RECODE); /* look for environment variables */ if ((cp=getenv("SF_PGP"))) strncpy(pgp_bin,cp,sizeof(pgp_bin)-1); if ((cp=getenv("SF_TAR"))) strncpy(tar_bin,cp,sizeof(tar_bin)-1); if ((cp=getenv("SF_GZIP"))) strncpy(gzip_bin,cp,sizeof(gzip_bin)-1); if ((cp=getenv("SF_BZIP2"))) strncpy(bzip2_bin,cp,sizeof(bzip2_bin)-1); if ((cp=getenv("SF_RECODE"))) strncpy(recode_bin,cp,sizeof(recode_bin)-1); if ((cp=getenv("SF_METAMAIL"))) strncpy(metamail_bin,cp,sizeof(metamail_bin)-1); /* do the support programs really exist? */ if (access(pgp_bin,X_OK)<0) strcpy(pgp_bin,"pgp"); if (access(tar_bin,X_OK)<0) strcpy(tar_bin,"tar"); if (access(gzip_bin,X_OK)<0) strcpy(gzip_bin,"gzip"); if (access(bzip2_bin,X_OK)<0) strcpy(bzip2_bin,"bzip2"); if (access(recode_bin,X_OK)<0) strcpy(recode_bin,"recode"); if (access(metamail_bin,X_OK)<0) strcpy(metamail_bin,"metamail"); /* enable simple interrupt handler */ signal(SIGTERM,cleanexit); signal(SIGABRT,cleanexit); signal(SIGQUIT,cleanexit); signal(SIGHUP,cleanexit); signal(SIGINT,cleanexit); /* set tmp file names */ tmpdir=mktmpdir(strlen(opt_v)); snprintf(MAXS(tartmp),"%s/receive.tar",tmpdir); snprintf(MAXS(fileslist),"%s/files",tmpdir); snprintf(MAXS(error_log),"%s/error.log",tmpdir); /* list files? */ if (listformat) { if (list(sls,listformat,from,pgpring,number,argc,argv)<0) { snprintf(MAXS(tmp),"no files in spool directory %s",userspool); message(prg,'W',tmp); } cleanup(); exit(0); } /* number specified? */ if (number) { /* loop over all args */ for (i=optind; inext) { /* loop over files list */ for (flp=slp->flist; flp!=NULL && found==0; flp=flp->next) { /* spool id found and spool file complete? */ if (flp->id==id && flp->csize==flp->tsize) { /* delete, bounce or receive spool file? */ if (del) delete_sf(flp,1); else if (*bounce) { if (*bouncelist) { snprintf(MAXS(tmp),"%s %d",bouncelist,id); strcpy(bouncelist,tmp); } else { snprintf(MAXS(bouncelist),"%d",id); } } else { receive_sf(flp,pgpring,header); } found=1; } } } /* not found? */ if (!found && id) { snprintf(MAXS(tmp),"spool file #%d not found",id); message(prg,'W',tmp); status=1; } } } else /* file name specified */ { /* loop over all args */ for (i=optind; inext) { /* loop over files list */ for (flp=slp->flist; flp!=NULL; flp=flp->next) { /* spool file incomplete? */ if (flp->csize!=flp->tsize) continue; /* translate UTF-7 name to the displayable file name */ utf2iso(1,NULL,fname,NULL,flp->fname); /* match? */ if (simplematch(fname,pattern,0)==1) { /* delete, bounce or receive spool file? */ if (del) delete_sf(flp,1); else if (*bounce) { if (*bouncelist) { snprintf(MAXS(tmp),"%s %d",bouncelist,flp->id); strcpy(bouncelist,tmp); } else snprintf(MAXS(bouncelist),"%d",flp->id); } else receive_sf(flp,pgpring,header); found=1; } } } /* not found? */ if (!found && !all) { snprintf(MAXS(tmp),"file %s not found",pattern); message(prg,'W',tmp); status=1; } all=0; } } /* files to bounce? */ if (*bounce && *bouncelist) { if (keep) snprintf(MAXS(tmp), "sendfile -bk=y %s %s %s",opt_v,bouncelist,bounce); else snprintf(MAXS(tmp), "sendfile -bk=n %s %s %s",opt_v,bouncelist,bounce); vsystem(tmp); } cleanup(); exit(status); } /* * list - list spool files with attributes * * INPUT: sls - sender list start * format - format of listing * from - select from user * pgpring - pgp ring file * number - getopt number flag * argc - from main() * argv - from main() * * RETURN: 0 if files found, -1 if no files to list */ int list(struct senderlist *sls, int format, char *from, char *pgpring, int number, int argc, char *argv[]) { int i, /* simple loop counter */ found, /* flag for files found */ mff, /* matching file flag */ fff; /* first file flag */ char *cp1,*cp2, /* simple character pointer */ line[MAXLEN], /* line to read in */ showtar[MAXLEN], /* shell command to look inside tar archive */ show_fname[MAXLEN]; /* file name to display */ struct senderlist *slp; /* sender list pointer */ struct filelist *flp; /* file list pointer */ FILE *pp; /* pipe input stream */ found=0; /* loop over sender list */ for (slp=sls; slp!=NULL; slp=slp->next) { /* match this sender? */ if (simplematch(slp->from,from,1)==1) { /* loop over files list */ for (flp=slp->flist,fff=1; flp!=NULL; flp=flp->next) { /* file not completly transfered? */ if (flp->csize!=flp->tsize) continue; /* wanted by CLI options? */ if (optindid) { mff = 1; break; } } else { if (simplematch(flp->fname,argv[i],0)==1) { mff = 1; break; } } } /* file is not selected by the user, try next one */ if (!mff) continue; } if (!found && format>1) printf("\nFiles in spool directory %s :\n",userspool); found=1; /* first file from this sender? */ if (fff) { fff=0; /* print from header */ printf("\nFrom %s\n",slp->from); for (i=1; i<80 && i<=strlen(slp->from)+5; i++) printf("-"); printf("\n"); } /* print spool file informations */ utf2iso(1,NULL,show_fname,NULL,flp->fname); printf("%3d) %s %9lld kB %s", flp->id,flp->rdate,(flp->osize+1023)/1024,show_fname); if (format>1) { /* tar archive, MIME file or encrypted? */ if (flp->flags&F_TAR && flp->flags&F_CRYPT) printf(" (archive,encrypted)"); else if (flp->flags&F_MIME && flp->flags&F_CRYPT) printf(" (MIME,encrypted)"); else if (flp->flags&F_MIME) printf(" (MIME)"); else if (flp->flags&F_TAR) printf(" (archive)"); else if (flp->flags&F_CRYPT) printf(" (encrypted)"); } printf("\n"); /* check signature */ if (*(flp->sign) && format>1) check_signature(flp,pgpring,1); /* comment available? */ cp1=flp->comment; if (*cp1 && format>1) { while ((cp2=strchr(cp1,'\n'))) { *cp2=0; printf(" \"%s\"\n",cp1); cp1=cp2+1; } printf(" \"%s\"\n",cp1); } /* on verbose mode look inside tar */ if (flp->flags&F_TAR && format==3 && !(flp->flags&F_CRYPT && (quiet || preserve) && !pgppass)) { /* encrypted, compressed or normal tar file? */ if (flp->flags&F_CRYPT) snprintf(MAXS(showtar),"%s %s -f < %s/%d.d | %s tvf -", pgp_bin,pgpvm,userspool,flp->id,tar_bin); else if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(showtar),"%s -d < %s/%d.d | %s tvf -", bzip2_bin,userspool,flp->id,tar_bin); else snprintf(MAXS(showtar),"%s -d < %s/%d.d | %s tvf -", gzip_bin,userspool,flp->id,tar_bin); } else { snprintf(MAXS(showtar),"%s tvf %s/%d.d",tar_bin,userspool,flp->id); } /* sneak inside... */ if ((pp=vpopen(showtar,"r")) == NULL) message(prg,'E',"contents of archive is not accessible"); else { if (flp->flags&F_CRYPT && !pgppass && fgetl(line,pp)) printf("\n\n %s",line); while (fgetl(line,pp)) printf(" %s",line); if (flp->flags&F_CRYPT && !pgppass) printf("\n"); } pclose(pp); } } } } if (found) { printf("\n%s",lll); return(0); } else return(-1); } /* * receive_sf - receive a spool file * * INPUT: flp - file list element * pgpring - pgp ring file (force pgp signature checking) * header - flag for receiving onnly the header to stdout */ void receive_sf(struct filelist *flp, char *pgpring, int header) { int utf, /* return code from utf2iso */ terr, /* tar error flag */ tom; /* tar overwrite message flag */ char *cp, /* simple character pointer */ *sad[10], /* spawn argument descriptor */ answer[FLEN], /* answer string */ line[MAXLEN], /* one line of text */ tmp[2*MAXLEN], /* temporary string */ tmpfile[MAXLEN], /* temporary file name */ cmd[2*MAXLEN], /* command string for system() */ sfile[MAXLEN], /* spool data file */ danger[OVERSIZE], /* dangerous file names */ fname[MAXLEN], /* file name to write */ nname[MAXLEN], /* file name in display format */ sname[MAXLEN]; /* file name in shell handling format */ static char overwrite='n'; /* overwrite mode */ struct stat finfo; /* information about a file */ struct utimbuf utb; /* binary time */ time_t dummy; /* dummy arg for localtime() */ FILE *pp, /* pipe input stream */ *inf, /* spool data file to read */ *outf; /* file to create */ /* oops? */ if (flp==NULL) return; tom=0; terr=0; *danger=0; *answer=0; unlink(error_log); unlink(tartmp); /* translate UTF-7 file name */ utf=utf2iso(1,fname,nname,sname,flp->fname); fname[FLEN-1]=nname[FLEN-1]=sname[FLEN-1]=0; if (*pgpring) { switch (check_signature(flp,pgpring,0)) { case 1: break; case 0: snprintf(MAXS(tmp),"no signature found for '%s'",nname); errno=0; message(prg,'E',tmp); return; case -1: snprintf(MAXS(tmp),"no public key found to check " "signature for '%s'",nname); errno=0; message(prg,'E',tmp); return; case -2: snprintf(MAXS(tmp),"bad signature for '%s'",nname); errno=0; message(prg,'E',tmp); return; default: return; } } /* determine overwrite mode */ if (quiet) overwrite='Y'; if (!strchr("YNS",overwrite)) overwrite='n'; (void) localtime(&dummy); /* show only the header? */ if (header) { snprintf(MAXS(tmp),"%s/%d.h",userspool,flp->id); printf("%d) %s\n",flp->id,nname); inf=rfopen(tmp,"r"); while (fgetl(line,inf)) printf("%s",line); printf("\n"); fclose(inf); return; } /* pipe to stdout? */ if (pipeout) { /* encrypted spool file? */ if (flp->flags&F_CRYPT) { snprintf(MAXS(cmd),"%s %s -f < %s/%d.d",pgp_bin,pgpvm,userspool,flp->id); if (vsystem(cmd)!=0) { errno=0; snprintf(MAXS(tmp),"cannot decrypt '%s' :",nname); message(prg,'E',tmp); return; } } /* compressed spool file? */ else if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(cmd),"%s -d < %s/%d.d",bzip2_bin,userspool,flp->id); else snprintf(MAXS(cmd),"%s -d < %s/%d.d",gzip_bin,userspool,flp->id); if (vsystem(cmd)!=0 && !(flp->flags&F_TAR)) { errno=0; snprintf(MAXS(tmp),"cannot decompress '%s' :",nname); message(prg,'E',tmp); return; } } else /* copy spool file to stdout */ { /* copy file */ snprintf(MAXS(tmp),"%s/%d.d",userspool,flp->id); if (fcopy(tmp,"",0)<0) { errno=0; snprintf(MAXS(tmp),"cannot read '%s'",nname); message(prg,'E',tmp); return; } } /* delete tar spool file if required */ if (!keep) delete_sf(flp,0); return; } /* tar file to receive? */ if (flp->flags&F_TAR) { /* save file in transfer shape? */ if (preserve) { /* set new file name */ fname[FLEN-12]=nname[FLEN-12]=sname[FLEN-12]=0; strcat(fname,".tar"); strcat(nname,".tar"); strcat(sname,".tar"); if (flp->flags&F_COMPRESS) { strcat(fname,".gz"); strcat(nname,".gz"); strcat(sname,".gz"); } if (flp->flags&F_CRYPT) { strcat(fname,".pgp"); strcat(nname,".pgp"); strcat(sname,".pgp"); } /* if file with same name already exists check what to do */ if (!quiet && checkfile(utf,fname,nname,sname,&overwrite)) return; /* copy file */ snprintf(MAXS(tmp),"%s/%d.d",userspool,flp->id); if (fcopy(tmp,fname,0666&~cmask)<0) { snprintf(MAXS(tmp),"cannot receive '%s'",nname); errno=0; message(prg,'E',tmp); return; } /* pgp signature to save? */ create_sigfile(flp->sign,fname,nname,&overwrite); if (!keep) delete_sf(flp,0); snprintf(MAXS(tmp),"'%s' received",nname); message(prg,'I',tmp); return; } /* encrypted tar spool file? */ if (flp->flags&F_CRYPT) { snprintf(MAXS(cmd),"%s %s -f < %s/%d.d > %s", pgp_bin,pgpvm,userspool,flp->id,tartmp); /* create temporary decrypted tar file */ vsystem(cmd); if (stat(tartmp,&finfo)<0 || finfo.st_size==0) { errno=0; snprintf(MAXS(tmp),"cannot decrypt '%s' :",nname); message(prg,'E',tmp); return; } if (!pgppass) printf("\n\n"); } /* test on (dangerous) symbolic links in tar file */ if (!(outf=rfopen(fileslist,"w"))) { message(prg,'E',"cannot open temporary fileslist file for writing"); return; } /* deactived symlink check - does not work with foreign tar */ #if DEADCODE /* compressed, encrypted or normal tar file? */ if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s tvf -", bzip2_bin,userspool,flp->id,tar_bin); else snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s tvf -", gzip_bin,userspool,flp->id,tar_bin); } else if (flp->flags&F_CRYPT) { snprintf(MAXS(cmd),"%s tvf %s",tar_bin,tartmp); } else { snprintf(MAXS(cmd),"%s tvf %s/%d.d",tar_bin,userspool,flp->id); } /* open pipe to read tar file-info */ if ((pp=vpopen(cmd,"r")) == NULL) { message(prg,'E',"cannot open spool file for reading"); return; } /* loop over all files in tar archive */ while (fgetl(line,pp)) { if ((cp=strchr(line,'\n'))) *cp=0; /* is it a (dangerous) symbolic link? */ if (*line == 'l') { fprintf(outf,"%s\n",line); } } pclose(pp); #endif /* test on dangerous file names in tar file */ /* compressed, encrypted or normal tar file? */ if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s tf -", bzip2_bin,userspool,flp->id,tar_bin); else snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s tf -", gzip_bin,userspool,flp->id,tar_bin); } else if (flp->flags&F_CRYPT) { snprintf(MAXS(cmd),"%s tf %s",tar_bin,tartmp); } else { snprintf(MAXS(cmd),"%s tf %s/%d.d",tar_bin,userspool,flp->id); } /* open pipe to read tar file-info */ if ((pp=vpopen(cmd,"r")) == NULL) { message(prg,'E',"cannot open spool file for reading"); return; } /* loop over all files in tar archive */ while (fgetl(line,pp)) { /* convert tar file name with escaped chars */ sprintf(fname,line); /* does the file already exist? */ if ((cp=strchr(fname,'\n'))) *cp=0; if (overwrite!='Y' && stat(fname,&finfo)==0 && !S_ISDIR(finfo.st_mode)) { if (!tom) printf("Archive '%s' will overwrite:\n",nname); tom=1; printf(" %s\n",fname); } /* is it a dangerous file name? */ if (strstr(fname," -> ") || strstr(fname," symbolic link ") || strstr(fname,"../") || strstr(fname,"/.") || fname[0]=='/' || (fname[0]=='.' && fname[1]!='/')) { fprintf(outf,"%s\n",fname); } } pclose(pp); fclose(outf); /* ask user for overwriting */ if (tom && overwrite!='Y') { printf("Overwrite (yn)? "); fgetl(answer,stdin); overwrite=answer[0]; if (toupper(overwrite)!='Y') return; } /* ask user for extracting dangerous files */ if (*danger && overwrite!='Y') { if ((inf=rfopen(fileslist,"r"))) { printf("Archive contains files with dangerous names:\n"); while (fgetl(line,inf)) printf(" %s",line); fclose(inf); printf("Continue with receiving (yn)? "); fgetl(tmp,stdin); overwrite=tmp[0]; if (toupper(overwrite)!='Y') return; } else { message(prg,'E',"cannot open temporary fileslist file for reading"); return; } } /* receive from tar file */ snprintf(MAXS(tmp),"receiving from archive '%s' :",nname); message(prg,'I',tmp); /* compressed, encrypted or normal tar file? */ if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s xvf - 2>%s", bzip2_bin,userspool,flp->id,tar_bin,error_log); else snprintf(MAXS(cmd),"%s -d < %s/%d.d | %s xvf - 2>%s", gzip_bin,userspool,flp->id,tar_bin,error_log); } else if (flp->flags&F_CRYPT) snprintf(MAXS(cmd),"%s xvf %s 2>%s",tar_bin,tartmp,error_log); else snprintf(MAXS(cmd),"%s xvf %s/%d.d 2>%s", tar_bin,userspool,flp->id,error_log); /* receive tar archive and check for errors */ terr=0; vsystem(cmd); if (stat(error_log,&finfo)==0 && finfo.st_size>10) { errno=0; inf=rfopen(error_log,"r"); while (fgetl(line,inf)) { if (str_beq(TAR": ",line) && !simplematch(line,TAR": Could not create symlink*File exists*",1)) { if (!terr) { terr=1; snprintf(MAXS(tmp),"errors while receive '%s' :",nname); message(prg,'E',tmp); } printf("%s",line); } } fclose(inf); } /* was there an error with tar? */ if (terr) { snprintf(MAXS(tmp),"leaving '%s' in spool intact",nname); message(prg,'I',tmp); } else { /* delete tar spool file */ if (!keep) delete_sf(flp,0); } return; } /* receive non-tar file */ /* save file in transfer shape? */ if (preserve && flp->flags&F_CRYPT) { fname[FLEN-5]=nname[FLEN-5]=sname[FLEN-5]=0; strcat(fname,".pgp"); strcat(nname,".pgp"); strcat(sname,".pgp"); } /* if file with same name already exists check what to do */ if (!quiet && checkfile(utf,fname,nname,sname,&overwrite)) return; /* leading . in file name? */ if (!strchr("yYr",overwrite) && fname[0]=='.') { /* skipping? */ if (overwrite=='S' || overwrite=='N') return; /* ask user what to do */ printf("'%s' starts with a '.' which may be dangerous\n",nname); printf("Receive it anyway (yY), rename (r) or skip (sS) it? "); fgetl(answer,stdin); overwrite=answer[0]; /* skipping this file? */ if (toupper(overwrite)=='S') return; /* request for renaming? */ if (overwrite=='r') { sprintf(fname,"Rename '%s' to? ",nname); if (getpromptline(fname,MAXLEN-1)==NULL || *fname=='\n' || *fname==0) strcpy(fname,nname); if ((cp=strrchr(fname,'\n'))) *cp=0; strcpy(nname,fname); } } /* safety fallback: try to delete an old file with the same name */ unlink(fname); if (stat(fname,&finfo)==0) { snprintf(MAXS(tmp),"cannot create '%s' : " "file does already exist and is not deletable",fname); errno=0; message(prg,'E',tmp); return; } /* save file encrypted? */ if (preserve && flp->flags&F_CRYPT) { /* copy file */ snprintf(MAXS(tmp),"%s/%d.d",userspool,flp->id); if (fcopy(tmp,fname,0666&~cmask)<0) { snprintf(MAXS(tmp),"cannot receive '%s'",nname); errno=0; message(prg,'E',tmp); return; } if ((flp->flags&F_SOURCE || flp->flags&F_TEXT) && !quiet) { snprintf(MAXS(tmp), "'%s' has a SOURCE or TEXT attribute, you have to decode it " "after pgp-decrypting with: recode %s:"CHARSET" '%s'", nname,flp->charset,nname); message(prg,'W',tmp); } if (flp->flags&F_MIME && !quiet) { snprintf(MAXS(tmp), "'%s' has the MIME attribute, you have to run it through" "metamail after pgp-decrypting",nname); message(prg,'W',tmp); } /* pgp signature to save? */ create_sigfile(flp->sign,fname,nname,&overwrite); if (!keep) delete_sf(flp,0); snprintf(MAXS(tmp),"'%s' received",nname); message(prg,'I',tmp); return; } /* spool file compressed or encrypted? */ if (flp->flags&F_COMPRESS || flp->flags&F_CRYPT) { /* source, text or MIME format? */ if ((flp->flags&F_SOURCE) || (flp->flags&F_TEXT) || (flp->flags&F_MIME)) { /* open pipe to uncompress or decrypt spool file */ if (flp->flags&F_COMPRESS) { if (str_eq(flp->compress,S_BZIP2)) snprintf(MAXS(cmd),"%s -d < %s/%d.d",bzip2_bin,userspool,flp->id); else snprintf(MAXS(cmd),"%s -d < %s/%d.d",gzip_bin,userspool,flp->id); } else if (flp->flags&F_CRYPT) snprintf(MAXS(cmd), "%s %s -f < %s/%d.d",pgp_bin,pgpvm,userspool,flp->id); if ((pp=vpopen(cmd,"r")) == NULL) { message(prg,'E',"cannot open spool file for reading"); return; } /* open output file */ if (!(outf=rfopen(fname,"w"))) { pclose(pp); printf("\n"); snprintf(MAXS(tmp),"cannot open '%s' for writing",nname); message(prg,'E',tmp); return; } /* translate CR LF to LF and write to output file */ crlf2lf(pp,outf,fname,nname); /* ready */ pclose(pp); fclose(outf); if (flp->flags&F_CRYPT && !pgppass) printf("\n\n"); } else /* binary format */ { snprintf(MAXS(sfile),"%s/%d.d",userspool,flp->id); /* try to create destination file */ /* open output file */ if (!(outf=rfopen(fname,"w"))) { snprintf(MAXS(tmp),"cannot open '%s' for writing",nname); message(prg,'E',tmp); return; } fclose(outf); /* compressed spool file? */ if (flp->flags&F_COMPRESS) { /* uncompress and receive binary file */ /* stupid bzip2 NEEDS file from stdin */ if (str_eq(flp->compress,S_BZIP2)) { strcpy(tmp,fname); if ((cp=strrchr(tmp,'/'))) *++cp=0; else *tmp=0; snprintf(MAXS(tmpfile),"%sreceive-%d.tmp",tmp,(int)getpid()); snprintf(MAXS(tmp),"%s -d < %s > %s",bzip2_bin,sfile,tmpfile); if (vsystem(tmp)) { snprintf(MAXS(tmp),"call to %s failed, cannot receive '%s'", bzip2_bin,nname); message(prg,'E',tmp); return; } if (rename(tmpfile,fname)<0) { snprintf(MAXS(tmp),"cannot write to '%s'",nname); message(prg,'E',tmp); unlink(tmpfile); return; } } else { /* gzip format */ sad[0]=gzip_bin; sad[1]="-dc"; sad[2]=sfile; sad[3]=NULL; if (spawn(sad,fname,cmask)<0) { errno=0; snprintf(MAXS(tmp), "call to %s failed, cannot receive '%s'",sad[0],nname); message(prg,'E',tmp); return; } } } /* encrypted spool file? */ if (flp->flags&F_CRYPT) { snprintf(MAXS(cmd),"%s %s -f < %s > '%s'",pgp_bin,pgpvm,sfile,fname); if (vsystem(cmd)!=0) { errno=0; snprintf(MAXS(tmp),"cannot receive '%s', pgp failed",nname); message(prg,'E',tmp); unlink(fname); return; } if (!pgppass) printf("\n\n"); } } } else /* not compressed and not encrypted or keep encryption */ { /* source, text or MIME format? */ if (((flp->flags&F_SOURCE) || (flp->flags&F_TEXT) || (flp->flags&F_MIME)) && !(flp->flags&F_CRYPT)) { /* open input file */ snprintf(MAXS(sfile),"%s/%d.d",userspool,flp->id); if ((inf=rfopen(sfile,"r")) == NULL) { message(prg,'E',"cannot open spool file for reading"); return; } /* open output file */ if ((outf=rfopen(fname,"w")) == NULL) { snprintf(MAXS(tmp),"cannot open '%s' for writing",nname); message(prg,'E',tmp); fclose(inf); return; } /* translate CR LF to LF and write to output file */ crlf2lf(inf,outf,fname,nname); /* ready */ fclose(inf); fclose(outf); } else /* binary file */ { /* copy file */ snprintf(MAXS(tmp),"%s/%d.d",userspool,flp->id); if (fcopy(tmp,fname,0666&~cmask)<0) { snprintf(MAXS(tmp),"cannot receive '%s'",nname); errno=0; message(prg,'E',tmp); return; } } } /* pgp signature to save? */ /* no more needed, because already saved in transfer shape! if (preserve) create_sigfile(flp->sign,fname,nname,&overwrite); */ /* executable flag set? */ if (flp->flags&F_EXE) chmod(fname,(S_IRWXU|S_IRWXG|S_IRWXO)&~cmask); snprintf(MAXS(tmp),"'%s' received",nname); message(prg,'I',tmp); /* foreign character set in text file? */ if ((flp->flags&F_TEXT) && !str_eq(flp->charset,CHARSET)) { /* call GNU recode */ snprintf(MAXS(tmp),"%s:"CHARSET,flp->charset); sad[0]=recode_bin; sad[1]=tmp; sad[2]=fname; sad[3]=NULL; if (spawn(sad,NULL,cmask)<0) { snprintf(MAXS(tmp), "call to %s failed, cannot translate character set in '%s'", recode_bin,nname); message(prg,'E',tmp); } } /* set the original date */ if (*(flp->date)) { if (!strstr(flp->date,"UTC")) strcat(flp->date," UTC"); utb.actime=utb.modtime=get_date(flp->date,NULL); utime(fname,&utb); } /* MIME? */ if (flp->flags&F_MIME) { /* metamail call allowed? */ if (nometamail) { snprintf(MAXS(tmp), "'%s' is a MIME file, you have to run it through metamail", nname); message(prg,'I',tmp); if (!keep) delete_sf(flp,0); } else { /* call metamail */ sad[0]=metamail_bin; sad[1]=fname; sad[2]=NULL; if (spawn(sad,NULL,cmask)<0) { snprintf(MAXS(tmp), "call to %s failed, keeping local file '%s'", metamail_bin,nname); message(prg,'E',tmp); } else { /* delete spool file and received MIME-file*/ if (!keep) delete_sf(flp,0); if (!nometamail) unlink(fname); } } } else /* delete spool file */ if (!keep) delete_sf(flp,0); } /* * crlf2lf - translate NVT format file to Unix text format file * * INPUT: inf - file to read from * outf - file to write to * fname - file name to write */ void crlf2lf(FILE *inf, FILE *outf, const char *fname, const char *nname) { int c1,c2; /* characters to read in */ char tmp[MAXLEN]; /* temporary string */ /* read first char */ c1=fgetc(inf); /* loop until EOF */ while ((c2=fgetc(inf)) != EOF) { /* crlf? */ if (c1=='\r' && c2=='\n') { /* write lf */ if(fputc(c2,outf)==EOF) { snprintf(MAXS(tmp),"cannot write to %s",nname); message(prg,'E',tmp); return; } /* read next char */ if ((c2=fgetc(inf)) == EOF) return; } else { /* write char */ if(fputc(c1,outf)==EOF) { snprintf(MAXS(tmp),"cannot write to %s",nname); message(prg,'E',tmp); return; } } c1=c2; } /* write last char */ if(fputc(c1,outf)==EOF) { snprintf(MAXS(tmp),"cannot write to %s",nname); message(prg,'E',tmp); return; } } /* * cleanexit - clean termination routine (only called by signal handler) */ void cleanexit() { printf("\r\n"); cleanup(); exit(4); } /* * cleanup - delete tmp files */ void cleanup() { /* ignore all relevant signals */ signal(SIGTERM,SIG_IGN); signal(SIGABRT,SIG_IGN); signal(SIGQUIT,SIG_IGN); signal(SIGHUP,SIG_IGN); signal(SIGINT,SIG_IGN); #ifndef DEBUG rmtmpdir(tmpdir); #endif } /* * checkfile - check file name before writing * * INPUT: fname - real file name * nname - normal file name to display * sname - file name for shell usage * overwrite - overwriting, renaming or skipping * * OUTPUT: fname - new real file name * nname - new normal name to display * sname - file name for shell usage * overwrite - overwriting, renaming or skipping * * RETURN: 0 if renaming or overwriting * 1 if skipping */ int checkfile(int utf, char *fname, char *nname, char *sname, char *overwrite) { char *cp, /* a simple string pointer */ tmp[MAXLEN], /* temporary string */ answer[FLEN]; /* answer string */ static char storeformat='c'; /* file name storing format */ struct stat finfo; /* information about a file */ if (quiet) storeformat='C'; /* rename files before receiving? */ if (ren) { sprintf(fname,"Rename '%s' to? ",nname); if (getpromptline(fname,MAXLEN-1)==NULL || *fname=='\n' || *fname==0) strcpy(fname,nname); if ((cp=strrchr(fname,'\n'))) *cp=0; strcpy(nname,fname); } else { /* need user request? */ if (!strchr("CNS",storeformat)) { /* found Unicode or 0x0? */ if (utf==1) { printf("The next file name contains characters which are not allowed " "in Unix.\nThese characters have been substituted with '_'.\n"); } /* found control or meta characters? */ if (utf&2) { printf("The next file name contains characters which may cause " "problems with your shell\n or may do strange things with " "your terminal.\n" "These characters have been substituted with '_'.\n"); if (utf&1) printf("Non-valid characters for Unix file names have been substituted" ", too.\n"); /* let user choose file name format */ /*if (strcmp(nname,sname)!=0) */ printf("Save the next file as:\n"); printf(" (c)omplete file name with control code characters " "(not displayable)\n"); printf(" (n)ormal file name: '%s'\n",nname); printf(" (u)ntainted file name: '%s'\n",sname); printf(" (s)kip it\n"); printf(" (r)ename it\n"); do { printf("c or n may cause severe security problems " "(Kids, don't try this at home!) !\n"); printf("Select one of c n u s r (or C N U S R for no more questions): "); fgetl(tmp,stdin); storeformat=tmp[0]; } while (strchr("cnusrCNUSR",storeformat)==NULL); } } /* set file name */ switch (toupper(storeformat)) { case 'S': return(1); case 'N': strcpy(fname,nname); break; case 'U': strcpy(fname,sname); strcpy(nname,sname); break; case 'R': sprintf(fname,"Rename '%s' to? ",nname); if (getpromptline(fname,MAXLEN-1)==NULL || *fname=='\n' || *fname==0) strcpy(fname,nname); if ((cp=strrchr(fname,'\n'))) *cp=0; strcpy(nname,fname); } } /* does the file already exist? */ while (stat(fname,&finfo)==0 && (*overwrite!='Y')) { /* skipping? */ if (*overwrite=='S' || *overwrite=='N') return(1); /* ask user what to do */ printf("'%s' already exists.\n" "Overwrite (yY), rename (r) or skip (sS) it? ",nname); fgetl(answer,stdin); *overwrite=answer[0]; /* request for renaming? */ if (*overwrite=='r') { sprintf(fname,"Rename '%s' to? ",nname); if (getpromptline(fname,MAXLEN-1)==NULL || *fname=='\n' || *fname==0) strcpy(fname,nname); if ((cp=strrchr(fname,'\n'))) *cp=0; strcpy(nname,fname); continue; } /* overwriting or leaving? */ if (toupper(*overwrite)=='Y') break; else return(1); } return(0); } /* * create_sigfile - create detached pgp signature file * * INPUT: sign - signature * fname - original file name * overwrite - overwriting, renaming or skipping * * RETURN: 0 if ok, -1 if failed */ int create_sigfile(const char *sign, const char *fname, const char *nname, char *overwrite) { char *cp, /* a simple string pointer */ tmp[MAXLEN], /* temporary string */ sigfile[MAXLEN], /* signature file */ nsigfile[MAXLEN], /* normal displayable signature file name */ answer[FLEN]; /* answer string */ struct stat finfo; /* information about a file */ FILE *outf; /* file to create */ /* no pgp signature to save? */ if (!*sign) return(0); snprintf(MAXS(sigfile),"%s.sig",fname); snprintf(MAXS(nsigfile),"%s.sig",nname); /* signature file does already exist? */ while (stat(sigfile,&finfo)==0 && (*overwrite!='Y')) { /* skipping? */ if (*overwrite=='S' || *overwrite=='N') return(-1); /* ask user what to do */ printf("'%s' already exists.\n" "Overwrite (yY), rename (r) or skip (sS) it? ",nsigfile); fgetl(answer,stdin); *overwrite=answer[0]; /* request for renaming? */ if (*overwrite=='r') { sprintf(nsigfile,"Rename to? "); if (getpromptline(nsigfile,MAXLEN-1)==NULL || *nsigfile=='\n' || *nsigfile==0) strcpy(nsigfile,sigfile); if ((cp=strrchr(nsigfile,'\n'))) *cp=0; strcpy(sigfile,nsigfile); continue; } /* overwriting or leaving? */ if (toupper(*overwrite)=='Y') break; else return(-1); } /* safety fallback: try to delete an old file with the same name */ unlink(fname); if (stat(sigfile,&finfo)==0) { snprintf(MAXS(tmp),"cannot create '%s' : " "file does already exist and is not deletable",sigfile); errno=0; message(prg,'E',tmp); return(-1); } if (!(outf=rfopen(sigfile,"w"))) { snprintf(MAXS(tmp),"cannot create signature file '%s' ",nsigfile); message(prg,'E',tmp); return(-1); } fprintf(outf,"%s",sign); fclose(outf); snprintf(MAXS(tmp),"signature file '%s' created",nsigfile); message(prg,'I',tmp); return(0); } /* * check_signature - check or print pgp signature * * INPUT: flp - file list pointer to spool file * pgpring - pgp ring file name * print - flag for printing signature status * * RETURN: 1 if good signature * 0 if no signature * -1 if signature not found in pgp key ring * -2 if bad signature * -3 if other error * */ int check_signature(struct filelist *flp, char *pgpring, int print) { int status; /* return status */ char *cp; /* simple character pointer */ char sigfile[FLEN], /* pgp signature file */ pgpopt[FLEN], /* pgp options */ tmp[MAXLEN], /* temp-string */ line[MAXLEN]; /* line to read in */ FILE *outf, /* output file */ *pp; /* pipe input stream */ status=0; if (!(*(flp->sign))) return(0); if (str_eq(pgpring,".")) *pgpring=0; /* write signature file */ snprintf(MAXS(sigfile),"%s/%d.d.sig",userspool,flp->id); if (!(outf=rfopen(sigfile,"w"))) { snprintf(MAXS(tmp),"cannot write signature file %s",sigfile); message(prg,'E',tmp); return(-2); } fprintf(outf,"%s",flp->sign); fclose(outf); /* build pgp options */ if (*pgpring) { if (access(pgpring,R_OK)<0) { snprintf(MAXS(tmp),"cannot read pgp pub ring file %s",pgpring); message(prg,'F',tmp); } snprintf(MAXS(pgpopt),"+batchmode=on +language=en +pubring=%s",pgpring); } else snprintf(MAXS(pgpopt),"+batchmode=on +language=en"); /* check signature file with pgp */ snprintf(MAXS(tmp),"%s %s %s 2>/dev/null",pgp_bin,pgpopt,sigfile); if (!(pp=vpopen(tmp,"r"))) { message(prg,'E',"cannot call pgp"); unlink(sigfile); return(-2); } /* print or check only result */ if (print) { while (fgetl(line,pp)) { if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strrchr(line,'.'))) *cp=0; if (strstr(line,"Good signature from user") || strstr(line,"Bad signature from user")) { printf(" (%s)\n",line); break; } if (strstr(line,"Key matching expected")) { printf(" (No matching signature found in pgp key file)\n"); break; } } } else { /* check only result */ while (fgetl(line,pp)) { if (strstr(line,"Good signature from user")) { status=1; break; } if (strstr(line,"Key matching expected")) { status=-1; break; } if (strstr(line,"Could not read key")) { status=-1; break; } if (strstr(line,"Bad signature from user")) { status=-2; break; } } } /* close pipe and delete signature file */ pclose(pp); unlink(sigfile); return(status); } /* * renumber - renumber spool files */ void renumber (struct senderlist *sls) { int i, /* actual spool file number */ nextfree, /* next free spool file number */ lastused, /* last used spool file number */ min, /* smallest spool file number */ max; /* biggest spool file number */ char tmp[MAXLEN], /* temporary string */ ofile[FLEN], /* old filename */ nfile[FLEN]; /* new filename */ struct filelist *flp; /* file list pointer */ struct senderlist *slp; /* sender list pointer */ struct stat finfo; /* information about a file */ FILE *lockf; /* lock file */ min = lastused = 0; max = nextfree = 1; if (chdir(userspool)<0) { snprintf(MAXS(tmp),"cannot change to %s",userspool); message(prg,'F',tmp); } /* create lock file */ lockf=rfopen("renumber","a+"); if (!lockf) message(prg,'F',"cannot open renumber file"); if (wlock_file(fileno(lockf))<0) { message(prg,'E',"spool is locked - try again later"); return; } /* loop over all spool files to find max spool file number */ for (slp=sls; slp; slp=slp->next) { for (flp=slp->flist; flp; flp=flp->next) { fprintf(lockf,"%d\n",flp->id); if (flp->id > max) max=flp->id; } } /* renumber loop */ while (minlastused && i>nextfree) min=i; } snprintf(MAXS(ofile),"%d.h",min); for (i=nextfree; i #include #include #include "string.h" /* #ifdef IRIX int toupper(char); int tolower(char); #endif */ /* * str_trim - substitute multiple white spaces with one space * and delete heading and trailing whitespace * * INPUT: string - string to trim * * OUTPUT: string - trimmed string * * RETURN: trimmed string */ char *str_trim(char *string) { char *rp, /* reading string pointer */ *wp; /* writing string pointer */ int ws; /* white space flag */ ws=0; if (*string) { /* loop over string */ for (wp=rp=string; *rp; rp++) { /* is it a white space? */ if (*rp==' ' || *rp=='\t' || *rp=='\n' || *rp=='\r') { /* store a blank if the last character was not a white space */ if (!ws) { *wp++=' '; ws=1; } } else /* no white space */ { /* store the character */ *wp++=*rp; ws=0; } } /* delete trailing blank */ if (ws) wp--; *wp=0; } return(string); } /* * str_toupper - transform string to upper case * * INPUT: string - string to transform * * OUTPUT: string - transformed string * * RETURN: string - transformed string */ char *str_toupper(char *string) { char *cp; /* change each character to it's upper case pedant */ for (cp=string; *cp; cp++) *cp = (char) toupper(*cp); return(string); } /* * str_tolower - transform string to lower case * * INPUT: string - string to transform * * OUTPUT: string - transformed string * * RETURN: string - transformed string */ char *str_tolower(char *string) { char *cp; /* change each character to it's upper case pedant */ for (cp=string; *cp; cp++) *cp = (char) tolower(*cp); return(string); } /* * str_beq - string begin equal test * * INPUT: s1 - string 1 * s1 - string 1 * * RETURN: 1 if begin is equal, 0 if begin is not equal */ int str_beq(const char *s1, const char *s2) { int len; if (strlen(s1) < strlen(s2)) len=strlen(s1); else len=strlen(s2); if (strncmp(s1,s2,len) == 0) return(1); else return(0); } /* * str_neq_nocase - string equal test until length n, ignoring case * * INPUT: s1 - string 1 * s1 - string 1 * len - max length to compare * * RETURN: 1 if is equal, 0 if is not equal (until size len) */ int str_neq_nocase(const char *s1, const char *s2, int len) { int i; char a,b; for (i=0;i #define NULL (char *)0 */ #define SM_MATCH 1 #define SM_NOMATCH 0 #define SM_ERROR -1 /* Fehler im Pattern */ static char sm_escchar( c ) char c; { switch( c ) { case 'a': c = '\a'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; } return(c); } int simplematch( text, pattern, nocase ) char *text, *pattern; int nocase; { char *retrypat = NULL, *retrytxt; unsigned char c,c1,c2; int notfound; retrytxt = text; while (*text || *pattern) { c = *(pattern++); if (nocase) c = tolower(c); switch (c) { case '*': retrypat = pattern; retrytxt = text; break; case '[': notfound = 1; if (*pattern == '^') { notfound = 0; pattern++; } while ((c = *(pattern++)) != ']') { if (c == '\\') c = sm_escchar(*(pattern++)); if (c == '\0') return(SM_ERROR); if (*pattern == '-') { c1 = c; c2 = *(++pattern); if (c2 == ']' || c2 == '\0' || c1 == '[') return(SM_ERROR); if ((*text >= c1 && *text <= c2) || (tolower(*text) >= tolower(c1) && tolower(*text) <= tolower(c2) && nocase)) notfound = !notfound; pattern++; } else if (*text == c || (nocase && tolower(*text) == tolower(c))) notfound = !notfound; } if (notfound) { pattern = retrypat; text = ++retrytxt; } case '?': if (*(text++) == '\0') return(SM_NOMATCH); break; case '\\': c = sm_escchar(*(pattern++)); if (c == '\0') return(SM_ERROR); default : if (*text == c || (nocase && tolower(*text) == c)) { if (*text) text++; } else { if (*text) { pattern = retrypat; text = ++retrytxt; } else return(SM_NOMATCH); } } if( pattern == NULL ) return(SM_NOMATCH); } return(SM_MATCH); } #ifdef SM_TEST #include main() { char s[1000],p[1000]; while(1) { printf("Text : "); fflush(stdout); scanf("%s",s); printf("Pattern: "); fflush(stdout); scanf("%s",p); printf("Result case-sensitive : %d\n",simplematch(s,p,0)); printf("Result case-insensitive: %d\n\n",simplematch(s,p,1)); } } #endif #if !defined(HAVE_STRERROR) /* * strerror - like strerror on many Unices, but not on SunOS 4.1.4 * * INPUT: int - error number to look up * * OUTPUT: none * * RETURN: string - string of the error number */ char *strerror(int errornumber) { #if __GLIBC__ < 2 && !defined(BSD) extern int sys_nerr; extern char *sys_errlist[]; #endif static char buffer[40]; if ((unsigned int) errornumber < sys_nerr) { return (char *)(sys_errlist[errornumber]); } (void) sprintf(buffer, "Unknown error: %d", errornumber); return (buffer); } #endif #if !defined(HAVE_SNPRINTF) #include "snprintf.c" #endif /* sfgetl: secure version of gets() : read a text line from a stream * * INPUT: s - string * z - size of string * f - input stream * * OUTPUT: s - read line (correctly terminated with \0) * * RETURN: s on success, NULL on error * * Remark: if line is longer than z, munch it */ char *sfgetl(char *s, int z, FILE *f) { char *S; int c; S=fgets(s,z,f); /* munch to EOL or EOF if there are chars pending */ if (S && *s && s[strlen(s)-1] != '\n') { do { c=fgetc(f); } while (c != EOF && c != '\n' && c != 0); } return(S); } sendfile-2.1b/src/io.h0000644000175100001440000000277410335147554014423 0ustar framstagusers/* * File: io.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-08-12 Framstag initial version * 1996-04-23 Framstag added file copying function * 2001-01-10 Framstag added rfopen() * 2005-06-02 Framstag added largefile support * 2005-11-13 Framstag added vsystem() * * Header-file for the read and write routines of the sendfile package. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif #if defined(SOLARIS2) #ifndef fileno int fileno(FILE *); #endif #endif #ifdef NEXT #include #endif #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif /* read n bytes from network socket */ int readn(int, char *, int); /* write n bytes to network socket */ int writen(int, char *, int); /* copy a file */ int fcopy(const char *, const char *, mode_t); /* where is a program in the path */ char *whereis(char *); /* open a regular file */ FILE *rfopen(const char *, const char *); /* mktmpdir - create a new temporary directory */ char *mktmpdir(int); /* rmtmpdir - delete the temporary directory */ void rmtmpdir(char *); /* spawn a subprocess and direct output to a file */ int spawn(char **, const char *, mode_t); /* system() with verbose output */ int vsystem(const char *); /* popen() with verbose output */ FILE* vpopen(const char *, const char *); /* quote a string so it ist shell escape safe */ char* shell_quote(const char *); sendfile-2.1b/src/wlock.c0000640000175100001440000001377210251136250015106 0ustar framstagusers/* * File: lock.c * * Author: Ulli Horlacher (framstag@belwue.de) * * History: * * 1995-11-02 Framstag initial version * 1998-09-29 Framstag print also PID on testing * * This program sets or tests advisory locks conforming to POSIX fcntl() call. * You may specify optionaly a program to start it within the lock context. * * Copyright © 1997 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include #include #include #include #include #include #include #include #include /* some systems are missing the getopt declarations */ int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; /* write-lock a file (POSIX conform) */ int wlock_file(int,int,int); /* test if a file is write-lock blocked (POSIX conform) */ int tlock_file(int,int,int); /* print short usage message */ void usage(); char *prg; /* name of the game */ int main(int argc, char *argv[]) { int i, /* simple loop counter */ status, /* return status */ lockf, /* lock file descriptor */ opt, /* getopt return value */ verbose, /* flag for verbose mode */ begin, /* begin of locking area */ length, /* length of locking area */ seconds, /* seconds to sleep */ pid; /* process ID */ char type; /* locl-type: testing or seting */ char cmd[32768]; /* program and arguments to start */ char *cp, /* simple string pointer */ *file, /* file to lock */ *nprg; /* next program to start */ verbose=0; begin=0; length=0; seconds=86400; strcpy(cmd,""); type='t'; /* default: test lock */ /* what's my name? */ prg=argv[0]; if ((cp=strrchr(prg,'/'))) prg=cp+1; while ((opt=getopt(argc, argv, "vtsb:l:a:")) > 0) { switch (opt) { case ':': case 'h': case '?': usage(); case 't': type='t'; break; case 's': type='s'; break; case 'v': verbose=1; break; case 'b': begin=atoi(optarg); break; case 'l': length=atoi(optarg); break; case 'a': seconds=atoi(optarg); break; } } if (argc-optind==0) usage(); file=argv[optind]; nprg=argv[optind+1]; /* try to open file */ if ((lockf=open(file,O_WRONLY|O_APPEND,S_IRUSR|S_IWUSR))<0) { fprintf(stderr,"%s: cannot open %s : %s\n",prg,file,strerror(errno)); exit(1); } /* set lock mode? */ if (type=='s') { /* try to lock it */ status=wlock_file(lockf,begin,length); /* lock failed */ if (status<0) { if (verbose) fprintf(stderr,"%s: lock failed for %s\n",prg,file); exit(2); } /* next program specified? */ if (nprg) { /* build command string */ for (i=optind+1;argv[i];i++) { strcat(cmd," "); strcat(cmd,argv[i]); } /* create subprocess */ pid=fork(); if (pid<0) { fprintf(stderr,"%s: cannot create subprocess : %s\n",prg,strerror(errno)); exit(2); } /* in subprocess start next program */ if (pid==0) { if (verbose) fprintf(stderr,"%s: executing %s\n",prg,cmd); execvp(nprg,&argv[optind+1]); fprintf(stderr,"%s: cannot execute %s : %s\n",prg,nprg,strerror(errno)); exit(2); } /* that's it */ wait(NULL); exit(0); } /* sleep for some time to keep lock alive */ if (verbose) fprintf(stderr,"%s: lock ok for %s, " "going into sleep for %d seconds\n", prg,file,seconds); sleep(seconds); exit(0); /* only test the file for locks */ } else { status=tlock_file(lockf,begin,length); if (status<0) { if (verbose) fprintf(stderr,"%s: testing lock for %s failed!\n",prg,file); exit(2); } if (status==0) { if (verbose) fprintf(stderr,"%s: no lock for %s\n",prg,file); exit(1); } if (status>0) { if (verbose) fprintf(stderr,"%s: %s is locked by PID %d\n", prg,file,status); exit(0); } } exit(0); } /* * wlock_file - write-lock a file (POSIX conform) * * INPUT: file descriptor * * RETURN: >= 0 if ok, -1 if error */ int wlock_file(int fd, int begin, int length) { struct flock lock; /* file locking structure */ /* fill out the file locking structure */ lock.l_type=F_WRLCK; lock.l_start=begin; lock.l_whence=SEEK_SET; lock.l_len=length; /* try to lock the file and return the status */ return(fcntl(fd,F_SETLK,&lock)); } /* * tlock_file - test if a file is write-lock blocked (POSIX conform) * * INPUT: fd - file descriptor * * RETURN: 0 if no lock, lock-PID if locked, -1 on error */ int tlock_file(int fd, int begin, int length) { int status; struct flock lock; /* file locking structure */ /* fill out the file locking structure */ lock.l_type=F_WRLCK; lock.l_start=begin; lock.l_whence=SEEK_SET; lock.l_len=length; /* test the lock status */ status=fcntl(fd,F_GETLK,&lock); if (status>=0) status=(lock.l_type!=F_UNLCK); if (status>0) status=lock.l_pid; return(status); } void usage() { printf("purpose: \"%s\" tests or sets a file with POSIX-fcntl() write-locks\n",prg); printf("usage: %s [-s [-a seconds]] [-t] [-v] [-b begin] [-l length] file\n",prg); printf(" or: %s -s [-v] [-b begin] [-l length] file program [arguments]\n",prg); printf("options: -t test lock (default)\n"); printf(" -s set lock\n"); printf(" -v verbose output\n"); printf(" -b lock starts at byte #begin\n"); printf(" -l lock is #length byte long\n"); printf(" -a lock is #seconds active (default=86400)\n"); printf(" program ... start this program within the lock context\n"); printf("Exit status: test: 0 = locked, 1 = not locked, 2 = error\n"); printf(" set: 0 = lock was successful, 2 = error\n"); printf("Examples: %s -s -v log_file\n",prg); printf(" %s -s -b 10 log_file vi log_file\n",prg); printf(" %s -vt log_file\n",prg); exit(0); } sendfile-2.1b/src/spool.h0000640000175100001440000000632310251136250015122 0ustar framstagusers/* * File: spool.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-09-01 Framstag initial version * 1996-04-12 Framstag sign is now in filelist * sign, comment and fname are now dynamic * 1996-04-24 Framstag added outgoing spool support * 1997-02-23 Framstag extended with TYPE=MIME * 1997-09-14 Framstag moved spoolid() from sendfiled.c to spool.c * 1998-11-12 Framstag outfilelist now contains file size, too * 2005-05-31 Framstag added largefile support * * Header-file for functions for operations on files in the sendfile spool * directory. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ /* attribute flags */ #define F_SOURCE 1 #define F_TEXT 2 #define F_MIME 4 #define F_COMPRESS 8 #define F_CRYPT 16 #define F_TAR 32 #define F_EXE 64 #define S_GZIP "GZIP" #define S_BZIP2 "BZIP2" /* list of all files from one sender */ struct filelist { int id, /* id number */ flags; /* binary, source, text, compress and tar flag */ off_t osize, /* original size */ csize, /* compressed size */ tsize; /* transfered size */ time_t rtime; /* receiving date */ char rdate[DLEN+1], /* receiving date */ date[DLEN+1], /* file date */ charset[DLEN+1], /* character set name */ compress[DLEN+1], /* compression method */ *sign, /* pgp signature */ *comment, /* file comment (ISO Latin-1) */ *fname; /* UTF-7 file name */ struct filelist *next; /* next list element */ }; /* list of all senders */ struct senderlist { char from[MAXLEN]; /* sender */ struct senderlist *next; /* next list element */ struct filelist *flist; /* list of files */ }; /* list of all files from to a single host */ struct outfilelist { struct outfilelist *next; /* next list element */ char *to, /* recipient name */ *from, /* sender name */ *fname, /* file name (UTF-7) */ *oshfn; /* outgoing spool header file name */ off_t size; /* size */ }; /* list of hosts for outgoing spool */ struct hostlist { struct hostlist *next; /* next list element */ char host[MAXLEN]; /* recipient host */ struct outfilelist *flist; /* list of files */ }; #ifdef deadcode /* rest list of spool files (from found forward addresses) */ struct restlist { struct restlist *next; /* next list element */ char to[FLEN], /* recipient name */ from[FLEN], /* sender name */ oshfn[MAXLEN], /* outgoing spool header file name */ host[MAXLEN]; /* recipient host */ }; #endif /* send string conforming to NVT standard */ void out(const char *); /* scan the spool directory and create structure lists */ struct senderlist *scanspool(char *); /* scan the outgoing spool directory and create structure lists */ struct hostlist *scanoutspool(char *); /* create new sender list element and fill it out */ struct senderlist *newsle(struct filelist *, const char *); /* create new host list element and fill it out */ struct hostlist *newhle(struct outfilelist *, const char *); /* delete a spool file */ int delete_sf(struct filelist *, int); /* get the next spool id number */ int spoolid(int); sendfile-2.1b/src/address.h0000640000175100001440000000162310251136250015411 0ustar framstagusers/* * File: address.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 12 Aug 95 Framstag initial version * 4 Jan 97 Framstag renamed from destination.h to address.h * added check_forward() * 22 Nov 97 Framstag added saft2rfc822() * * Determine own username, recipient username and host and look * for an alias in /USERSPOOL/config/aliases and in ~/.elm/aliases.text * * Copyright © 1995 Ulli Horlacher * This file is covered by the GNU General Public License */ /* get recipient user and host */ void destination(int, char **, char *, char *, char *, char *); /* test if there is an forward address set */ int check_forward(int, char *, char *, char *); /* look for correct SAFT server and open connection */ int saft_connect(const char *, char *, char *, char *, char *); /* SAFT URL to RFC822 mail address translation */ int saft2rfc822(char *); sendfile-2.1b/src/fetchfile.c0000640000175100001440000010651510765534466015743 0ustar framstagusers/* * File: fetchfile.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Michael Neumayer (eumel@42.org) * * History: * * 1997-09-28 Framstag initial version * 1997-10-03 Framstag added -r autoreceive option * 1997-10-05 Framstag better pgp error handling * 1997-10-24 Framstag added check for pgp key files * 1997-12-11 Eumel fixed pgp my_ID problem * 1997-12-19 Framstag default key length is now 1024 bit * 1998-01-03 Framstag config options id and server merged to o-saft * 1998-03-11 Framstag new default user configuration directory * 2001-02-04 Framstag added secure mktmpdir() * 2005-06-06 Maide added multiprotocol cababilities * 2005-06-06 Maide replaced numeric ports with service string * 2005-06-06 Maide added out of memory error message * 2005-06-06 Maide added -4/-6 command line options and * corresponding help text * * The fetchfile client of the sendfile package. * Lists or gets files from a SAFT server to put them into the local spool. * * Copyright © 1997,1998 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* autoconf header */ #include #include #include #include #include #include #include #include #include #include #include #include #include "string.h" /* extended string functions */ #include "net.h" /* the network routines */ #include "io.h" /* (socket) read/write */ #include "message.h" /* information, warning and error messages */ #include "spool.h" /* operations on files in the sendfile spool */ #include "utf7.h" /* UTF-7 coding */ #include "address.h" /* address checking */ #include "getline.h" /* get a line of text from stdin */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #if defined(SOLARIS2) int gethostname(char *, int); #endif #if defined(LINUX) int gethostname(char *, size_t); int symlink(const char *, const char *); #endif #ifndef AIX #ifndef CONVEXOS FILE *popen(const char *, const char *); #endif int pclose(FILE *); #endif #ifdef NEXT int shutdown(int, int); #endif #if defined(AIX3) || defined(ULTRIX) #include "bsd.h" #endif /* print short help usage text */ int usage(); /* get file list from server */ int get_list(int, const char *, const char *, FILE *); /* get file from server */ int get_file(int, int, int); /* delete a file from the server */ int delete_file(int, int); /* clean termination routine */ void cleanexit(); /* delete tmp-file */ void cleanup(); /* delete tmp-file */ void init(); /* test local sendfiled */ int sendfiled_test(const char *); /* exit wit receive evaluation */ void rexit(int); /* global variables */ int verbose=0, /* flag for verbose mode */ xonf=1, /* exit on fatalerror flag */ client=1, /* flag to determine client or server */ quiet=0, /* quiet mode */ ignore=0, /* ignore testing flag */ packet_size=0; /* packet size */ char *prg, /* name of the game */ *tmpdir, /* directory for temporary files */ swd[MAXLEN], /* start working directory */ rfilen[MAXLEN], /* receive files for -R option */ userspool[MAXLEN], /* user spool directory */ userconfig[MAXLEN], /* user configuration directory */ listfile[MAXLEN], /* file with list command output */ pgp_bin[MAXLEN], /* the pgp binary */ pgptmp[MAXLEN]; /* name of pgp temporary file */ struct passwd *pwe; /* password entry */ struct senderlist *sls; /* sender list start */ int main(int argc, char *argv[]) { int i, /* simple loop counter */ n, /* number of files on the server */ pid, /* current proccess id */ sockfd, /* socket file descriptor */ opt, /* option to test for */ number, /* file number */ wconf, /* flag for writing config file (0=reading) */ del, /* flag for deleting previous sent files */ all, /* flag for specifying all files */ numbers, /* flag for specifying file numbers */ ptso, /* flag for "pipe to standard output" */ keep, /* flag for keeping files on server */ list; /* flag for listing files in outgoing spool */ char *cp, /* simple string pointer */ *argp, /* argument string pointer */ *user, /* sending user pattern */ id[FLEN], /* user identication for SAFT server */ server[FLEN], /* SAFT server */ alternate[MAXLEN], /* alternate user and/or SAFT server */ cmd[MAXLEN], /* cmd string for system-call */ line[MAXLEN], /* one line of text */ from[MAXLEN], /* sender address */ fname[MAXLEN], /* file name */ conffile[MAXLEN], /* config file name */ response[MAXLEN], /* signed response to authorization challenge */ tmp[3*MAXLEN]; /* temporary string */ FILE *pp, /* pipe */ *listf, /* list command output file */ *inf, /* input file */ *outf; /* output file */ struct stat finfo; /* information about a file */ n=0; del=0; all=0; ptso=0; list=0; keep=0; sockfd=0; verbose=0; numbers=0; *id=0; *server=0; *rfilen=0; *conffile=0; *response=0; *alternate=0; user="*"; listf=NULL; pid=(int)getpid(); getcwd(MAXS(swd)); prg=argv[0]; if ((cp=strrchr(prg,'/'))) prg=cp+1; /* protect all tmp-files */ umask(~(S_IRUSR|S_IWUSR)); /* support programs defaults */ strcpy(pgp_bin,PGP); /* look for environment variables */ if ((cp=getenv("SF_PGP"))) strcpy(pgp_bin,cp); /* do the support programs really exist? */ if (access(pgp_bin,X_OK)<0) strcpy(pgp_bin,"pgp"); /* get the own user name and tmpdir */ if ((pwe=getpwuid(getuid())) == NULL) message(prg,'F',"cannot access user system informations"); tmpdir=mktmpdir(verbose); /* set various file names and check user spool and configuration directory */ snprintf(MAXS(pgptmp),"%s/fetchfile.pgp",tmpdir); snprintf(MAXS(userspool),SPOOL"/%s",pwe->pw_name); if (stat(userspool,&finfo)<0) sendfiled_test(pwe->pw_name); snprintf(MAXS(userconfig),"%s/.sendfile",pwe->pw_dir); snprintf(MAXS(tmp),"%s/config",userspool); if (stat(userconfig,&finfo)<0 && stat(userspool,&finfo)==0) symlink(tmp,userconfig); snprintf(MAXS(tmp),"%s/.sfspool",pwe->pw_dir); if (stat(tmp,&finfo)==0 && finfo.st_mode&S_IFDIR) strcpy(userspool,tmp); /* scan the command line on options */ #ifndef ENABLE_MULTIPROTOCOL while ((opt=getopt(argc, argv, "vVqQ?hrPIliadkns:f:C:")) > 0) { #else while ((opt=getopt(argc, argv, "vVqQ?hrPIliadkns:f:C:46")) > 0) { #endif switch (opt) { case ':': case 'h': case '?': exit(usage()); case 'r': strcpy(rfilen,"receive -n "); break; case 's': strcpy(alternate,optarg); break; case 'C': strcpy(conffile,optarg); break; case 'f': user=optarg; break; case 'd': del=1; break; case 'k': keep=1; break; case 'P': ptso=1; break; case 'i': ignore=1; break; case 'n': numbers=1; break; case 'a': all=1; break; case 'l': list=1; break; case 'q': quiet=1; break; case 'Q': quiet=2; break; case 'v': verbose=1; break; case 'V': message(prg,'I',"version "VERSION" revision "REVISION); exit(0); case 'I': init(); exit(0); #ifdef ENABLE_MULTIPROTOCOL case '4': addressFamily = PF_INET; break; case '6': addressFamily = PF_INET6; break; #endif } } /* too few arguments? */ if (argc-optind<1 && !all && !list && !*conffile) exit(usage()); /* incompatible options? */ if (*conffile && (del || keep || all || list || numbers)) { errno=0; message(prg,'F',"you cannot mix -C with any other option"); } if (del && keep) { errno=0; message(prg,'F',"you cannot delete and keep a file at the same time"); } if (ptso && *rfilen) { errno=0; message(prg,'F',"you cannot auto-receive and pipe to stdout (-R and -n options)"); } if (list && (del || keep || all || *rfilen || ptso)) { errno=0; message(prg,'F',"you cannot not specify any other option with -l"); } if (all && argc>optind) { errno=0; message(prg,'F',"you cannot specify file names or numbers " "together with -a option"); } /* alternate user or server specified? */ if (*alternate) { if (str_beq_nocase(alternate,"saft://")) saft2rfc822(alternate); if ((cp=strchr(alternate,'@'))) { *cp=0; strcpy(id,alternate); strcpy(server,cp+1); } else { strcpy(server,alternate); } } /* check tmp files */ unlink(pgptmp); if (stat(pgptmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",pgptmp); message(prg,'F',tmp); } /* parse the global config-file */ if ((inf=rfopen(CONFIG,"r"))) { while (fgetl(line,inf)) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; str_tolower(str_trim(line)); /* is there an option and an argument? */ if ((argp=strchr(line,' '))) { *argp=0; argp++; if (str_eq(line,"packet")) { packet_size=atoi(argp); continue; } } } fclose(inf); } /* check pgp key files */ snprintf(MAXS(tmp),"%s/private.pgp",userconfig); if (stat(tmp,&finfo)<0) { snprintf(MAXS(line),"no access to %s (try 'fetchfile -I' first)",tmp); message(prg,'F',line); } snprintf(MAXS(tmp),"%s/public.pgp",userconfig); if (stat(tmp,&finfo)<0) { snprintf(MAXS(line),"no access to %s (try 'fetchfile -I' first)",tmp); message(prg,'F',line); } /* parse the user config-file */ snprintf(MAXS(tmp),"%s/config",userconfig); if ((inf=rfopen(tmp,"r"))) { while (fgetl(line,inf)) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; str_tolower(str_trim(line)); /* is there an option and an argument? */ if ((argp=strchr(line,' '))) { *argp=0; argp++; if (str_eq(line,"id") && !*id) { /* depreciated */ strcpy(id,argp); continue; } if (str_eq(line,"server") && !*server) { /* depreciated */ strcpy(server,argp); continue; } if (str_eq(line,"o-saft") && !*server) { if (str_beq_nocase(argp,"saft://")) saft2rfc822(argp); if ((cp=strchr(argp,'@'))) { *cp=0; strcpy(id,argp); strcpy(server,cp+1); } else { strcpy(id,pwe->pw_name); strcpy(server,argp); } } } } fclose(inf); } if (!*id) strcpy(id,pwe->pw_name); if (!*server) strcpy(server,"localhost"); snprintf(MAXS(listfile),"%s/%s@%s:fetch.lis",userspool,id,server); /* initiate the connection to the server */ if (!*server) { errno=0; message(prg,'F',"no SAFT server is defined"); } snprintf(MAXS(tmp),"connecting to SAFT server %s",server); if (quiet<2) message(prg,'I',tmp); #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection(server,SAFT); #else sockfd=open_connection(server,SERVICE); #endif if (sockfd==-1) snprintf(MAXS(tmp),"cannot create a network socket"); if (sockfd==-2) snprintf(MAXS(tmp),"cannot open connection to %s",server); if (sockfd==-3) snprintf(MAXS(tmp),"%s is unknown",server); if (sockfd==-4) snprintf(MAXS(tmp),"out of memory"); if (sockfd<0) { errno=0; message(prg,'F',tmp); } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { errno=0; snprintf(MAXS(tmp),"No SAFT server on port %d at %s",SAFT,server); message(prg,'F',tmp); } /* send ID */ snprintf(MAXS(tmp),"ID %s",id); sock_putline(sockfd,tmp); sock_getline(sockfd,line); if (str_beq(line,"520")) { errno=0; snprintf(MAXS(tmp),"user %s is unknown on SAFT-server %s",id,server); message(prg,'F',tmp); } if (!str_beq(line,"331")) { errno=0; snprintf(MAXS(tmp),"server error: %s",line+4); message(prg,'F',tmp); } str_trim(line); cp=strrchr(line,' '); if (!cp) { errno=0; message(prg,'F',"bad answer from server"); } outf=rfopen(pgptmp,"w"); if (!outf) { errno=0; snprintf(MAXS(tmp),"cannot open/write to %s",pgptmp); message(prg,'F',tmp); } fprintf(outf,"%s",cp+1); fclose(outf); /* goto user spool directory */ if (chdir(userspool)<0) { snprintf(MAXS(tmp),"cannot change to %s",userspool); message(prg,'F',tmp); } /* call pgp */ /* DONT REMOVE 2>/dev/null IN THE FOLLOWING LINE! */ snprintf(MAXS(cmd),"cd %s; PGPPATH='.' %s -sbaf " "+secring=private.pgp +pubring=public.pgp <%s 2>/dev/null", userconfig,pgp_bin,pgptmp); if (verbose) printf("call: %s\n",cmd); if (!(pp=popen(cmd,"r"))) message(prg,'F',"call to pgp failed"); while (fgetl(line,pp) && strlen(response)+strlen(line)+3 < sizeof(response)) { if ((cp=strchr(line,'\n'))) *cp=0; strcat(response,line); strcat(response,"\r\n"); } pclose(pp); /* wrong pgp output? */ if (!strstr(response,"BEGIN PGP MESSAGE")) { errno=0; message(prg,'E',"corrupt pgp reply:"); cp=strrchr(cmd,'2'); *cp=0; system(cmd); message(prg,'F',"corrupt pgp reply"); } iso2utf(tmp,response); snprintf(MAXS(response),"AUTH %s",tmp); sendheader(sockfd,response); /* config file transfer? */ if (*conffile) { if (*conffile=='w') wconf=1; else wconf=0; /* extract real file name */ if (!(cp=strchr(conffile+1,'='))) cp=conffile; strcpy(tmp,cp+1); if (*tmp == '/') strcpy(conffile,tmp); else snprintf(MAXS(conffile),"%s/%s",swd,tmp); /* write config file */ if (wconf) { if ((cp=strrchr(conffile,'/'))) cp++; else cp=conffile; snprintf(MAXS(tmp),"CONF WRITE %s",cp); sock_putline(sockfd,tmp); sock_getline(sockfd,line); if (!str_beq(line,"302 ") && !str_beq(line,"200 ")) { errno=0; snprintf(MAXS(tmp),"server error: %s",line+4); message(prg,'F',tmp); } inf=rfopen(conffile,"r"); if (!inf) { snprintf(MAXS(tmp),"cannot open %s",conffile); message(prg,'F',tmp); } if (quiet<2) { snprintf(MAXS(tmp),"transfering %s",conffile); message(prg,'I',tmp); } /* send the file */ while (fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; sock_putline(sockfd,line); } sock_putline(sockfd,"\004"); /* End Of Transmission */ fclose(inf); sock_getline(sockfd,line); if (!str_beq(line,"201 ")) { errno=0; snprintf(MAXS(tmp),"server error: %s",line+4); message(prg,'F',tmp); } } else { /* read config file */ if ((cp=strrchr(conffile,'/'))) cp++; else cp=conffile; snprintf(MAXS(tmp),"CONF READ %s",cp); sock_putline(sockfd,tmp); while (sock_getline(sockfd,line)) { if (!str_beq(line,"250")) { errno=0; snprintf(MAXS(tmp),"server error: %s",line+4); message(prg,'F',tmp); } if (str_beq("250 ",line)) break; utf2iso(0,NULL,tmp,NULL,line+4); printf("%s\n",tmp); } } sock_putline(sockfd,"QUIT"); getreply(sockfd); close(sockfd); cleanup(); exit(0); } /* enable simple interrupt handler */ signal(SIGTERM,cleanexit); signal(SIGABRT,cleanexit); signal(SIGQUIT,cleanexit); signal(SIGHUP,cleanexit); signal(SIGINT,cleanexit); /* list files in outgoing spool */ if (list) { n=get_list(sockfd,server,id,listf); sock_putline(sockfd,"QUIT"); getreply(sockfd); close(sockfd); cleanup(); exit(n); } /* set tcp packet length */ if (packet_size<1) packet_size=PACKET; /* scan local spool */ sls=scanspool(""); if (numbers) { for (i=optind; i0) { /* change back to starting directory */ if (chdir(swd)<0) { snprintf(MAXS(tmp),"cannot change back to %s",swd); message(prg,'E',tmp); } else if (verbose) printf("shell-call: %s\n",rfilen); /* call receive */ system(rfilen); } exit(n); } /* * delete_file - delete a file from the server * * INPUT: sockfd - socket file descriptor * number - spool file number * * RETURN: 0 on success, -1 on error */ int delete_file(int sockfd, int number) { char line[MAXLEN]; /* one line of text */ /* send LIST command */ snprintf(MAXS(line),"DEL %d",number); sock_putline(sockfd,line); sock_getline(sockfd,line); if (str_beq(line,"200 ")) return(0); else return(-1); } /* * get_list - get list of files from server * * INPUT: sockfd - socket file descriptor * server - server name * id - user name * listf - list command output file * * RETURN: number of files, -1 on error */ int get_list(int sockfd, const char *server, const char *id, FILE *listf) { int i, /* simple loop counter */ n, /* number of files */ number; /* file number */ unsigned long size; /* file size */ char *cp, /* simple string pointer */ tmp[MAXLEN], /* temporary string */ line[MAXLEN], /* one line of text */ from[MAXLEN]; /* address and name of sender */ char *flist[6]; /* file list elements */ n=0; *from=0; /* send LIST command */ sock_putline(sockfd,"LIST"); for (;;) { /* get one line of answer from server */ sock_getline(sockfd,line); str_trim(line); /* invalid answer? */ if (!str_beq(line,"250")) { errno=0; snprintf(MAXS(tmp),"invalid answer from server: %s",line+4); message(prg,'E',tmp); return(n); } /* last answer line? */ if (str_beq(line,"250 ")) { if (!listf) printf("\n"); return(n); } /* write only to list file? */ if (listf) { fprintf(listf,"%s\n",line+4); continue; } /* print server ID on top */ if (!*from) { sprintf(tmp,"Files on SAFT-server %s for user %s:",server,id); printf("\n%s\n",tmp); for (i=1; i<80 && i<=strlen(tmp); i++) printf("="); printf("\n"); } /* split file list */ cp=line+4; str_trim(cp); for(i=1;i<6;i++) { flist[i]=cp; if ((cp=strchr(cp,' '))) { *cp=0; cp++; } } /* new from? */ if (!str_eq(from,flist[3])) { strcpy(from,flist[3]); utf2iso(0,NULL,tmp,NULL,from); printf("\nFrom %s\n",tmp); for (i=1; i<80 && i<=strlen(tmp)+5; i++) printf("-"); printf("\n"); } /* build and print list line */ if ((cp=strrchr(flist[5],':')) > strchr(flist[5],':')) *cp=0; number=atoi(flist[1]); size=atol(flist[4]); size=(size+1023)/1024; sprintf(tmp,"%3d) %s %8lu kB %s",number,flist[5],size,flist[2]); utf2iso(1,NULL,line,NULL,tmp); printf("%s\n",line); n++; } } /* * get_file - get a file from the server * * INPUT: sockfd - socket file descriptor * number - file number * ptso - flag for "pipe to standard output" * * RETURN: 0 if ok, -1 on error */ int get_file(int sockfd, int number, int ptso) { int percent, /* what percentage of file has been transmitted */ chunk, /* number of bytes in one read chunk */ shfd, /* spool header file descriptor */ sdfd, /* spool data file descriptor */ id; /* local spool id */ unsigned long msec, /* milliseconds */ size, /* total file size */ rsize, /* rest file size */ offset, /* bytes that have been already transfered */ bytes; /* bytes to receive */ char *cp, /* simple string pointer */ date[DLEN], /* date string */ shfile[FLEN], /* spool header file */ sdfile[FLEN], /* spool data file */ packet[OVERSIZE], /* one line of text */ line[MAXLEN], /* one line of text */ from[MAXLEN], /* sender name (address) */ fname[MAXLEN], /* file name */ tmp[MAXLEN]; /* temporary string */ time_t sec1,sec2; /* unix time */ float thruput; /* net throughput */ struct filelist * flp; /* file list pointer */ struct senderlist *slp; /* sender list pointer */ struct timeval tv1,tv2; #if !defined(SOLARIS2) && !defined(IRIX) struct timezone tz; #endif id=0; shfd=0; sdfd=0; size=0; offset=0; *date=0; flp=NULL; /* get time normal */ #if defined(SOLARIS2) || defined(IRIX) #ifdef _SVID_GETTOD gettimeofday(&tv1); #else gettimeofday(&tv1,NULL); #endif #else gettimeofday(&tv1,&tz); #endif sec1=0; /* get next spool id */ if (!ptso) { id=spoolid(999999); if (!id) message(prg,'F',"cannot create local spool file"); /* open spool header and data files */ snprintf(MAXS(shfile),"%d.h",id); snprintf(MAXS(sdfile),"%d.d",id); sdfd=open(sdfile,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); shfd=open(shfile,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); if (shfd<0 || sdfd<0) message(prg,'F',"cannot create local spool file"); } snprintf(MAXS(tmp),"GET HEADER %d",number); sock_putline(sockfd,tmp); for (;;) { /* get one line of answer from server */ sock_getline(sockfd,line); str_trim(line); /* invalid answer? */ if (!str_beq(line,"250")) { if (!ptso) { close(sdfd); close(shfd); unlink(sdfile); unlink(shfile); } errno=0; snprintf(MAXS(tmp),"server-error: %s",line+4); message(prg,'E',tmp); return(-1); } /* last answer line? */ if (str_beq(line,"250 ")) break; /* make SAFT commands uppercase */ if ((cp=strchr(line+4,' '))) { *cp=0; str_toupper(line+4); *cp='\t'; } /* store attributes */ if (str_beq(line+4,"FILE")) strcpy(fname,line+9); if (str_beq(line+4,"SIZE")) size=atol(line+9); if (str_beq(line+4,"DATE")) utf2iso(1,date,NULL,NULL,line+9); if (str_beq(line+4,"FROM")) { if ((cp=strchr(line+10,' '))) { *cp=0; snprintf(MAXS(tmp),"%s (%s)",line+9,cp+1); *cp=' '; } else strcpy(tmp,line+9); utf2iso(1,from,NULL,NULL,tmp); } strcat(line,"\n"); if (ptso) printf("%s",line+4); else write(shfd,line+4,strlen(line+4)); } close(shfd); /* check if file has been already fetched and how much of it */ if (!ignore) { /* loop over sender list */ for (slp=sls, offset=0; slp!=NULL; slp=slp->next) { /* same sender? */ if (str_eq(slp->from,from)) { /* loop over files list */ for (flp=slp->flist; flp!=NULL; flp=flp->next) { /* same file? */ if (str_eq(flp->fname,fname) && flp->csize==size && (*date==0 || str_eq(flp->date,date))) { offset=flp->tsize; break; } } } /* leave loop if found */ if (offset) break; } } utf2iso(1,NULL,tmp,NULL,fname); strcpy(fname,tmp); if (quiet<2) { if (flp && flp->csize==offset) { snprintf(MAXS(tmp),"file %d (%s) has been already fetched",number,fname); message(prg,'I',tmp); } else { if (quiet==1) { if (offset) snprintf(MAXS(tmp),"resuming fetching file %d (%s) with %ld kB", number,fname,(size+1023)/1024); else snprintf(MAXS(tmp),"fetching file %d (%s) with %ld kB", number,fname,(size+1023)/1024); message(prg,'I',tmp); } } } if (flp && flp->csize==offset) { close(sdfd); unlink(sdfile); unlink(shfile); return(0); } snprintf(MAXS(tmp),"GET FILE %d %ld",number,offset); sock_putline(sockfd,tmp); sock_getline(sockfd,line); /* invalid answer? */ if (!str_beq(line,"231 ")) { if (!ptso) { close(sdfd); unlink(sdfile); unlink(shfile); } errno=0; snprintf(MAXS(tmp),"server-error: %s",line+4); message(prg,'E',tmp); return(-1); } if (ptso) printf("DATA\n"); fflush(stdout); rsize=atol(line+4); /* resend active? */ if (offset && quiet<2) { snprintf(MAXS(tmp),"resuming at byte %ld",offset); message("",'I',tmp); } bytes=0; while (bytessec1) { fprintf(stderr,"%s: %3d%% (%ld of %ld kB)\r", fname,percent,(bytes+offset-1)/1024+1,(size-1)/1024+1); fflush(stderr); sec1=sec2; } } write(sdfd,packet,chunk); } } if (!ptso) close(sdfd); /* note spool number for auto-receive */ if (*rfilen) { sprintf(tmp," %d",id); strcat(rfilen,tmp); } if (quiet<2) { /* get time difference */ #if defined(SOLARIS2) || defined(IRIX) #ifdef _SVID_GETTOD gettimeofday(&tv2); #else gettimeofday(&tv2,NULL); #endif #else gettimeofday(&tv2,&tz); #endif msec=(tv2.tv_usec-tv1.tv_usec)/1000+(tv2.tv_sec-tv1.tv_sec)*1000; if (msec<1) msec=1; thruput=bytes*1000.0/msec; /* print transfer statistics */ if (quiet==1) { if (thruput>9999) snprintf(MAXS(tmp), "transfer of %s completed: %.1f kB/s",fname,thruput/1024); else snprintf(MAXS(tmp), "transfer of %s completed: %d byte/s",fname,(int)thruput); message("",'I',tmp); } else { if (bytes>9999) fprintf(stderr,"%s: 100%% (%ld kB, ",fname,bytes/1024); else fprintf(stderr,"%s: 100%% (%ld byte, ",fname,bytes); if (thruput>9999) fprintf(stderr,"%.1f kB/s) \n",thruput/1024); else fprintf(stderr,"%d byte/s) \n",(int)thruput); fflush(stderr); } } return(0); } /* * reply - dummy function, only needed for linking */ void reply(int x) { } /* * init - initialize spool and pgp for fetchfile */ void init() { char answer[FLEN], /* answer string */ server[FLEN], /* SAFT server */ configf[MAXLEN], /* config file */ tmp[MAXLEN]; /* temporary string */ struct stat finfo; /* information about a file */ FILE *outf; /* file to create */ *server=0; sprintf(configf,"%s/config",userconfig); umask(~S_IRWXU); printf("\nThis is the init routine for %s.\n",prg); printf("It will create the necessary pgp files and the spool directory.\n"); printf("You can press Ctrl-C at any time to stop this procedure.\n\n"); snprintf(MAXS(userspool),SPOOL"/%s",pwe->pw_name); if (stat(userspool,&finfo)<0 || !(finfo.st_mode&S_IFDIR)) { printf("User spool %s does not exist.\n",userspool); snprintf(MAXS(userspool),"%s/.sfspool",pwe->pw_dir); printf("May I create local spool %s? ",userspool); fgetl(answer,stdin); if (*answer!='y' && *answer!='Y') { errno=0; message(prg,'F',"cannot continue with answer 'no'."); } if (mkdir(userspool,S_IRWXU)<0) { sprintf(tmp,"cannot create directory %s",userspool); message(prg,'F',tmp); } } if (stat(userconfig,&finfo)<0) { if (mkdir(userconfig,S_IRWXU)<0) { sprintf(tmp,"cannot create config directory %s",userconfig); message(prg,'F',tmp); } } if (chdir(userconfig)<0) { sprintf(tmp,"cannot change to directory %s",userconfig); message(prg,'F',tmp); } if (!(outf=rfopen(configf,"a"))) { snprintf(MAXS(tmp),"cannot open %s",configf); message(prg,'F',tmp); } printf("What is the address of your SAFT server where you want to " "poll your files?\n"); while (getpromptline(MAXS(server))==NULL || *server=='\n' || *server==0) printf("Illegal address! Please repeat: "); fprintf(outf,"\n# The address of your default SAFT-server for fetchfile\n"); fprintf(outf,"server = %s\n",server); fclose(outf); if (stat("public.pgp",&finfo)==0 || stat("private.pgp",&finfo)==0) { printf("There are already pgp files in your config directory %s\n",userconfig); printf("Overwrite them? "); fgetl(answer,stdin); if (*answer!='y' && *answer!='Y') { errno=0; message(prg,'F',"cannot continue with answer 'no'."); } } printf("\npgp will now be started to create a new sendfile-only key pair.\n"); printf("When asked, you can enter your normal e-mail address.\n\n"); printf("YOU MUST ENTER AN EMPTY PASS PHRASE, "); printf("OR FETCHFILE WILL NOT WORK!\n\n"); if (system("PGPPATH='.' " " pgp -kg +pubring=public.pgp +secring=private.pgp 1024")) message(prg,'F',"pgp call failed"); printf("\nYou should now send %s/public.pgp to\n",userconfig); printf("root@%s, because this file has to be stored in your\n",server); printf("sendfile spool on %s\n",server); printf("For example you can type:\n"); printf("sendfile -c 'this is my SAFT/fetchfile public key' \\\n"); printf(" %s/public.pgp root@%s\n\n",userconfig,server); printf("If you want to change your default SAFT server, then edit\n%s\n\n", configf); exit(0); } /* * sendfiled_test - test local sendfiled * * INPUT: user - user name * * RETURN: 0 if ok, -1 if failed */ int sendfiled_test(const char *user) { int sockfd; /* socket file descriptor */ char line[MAXLEN]; /* one line of text */ /* test the local sendfiled */ if (verbose) printf("testing local SAFT server:\n"); #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection("127.0.0.1",SAFT); #else sockfd=open_connection("127.0.0.1",SERVICE); #endif sock_getline(sockfd,line); /* no local server? */ if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) return(-1); /* test if you can receive messages */ snprintf(MAXS(line),"FROM %s",user); sock_putline(sockfd,line); sock_getline(sockfd,line); if (!str_beq(line,"200 ")) return(-1); snprintf(MAXS(line),"TO %s",user); sock_putline(sockfd,line); sock_getline(sockfd,line); if (!str_beq(line,"200 ")) return(-1); sock_putline(sockfd,"FILE test"); sock_getline(sockfd,line); if (!str_beq(line,"200 ")) return(-1); sock_putline(sockfd,"QUIT"); sock_getline(sockfd,line); close(sockfd); return(0); } /* * usage - print short help usage text */ int usage() { fprintf(stderr,"\n"); fprintf(stderr,"usage: %s [OPTIONS]\n",prg); fprintf(stderr," or: %s [OPTIONS] file [...]\n",prg); fprintf(stderr," or: %s [OPTIONS] -n file-number [...]\n",prg); fprintf(stderr,"options: -l only list files\n"); fprintf(stderr," -a fetch all files\n"); fprintf(stderr," -k keep file on SAFT-server after receiving\n"); fprintf(stderr," -d delete file on SAFT-server without receiving\n"); fprintf(stderr," -n fetch file number instead of file name\n"); fprintf(stderr," -P pipe file directly to stdout\n"); fprintf(stderr," -r call receive automatically\n"); fprintf(stderr," -i ignore testing if file has already been fetched\n"); fprintf(stderr," -q quiet mode 1: no information messages\n"); fprintf(stderr," -Q quiet mode 2: no information or transfer messages\n"); fprintf(stderr," -v verbose output\n"); fprintf(stderr," -V show version information\n"); fprintf(stderr," -I initalize fetchfile (pgp and spool)\n"); fprintf(stderr," -f user fetch only files from this user\n"); fprintf(stderr," -s [user@]server specify alternate SAFT-server and user name\n"); fprintf(stderr," -Cw=conffile send config file to server\n"); fprintf(stderr," -Cr=conffile read config file from server\n"); fprintf(stderr," (conffile is \"config\" or \"restrictions\", see: man sendfile)\n"); #ifdef ENABLE_MULTIPROTOCOL fprintf(stderr," -4 explicitly force ipv4 connections\n"); fprintf(stderr," -6 explicitly force ipv6 connections\n"); #endif fprintf(stderr,"examples: %s -l\n",prg); fprintf(stderr," %s -a\n",prg); fprintf(stderr," %s hoppel.gif\n\n",prg); return(2); } sendfile-2.1b/src/getdate.c0000640000175100001440000013367210251136250015406 0ustar framstagusers/* ** Originally written by Steven M. Bellovin while ** at the University of North Carolina at Chapel Hill. Later tweaked by ** a couple of people on Usenet. Completely overhauled by Rich $alz ** and Jim Berets in August, 1990; ** send any email to Rich. ** ** This grammar has 10 shift/reduce conflicts. ** ** This code is in the public domain and has no copyright. */ /* 2000-01-02 chatila@faxmate.com fixed a Y2K bug in Convert() */ #define YYBISON 1 /* Identify Bison output. */ #define tAGO 258 #define tDAY 259 #define tDAYZONE 260 #define tID 261 #define tMERIDIAN 262 #define tMINUTE_UNIT 263 #define tMONTH 264 #define tMONTH_UNIT 265 #define tSEC_UNIT 266 #define tSNUMBER 267 #define tUNUMBER 268 #define tZONE 269 #define tDST 270 #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HPUX #define alloca(x) malloc(x) #endif /* ** The code at the top of get_date which figures out the offset of the ** current time zone checks various CPP symbols to see if special ** tricks are need, but defaults to using the gettimeofday system call. ** Include if that will be used. */ #if defined (vms) #include #include #else #include #if defined(TIME_WITH_SYS_TIME) #include #include #else #if defined(HAVE_SYS_TIME_H) #include #else #include #endif #endif #ifdef timezone #undef timezone /* needed for sgi */ #endif #if defined (HAVE_SYS_TIMEB_H) #include #else /* ** We use the obsolete `struct timeb' as part of our interface! ** Since the system doesn't have it, we define it here; ** our callers must do likewise. */ struct timeb { time_t time; /* Seconds since the epoch */ unsigned short millitm; /* Field not used */ short timezone; /* Minutes west of GMT */ short dstflag; /* Field not used */ }; #endif /* defined (HAVE_SYS_TIMEB_H) */ #endif /* defined (vms) */ extern struct tm *gmtime (); extern struct tm *localtime (); #define yyparse getdate_yyparse #define yylex getdate_yylex #define yyerror getdate_yyerror static int yylex (); static int yyerror (); #define EPOCH 1970 #define HOUR(x) ((time_t)(x) * 60) #define SECSPERDAY (24L * 60L * 60L) #define MAX_BUFF_LEN 128 /* size of buffer to read the date into */ /* ** An entry in the lexical lookup table. */ typedef struct _TABLE { const char *name; int type; time_t value; } TABLE; /* ** Daylight-savings mode: on, off, or not yet known. */ typedef enum _DSTMODE { DSTon, DSToff, DSTmaybe } DSTMODE; /* ** Meridian: am, pm, or 24-hour style. */ typedef enum _MERIDIAN { MERam, MERpm, MER24 } MERIDIAN; /* ** Global variables. We could get rid of most of these by using a good ** union as the yacc stack. (This routine was originally written before ** yacc had the %union construct.) Maybe someday; right now we only use ** the %union very rarely. */ static char *yyInput; static DSTMODE yyDSTmode; static time_t yyDayOrdinal; static time_t yyDayNumber; static int yyHaveDate; static int yyHaveDay; static int yyHaveRel; static int yyHaveTime; static int yyHaveZone; static time_t yyTimezone; static time_t yyDay; static time_t yyHour; static time_t yyMinutes; static time_t yyMonth; static time_t yySeconds; static time_t yyYear; static MERIDIAN yyMeridian; static time_t yyRelMonth; static time_t yyRelSeconds; typedef union { time_t Number; enum _MERIDIAN Meridian; } YYSTYPE; #ifndef YYLTYPE typedef struct yyltype { int timestamp; int first_line; int first_column; int last_line; int last_column; char *text; } yyltype; #define YYLTYPE yyltype #endif #include #ifndef __cplusplus #ifndef __STDC__ #define const #endif #endif #define YYFINAL 52 #define YYFLAG -32768 #define YYNTBASE 19 #define YYTRANSLATE(x) ((unsigned)(x) <= 270 ? yytranslate[x] : 29) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 2, 2, 18, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; #if YYDEBUG != 0 static const short yyprhs[] = { 0, 0, 1, 4, 6, 8, 10, 12, 14, 16, 19, 24, 29, 36, 43, 45, 47, 50, 52, 55, 58, 62, 68, 72, 76, 79, 84, 87, 91, 94, 96, 99, 102, 104, 107, 110, 112, 115, 118, 120, 122, 123 }; static const short yyrhs[] = { -1, 19, 20, 0, 21, 0, 22, 0, 24, 0, 23, 0, 25, 0, 27, 0, 13, 7, 0, 13, 16, 13, 28, 0, 13, 16, 13, 12, 0, 13, 16, 13, 16, 13, 28, 0, 13, 16, 13, 16, 13, 12, 0, 14, 0, 5, 0, 14, 15, 0, 4, 0, 4, 17, 0, 13, 4, 0, 13, 18, 13, 0, 13, 18, 13, 18, 13, 0, 13, 12, 12, 0, 13, 9, 12, 0, 9, 13, 0, 9, 13, 17, 13, 0, 13, 9, 0, 13, 9, 13, 0, 26, 3, 0, 26, 0, 13, 8, 0, 12, 8, 0, 8, 0, 12, 11, 0, 13, 11, 0, 11, 0, 12, 10, 0, 13, 10, 0, 10, 0, 13, 0, 0, 7, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, 174, 175, 178, 181, 184, 187, 190, 193, 196, 202, 208, 215, 221, 231, 235, 239, 246, 250, 254, 260, 264, 269, 275, 281, 285, 290, 294, 301, 305, 308, 311, 314, 317, 320, 323, 326, 329, 332, 337, 364, 367 }; static const char * const yytname[] = { "$","error","$illegal.","tAGO","tDAY", "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT", "tSNUMBER","tUNUMBER","tZONE","tDST","':'","','","'/'","spec","item","time", "zone","day","date","rel","relunit","number","o_merid","" }; #endif static const short yyr1[] = { 0, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 28, 28 }; static const short yyr2[] = { 0, 0, 2, 1, 1, 1, 1, 1, 1, 2, 4, 4, 6, 6, 1, 1, 2, 1, 2, 2, 3, 5, 3, 3, 2, 4, 2, 3, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 0, 1 }; static const short yydefact[] = { 1, 0, 17, 15, 32, 0, 38, 35, 0, 39, 14, 2, 3, 4, 6, 5, 7, 29, 8, 18, 24, 31, 36, 33, 19, 9, 30, 26, 37, 34, 0, 0, 0, 16, 28, 0, 23, 27, 22, 40, 20, 25, 41, 11, 0, 10, 0, 40, 21, 13, 12, 0, 0 }; static const short yydefgoto[] = { 1, 11, 12, 13, 14, 15, 16, 17, 18, 45 }; static const short yypact[] = {-32768, 0, -1,-32768,-32768, 4,-32768,-32768, 25, 11, -8, -32768,-32768,-32768,-32768,-32768,-32768, 21,-32768,-32768, 9, -32768,-32768,-32768,-32768,-32768,-32768, -10,-32768,-32768, 16, 19, 24,-32768,-32768, 26,-32768,-32768,-32768, 18, 13, -32768,-32768,-32768, 27,-32768, 28, -6,-32768,-32768,-32768, 38,-32768 }; static const short yypgoto[] = {-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5 }; #define YYLAST 42 static const short yytable[] = { 51, 42, 36, 37, 2, 3, 49, 33, 4, 5, 6, 7, 8, 9, 10, 24, 19, 20, 25, 26, 27, 28, 29, 30, 34, 42, 35, 31, 38, 32, 43, 46, 39, 21, 44, 22, 23, 40, 52, 41, 47, 48, 50 }; static const short yycheck[] = { 0, 7, 12, 13, 4, 5, 12, 15, 8, 9, 10, 11, 12, 13, 14, 4, 17, 13, 7, 8, 9, 10, 11, 12, 3, 7, 17, 16, 12, 18, 12, 18, 13, 8, 16, 10, 11, 13, 0, 13, 13, 13, 47 }; /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef alloca #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not GNU C. */ #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) #include #else /* not sparc */ #if defined (MSDOS) && !defined (__TURBOC__) #include #else /* not MSDOS, or __TURBOC__ */ #if defined(_AIX) #include #pragma alloca #else /* not MSDOS, __TURBOC__, or _AIX */ #ifdef __hpux #ifdef __cplusplus extern "C" { void *alloca (unsigned int); }; #else /* not __cplusplus */ void *alloca (); #endif /* not __cplusplus */ #endif /* __hpux */ #endif /* not _AIX */ #endif /* not MSDOS, or __TURBOC__ */ #endif /* not sparc. */ #endif /* not GNU C. */ #endif /* alloca not defined. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ /* Note: there must be only one dollar sign in this file. It is replaced by the list of actions, each action as one case of the switch. */ #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT return(0) #define YYABORT return(1) #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(token, value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { yychar = (token), yylval = (value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 #ifndef YYPURE #define YYLEX yylex() #endif #ifdef YYPURE #ifdef YYLSP_NEEDED #define YYLEX yylex(&yylval, &yylloc) #else #define YYLEX yylex(&yylval) #endif #endif /* If nonreentrant, generate the variables here */ #ifndef YYPURE int yychar; /* the lookahead symbol */ YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ #ifdef YYLSP_NEEDED YYLTYPE yylloc; /* location data for the lookahead */ /* symbol */ #endif int yynerrs; /* number of parse errors so far */ #endif /* not YYPURE */ #if YYDEBUG != 0 int yydebug; /* nonzero means print parse trace */ /* Since this is uninitialized, it does not stop multiple parsers from coexisting. */ #endif /* YYINITDEPTH indicates the initial size of the parser's stacks */ #ifndef YYINITDEPTH #define YYINITDEPTH 200 #endif /* YYMAXDEPTH is the maximum size the stacks can grow to (effective only if the built-in stack extension method is used). */ #if YYMAXDEPTH == 0 #undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH #define YYMAXDEPTH 10000 #endif /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ int yyparse (void); #endif #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) #else /* not GNU C or C++ */ #ifndef __cplusplus /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __yy_bcopy (from, to, count) char *from; char *to; int count; { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #else /* __cplusplus */ /* This is the most reliable way to avoid incompatibilities in available built-in functions on various systems. */ static void __yy_bcopy (char *from, char *to, int count) { register char *f = from; register char *t = to; register int i = count; while (i-- > 0) *t++ = *f++; } #endif #endif int yyparse() { register int yystate; register int yyn; register short *yyssp; register YYSTYPE *yyvsp; int yyerrstatus; /* number of tokens to shift before error messages enabled */ int yychar1 = 0; /* lookahead token as an internal (translated) token number */ short yyssa[YYINITDEPTH]; /* the state stack */ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ short *yyss = yyssa; /* refer to the stacks thru separate pointers */ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ #ifdef YYLSP_NEEDED YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else #define YYPOPSTACK (yyvsp--, yyssp--) #endif int yystacksize = YYINITDEPTH; #ifdef YYPURE int yychar; YYSTYPE yylval; int yynerrs; #ifdef YYLSP_NEEDED YYLTYPE yylloc; #endif #endif YYSTYPE yyval; /* the variable used to return */ /* semantic values from the action */ /* routines */ int yylen; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Starting parse\n"); #endif yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss - 1; yyvsp = yyvs; #ifdef YYLSP_NEEDED yylsp = yyls; #endif /* Push a new state, which is found in yystate . */ /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yynewstate: *++yyssp = yystate; if (yyssp >= yyss + yystacksize - 1) { /* Give user a chance to reallocate the stack */ /* Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; #ifdef YYLSP_NEEDED YYLTYPE *yyls1 = yyls; #endif /* Get the current used size of the three stacks, in elements. */ int size = yyssp - yyss + 1; #ifdef yyoverflow /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ #ifdef YYLSP_NEEDED /* This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow("parser stack overflow", &yyss1, size * sizeof (*yyssp), &yyvs1, size * sizeof (*yyvsp), &yyls1, size * sizeof (*yylsp), &yystacksize); #else yyoverflow("parser stack overflow", &yyss1, size * sizeof (*yyssp), &yyvs1, size * sizeof (*yyvsp), &yystacksize); #endif yyss = yyss1; yyvs = yyvs1; #ifdef YYLSP_NEEDED yyls = yyls1; #endif #else /* no yyoverflow */ /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) { yyerror("parser stack overflow"); return 2; } yystacksize *= 2; if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); #ifdef YYLSP_NEEDED yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); #endif #endif /* no yyoverflow */ yyssp = yyss + size - 1; yyvsp = yyvs + size - 1; #ifdef YYLSP_NEEDED yylsp = yyls + size - 1; #endif #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Stack size increased to %d\n", yystacksize); #endif if (yyssp >= yyss + yystacksize - 1) YYABORT; } #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Entering state %d\n", yystate); #endif goto yybackup; yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* yychar is either YYEMPTY or YYEOF or a valid token in external form. */ if (yychar == YYEMPTY) { #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Reading a token: "); #endif yychar = YYLEX; } /* Convert token to internal form (in yychar1) for indexing tables with */ if (yychar <= 0) /* This means end of input. */ { yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Now at end of input.\n"); #endif } else { yychar1 = YYTRANSLATE(yychar); #if YYDEBUG != 0 if (yydebug) { fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ #ifdef YYPRINT YYPRINT (stderr, yychar, yylval); #endif fprintf (stderr, ")\n"); } #endif } yyn += yychar1; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; yyn = yytable[yyn]; /* yyn is what to do for this token type in this state. Negative => reduce, -yyn is rule number. Positive => shift, yyn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (yyn < 0) { if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); #endif /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; #ifdef YYLSP_NEEDED *++yylsp = yylloc; #endif /* count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /* Do the default action for the current state. */ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; /* Do a reduction. yyn is the number of a rule to reduce with. */ yyreduce: yylen = yyr2[yyn]; if (yylen > 0) yyval = yyvsp[1-yylen]; /* implement default value of the action */ #if YYDEBUG != 0 if (yydebug) { int i; fprintf (stderr, "Reducing via rule %d (line %d), ", yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) fprintf (stderr, "%s ", yytname[yyrhs[i]]); fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); } #endif switch (yyn) { case 3: { yyHaveTime++; ; break;} case 4: { yyHaveZone++; ; break;} case 5: { yyHaveDate++; ; break;} case 6: { yyHaveDay++; ; break;} case 7: { yyHaveRel++; ; break;} case 9: { yyHour = yyvsp[-1].Number; yyMinutes = 0; yySeconds = 0; yyMeridian = yyvsp[0].Meridian; ; break;} case 10: { yyHour = yyvsp[-3].Number; yyMinutes = yyvsp[-1].Number; yySeconds = 0; yyMeridian = yyvsp[0].Meridian; ; break;} case 11: { yyHour = yyvsp[-3].Number; yyMinutes = yyvsp[-1].Number; yyMeridian = MER24; yyDSTmode = DSToff; yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60); ; break;} case 12: { yyHour = yyvsp[-5].Number; yyMinutes = yyvsp[-3].Number; yySeconds = yyvsp[-1].Number; yyMeridian = yyvsp[0].Meridian; ; break;} case 13: { yyHour = yyvsp[-5].Number; yyMinutes = yyvsp[-3].Number; yySeconds = yyvsp[-1].Number; yyMeridian = MER24; yyDSTmode = DSToff; yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60); ; break;} case 14: { yyTimezone = yyvsp[0].Number; yyDSTmode = DSToff; ; break;} case 15: { yyTimezone = yyvsp[0].Number; yyDSTmode = DSTon; ; break;} case 16: { yyTimezone = yyvsp[-1].Number; yyDSTmode = DSTon; ; break;} case 17: { yyDayOrdinal = 1; yyDayNumber = yyvsp[0].Number; ; break;} case 18: { yyDayOrdinal = 1; yyDayNumber = yyvsp[-1].Number; ; break;} case 19: { yyDayOrdinal = yyvsp[-1].Number; yyDayNumber = yyvsp[0].Number; ; break;} case 20: { yyMonth = yyvsp[-2].Number; yyDay = yyvsp[0].Number; ; break;} case 21: { yyMonth = yyvsp[-4].Number; yyDay = yyvsp[-2].Number; yyYear = yyvsp[0].Number; ; break;} case 22: { /* ISO 8601 format. yyyy-mm-dd. */ yyYear = yyvsp[-2].Number; yyMonth = -yyvsp[-1].Number; yyDay = -yyvsp[0].Number; ; break;} case 23: { /* e.g. 17-JUN-1992. */ yyDay = yyvsp[-2].Number; yyMonth = yyvsp[-1].Number; yyYear = -yyvsp[0].Number; ; break;} case 24: { yyMonth = yyvsp[-1].Number; yyDay = yyvsp[0].Number; ; break;} case 25: { yyMonth = yyvsp[-3].Number; yyDay = yyvsp[-2].Number; yyYear = yyvsp[0].Number; ; break;} case 26: { yyMonth = yyvsp[0].Number; yyDay = yyvsp[-1].Number; ; break;} case 27: { yyMonth = yyvsp[-1].Number; yyDay = yyvsp[-2].Number; yyYear = yyvsp[0].Number; ; break;} case 28: { yyRelSeconds = -yyRelSeconds; yyRelMonth = -yyRelMonth; ; break;} case 30: { yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L; ; break;} case 31: { yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L; ; break;} case 32: { yyRelSeconds += yyvsp[0].Number * 60L; ; break;} case 33: { yyRelSeconds += yyvsp[-1].Number; ; break;} case 34: { yyRelSeconds += yyvsp[-1].Number; ; break;} case 35: { yyRelSeconds++; ; break;} case 36: { yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; ; break;} case 37: { yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number; ; break;} case 38: { yyRelMonth += yyvsp[0].Number; ; break;} case 39: { if (yyHaveTime && yyHaveDate && !yyHaveRel) yyYear = yyvsp[0].Number; else { if (yyvsp[0].Number>10000) { yyHaveDate++; yyDay= (yyvsp[0].Number)%100; yyMonth= (yyvsp[0].Number/100)%100; yyYear = yyvsp[0].Number/10000; } else { yyHaveTime++; if (yyvsp[0].Number < 100) { yyHour = yyvsp[0].Number; yyMinutes = 0; } else { yyHour = yyvsp[0].Number / 100; yyMinutes = yyvsp[0].Number % 100; } yySeconds = 0; yyMeridian = MER24; } } ; break;} case 40: { yyval.Meridian = MER24; ; break;} case 41: { yyval.Meridian = yyvsp[0].Meridian; ; break;} } /* the action file gets copied in in place of this dollarsign */ yyvsp -= yylen; yyssp -= yylen; #ifdef YYLSP_NEEDED yylsp -= yylen; #endif #if YYDEBUG != 0 if (yydebug) { short *ssp1 = yyss - 1; fprintf (stderr, "state stack now"); while (ssp1 != yyssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif *++yyvsp = yyval; #ifdef YYLSP_NEEDED yylsp++; if (yylen == 0) { yylsp->first_line = yylloc.first_line; yylsp->first_column = yylloc.first_column; yylsp->last_line = (yylsp-1)->last_line; yylsp->last_column = (yylsp-1)->last_column; yylsp->text = 0; } else { yylsp->last_line = (yylsp+yylen-1)->last_line; yylsp->last_column = (yylsp+yylen-1)->last_column; } #endif /* Now "shift" the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTBASE] + *yyssp; if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; yyerrlab: /* here on detecting error */ if (! yyerrstatus) /* If not already recovering from an error, report this error. */ { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) { int size = 0; char *msg; int x, count; count = 0; /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ for (x = (yyn < 0 ? -yyn : 0); x < (sizeof(yytname) / sizeof(char *)); x++) if (yycheck[x + yyn] == x) size += strlen(yytname[x]) + 15, count++; msg = (char *) malloc(size + 15); if (msg != 0) { strcpy(msg, "parse error"); if (count < 5) { count = 0; for (x = (yyn < 0 ? -yyn : 0); x < (sizeof(yytname) / sizeof(char *)); x++) if (yycheck[x + yyn] == x) { strcat(msg, count == 0 ? ", expecting `" : " or `"); strcat(msg, yytname[x]); strcat(msg, "'"); count++; } } yyerror(msg); free(msg); } else yyerror ("parse error; also virtual memory exceeded"); } else #endif /* YYERROR_VERBOSE */ yyerror("parse error"); } goto yyerrlab1; yyerrlab1: /* here on error raised explicitly by an action */ if (yyerrstatus == 3) { /* if just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) YYABORT; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); #endif yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ yyerrstatus = 3; /* Each real token shifted decrements this */ goto yyerrhandle; yyerrdefault: /* current state does not do anything special for the error token. */ #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ if (yyn) goto yydefault; #endif yyerrpop: /* pop the current state because it cannot handle the error token */ if (yyssp == yyss) YYABORT; yyvsp--; yystate = *--yyssp; #ifdef YYLSP_NEEDED yylsp--; #endif #if YYDEBUG != 0 if (yydebug) { short *ssp1 = yyss - 1; fprintf (stderr, "Error: state stack now"); while (ssp1 != yyssp) fprintf (stderr, " %d", *++ssp1); fprintf (stderr, "\n"); } #endif yyerrhandle: yyn = yypact[yystate]; if (yyn == YYFLAG) goto yyerrdefault; yyn += YYTERROR; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) goto yyerrdefault; yyn = yytable[yyn]; if (yyn < 0) { if (yyn == YYFLAG) goto yyerrpop; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; #if YYDEBUG != 0 if (yydebug) fprintf(stderr, "Shifting error token, "); #endif *++yyvsp = yylval; #ifdef YYLSP_NEEDED *++yylsp = yylloc; #endif yystate = yyn; goto yynewstate; } /* Month and day table. */ static TABLE const MonthDayTable[] = { { "january", tMONTH, 1 }, { "february", tMONTH, 2 }, { "march", tMONTH, 3 }, { "april", tMONTH, 4 }, { "may", tMONTH, 5 }, { "june", tMONTH, 6 }, { "july", tMONTH, 7 }, { "august", tMONTH, 8 }, { "september", tMONTH, 9 }, { "sept", tMONTH, 9 }, { "october", tMONTH, 10 }, { "november", tMONTH, 11 }, { "december", tMONTH, 12 }, { "sunday", tDAY, 0 }, { "monday", tDAY, 1 }, { "tuesday", tDAY, 2 }, { "tues", tDAY, 2 }, { "wednesday", tDAY, 3 }, { "wednes", tDAY, 3 }, { "thursday", tDAY, 4 }, { "thur", tDAY, 4 }, { "thurs", tDAY, 4 }, { "friday", tDAY, 5 }, { "saturday", tDAY, 6 }, { NULL } }; /* Time units table. */ static TABLE const UnitsTable[] = { { "year", tMONTH_UNIT, 12 }, { "month", tMONTH_UNIT, 1 }, { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 }, { "week", tMINUTE_UNIT, 7 * 24 * 60 }, { "day", tMINUTE_UNIT, 1 * 24 * 60 }, { "hour", tMINUTE_UNIT, 60 }, { "minute", tMINUTE_UNIT, 1 }, { "min", tMINUTE_UNIT, 1 }, { "second", tSEC_UNIT, 1 }, { "sec", tSEC_UNIT, 1 }, { NULL } }; /* Assorted relative-time words. */ static TABLE const OtherTable[] = { { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, { "today", tMINUTE_UNIT, 0 }, { "now", tMINUTE_UNIT, 0 }, { "last", tUNUMBER, -1 }, { "this", tMINUTE_UNIT, 0 }, { "next", tUNUMBER, 2 }, { "first", tUNUMBER, 1 }, /* { "second", tUNUMBER, 2 }, */ { "third", tUNUMBER, 3 }, { "fourth", tUNUMBER, 4 }, { "fifth", tUNUMBER, 5 }, { "sixth", tUNUMBER, 6 }, { "seventh", tUNUMBER, 7 }, { "eighth", tUNUMBER, 8 }, { "ninth", tUNUMBER, 9 }, { "tenth", tUNUMBER, 10 }, { "eleventh", tUNUMBER, 11 }, { "twelfth", tUNUMBER, 12 }, { "ago", tAGO, 1 }, { NULL } }; /* The timezone table. */ /* Some of these are commented out because a time_t can't store a float. */ static TABLE const TimezoneTable[] = { { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */ { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ { "utc", tZONE, HOUR ( 0) }, { "wet", tZONE, HOUR ( 0) }, /* Western European */ { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */ { "wat", tZONE, HOUR ( 1) }, /* West Africa */ { "at", tZONE, HOUR ( 2) }, /* Azores */ #if 0 /* For completeness. BST is also British Summer, and GST is * also Guam Standard. */ { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */ { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */ #endif #if 0 { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */ { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */ { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */ #endif { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */ { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */ { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */ { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */ { "cst", tZONE, HOUR ( 6) }, /* Central Standard */ { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */ { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */ { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */ { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */ { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */ { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */ { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */ { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */ { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */ { "cat", tZONE, HOUR (10) }, /* Central Alaska */ { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */ { "nt", tZONE, HOUR (11) }, /* Nome */ { "idlw", tZONE, HOUR (12) }, /* International Date Line West */ { "cet", tZONE, -HOUR (1) }, /* Central European */ { "met", tZONE, -HOUR (1) }, /* Middle European */ { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */ { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */ { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */ { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */ { "fwt", tZONE, -HOUR (1) }, /* French Winter */ { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */ { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */ { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */ #if 0 { "it", tZONE, -HOUR (3.5) },/* Iran */ #endif { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */ { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */ #if 0 { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */ #endif { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */ #if 0 /* For completeness. NST is also Newfoundland Standard, and SST is * also Swedish Summer. */ { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */ { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */ #endif /* 0 */ { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */ { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */ #if 0 { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */ #endif { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */ { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */ #if 0 { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */ { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */ #endif { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */ { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */ { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */ { "nzt", tZONE, -HOUR (12) }, /* New Zealand */ { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */ { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */ { "idle", tZONE, -HOUR (12) }, /* International Date Line East */ { NULL } }; /* Military timezone table. */ static TABLE const MilitaryTable[] = { { "a", tZONE, HOUR ( 1) }, { "b", tZONE, HOUR ( 2) }, { "c", tZONE, HOUR ( 3) }, { "d", tZONE, HOUR ( 4) }, { "e", tZONE, HOUR ( 5) }, { "f", tZONE, HOUR ( 6) }, { "g", tZONE, HOUR ( 7) }, { "h", tZONE, HOUR ( 8) }, { "i", tZONE, HOUR ( 9) }, { "k", tZONE, HOUR ( 10) }, { "l", tZONE, HOUR ( 11) }, { "m", tZONE, HOUR ( 12) }, { "n", tZONE, HOUR (- 1) }, { "o", tZONE, HOUR (- 2) }, { "p", tZONE, HOUR (- 3) }, { "q", tZONE, HOUR (- 4) }, { "r", tZONE, HOUR (- 5) }, { "s", tZONE, HOUR (- 6) }, { "t", tZONE, HOUR (- 7) }, { "u", tZONE, HOUR (- 8) }, { "v", tZONE, HOUR (- 9) }, { "w", tZONE, HOUR (-10) }, { "x", tZONE, HOUR (-11) }, { "y", tZONE, HOUR (-12) }, { "z", tZONE, HOUR ( 0) }, { NULL } }; /* ARGSUSED */ static int yyerror (s) char *s; { return 0; } static time_t ToSeconds (Hours, Minutes, Seconds, Meridian) time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian; { if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) return -1; switch (Meridian) { case MER24: if (Hours < 0 || Hours > 23) return -1; return (Hours * 60L + Minutes) * 60L + Seconds; case MERam: if (Hours < 1 || Hours > 12) return -1; return (Hours * 60L + Minutes) * 60L + Seconds; case MERpm: if (Hours < 1 || Hours > 12) return -1; return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; default: abort(); } /* NOTREACHED */ } static time_t Convert (Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode) time_t Month; time_t Day; time_t Year; time_t Hours; time_t Minutes; time_t Seconds; MERIDIAN Meridian; DSTMODE DSTmode; { static int DaysInMonth[12] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t tod; time_t Julian; int i; if (Year < 0) Year = -Year; if (Year < 100) Year += 1900; DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 29 : 28; if (Year < EPOCH /* || Year > 1999 */ || Month < 1 || Month > 12 /* Lint fluff: "conversion from long may lose accuracy" */ || Day < 1 || Day > DaysInMonth[(int)--Month]) return -1; for (Julian = Day - 1, i = 0; i < Month; i++) Julian += DaysInMonth[i]; for (i = EPOCH; i < Year; i++) Julian += 365 + (i % 4 == 0); Julian *= SECSPERDAY; Julian += yyTimezone * 60L; if ((tod = ToSeconds (Hours, Minutes, Seconds, Meridian)) < 0) return -1; Julian += tod; if (DSTmode == DSTon || (DSTmode == DSTmaybe && localtime (&Julian)->tm_isdst)) Julian -= 60 * 60; return Julian; } static time_t DSTcorrect (Start, Future) time_t Start; time_t Future; { time_t StartDay; time_t FutureDay; StartDay = (localtime (&Start)->tm_hour + 1) % 24; FutureDay = (localtime (&Future)->tm_hour + 1) % 24; return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; } static time_t RelativeDate (Start, DayOrdinal, DayNumber) time_t Start; time_t DayOrdinal; time_t DayNumber; { struct tm *tm; time_t now; now = Start; tm = localtime (&now); now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); return DSTcorrect (Start, now); } static time_t RelativeMonth (Start, RelMonth) time_t Start; time_t RelMonth; { struct tm *tm; time_t Month; time_t Year; if (RelMonth == 0) return 0; tm = localtime (&Start); Month = 12 * tm->tm_year + tm->tm_mon + RelMonth; Year = Month / 12; Month = Month % 12 + 1; return DSTcorrect (Start, Convert (Month, (time_t)tm->tm_mday, Year, (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, MER24, DSTmaybe)); } static int LookupWord (buff) char *buff; { register char *p; register char *q; register const TABLE *tp; int i; int abbrev; /* Make it lowercase. */ for (p = buff; *p; p++) if (isupper ((int)*p)) *p = (char)tolower ((int)*p); if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) { yylval.Meridian = MERam; return tMERIDIAN; } if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) { yylval.Meridian = MERpm; return tMERIDIAN; } /* See if we have an abbreviation for a month. */ if (strlen (buff) == 3) abbrev = 1; else if (strlen (buff) == 4 && buff[3] == '.') { abbrev = 1; buff[3] = '\0'; } else abbrev = 0; for (tp = MonthDayTable; tp->name; tp++) { if (abbrev) { if (strncmp (buff, tp->name, 3) == 0) { yylval.Number = tp->value; return tp->type; } } else if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } } for (tp = TimezoneTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } if (strcmp (buff, "dst") == 0) return tDST; for (tp = UnitsTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Strip off any plural and try the units table again. */ i = strlen (buff) - 1; if (buff[i] == 's') { buff[i] = '\0'; for (tp = UnitsTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } buff[i] = 's'; /* Put back for "this" in OtherTable. */ } for (tp = OtherTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } /* Military timezones. */ if (buff[1] == '\0' && isalpha ((int)*buff)) { for (tp = MilitaryTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } } /* Drop out any periods and try the timezone table again. */ for (i = 0, p = q = buff; *q; q++) if (*q != '.') *p++ = *q; else i++; *p = '\0'; if (i) for (tp = TimezoneTable; tp->name; tp++) if (strcmp (buff, tp->name) == 0) { yylval.Number = tp->value; return tp->type; } return tID; } static int yylex () { register char c; register char *p; char buff[20]; int Count; int sign; for ( ; ; ) { while (isspace ((int)*yyInput)) yyInput++; if (isdigit ((int)(c = *yyInput)) || c == '-' || c == '+') { if (c == '-' || c == '+') { sign = c == '-' ? -1 : 1; if (!isdigit ((int)*++yyInput)) /* skip the '-' sign */ continue; } else sign = 0; for (yylval.Number = 0; isdigit ((int)(c = *yyInput++)); ) yylval.Number = 10 * yylval.Number + c - '0'; yyInput--; if (sign < 0) yylval.Number = -yylval.Number; return sign ? tSNUMBER : tUNUMBER; } if (isalpha ((int)c)) { for (p = buff; isalpha ((int)(c = *yyInput++)) || c == '.'; ) if (p < &buff[sizeof buff - 1]) *p++ = c; *p = '\0'; yyInput--; return LookupWord (buff); } if (c != '(') return *yyInput++; Count = 0; do { c = *yyInput++; if (c == '\0') return c; if (c == '(') Count++; else if (c == ')') Count--; } while (Count > 0); } } #define TM_YEAR_ORIGIN 1900 /* Yield A - B, measured in seconds. */ static long difftm (a, b) struct tm *a, *b; { int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); int by = b->tm_year + (TM_YEAR_ORIGIN - 1); long days = ( /* difference in day of year */ a->tm_yday - b->tm_yday /* + intervening leap days */ + ((ay >> 2) - (by >> 2)) - (ay/100 - by/100) + ((ay/100 >> 2) - (by/100 >> 2)) /* + difference in years * 365 */ + (long)(ay-by) * 365 ); return (60*(60*(24*days + (a->tm_hour - b->tm_hour)) + (a->tm_min - b->tm_min)) + (a->tm_sec - b->tm_sec)); } time_t get_date (p, now) char *p; struct timeb *now; { struct tm *tm, gmt; struct timeb ftz; time_t Start; time_t tod; yyInput = p; if (now == NULL) { now = &ftz; (void)time (&ftz.time); if (! (tm = gmtime (&ftz.time))) return -1; gmt = *tm; /* Make a copy, in case localtime modifies *tm. */ if (! (tm = localtime (&ftz.time))) return -1; ftz.timezone = difftm (&gmt, tm) / 60; if (tm->tm_isdst) ftz.timezone += 60; } tm = localtime (&now->time); yyYear = tm->tm_year; yyMonth = tm->tm_mon + 1; yyDay = tm->tm_mday; yyTimezone = now->timezone; yyDSTmode = DSTmaybe; yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24; yyRelSeconds = 0; yyRelMonth = 0; yyHaveDate = 0; yyHaveDay = 0; yyHaveRel = 0; yyHaveTime = 0; yyHaveZone = 0; if (yyparse () || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) return -1; if (yyHaveDate || yyHaveTime || yyHaveDay) { Start = Convert (yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, yyMeridian, yyDSTmode); if (Start < 0) return -1; } else { Start = now->time; if (!yyHaveRel) Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; } Start += yyRelSeconds; Start += RelativeMonth (Start, yyRelMonth); if (yyHaveDay && !yyHaveDate) { tod = RelativeDate (Start, yyDayOrdinal, yyDayNumber); Start += tod; } /* Have to do *something* with a legitimate -1 so it's distinguishable * from the error return value. (Alternately could set errno on error.) */ return Start == -1 ? 0 : Start; } #if defined (TEST) /* ARGSUSED */ int main (ac, av) int ac; char *av[]; { char buff[MAX_BUFF_LEN + 1]; time_t d; (void)printf ("Enter date, or blank line to exit.\n\t> "); (void)fflush (stdout); buff[MAX_BUFF_LEN] = 0; while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0]) { d = get_date (buff, (struct timeb *)NULL); if (d == -1) (void)printf ("Bad format - couldn't convert.\n"); else (void)printf ("%s", ctime (&d)); (void)printf ("\t> "); (void)fflush (stdout); } exit (0); /* NOTREACHED */ } #endif /* defined (TEST) */ sendfile-2.1b/src/spool.c0000640000175100001440000005442310251136250015121 0ustar framstagusers/* * File: spool.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-09-01 Framstag initial version * 1995-10-10 Framstag open bug fixed * 1995-11-01 Framstag added pgp signature (dummy) * 1995-11-05 Framstag added NeXT support * 1995-11-15 Framstag fixed memory leak (oops :-) ) * 1996-01-24 Framstag new (received) DATEFORMAT * 1996-01-25 Framstag added keep and deljunk config * 1996-02-06 Framstag added ATTRIBUTE=EXE * 1996-03-16 Framstag recognize file size 0 correctly * 1996-04-02 Framstag FROM now in UTF-7 * 1996-04-12 Framstag sign is now in filelist * sign, comment and fname are now dynamic * added pgp support * 1996-04-20 Framstag build sender list only for requested sender * (wildcards are ok) * 1996-04-24 Framstag added scanoutspool function * 1996-06-24 Framstag fixed bug when FROM contains no real name * 1997-01-07 Framstag fixed bug when spool data file does not exist * 1997-02-03 Framstag sprintf() -> snprintf() * 1997-01-20 Framstag fixed bug with TEXT=charset attribute * 1997-02-23 Framstag modified str_* function names * extended with TYPE=MIME * 1997-03-19 Framstag fixed TYPE=TEXT parsing bug * 1997-09-12 Framstag empty date header is now allowed * 1997-09-14 Framstag moved spoolid() from sendfiled.c to spool.c * 1997-09-17 Framstag sender comparision ignores now real name * 1997-09-18 Framstag better header line parsing * 1997-09-24 Framstag more effizient spool junk removing * 1997-11-15 Framstag expire too big junk files, too * 1997-12-10 Framstag added compression method for filelist * 1998-05-19 Framstag fixed maxfiles counting bug in spoolid() * 1998-11-12 Framstag scanoutspool() now gets file size, too * 2005-05-31 Framstag added largefile support * * Functions for operations on files in the sendfile spool directory. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #include #include #include #include #include #include #include #include #include "io.h" /* misc IO routines */ #include "spool.h" /* operations on files in the sendfile spool */ #include "utf7.h" /* UTF-7 coding */ #include "message.h" /* information, warning and error messages */ #include "string.h" /* extended string functions */ #include "reply.h" /* the 3 digit reply codes with text messages */ /* * scanspool - scan through spool directory, build list-structures and * delete old files if necessary * * INPUT: sender - sender name (wildcards * and ? are allowed) * * RETURN: start of sender list */ struct senderlist *scanspool(char *sender) { extern int client; /* flag to determine client or server */ extern char userspool[]; /* user spool directory */ unsigned char *ucp; /* simple unsigned character pointer */ char *cp, /* simple character pointer */ *arg, /* the argument(s) of the header line */ *compress, /* compression method */ line[MAXLEN], /* config line */ hline[MAXLEN], /* header line */ from[MAXLEN], /* header from line */ fname[MAXLEN], /* header file line */ comment[MAXLEN], /* file comment (printable string) */ tmp[MAXLEN], /* temporary string */ msg[MAXLEN], /* information/error message */ sign[MAXLEN], /* pgp signature (Latin-1) */ date[DLEN+1], /* file date */ charset[DLEN+1], /* character set name */ rdate[DLEN+1], /* receive date */ file[FLEN+1]; /* spool file name */ int i, id, /* spool file id number */ hfc, /* header file corruption flag */ keep, /* keep spool files at least xx days */ deljunk, /* delete corrupted spool files after xx days */ flags; /* source, text, compress, tar and exe flag */ off_t osize, /* original file size */ csize, /* compressed file size */ tsize; /* true spool data file size */ time_t ctime, /* current time */ rtime; /* receiving time */ FILE *hf, /* header file */ *inf; /* config file */ struct stat finfo; /* information about a file */ #ifdef NEXT FILE *pp; /* pipe */ #else struct dirent *dire; /* directory entry */ DIR *dp; /* directory pointer */ #endif struct filelist *flp, /* file list pointer */ *fln; /* new file list element */ struct senderlist *sls, /* sender list start */ *sln, /* sender list next pointer */ *slp; /* sender list pointer */ static struct senderlist *sll=NULL; /* last sender list start */ keep=0; deljunk=10; ctime=time(NULL); flp=NULL; /* is there already an old senderlist? */ if (sll) /* delete old senderlist and free memory */ for (slp=sll; slp!=NULL;) { for (flp=slp->flist; flp!=NULL; ) { fln=flp->next; free(flp->sign); free(flp->fname); free(flp->comment); free(flp); flp=fln; } sln=slp->next; free(slp); slp=sln; } sls=sll=NULL; /* parse the config-file */ if ((inf=rfopen(CONFIG,"r"))) { while ((fgetl(line,inf))) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; str_trim(line); str_tolower(line); /* is there an option and an argument? */ if ((cp=strchr(line,' '))) { *cp=0; cp++; if (str_eq(line,"keep")) { keep=atoi(cp); continue; } if (str_eq(line,"deljunk")) { deljunk=atoi(cp); continue; } } } fclose(inf); } /* mega stupid NeXT has broken readdir() */ #ifdef NEXT /* open spool dir */ snprintf(MAXS(tmp),"ls %s 2>/dev/null",userspool); if ((pp=popen(tmp,"r")) == NULL) return(NULL); /* scan through spool directory */ while (fgetl(tmp,pp)) { if ((cp=strrchr(tmp,'\n'))) *cp=0; /* look for header files */ if ((cp=strchr(tmp,'.')) && str_eq(cp,".h")) { /* extract spool id */ *cp=0; id=atoi(tmp); #ifdef JEDPARSE }} #endif #else /* open spool dir */ if ((dp=opendir(userspool)) == NULL) return(NULL); /* scan through spool directory */ while ((dire=readdir(dp))) { /* look for header files */ if ((cp=strchr(dire->d_name,'.')) && str_eq(cp,".h")) { /* extract spool id */ *cp=0; id=atoi(dire->d_name); #endif /* open header file */ snprintf(MAXS(file),"%s/%d.h",userspool,id); hf=rfopen(file,"r"); /* error? */ if (!hf) { /* called from receive client? */ if (client) { snprintf(MAXS(msg),"cannot open spool file %s",file); message("",'E',msg); } /* skip this spool file */ continue; } /* initialisize header entries */ flags=0; csize=0; tsize=0; osize=0; *from=0; *date=0; *sign=0; *fname=0; *charset=0; *comment=0; compress=""; /* does the spool data file exist? */ snprintf(MAXS(file),"%s/%d.d",userspool,id); if (stat(file,&finfo)<0) { snprintf(MAXS(file),"%s/%d.h",userspool,id); unlink(file); continue; } /* get time of receiving (local) */ rtime=finfo.st_mtime; /* spool file expired? */ if (keep>0 && (ctime-rtime)/DAYSEC>=keep) { fclose(hf); unlink(file); snprintf(MAXS(file),"%s/%d.h",userspool,id); unlink(file); continue; } strftime(rdate,21,DATEFORMAT,localtime(&rtime)); /* read header file */ hfc=0; while ((fgetl(hline,hf)) && hfc==0) { /* prepare the header line */ if ((cp=strchr(hline,'\n'))) *cp=0; cp=strchr(hline,'\t'); /* corrupt header file line? */ if (cp==NULL) { hfc=1; continue; } str_trim(hline); cp=strchr(hline,' '); if (cp==NULL) continue; arg=cp+1; *cp=0; /* extract the header-name and the argument */ if (str_eq(hline,"FROM")) { if ((cp=strchr(arg,' '))) { *cp=0; snprintf(MAXS(tmp),"%s (%s)",arg,cp+1); } else strcpy(tmp,arg); utf2iso(0,from,NULL,NULL,tmp); continue; } if (str_eq(hline,"FILE")) { strcpy(fname,arg); continue; } if (str_eq(hline,"DATE")) { strncpy(date,arg,DLEN); continue; } if (str_eq(hline,"SIZE")) { sscanf(arg,"%lld %lld",&csize,&osize); tsize=finfo.st_size; continue; } if (str_eq(hline,"ATTR")) { str_toupper(arg); if (str_eq(arg,"TAR")) flags=flags|F_TAR; if (str_eq(arg,"EXE")) flags=flags|F_EXE; continue; } if (str_eq(hline,"TYPE")) { str_toupper(arg); if (strstr(arg,"SOURCE")) flags=flags|F_SOURCE; if (strstr(arg,"TEXT")) flags=flags|F_TEXT; if (strstr(arg,"MIME")) flags=flags|F_MIME; if (strstr(arg,"CRYPTED")) flags=flags|F_CRYPT; if (strstr(arg,"COMPRESSED")) { flags=flags|F_COMPRESS; if (strstr(arg,"COMPRESSED=BZIP2")) compress=S_BZIP2; else compress=S_GZIP; } if (strstr(arg,"TEXT=")) { strncpy(charset,strchr(arg,'=')+1,DLEN); charset[DLEN]=0; if ((cp=strchr(charset,' '))) *cp=0; } continue; } /* comment and signature are only needed for receive client */ if (client) { if (str_eq(hline,"COMMENT")) { /* save comment in printable code */ utf2iso(0,comment,NULL,NULL,arg); for (ucp=(unsigned char *)comment,i=0; *ucp; ucp++) if (*ucp==9 || *ucp==10 || (*ucp>31 && *ucp<127) || *ucp>159) comment[i++]=*ucp; comment[i]=0; continue; } if (str_eq(hline,"SIGN")) { utf2iso(0,sign,NULL,NULL,arg); continue; } } } fclose(hf); /* junk file expired? */ if (*from==0 || *fname==0 || (tsize!=csize && deljunk>0 && (ctime-rtime)/DAYSEC>=deljunk)) { snprintf(MAXS(file),"%s/%d.d",userspool,id); unlink(file); snprintf(MAXS(file),"%s/%d.h",userspool,id); unlink(file); continue; } /* bad header file? */ if (*from==0 || *fname==0) continue; /* is it a requested sender name? (ignore real name) */ strcpy(line,from); if ((cp=strchr(line,' '))) *cp=0; strcpy(tmp,sender); if ((cp=strchr(tmp,' '))) *cp=0; if (sender==NULL || *sender==0 || simplematch(line,tmp,1)) { /* create new file list element */ if ((fln=(struct filelist *) malloc(sizeof(struct filelist))) == NULL || (fln->fname= (char *) malloc(strlen(fname)+1)) == NULL || (fln->comment= (char *) malloc(strlen(comment)+1)) == NULL || (fln->sign= (char *) malloc(strlen(sign)+1)) == NULL) { if (client) message("",'F',"cannot allocate memory"); else reply(453); } /* fill in new file list element */ fln->id=id; fln->next=NULL; fln->osize=osize; fln->csize=csize; fln->tsize=tsize; fln->flags=flags; fln->rtime=rtime; strcpy(fln->date,date); strcpy(fln->sign,sign); strcpy(fln->fname,fname); strcpy(fln->rdate,rdate); strcpy(fln->charset,charset); strcpy(fln->comment,comment); strcpy(fln->compress,compress); /* first sender? */ if (sls==NULL) sls=newsle(fln,from); else { /* search for sender in senderlist */ slp=sls; while (slp->next && !str_eq(slp->from,from)) slp=slp->next; /* sender not found in sender list? */ if (!str_eq(slp->from,from)) /* create new sender list element and append it */ slp->next=newsle(fln,from); else { /* is it the smallest id? */ if (id < slp->flist->id) { fln->next=slp->flist; slp->flist=fln; } else { /* insert into files list */ for (flp=slp->flist; flp->next!=NULL; flp=flp->next) { if (id < flp->next->id) { fln->next=flp->next; flp->next=fln; break; } } /* last element? */ if (flp->next==NULL) flp->next=fln; } } } } } } #ifdef NEXT pclose(pp); #else closedir(dp); #endif sll=sls; return(sls); } /* * scanoutspool - scan through outgoing spool directory, build list-structures * and delete bad files if necessary * * INPUT: sender - sender name * * RETURN: start of host list, NULL on error * * REMARK: if no files in outgoing spool are found a special hostlist structure * will be returned with all zeros values. * * All header lines in the outgoing spool files are SAFT-conform (strings are * in UTF-7, etc). */ struct hostlist *scanoutspool(char *sender) { extern int client; /* flag to determine client or server */ char *cp, /* simple character pointer */ *arg, /* the argument(s) of the header line */ hline[MAXLEN], /* header line */ host[MAXLEN], /* header recipient host line */ to[MAXLEN], /* header recipient user line */ from[MAXLEN], /* header from line */ fname[MAXLEN], /* header file line */ tmp[MAXLEN], /* temporary string */ msg[MAXLEN], /* information/error message */ hfn[MAXLEN], /* outgoing spool header file name */ dfn[MAXLEN]; /* outgoing spool data file name */ int hfc; /* header file corruption flag */ off_t size; /* size of outgoing spool data file */ FILE *hf; /* header file */ struct stat finfo; /* information about a file */ #ifdef NEXT FILE *pp; /* pipe */ #else struct dirent *dire; /* directory entry */ DIR *dp; /* directory pointer */ #endif struct outfilelist *oflp, /* outgoing file list pointer */ *ofln; /* new file list element */ struct hostlist *hls, /* host list start */ *hln, /* host list next pointer */ *hlp; /* host list pointer */ static struct hostlist *hll=NULL; /* last host list start */ oflp=NULL; /* is there already an old hostlist? */ if (hll) { /* delete old hostlist and free memory */ for (hlp=hll; hlp;) { for (oflp=hlp->flist; oflp;) { ofln=oflp->next; free(oflp->to); free(oflp->oshfn); free(oflp->fname); free(oflp); oflp=ofln; } hln=hlp->next; free(hlp); hlp=hln; } } /* create first empty host list element */ hls=hll=newhle(NULL,""); /* mega stupid NeXT has broken readdir() */ #ifdef NEXT /* open spool dir */ snprintf(MAXS(tmp),"cd %s;ls %s_*.h 2>/dev/null",OUTGOING,sender); if ((pp=popen(tmp,"r")) == NULL) return(NULL); /* scan through spool directory */ while (fgetl(hfn,pp)) { if ((cp=strrchr(hfn,'\n'))) *cp=0; #ifdef JEDPARSE } #endif #else /* open spool dir */ if (!(dp=opendir(OUTGOING))) return(NULL); /* scan through outgoing spool directory */ while ((dire=readdir(dp))) { strcpy(hfn,dire->d_name); #endif /* look for header files */ snprintf(MAXS(tmp),"%s*.h",sender); if (simplematch(hfn,tmp,1)==0) continue; strcpy(tmp,hfn); snprintf(MAXS(hfn),OUTGOING"/%s",tmp); /* open header file */ if ((hf=rfopen(hfn,"r")) == NULL) { /* called from receive client? */ if (client) { snprintf(MAXS(msg),"cannot open outgoing spool file %s",hfn); message("",'E',msg); } continue; } /* initialisize header entries */ size=0; *to=0; *host=0; *from=0; *fname=0; /* read header file */ hfc=0; while (fgetl(hline,hf) && hfc==0) { /* prepare the header line */ if ((cp=strchr(hline,'\n'))) *cp=0; cp=strchr(hline,'\t'); /* corrupt header file line? */ if (cp==NULL) { hfc=1; continue; } arg=cp+1; *cp=0; /* extract the header-name and the argument */ /* check the from line */ if (str_eq(hline,"FROM")) { if ((cp=strchr(arg,' '))) *cp=0; utf2iso(0,from,NULL,NULL,arg); /* wrong from line? */ if (*sender && !str_eq(from,sender)) hfc=1; continue; } /* check the to line */ if (str_eq(hline,"TO")) { if (!(cp=strchr(arg,'@'))) hfc=1; else { strcpy(host,cp+1); *cp=0; utf2iso(0,to,NULL,NULL,arg); } continue; } if (str_eq(hline,"FILE")) { strcpy(fname,arg); continue; } if (str_eq(hline,"SIZE")) { sscanf(arg,"%lld",&size); strcpy(dfn,hfn); dfn[strlen(dfn)-1]='d'; /* wrong size? */ if (stat(dfn,&finfo)<0 || finfo.st_size!=size) hfc=1; continue; } } fclose(hf); /* delete bad files */ if (*from==0 || *fname==0 || *to==0 || *host==0 || hfc) { strcpy(dfn,hfn); dfn[strlen(dfn)-1]='d'; unlink(dfn); unlink(hfn); continue; } /* create new outgoing file list element */ if ((ofln=(struct outfilelist *)malloc(sizeof(struct outfilelist)))==NULL|| (ofln->fname= (char *)malloc(strlen(fname)+1)) ==NULL|| (ofln->to= (char *)malloc(strlen(to)+1)) ==NULL|| (ofln->oshfn= (char *)malloc(strlen(hfn)+1)) ==NULL|| (ofln->from= (char *)malloc(strlen(from)+1)) ==NULL){ if (client) message("",'F',"cannot allocate memory"); else reply(453); } /* fill in new outgoing file list element */ ofln->next=NULL; ofln->size=size; strcpy(ofln->to,to); strcpy(ofln->from,from); strcpy(ofln->oshfn,hfn); strcpy(ofln->fname,fname); /* first host? */ if (hls->flist==NULL) { hls->flist=ofln; strcpy(hls->host,host); } else { /* search for host in hostlist */ hlp=hls; while (hlp->next && !str_eq(hlp->host,host)) hlp=hlp->next; /* host not found in host list? */ if (!str_eq(hlp->host,host)) /* create new host list element */ hlp->next=newhle(ofln,host); else /* append to outgoing file list */ { for (oflp=hlp->flist; oflp->next!=NULL; oflp=oflp->next); oflp->next=ofln; } } } #ifdef NEXT pclose(pp); #else closedir(dp); #endif hll=hls; return(hls); } /* * newsle - create new sender list element and fill it out * * INPUT: flp - first file list element * from - sendername * * RETURN: start of sender list */ struct senderlist *newsle(struct filelist *flp, const char *from) { struct senderlist *sln; /* new sender list element */ extern int client; /* flag to determine client or server */ /* create new sender list element */ if ((sln=(struct senderlist *)malloc(sizeof(struct senderlist))) == NULL) { if (client) message("",'F',"cannot allocate memory"); else reply(453); } /* fill it out */ sln->next=NULL; sln->flist=flp; strcpy(sln->from,from); return(sln); } /* * newhle - create new host list element and fill it out * * INPUT: oflp - first outgoing file list element * host - host name * * RETURN: start of sender list */ struct hostlist *newhle(struct outfilelist *oflp, const char *host) { struct hostlist *hln; /* new host list element */ extern int client; /* flag to determine client or server */ /* create new host list element */ if ((hln=(struct hostlist *)malloc(sizeof(struct hostlist))) == NULL) { if (client) message("",'F',"cannot allocate memory"); else reply(453); } /* fill it out */ hln->next=NULL; hln->flist=oflp; strcpy(hln->host,host); return(hln); } /* * delete_sf - delete a spool file * * INPUT: flp - file list pointer * verbose - if set, print success message * * RETURN: 0 on success, -1 on fail */ int delete_sf(struct filelist *flp, int verbose) { char msg[MAXLEN], /* information/error message */ file[MAXLEN], /* spool file */ fname[MAXLEN]; /* displayble file name */ extern int client; /* flag to determine client or server */ extern char userspool[]; /* user spool directory */ snprintf(MAXS(file),"%s/%d.d",userspool,flp->id); unlink(file); snprintf(MAXS(file),"%s/%d.h",userspool,flp->id); utf2iso(1,NULL,fname,NULL,flp->fname); if(unlink(file)<0) { if (client) { snprintf(MAXS(msg),"cannot delete spoolfile #%d",flp->id); message("",'W',msg); } return(-1); } else { if (verbose) { snprintf(MAXS(msg),"%s deleted",fname); message("",'I',msg); } return(0); } } /* * spoolid - find the next spool id and touch header and data file * * INPUT: maxfiles - maximum number of allowed spool files * * RETURN: spool id, 0 if failed, -number of files in spool if maxfiles exceeded * * The working directory has to be the user spool! */ int spoolid(int maxfiles) { int i, /* simple loop count */ n, /* number of files in spool */ fd, /* file descriptor of spool id header file */ id, /* id number */ idmax; /* biggest id number */ char *cp, /* character pointer to '.' in file name */ file[MAXLEN]; /* complete file name */ #ifdef NEXT char tmp[MAXLEN]; /* tmp string */ FILE *pp; /* pipe */ #else struct dirent *dire; /* directory entry */ DIR *dp; /* directory pointer */ #endif /* try to create next spool files */ for (i=1; i<5; i++) { /* initialisize */ n=0; id=0; fd=0; idmax=0; #ifdef NEXT /* stupid NeXT has a broken readdir(); this is a dirty workaround */ /* open spool dir */ if ((pp=popen("ls . 2>/dev/null","r")) == NULL) return(NULL); /* scan through spool directory */ while (fgetl(tmp,pp)) { if ((cp=strrchr(tmp,'\n'))) *cp=0; cp=strchr(tmp,'.'); if (cp && str_eq(cp,".h")) { n++; *cp=0; id=atoi(tmp); if (id>idmax) idmax=id; } } pclose(pp); #else /* open spool dir */ dp=opendir("."); /* scan through spool directory and get the highest spool id */ while ((dire=readdir(dp))) { cp=strchr(dire->d_name,'.'); if (cp && str_eq(cp,".h")) { *cp=0; n++; id=atoi(dire->d_name); if (id>idmax) idmax=id; } } closedir(dp); #endif id=idmax+1; if (n>maxfiles) return(-n); /* try to create header spool file */ snprintf(MAXS(file),"%d.h",id); fd=open(file,O_CREAT|O_EXCL,S_IRUSR|S_IWUSR); /* successfull? */ if (fd>=0) { close(fd); /* create data spool file */ snprintf(MAXS(file),"%d.d",id); close(open(file,O_CREAT|O_LARGEFILE,S_IRUSR|S_IWUSR)); return(id); } /* wait and test again */ sleep(1); } /* failed */ return(0); } sendfile-2.1b/src/sendmsg.c0000640000175100001440000003266511025463105015433 0ustar framstagusers/* * File: sendmsg.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-08-11 Framstag initial version * 1995-08-12 Framstag elm alias support * 1995-11-02 Framstag added minimal chat mode * 1995-11-14 Framstag added message receiving modes * 1995-12-21 Framstag avoid unnecessary error message while * configuring the own tty * 1995-12-21 Framstag better server connect testing * 1996-02-20 Framstag changed msg-tty file to support NFS * 1996-04-01 Framstag added multiline mode * 1996-04-17 Framstag new error handling for open_connection * 1996-05-02 Framstag fixed stupid shutdown() programming bug * 1996-05-03 Framstag fixed bug with gethostname() * 1996-05-24 Framstag sendmsg no longer tries to configure the tty * when there is none (sending via pipe) * 1996-08-12 Framstag no questions asked when in batch mode (no tty) * 1996-11-13 Framstag faster mesg/tty handling * 1996-11-26 Framstag added -n option * 1997-01-04 Framstag added saft_connect()-call * 1997-02-03 Framstag better tty configuration * sprintf() -> snprintf() * added -u and -f options * added -u and -f options * changed tty permission testing and -m behaviour * 1997-02-23 Framstag modified str_* function names * 1997-06-19 Framstag changend tty testing and behaviour * 1997-06-23 Framstag added readline support * 1997-06-24 Framstag fixed some prompt bugs * 1997-07-04 Framstag added cleanup signal handler * 1998-01-03 Framstag better tty configuration * 1998-01-17 Framstag check SAFT-URL for alternative tcp port * 1998-03-29 Framstag "sendmsg -m 2>/dev/null" now works * 1998-04-06 Framstag added -s message option * 1998-07-12 Framstag added option -r * 1998-08-21 Framstag fixed bug if tty can receive msg * 1998-09-17 Framstag added option -q * 2005-06-06 Maide added multiprotocol cababilities * 2005-06-06 Maide replaced numeric ports with service string * 2005-06-06 Maide added -4/-6 command line options and * corresponding help text * 2006-11-27 Framstag correct exit code now on error * 2008-03-11 Framstag reconnect and resend after server timeout * 2008-06-16 Joey prevent buffer overflow for getopt-strings * * The sendmessage client of the sendfile package. * Sends a single line text message to the SAFT-server of the destination * system to be displayed on the recipients terminal. * * Copyright © 1995-2008 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #include #include #include #include #include #include #include #include #include #include #include "string.h" /* extended string functions */ #include "net.h" /* the network routines */ #include "io.h" /* (socket) read/write */ #include "message.h" /* information, warning and error messages */ #include "utf7.h" /* UTF-7 coding */ #include "address.h" /* address checking */ #include "getline.h" /* get a line of text from stdin */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #if defined(SOLARIS2) int gethostname(char *, int); #endif #if defined(LINUX) int gethostname(char *, size_t); #endif #ifndef AIX3 #ifndef CONVEXOS FILE *popen(const char *, const char *); #endif int pclose(FILE *); #else #include "bsd.h" #endif #ifdef NEXT int shutdown(int, int); #endif /* print short help usage text */ int usage(); /* clean termination routine */ void cleanup(); /* global variables */ int xonf=1, /* exit on fatalerror flag */ client=1, /* flag to determine client or server */ quiet=0, /* quiet mode */ verbose=0, /* flag for verbose mode */ packet_size; /* only needed for linking */ char *prg; /* name of the game */ int main(int argc, char *argv[]) { int sockfd, /* socket file descriptor */ chat, /* flag for chat mode */ reply, /* flag for reply mode */ force, /* flag for force sending */ receive, /* receiving flag */ multiline, /* flag for sending a multiline message */ opt; /* option to test for */ char *cp, /* simple character pointer */ *tty, /* the tty device with path */ *sr, /* server reply */ ttyt[FLEN], /* the tty on which sendfiled will write (see msgcf) */ recipient[FLEN], /* recipient at serverhost */ user[FLEN], /* local user name */ from[FLEN], /* alternative from name */ host[FLEN], /* name of serverhost */ localhost[FLEN], /* name of the local host */ msgcf[FLEN], /* message control file */ msg[MAXLEN], /* message from ARGV */ line[MAXLEN], /* input or output string */ login[MAXLEN], /* login user name */ tmp[3*MAXLEN]; /* temporary string */ char utf_msg[LEN_UTF], /* msg in UTF-7 format */ iso_msg[LEN_ISO]; /* msg in ISO Latin-1 format */ FILE *inf, /* input file */ *outf; /* output file */ struct stat finfo; /* information about a file */ chat=0; force=0; reply=0; sockfd=0; verbose=0; receive=0; multiline=0; *msg=0; *host=0; *user=0; *from=0; *line=0; *ttyt=0; *iso_msg=0; *recipient=0; tty=NULL; prg=argv[0]; if ((cp=strrchr(prg,'/'))) prg=cp+1; memset(msg,0,sizeof(msg)); memset(from,0,sizeof(from)); memset(login,0,sizeof(login)); /* scan the command line on options */ #ifndef ENABLE_MULTIPROTOCOL while ((opt=getopt(argc,argv,"rcvVmMlhq?fs:u:")) > 0) { #else while ((opt=getopt(argc,argv,"rcvVmMlhq?fs:u:46")) > 0) { #endif switch (opt) { case ':': case 'h': case '?': return(usage()); case 'c': chat=1; break; case 'r': reply=1; break; case 'q': quiet=2; break; case 'v': verbose=1; break; case 'm': receive=1; break; case 'M': receive=2; break; case 'l': multiline=1; break; case 'f': force=1; break; case 's': strncpy(msg,optarg,sizeof(msg)-1); break; case 'u': strncpy(from,optarg,sizeof(from)-1); break; case 'V': message(prg,'I',"version "VERSION" revision "REVISION); return(0); #ifdef ENABLE_MULTIPROTOCOL case '4': addressFamily = PF_INET; break; case '6': addressFamily = PF_INET6; break; #endif } } /* too few arguments? */ if (argc-optind<1 && receive==0 && reply==0) return(usage()); /* incompatible options? */ if (*msg && (multiline || chat)) { multiline=chat=0; message(prg,'W',"you cannot specify option -s together with -c or -l"); } /* get the local host name */ if (gethostname(localhost,FLEN-1)<0) strcpy(localhost,"localhost"); /* get own user name, recipient name and host */ if (reply) argc=0; destination(argc,argv,user,recipient,host,NULL); if (reply && !*recipient) { errno=0; message(prg,'F',"no reply address found"); } if (*from) iso2utf(user,from); strncpy(login,user,sizeof(login)-1); if ((cp=strchr(login,' '))) *cp=0; /* enable simple interrupt handler */ signal(SIGTERM,cleanup); signal(SIGABRT,cleanup); signal(SIGQUIT,cleanup); signal(SIGHUP,cleanup); signal(SIGINT,cleanup); if (!force) { /* test the local sendfiled */ if (verbose) printf("testing local SAFT server:\n"); #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection("127.0.0.1",SAFT); #else sockfd=open_connection("127.0.0.1",SERVICE); #endif sock_getline(sockfd,line); /* no local server? */ if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) message(prg,'W',"there is no local SAFT server - " "you cannot receive messages"); else { /* test if you can receive messages */ snprintf(MAXS(line),"FROM %s",login); sock_putline(sockfd,line); sock_getline(sockfd,line); snprintf(MAXS(line),"TO %s",login); sock_putline(sockfd,line); sock_getline(sockfd,line); if (str_beq(line,"521 ")) { errno=0; message(prg,'F',"You are not allowed to use the sendmsg service"); } if (!str_beq(line,"200 ")) message(prg,'W',"local server error - you cannot receive messages"); if (isatty(fileno(stdin))) { /* get tty name */ if (!(tty=ttyname(fileno(stdin))) || *tty!='/') message(prg,'F',"cannot determine your tty name"); else { /* the message tty config file */ snprintf(MAXS(msgcf),"%s/%s/config/tty@%s",SPOOL,login,localhost); /* open tty write permissions if necessary */ if (receive) { if (receive==1) { /* mark current tty as active for receiving */ if ((outf=rfopen(msgcf,"w"))) { fprintf(outf,"%s\n",tty); fclose(outf); if (chmod(tty,S_IRUSR|S_IWUSR|S_IWGRP)<0) { snprintf(MAXS(tmp),"cannot open your tty %s for writing",tty); message(prg,'W',tmp); } else if (argc-optind<1) { message(prg,'I', "receiving messages is now restricted to this tty"); } } else { snprintf(MAXS(tmp),"cannot configure your tty " "(no write access to %s)",msgcf); message(prg,'W',tmp); } } if (receive==2) { unlink(msgcf); if (argc-optind<1) message(prg,'I', "receiving messages is now possible on all ttys"); } } else { /* keep tty status and mode */ /* is the current tty writable? */ if (stat(tty,&finfo)<0 || !(finfo.st_mode&S_IWGRP)) { errno=0; snprintf(MAXS(tmp),"your tty %s is write protected; " "try sendmsg -m",tty); message(prg,'F',tmp); } /* read the receiving tty from the message config file */ if ((inf=rfopen(msgcf,"r"))) { fgetl(ttyt,inf); fclose(inf); if ((cp=strchr(ttyt,'\n'))) *cp=0; } else { strcpy(ttyt,tty); /* mark current tty as active for receiving */ if ((outf=rfopen(msgcf,"w"))) { fprintf(outf,tty); fclose(outf); } } /* is the current tty active for sendfiled? */ if (!str_eq(tty,ttyt)) { errno=0; message(prg,'F', "you cannot receive an answer message on this tty; " "try sendmsg -m or sendmsg -f"); } } } } } shutdown(sockfd,2); } if (argc-optind<1 && !reply) return(0); /* name the local host */ if (str_eq(host,"127.0.0.1")) strcpy(host,localhost); /* look for correct SAFT server and open connection */ sockfd=saft_connect("msg",recipient,user,host,tmp); /* send several lines at once? */ if (multiline) { if (isatty(fileno(stdin))) printf("Enter multiline message (max 10 lines! End with Ctrl-D):\n"); /* read until EOF */ while (*line=0,getpromptline(line,LEN_ISO-1)) { if ((cp=strchr(line,'\n'))) *cp=0; /* message text too long? */ if (strlen(iso_msg)+strlen(line)>LEN_ISO*.8) { errno=0; message(prg,'F',"message line too long"); } /* add a new line if necessary */ if (*iso_msg || !*line) strcat(iso_msg,"\r\n"); /* add the text line */ strncat(iso_msg,line,LEN_ISO-1); iso_msg[LEN_ISO-1]=0; } if (*iso_msg) { /* encode to UTF-7 */ iso2utf(utf_msg,iso_msg); /* message text too long? */ if (strlen(utf_msg)>MAXLEN-10) { errno=0; message(prg,'F',"message line too long"); } /* send the message */ snprintf(MAXS(tmp),"MSG %s",utf_msg); sendheader(sockfd,tmp); } } else { /* single line or chat mode */ do { /* read the message */ *iso_msg=0; /* message given by -s option? */ if (*msg) strcpy(iso_msg,msg); else { /* prompt for message */ if (isatty(fileno(stdin))) strcpy(iso_msg,"message: "); if (!getpromptline(iso_msg,LEN_ISO-1)) { printf("\n"); break; } } if (!*iso_msg) break; /* strip off new line */ cp=strrchr(iso_msg,'\n'); if (cp && (cp!=(char *)iso_msg)) *cp=0; /* encode to UTF-7 */ iso2utf(utf_msg,iso_msg); /* send the message */ snprintf(MAXS(line),"MSG %s",utf_msg); sock_putline(sockfd,line); xonf=0; sr=getreply(sockfd); xonf=1; if (!(str_beq(sr,"200") || str_beq(sr,"202"))) { if (strstr(sr,"Timeout")) { sockfd=saft_connect("msg",recipient,user,host,tmp); sendheader(sockfd,line); } else { exit(1); } } } while (chat); } /* close the connection */ sock_putline(sockfd,"QUIT"); getreply(sockfd); close(sockfd); return(0); } /* cleanup - clean termination routine */ void cleanup() { printf("\r\n"); } /* * usage - print short help usage text */ int usage() { fprintf(stderr,"usage: %s [-vfmMr] [-s 'message' ] user[@host]\n",prg); fprintf(stderr,"options: -v verbose mode\n"); fprintf(stderr," -f force sending of messages and ignore the tty status\n"); fprintf(stderr," -m allow receiving messages only on this tty\n"); fprintf(stderr," -M allow receiving messages on other ttys, too\n"); fprintf(stderr," -s send 'message'\n"); fprintf(stderr," -r reply to last received message\n"); #ifdef ENABLE_MULTIPROTOCOL fprintf(stderr," -4 explicitly force ipv4 connections\n"); fprintf(stderr," -6 explicitly force ipv6 connections\n"); #endif fprintf(stderr,"example: %s framstag@bofh.belwue.de\n",prg); return(2); } sendfile-2.1b/src/lock.c0000640000175100001440000000265010251136250014710 0ustar framstagusers/* * File: lock.c * * Author: Ulli Horlacher (framstag@belwue.de) * * History: * * 1998-05-10 Framstag moved from sendfiled.c * * These are functions which sets or tests advisory locks conforming to POSIX * fcntl() call. * * Copyright © 1998 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include #include #include #include #include #include #include /* * wlock_file - write-lock a file (POSIX conform) * * INPUT: file descriptor * * RETURN: >= 0 if ok, -1 if error */ int wlock_file(int fd) { struct flock lock; /* file locking structure */ /* fill out the file locking structure */ lock.l_type=F_WRLCK; lock.l_start=0; lock.l_whence=SEEK_SET; lock.l_len=0; /* try to lock the file and return the status */ return(fcntl(fd,F_SETLK,&lock)); } /* * tlock_file - test if a file is write-lock blocked (POSIX conform) * * INPUT: fd - file descriptor * * RETURN: 0 if no lock, 1 if locked, -1 on error */ int tlock_file(int fd) { int status; struct flock lock; /* file locking structure */ /* fill out the file locking structure */ lock.l_type=F_WRLCK; lock.l_start=0; lock.l_whence=SEEK_SET; lock.l_len=0; /* test the lock status */ status=fcntl(fd,F_GETLK,&lock); if (status>=0) status=(lock.l_type!=F_UNLCK); return(status); } sendfile-2.1b/src/message.c0000640000175100001440000000464510765530564015432 0ustar framstagusers/* * File: message.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Martin Buck (Martin-2.Buck@student.uni-ulm.de) * Christoph 'GNUish' Goern (goern@janus.beuel.rhein.de) * * History: * 1995-08-11 Framstag initial version * 1995-09-01 Framstag added global variable prg * 1995-12-21 Framstag with or without unix error message * 1995-02-19 mbuck alternative message format * 1995-04-12 Framstag added call to cleanup routine * 1997-02-14 GNUish renamed ALT_MESSAGES to GNU_MESSAGES * 1997-09-21 Framstag severity level printed in word * 2001-02-16 Framstag added severity level X (without cleanup) * * VMS-like information, warning and error message routine. * * Copyright © 1995-2001 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include #include #include #include "globals.h" #include "message.h" #include "string.h" /* exit on fatalerror flag */ extern int xonf; /* * message - print information, warning and error messages on stderr * ( shameless plug from VMS :-) ) * * INPUT: cmd - command or programm which sends message * severity - severity of message * text - text of message * * exit program on a fatal 'F' (with cleanup) or exit 'X' error */ void message(char *cmd, char severity, const char *text) { char *facility; /* facility id */ extern char *prg; /* name of the game */ /* no cmd? then use global variable prg */ if (*cmd==0) cmd=prg; /* strip off path */ facility=strrchr(cmd,'/'); if (!facility) facility=cmd; else facility++; /* print the message */ severity=toupper(severity); #ifdef GNU_MESSAGES fprintf(stderr, "%s: %s: %s", facility, #else fprintf(stderr, "%%%s-%s: %s", facility, #endif (severity == 'F') ? "Fatalerror" : ((severity == 'X') ? "Fatalerror" : ((severity == 'E') ? "Error" : ((severity == 'W') ? "Warning" : ((severity == 'I') ? "Info" : "Unknown")))), text); /* fprintf(stderr,"%%%s-%c, %s",facility,severity,text); */ /* on error print the internal error message, too */ if ((severity=='E' || severity=='F' || severity=='X') && errno) fprintf(stderr," : %s",strerror(errno)); fprintf(stderr,"\n"); /* exit on a fatal error */ if (toupper(severity)=='X') exit(1); if (toupper(severity)=='F') { cleanup(); if (xonf) exit(1); } } sendfile-2.1b/src/getline.c0000640000175100001440000000266410251136250015414 0ustar framstagusers/* * File: getline.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1997-06-23 Framstag initial version * 1997-06-24 Framstag better handling of EOF * 1997-09-23 Framstag fixed idiotic prompting bug * 1997-12-14 Framstag renamed getline() to getpromptline() * * Reads a single line of text from stdin. * * Copyright © 1997 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include "config.h" #include "string.h" #include "getline.h" #if defined(SOLARIS2) || defined(LINUX) #ifndef fileno int fileno(FILE *); #endif #endif #ifdef HAVE_LIBREADLINE #include #include char *readline(const char *); /* * getpromptline - get one line of text from stdin * * INPUT: line - prompt * * OUTPUT: line - input text line * * RETURN: input text line */ char *getpromptline(char *line, int len) { char *cp; /* is stdin a tty? */ if (isatty(fileno(stdin))) { cp=readline(line); if (!cp || strlen(cp) > len) { if (cp) free(cp); *line=0; return(NULL); } strcpy(line,cp); free(cp); return(line); } else /* no tty */ return(sfgetl(line,len,stdin)); } #else char *getpromptline(char *line, int len) { printf("%s",line); return(sfgetl(line,len,stdin)); } #endif sendfile-2.1b/src/utf7.c0000640000175100001440000002740010251136250014645 0ustar framstagusers/* * File: utf7.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-08-12 Framstag initial version * 1996-03-22 Framstag replaced some unsigned char with char * 1996-04-04 Framstag fixed memory leak in utf2iso * 1997-02-23 Framstag modified str_* function names * 1997-07-04 Framstag added NULL argument for utf2iso * 1997-07-10 Framstag '=' is not allowed in mbase64! * bugfix: corrupt UTF7 string will now be ignored * 1998-07-21 Framstag allow single spaces in UTF7 strings * 1998-10-29 Framstag iso2utf -> iso2utf7 * 1999-03-13 Framstag added uni2utf() and utf2uni() * * UTF-7 and Unicode coding routines for the sendfile package. * Look at utf7.h for a list of the functions. * * Copyright © 1995-1999 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include #include "string.h" /* extended string functions */ #include "utf7.h" /* * utf2iso - UTF-7 to ISO Latin-1 decoding * * INPUT: fnf - unix file name flag; if >0 substitute '/' with '_' * utf - UTF-7 encoded string * * OUTPUT: iso - ISO Latin-1 string * show - ISO Latin-1 string without control codes * shell - ISO Latin-1 string without control codes and meta characters * * RETURN: 2 digit binary code * - if no digit is set: no special chars found * - if 1st digit is set: Unicode characters or '/' or '\0' found * - if 2nd digit is set: meta chars or control code chars found * * REMARK: iso, show and shell may be NULL in which case they will be ignored */ int utf2iso(int fnf, char *iso, char *show, char *shell, char *utf) { int ucc, /* Unicode character count */ flags=0; /* output flags */ char *cp, *cp2, *cp3, /* char pointers for positioning substrings */ mbase_part[LEN_UTF]; /* mbase64 string */ pstr_t *uni_part; /* Unicode part pstring */ /* initialisize the strings */ if (iso) *iso=0; if (show) *show=0; if (shell) *shell=0; uni_part=pstr_create(LEN_UNI); /* loop over the UTF-7 encoded string to find mbase64 parts */ for (cp=utf, cp2=utf+1; *cp!=0; cp++, cp2++) { /* mbase64 shift char? */ if (*cp=='+') { /* end of mbase64 part? */ if (*cp2=='-' || *cp2==0) { if (iso) strcat(iso,"+"); if (show) strcat(show,"+"); if (shell) strcat(shell,"+"); /* still more string to parse? */ if (*cp2!=0) { cp++; cp2++; } } else { /* find end of mbase64 part */ for (cp3=cp2; *cp3!='-'; cp3++); /* cut out mbase64 part string */ *mbase_part=0; strncat(mbase_part,cp2,cp3-cp2); /* decode it to Unicode */ decode_mbase64(uni_part,mbase_part); /* loop over Unicode pstring to look for ISO Latin-1 chars */ for (ucc=1; ucc<=uni_part->length; ucc+=2) { /* next character a ISO Latin-1 char? */ if (uni_part->string[ucc]==0) add_char(fnf,iso,show,shell,uni_part->string[ucc+1],&flags); else { /* substitute non valid Unicode character with '_' */ flags = flags|1; if (iso) strcat(iso,"_"); if (show) strcat(show,"_"); if (shell) strcat(shell,"_"); } } /* adjust the pointers */ cp = cp3; cp2 = ++cp3; } } else /* add a ISO Latin-1 char */ add_char(fnf,iso,show,shell,*cp,&flags); } /* dont allow "." or ".." as file names */ if (fnf) { if (iso && str_eq(iso,".")) { strcpy(iso,"_"); flags = flags|1; } if (show && str_eq(show,".")) { strcpy(show,"_"); flags = flags|1; } if (shell && str_eq(shell,".")) { strcpy(shell,"_"); flags = flags|1; } if (iso && str_eq(iso,"..")) { strcpy(iso,"__"); flags = flags|1; } if (show && str_eq(show,"..")) { strcpy(show,"__"); flags = flags|1; } if (shell && str_eq(shell,"..")) { strcpy(shell,"__"); flags = flags|1; } } /* free memory for no longer used Unicode pstring */ pstr_delete(uni_part); return(flags); } /* * add_char - add a char depending on its range * * INPUT: fnf - unix file name flag; if >0 substitute '/' with '_' * c - char to add * flags - return flags for utf2iso function * * OUTPUT: iso - ISO Latin-1 string * show - ISO Latin-1 string without control codes * shell - ISO Latin-1 string without control codes and meta characters * flags - return flags for utf2iso function */ void add_char(int fnf, char *iso, char *show, char *shell, char c, int *flags) { unsigned char sc[2]; /* string to add */ const char *meta="\"!#$&'()*?\\`| "; /* (bourne) shell meta characters */ /* build the string to add */ sc[0] = c; sc[1] = 0; /* is it a non valid char for a UNIX file name? */ if (*sc==0 || (*sc=='/' && fnf)) { *flags = *flags|1; *sc = '_'; } /* add the char to the iso-string */ if (iso) strcat(iso,(char *)sc); /* is it a control code? */ if (*sc<32 || (*sc>126 && *sc<161)) { *flags = *flags|2; *sc = '_'; } /* add the char to the show-string */ if (show) strcat(show,(char *)sc); /* is it a meta char? */ if (strchr(meta,*(char *)sc)) { *flags = *flags|2; *sc = '_'; } /* add the char to the shell-string */ if (shell) strcat(shell,(char *)sc); } /* * iso2utf - ISO Latin-1 to UTF-7 encoding * * INPUT: iso - ISO Latin-1 string * * OUTPUT: utf - UTF-7 encoded string */ void iso2utf(char *utf_name, char *iso_name) { iso2utf7(utf_name,iso_name,1); } /* * iso2utf7 - ISO Latin-1 to UTF-7 encoding * * INPUT: iso - ISO Latin-1 string * withspace - flag for encoding spaces * * OUTPUT: utf - UTF-7 encoded string */ void iso2utf7(char *utf_name, char *iso_name, int withspace) { char *cp, *cp2, /* string pointers */ *DO_set="abcdefghijklmnopqrstuvwxyz" /* mbase64 D and O sets */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "01234567890" "'(),-./:?!\"#$%&*;<>@[]^_`{}|"; char iso_part[LEN_ISO], /* ISO Latin-1 part string */ mbase_part[LEN_UTF]; /* mbase64 part string */ pstr_t *uni_part; /* Unicode part pstring */ /* initialisize the strings */ utf_name[0]=0; uni_part=pstr_create(LEN_UNI); /* scan the iso-string */ for (cp=iso_name; *cp!=0 ; cp++) { /* char in DO set (or is it a middle single space)? */ if (strchr(DO_set,*cp) || (cp!=iso_name && *(cp+1) && withspace && *cp==32 && *(cp+1)!=32)) strncat(utf_name,cp,1); else { /* add UTF-7 shift char */ strcat(utf_name,"+"); /* +- short encoding? */ if (*cp=='+') strcat(utf_name,"-"); else { /* search for the next char in the DO set */ cp2=cp; cp2++; while (strchr(DO_set,*cp2)==NULL && *cp2!=0) cp2++; /*while ((strchr(DO_set,(int)*cp2)==NULL) && (*cp2!=NULL)) cp2++;*/ /* cut out the iso-part string */ *iso_part=0; strncat(iso_part,cp,cp2-cp); /* translate it to Unicode */ iso2uni(uni_part,iso_part); /* encode to mbase64 */ encode_mbase64(mbase_part,uni_part); /* add it to the utf string */ strcat(utf_name,mbase_part); strcat(utf_name,"-"); cp=cp2-1; } } } /* free memory for no longer used Unicode pstring */ pstr_delete(uni_part); } /* * uni2utf - Unicode to UTF-7 encoding * * INPUT: uni - unicode pstring * * OUTPUT: utf - UTF-7 encoded string */ void uni2utf(char *utf, pstr_t *uni) { /* encode to mbase64 */ encode_mbase64(utf+1,uni); /* build utf7 string */ utf[0]='+'; strcat(utf,"-"); } /* * utf2uni - UTF-7 to Unicode decoding * * INPUT: utf - UTF-7 encoded string * * OUTPUT: uni - unicode pstring */ void utf2uni(pstr_t *uni, char *utf) { char *cp, *cp2, *cp3, /* char pointers for positioning substrings */ mbase_part[LEN_UTF]; /* mbase64 string */ pstr_t *uni_part; /* Unicode part pstring */ uni_part=pstr_create(LEN_UNI); /* loop over the UTF-7 encoded string to find mbase64 parts */ for (cp=utf, cp2=utf+1; *cp!=0; cp++, cp2++) { /* mbase64 shift char? */ if (*cp=='+') { /* short end of mbase64 part ("+-")? */ if (*cp2=='-' || *cp2==0) { if (pstr_addchar(uni,0)<0) return; if (pstr_addchar(uni,'+')<0) return; /* still more string to parse? */ if (*cp2!=0) { cp++; cp2++; } } else { /* find end of mbase64 part */ for (cp3=cp2; *cp3!='-'; cp3++); /* cut out mbase64 part string */ *mbase_part=0; strncat(mbase_part,cp2,cp3-cp2); /* decode it to Unicode */ decode_mbase64(uni_part,mbase_part); /* add unicode part string */ if (pstr_addpstring(uni,uni_part)<0) return; /* adjust the pointers */ cp = cp3; cp2 = ++cp3; } } else { /* add a ISO Latin-1 char */ if (pstr_addchar(uni,0)<0) return; if (pstr_addchar(uni,*cp)<0) return; } } /* free memory for no longer used Unicode pstring */ pstr_delete(uni_part); } /* * iso2uni - transform ISO Latin-1 to Unicode * * INPUT: iso - ISO Latin-1 string * * OUTPUT: uni - Unicode pstring */ void iso2uni(pstr_t *uni, char *iso) { char *cp; /* character pointer */ /* Unicode length is 0 at start */ uni->length=0; /* loop over iso string */ for (cp=iso; *cp!=0; cp++) { /* first byte of Unicode character is always 0 */ if (pstr_addchar(uni,0)<0) return; /* add the ISO Latin-1 char byte */ if (pstr_addchar(uni,*cp)<0) return; } } /* * The functions decode_mbase64 and encode_mbase64 are based on encdec.c * by Jürgen Hägg which has been debugged and rewritten to use as C functions. * The original header was: * * Written by Jürgen Hägg 1993 * Version 1.1 * * (This filter is written for use in a MTA written in perl.) * * Please send comments and bugfixes when you find them. * Permission to use and change this program is given for any purpose * as long as this note remains unchanged. * * The usage() is the manual. * Use encdec as you wish :-) * */ void decode_mbase64(pstr_t *outstring, char *instring) { int i, j, num, len, err; long d, val; char *p, *c; static char vec[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; unsigned char nw[4]; outstring->length = 0; len = strlen(instring); strcat(instring,"=="); for (i=0; i=0; j--) { nw[j] = val & 255; val >>= 8; } for (j=0; jlength/2 != outstring->length/2.) outstring->length--; } void encode_mbase64(char *outstring, pstr_t *instring) { int n = 0, iz, oz = 0, i; unsigned char c; long val = 0; unsigned char enc[4]; static char vec[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; for (iz=1; iz<=instring->length; iz++) { c=instring->string[iz]; if (n++<=2) { val <<= 8; val += c; continue; } for (i=0; i<4; i++) { enc[i] = val&63; val >>= 6; } for (i=3; i>=0; i--) outstring[oz++] = vec[(int)enc[i]]; n = 1; val = c; } if (n==1) { val <<= 16; for (i=0; i<4; i++) { enc[i] = val&63; val >>= 6; } enc[0] = enc[1] = 64; } if (n==2) { val <<= 8; for (i=0; i<4; i++) { enc[i] = val&63; val >>= 6; } enc[0] = 64; } if (n==3) for (i=0; i<4; i++) { enc[i] = val&63; val >>= 6; } if (n) for (i=3; i>=0; i--) { c = vec[(int)enc[i]]; if (c!='=') outstring[oz++] = c; } outstring[oz] = 0; } sendfile-2.1b/src/io.c0000644000175100001440000002753010335565640014413 0ustar framstagusers/* * File: io.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-08-11 Framstag initial version * 1996-04-23 Framstag added file copying function * 1996-05-02 Framstag corrected file creating bug in fcopy() * 1996-06-24 Framstag enhanced fcopy() to copy to stdout * 1997-02-02 Framstag improved reliability for fcopy() with NFS * 1997-02-24 Framstag sprintf() -> snprintf() * 1997-05-05 Framstag better IRIX support (blksize) * 1997-12-09 Framstag added whereis() * 2001-01-10 Framstag added rfopen() * 2001-02-04 Framstag added mktmpdir() and rmtmpdir() * 2001-02-16 Framstag fixed cleanup loop * 2002-08-04 Framstag moved spawn() from receice.c * 2002-12-19 Framstag rmtmpdir: ignore non-existing tmpdir * 2005-05-31 Framstag added largefile support * enhanced fcopy performance (fixed blksize bug) * 2005-11-10 Framstag added vsystem() * 2005-11-11 Framstag added vpopen() * * Socket read and write routines and file copy function of the * sendfile package. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #include #include #include #include #include #include #include #include #include #include #include "io.h" /* (socket) read/write */ #include "net.h" /* the network routines */ #include "string.h" /* extended string functions */ #include "message.h" /* information, warning and error messages */ /* * readn - read n bytes from network socket * * INPUT: fd - socket file descriptor * ptr - empty string * nbytes - number of bytes to read * * RETURN: number of actual read bytes * * this function is derived from example code from * "Unix Networking Programming" by W. R. Stevens */ int readn(int fd, char *ptr, int nbytes) { int nleft, nread; nleft=nbytes; while (nleft>0) { nread=read(fd, ptr, nleft); if (nread<0) return(nread); else if (nread==0) break; nleft-=nread; ptr+=nread; } return(nbytes-nleft); } /* * writen - write n bytes to network socket * * INPUT: fd - socket file descriptor * ptr - string to send * nbytes - number of bytes to send * * RETURN: number of actual written bytes * * this function is derived from example code from * "Unix Networking Programming" by W. R. Stevens */ int writen(int fd, char *ptr, int nbytes) { int nleft, nwritten; nleft=nbytes; while (nleft>0) { nwritten=write(fd, ptr, nleft); if (nwritten<0) return(nwritten); nleft-=nwritten; ptr+=nwritten; } return(nbytes-nleft); } /* * fcopy - copy a file (copy to stdout if there is no destination filename) * * INPUT: from - source file * to - destination file * mode - file protection mode * * RETURN: 0 if ok, -1 on failure * */ int fcopy(const char *from, const char *to, mode_t mode) { int fdin, fdout; /* file descriptor in/out */ int rbytes, /* read bytes */ wbytes; /* written bytes */ char tmp[MAXLEN], /* temporary string */ *buf; /* copy buffer */ struct stat finfo; /* information about a file */ off_t fsize, /* original file size */ wtotal; /* total read bytes */ long blksize; /* file system block size */ wtotal=0; /* get the original file size */ if (stat(from,&finfo)<0) { snprintf(MAXS(tmp),"cannot access '%s'",from); message("",'E',tmp); return(-1); } fsize=finfo.st_size; #ifdef HAVE_ST_BLKSIZE blksize=finfo.st_blksize; #else blksize=1024; #endif /* open source file */ fdin=open(from,O_RDONLY|O_LARGEFILE,0); if (fdin<0) { snprintf(MAXS(tmp),"error opening '%s'",from); message("",'E',tmp); return(-1); } /* destination file specified? */ if (*to) { /* open destination file */ fdout=creat(to,mode); if (fdout<0) { snprintf(MAXS(tmp),"error creating '%s'",to); message("",'E',tmp); close(fdin); return(-1); } /* ANSI C can not dynamicly allocate with buf[blksize] */ buf=(char *)malloc(blksize); if (!buf) message("",'F',"out of memory"); /* read until EOF */ while ((rbytes=read(fdin,buf,blksize)) > 0) { /* write to destination file */ wbytes=write(fdout,buf,rbytes); if (wbytes!=rbytes) { /* write error */ close(fdin); close(fdout); free(buf); snprintf(MAXS(tmp),"error writing '%s'",to); message("",'E',tmp); return(-1); } wtotal+=wbytes; } close(fdout); } else /* copy to stdout */ { /* ANSI C can not dynamicly allocate with buf[blksize] */ buf=(char *)malloc(blksize); if (!buf) message("",'F',"out of memory"); /* read until EOF */ while ((rbytes=read(fdin,buf,blksize)) > 0) { /* write to stdout */ wbytes=write(fileno(stdout),buf,rbytes); wtotal+=wbytes; } } close(fdin); free(buf); /* read error? */ if (rbytes<0) { snprintf(MAXS(tmp),"error reading '%s'",from); message("",'E',tmp); return(-1); } /* count mismatch or read/write errors? */ if (fsize!=wtotal) { errno=0; snprintf(MAXS(tmp),"wrong byte count for '%s'",from); message("",'E',tmp); return(-1); } return(0); } /* * whereis - where is a program in the path * * INPUT: prg - program to look for * * RETURN: NULL if not found else path to file */ char *whereis(char *prg) { int len; static char filepath[MAXLEN]; /* file with path */ char *path; /* $PATH */ char *cp; /* when file contains a / test directly */ if (strchr(prg,'/')) { if (access(prg,X_OK)==0) return(prg); else return(NULL); } len=strlen(prg); path=getenv("PATH"); if (!path || !strchr(path,'/')) return(NULL); while (*path==':') path++; while (*path) { snprintf(filepath,MAXLEN-2-len,"%s",path); if ((cp=strchr(filepath,':'))) *cp=0; strcat(filepath,"/"); strcat(filepath,prg); if (access(filepath,X_OK)==0) return(filepath); if ((cp=strchr(path,':'))) path=cp+1; else return(NULL); } return(NULL); } /* * rfopen - open a regular file * * INPUT: file - file name (with path) * mode - fopen mode * * RETURN: same like fopen(), but NULL if file is not a regular file */ FILE *rfopen(const char *file, const char *mode) { struct stat finfo; /* information about a file */ /* what kind of file ist it and do we have access at all? */ if (stat(file,&finfo)<0) { /* no such file ==> open it! (mode can be "w" or "a+") */ if (errno==ENOENT) return(fopen(file,mode)); else /* other error */ return(NULL); } else { /* regular file? */ if (finfo.st_mode&S_IFREG) { return(fopen(file,mode)); } else { errno=EIO; return(NULL); } } } /* * mktmpdir - create a new temporary directory * * INPUT: verbose - flag * * RETURN: full path of the temporary directory * * ENVIRONMENT: SF_TMPDIR, TMPDIR */ char *mktmpdir(int verbose) { char *cp; /* a simple string pointer */ char tmp[MAXLEN]; /* temporary string */ static char tmpdir[FLEN]; /* directory for temporary files */ /* get tmpdir base */ if ((cp=getenv("SF_TMPDIR"))) snprintf(tmpdir,FLEN-30,"%s",cp); else if ((cp=getenv("TMPDIR"))) snprintf(tmpdir,FLEN-30,"%s",cp); else strcpy(tmpdir,"/tmp"); snprintf(tmp,30,"/sf_%u.tmp",(unsigned int)(time(NULL)*getpid())); strcat(tmpdir,tmp); if (mkdir(tmpdir,S_IRWXU)<0 || chmod(tmpdir,S_IRWXU)<0) { snprintf(MAXS(tmp),"cannot create tmpdir %s",tmpdir); message("",'F',tmp); } if (verbose) { snprintf(MAXS(tmp),"directory for temporary files is: %s",tmpdir); message("",'I',tmp); } return(tmpdir); } /* * rmtmpdir - delete the temporary directory * * INPUT: full path of the temporary directory */ void rmtmpdir(char *tmpdir) { char cwd[FLEN]; /* current directory */ char tmp[MAXLEN]; /* temporary string */ struct dirent *dire; /* directory entry */ DIR *dp=NULL; /* directory pointer */ if (!tmpdir || !*tmpdir) return; if (!getcwd(MAXS(cwd))) strcpy(cwd,"/tmp"); /* open dir */ if (chdir(tmpdir) < 0 || !(dp=opendir(tmpdir))) { /* snprintf(MAXS(tmp),"cleanup: cannot open %s",tmpdir); message("",'X',tmp); */ return; } while ((dire=readdir(dp))) { /* skip . and .. */ if (strcmp(dire->d_name,".")==0 || strcmp(dire->d_name,"..")==0) continue; /* delete file */ if (unlink(dire->d_name) < 0) { snprintf(MAXS(tmp),"cannot remove %s/%s",tmpdir,dire->d_name); message("",'W',tmp); } } chdir(cwd); if (rmdir(tmpdir) < 0) { snprintf(MAXS(tmp),"cannot remove %s",tmpdir); message("",'X',tmp); } } /* * spawn - spawn a subprocess and direct output to a file * * INPUT: sad - spawn argument descriptor * output - output file, may be NULL * cmask - protection mask * * RETURN: 0 on success, -1 on failure * */ int spawn(char **sad, const char *output, mode_t cmask) { int status, /* fork status */ fd; /* output file descriptor */ pid_t pid; /* process id */ #ifdef DEBUG extern int verbose; if (verbose) { int i; for (i=0; sad[i]; i++) { printf("sad[%d]=\"%s\"\n",i,sad[i]); } } #endif /* spawn subprocess */ pid=fork(); /* failed? */ if (pid<0) { message("",'E',"cannot fork subprocess"); return(-1); } /* is this the subprocess? */ if (pid==0) { /* redirect stdout? */ if (output) { /* close stdout */ close(1); /* open output file as stdout */ fd=creat(output,0666&~cmask); if (fd!=1) { errno=0; message("",'E',"file descriptor mismatch"); cleanup(); exit(1); } } /* execute program */ execvp(sad[0],sad); /* oops - failed */ message("",'F',"execvp() failed!"); cleanup(); exit(2); } /* wait for termination of subprocess */ #ifdef NEXT wait(&status); #else waitpid(pid,&status,0); #endif /* error in subprocess? */ if (status) return(-1); return(0); } /* * vsystem - system() with verbose output * * INPUT: cmd - shell command string * * RETURN: system() return code */ int vsystem(const char *cmd) { char tmp[MAXLEN]; extern int verbose; extern char *prg; if (verbose) { snprintf(MAXS(tmp),"shell-call: %s\n",cmd); message(prg,'I',tmp); } return(system(cmd)); } /* * vpopen - popen() with verbose output * * INPUT: cmd - shell command string * type - popen type string (r or w) * * RETURN: popen() FILE */ FILE* vpopen(const char *cmd, const char *type) { char tmp[MAXLEN]; extern int verbose; extern char *prg; if (verbose) { *tmp = 0; switch (*type) { case 'r': snprintf(MAXS(tmp),"shell-call: %s|",cmd); break; case 'w': snprintf(MAXS(tmp),"shell-call: |%s",cmd); break; } message(prg,'I',tmp); } return(popen(cmd,type)); } /* * shell_quote - quote a string so it ist shell escape safe * * INPUT: string - string to quote * * RETURN: quoted string * * REMARK: this function is not rentrant safe! */ char* shell_quote(const char *string) { static char quoted[MAXLEN]; const char *special=" [](){}<>?*~#$&|;'\n\t\v\b\r\f\a\"\\"; const char *sp; char *qp; qp=quoted; for (sp=string; *sp; sp++) { if (strchr(special,*sp)) { if (qp-quoted+2 >= MAXLEN) break; *qp='\\'; qp++; } if (qp-quoted+1 >= MAXLEN) break; *qp=*sp; qp++; } qp++; *qp=0; return(quoted); } /* int main(int argc, char *argv[]) { char *filepath; filepath=whereis(argv[1]); if (filepath) { printf("%s\n",filepath); exit(0); } exit(1); } */ sendfile-2.1b/src/lock.h0000640000175100001440000000070310251136250014712 0ustar framstagusers/* * File: lock.h * * Author: Ulli Horlacher (framstag@belwue.de) * * History: * * 1998-05-10 Framstag moved from sendfiled.c * * These are functions which sets or tests advisory locks conforming to POSIX * fcntl() call. * * Copyright © 1998 Ulli Horlacher * This file is covered by the GNU General Public License */ /* write-lock a file */ int wlock_file(int); /* test the lock status of a file */ int tlock_file(int); sendfile-2.1b/src/peername.h0000640000175100001440000000012010251136250015547 0ustar framstagusers/* returns the peername of the connecting host on stdin */ char *peername(int); sendfile-2.1b/src/net.c0000640000175100001440000005414510765537555014603 0ustar framstagusers/* * File: net.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Heiko Schlichting (heiko@fu-berlin.de) * Holger Berger (Holger.Berger@rus.uni-stuttgart.de) * Andreas "Ako" Koppenhöfer (koppenhoefer@belwue.de) * * History: * * 1995-08-11 Framstag initial version * 1995-09-10 Framstag some debugging * 1995-11-15 Framstag improved sock_getline * 1995-12-21 Framstag simplified sock_getline and getreply * 1996-04-17 Framstag new error handling in open_connection * 1996-05-14 Framstag included and modified send_data() * 1996-05-21 Framstag gettimeofday() fix for Solaris-2 * 1996-06-20 Framstag always use gethostbyname() * 1996-08-03 Framstag corrected thruput value * 1996-09-04 Heiko some fixes for IRIX * 1996-09-24 Heiko added get_domainname() * 1996-11-19 Framstag fix for broken AIX include-files * 1996-12-29 Framstag moved get_domainname to reply.c * 1997-01-19 Framstag added "resuming at ..." output * 1997-01-25 Framstag send_data can now read from stdin, too * 1997-01-31 Framstag print final transfer statistic with quiet mode 1 * 1997-02-24 Framstag sprintf() -> snprintf() * 1997-06-15 Framstag added file reading test mode * corrected transfer statistics output * 1997-06-16 Hobel socket tuning * 1997-06-30 Framstag fixed bug in transfer statistics output * 1997-08-21 Framstag sendheader can handle better reply code 202 * 1997-12-09 Framstag added sendcommand() * 1997-12-15 Framstag new parameter for send_data(): speed * 1998-02-27 Framstag more verbose transfer statistics * 1998-03-07 Framstag better detection of non-interactive mode * added -i option for more transfer information * 1998-04-02 Framstag don't ask for server-reply on QUIT command * 1998-06-23 Framstag fixed byte counting bug in transfer statistics * 1998-07-04 Ako set tcp timeout option * 1998-07-07 Ako fixed fflush(NULL) bug for SunOS 4 * 1998-08-21 Framstag added maximum thruput option for send_data * 2005-05-30 Framstag fixed system includes for Linux * 2005-05-31 Framstag added largefile support * 2005-06-06 Maide added multiprotocol cababilities * * Network routines for the the sendfile client of the sendfile package. * Look at net.h for a list of the functions. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ /* #ifdef NEXT typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; typedef long daddr_t; typedef char *caddr_t; typedef long time_t; #define _TIME_T #endif */ #include "config.h" /* various definitions */ #include #include #include #include #include #include #include #include #include #include #include #include #include "string.h" /* extended string functions */ #include "message.h" /* information, warning and error messages */ #include "net.h" /* network stuff */ #include "io.h" /* socket read/write */ /* stupid AIX comes with no include files for networking and other stuff */ #if defined(AIX3) || defined(ULTRIX) #include "bsd.h" #endif /* #ifdef SOLARIS2 #ifdef _SVID_GETTOD int gettimeofday(struct timeval *); #else int gettimeofday(struct timeval *, void *); #endif #endif */ #if defined(SOLARIS2) #ifndef fileno int fileno(FILE *); #endif #endif /* #ifdef IRIX u_short htons(u_short hostshort); #endif */ extern int client; /* client or server flag */ extern int verbose; /* flag for verbose mode */ extern char *prg; /* name of the game */ #ifdef ENABLE_MULTIPROTOCOL int addressFamily = PF_UNSPEC; /* address family to be used or PF_UNSPEC */ #endif #ifndef ENABLE_MULTIPROTOCOL /* * open_connection - obsolete ipv4 open_connection * * INPUT: adr - ip address or name of server to connect to * port - port number to connect to * * RETURN: socket file descriptor * -1 if socket creation failed * -2 if connection failed * -3 if unknown host * * this function is derived from example code from * "Unix Networking Programming" by W. R. Stevens */ int open_connection(char *adr, int port) { int sockfd, /* socket file descriptor */ num=1; /* flag for numeric ip address */ struct sockaddr_in serv_addr; /* internet socket */ struct in_addr hostaddr; struct hostent *hostp; /* host entity */ char *cp, /* character pointer */ hostip[17], /* server host ip address */ hostname[MAXLEN]; /* server host name */ /* split off port from hostname */ strcpy(hostname,adr); if ((cp=strchr(hostname,':'))) *cp=0; /* open socket */ sockfd=socket(AF_INET,SOCK_STREAM,0); if (sockfd<0) return(-1); #ifdef DEBUG message(prg,'I',"socket ok"); #endif /* initialisize serv_addr */ memset((char *) &serv_addr, 0, sizeof(serv_addr)); /* numeric oder symbolic ip address? */ for (cp=hostname; *cp>0; cp++) { if (*cp>'@') { num=0; break; } } /* quick hack: gethostbyname() does also work with numeric addresses */ num=0; /* look for server host address */ if (num) { hostaddr.s_addr=inet_addr(hostname); hostp=gethostbyaddr((char *)&hostaddr,sizeof(hostaddr),AF_INET); } else hostp=gethostbyname(hostname); if (hostp==NULL) return(-3); /* convert binary structure to ASCII hostip */ strcpy(hostip,inet_ntoa(*(struct in_addr *) *hostp->h_addr_list)); #ifdef DEBUG printf("host: %s\n",hostip); #endif /* fill out server address descriptor */ serv_addr.sin_family =AF_INET; serv_addr.sin_addr.s_addr=inet_addr(hostip); serv_addr.sin_port =htons(port); /* befor connecting, let's do some tuning :-) hobel */ { int flag; flag=1; #ifdef SO_KEEPALIVE if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_NODELAY flag=1; if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_BUFFER flag=TCP_BUFFER; if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); flag=TCP_BUFFER; if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_RFC1323 flag=1; if(setsockopt(sockfd, IPPROTO_TCP,TCP_RFC1323, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_WINSHIFT flag=1; /* this gives the power of two to be shifted */ if(setsockopt(sockfd, IPPROTO_TCP, TCP_WINSHIFT, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif } /* connect to server */ if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) return(-2); #ifdef DEBUG message(prg,'I',"connect ok"); #endif return(sockfd); } #else /* ENABLE_MULTIPROTOCOL */ /* * tune_socket - open socket and connect to client * * before connecting, let's do some tuning :-) - hobel * */ static inline void tune_socket(int sockfd) { int flag; flag=1; #ifdef SO_KEEPALIVE if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_NODELAY flag=1; if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_BUFFER flag=TCP_BUFFER; if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); flag=TCP_BUFFER; if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_RFC1323 flag=1; if(setsockopt(sockfd, IPPROTO_TCP,TCP_RFC1323, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif #ifdef TCP_WINSHIFT flag=1; /* this gives the power of two to be shifted */ if(setsockopt(sockfd, IPPROTO_TCP, TCP_WINSHIFT, (void *)&flag, sizeof(flag))<0) message(prg,'W',"could not configure socket"); #endif } /* * parse_address - get hostname and service/port string * * INPUT: address - the host[:port] string to parse * * OUTPUT: hostname - the host part * service - the service or port number part * * RETURN: 0 - success * -1 - parse error */ int parse_address(char* addr, char** hostname, char** service) { char *cp; /* character pointer */ *hostname = addr; if (*addr == '[') { addr++; *hostname = addr; if ((cp=strchr(addr,']')) == NULL) { return -1; } *cp = 0; cp++; if (service != NULL) { if (*cp == 0) { *service = SERVICE; } else if (*cp == ':') { *cp=0; cp++; *service = cp; } else { return -1; } } } else { *hostname = addr; if ((cp=strchr(addr,':'))) { *cp=0; cp++; } if (*service == NULL) { if (cp != NULL) *service = cp; else *service = SERVICE; } } return 0; } /* * open_connection - open socket and connect to client * * INPUT: adr - ip address or name of server to connect to * service - the service or port number to connect to * * RETURN: socket file descriptor * -1 if socket creation failed * -2 if connection failed * -3 if unknown host * -4 if out of memory * * this function is derived from example code from * "Unix Networking Programming" by W. R. Stevens */ int open_connection(char *adr, char* service) { int sockfd; /* socket file descriptor */ char *hostname; /* hostname */ char *hostptr; /* pointer to malloc'ed hostname buffer */ int result; /* catch results */ struct addrinfo* addressInfo; /* all available addresses for adr/service */ struct addrinfo* aiptr; /* pointer for iterating through address records */ struct addrinfo hints; /* hints for getaddrinfo */ int error = -3; /* split off port from hostname */ hostptr = strdup(adr); if (hostptr == NULL) return -4; if (parse_address(hostptr, &hostname, &service) < 0) { free(hostptr); return -3; } hints.ai_flags = 0; hints.ai_family = addressFamily; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_addrlen = 0; hints.ai_addr = NULL; hints.ai_canonname = NULL; hints.ai_next = NULL; result = getaddrinfo(hostname, service, &hints, &addressInfo); free(hostptr); if (result < 0) return (-3); for (aiptr = addressInfo; aiptr != NULL; aiptr = aiptr->ai_next) { sockfd = socket(aiptr->ai_family, aiptr->ai_socktype, aiptr->ai_protocol); if (sockfd < 0) error = -1; else { #ifdef DEBUG message(prg,'I',"socket ok"); #endif tune_socket(sockfd); if (connect(sockfd, aiptr->ai_addr, aiptr->ai_addrlen) < 0) { close(sockfd); /* we need a clean state as the next address may well be a different protocol */ error = -2; } else { #ifdef DEBUG message(prg,'I',"connect ok"); #endif freeaddrinfo(addressInfo); return sockfd; } } } freeaddrinfo(addressInfo); return error; } #endif /* ENABLE_MULTIPROTOCOL */ /* * sock_getline - get a (command) line from the network socket * * INPUT: fd - socket file descriptor * line - empty string * * OUTPUT: line - read string * * RETURN: number of read bytes, -1 on error * * this function is derived from example code from * "Unix Networking Programming" by W. R. Stevens */ int sock_getline(int fd, char *line) { int n, rc; unsigned char c; char tmp[MAXLEN]; *line=0; for (n=0; n0 && line[n-1]=='\r') line[--n]=0; /* on verbose mode show the whole line */ if (verbose) printf("%s\n",line); return(n); } /* * sock_putline - send a line to the network socket * * INPUT: fd - socket file descriptor * line - string to send * * RETURN: number of send bytes */ int sock_putline(int fd, const char *line) { int n; /* number of send bytes */ char cmd[MAXLEN]; /* command line to send */ /* prepare string */ strcpy(cmd,line); strcat(cmd,"\r\n"); /* on verbose mode show what goes up */ if (verbose) printf("-> %s\n",line); /* and up and away :-) */ if (fd) n=writen(fd,cmd,strlen(cmd)); else /* test mode, no real sending */ n=strlen(cmd); return(n); } /* * getreply - get the reply on a command from the server * * INPUT: fd - socket file descriptor * * RETURN: the reply line string */ char *getreply(int fd) { int len; /* reply message length */ char msg[MAXLEN]; /* intermediate information/error message */ static char reply[MAXLEN]; /* reply string from server */ do { if (fd) { /* get the next reply line */ len=sock_getline(fd,reply); /* link failure? */ if (len<0) { errno=0; strcpy(msg,"server has closed the connection"); if (*reply) snprintf(MAXS(msg),"%s, last data: \"%s\"",msg,reply); if (client) { errno=0; message("",'F',msg); } /* return(""); */ return(reply); } /* reply message too short? */ if (len<4) { errno=0; snprintf(MAXS(msg),"corrupt reply: \"%s\"",reply); if (client) { errno=0; message(prg,'F',msg); strcpy(reply,msg); return(reply); } else { return(""); } } } else { /* test mode without network connection */ strcpy(reply,"222 test mode"); } } while (reply[3]=='-'); /* quit if there was a fatal server error */ if (reply[0]=='4') { errno=0; snprintf(MAXS(msg),"server error: %s",&reply[4]); if (client) { errno=0; message(prg,'F',msg); strcpy(reply,msg); return(reply); } else { return(""); } } return(reply); } /* * sendcommand - send a command line to the network socket and get the answer * * INPUT: fd - socket file descriptor * command - string to send * * OUTPUT: answer - answer string * * RETURN: answer string * * If answer is the NULL-pointer, the answer will bis discared. * See also sendheader() * Hack: because some SAFT-servers hang on the QUIT command, we don't ask for * the reply in this case. */ char *sendcommand(int fd, const char *command, char *answer) { if (answer) *answer=0; sock_putline(fd,command); if (answer) strcpy(answer,getreply(fd)); else if (!str_eq(command,"QUIT")) getreply(fd); return(answer); } /* * sendheader - send a headerline and check the reply code * * INPUT: fd - socket file descriptor * line - header line * * RETURN: 0 on sucess, -1 on server fatal error, 1 on header ignored * * Return value -1 never occurs because the program will terminate before * See also sendcommand() */ int sendheader(int fd, char *line) { char msg[MAXLEN], /* intermediate information/error message */ *reply; /* reply string from server */ /* on test mode return */ if (!fd) return(0); /* send the header line */ sock_putline(fd,line); /* server reply ok? */ reply=getreply(fd); if (str_beq(reply,"200")) return(0); if (str_beq(reply,"202")) return(1); errno=0; snprintf(MAXS(msg),"server error: %s",&reply[4]); message(prg,'F',msg); return(-1); } /* * send_data - send file data * * INPUT: sockfd - socket file descriptor * size - bytes to send * file - file to send ("" if read from stdin) * tinfo - additional transfer information * iso_name - name of the original file * type - file type string * mtp - maximum thruput * * OUTPUT: ttime - transfer time in ms * * RETURN: 0 if ok, 1 if already transfered, -1 if transfer failed */ int send_data(int sockfd, off_t size, const char *file, const char *tinfo, const char *iso_name, const char *type, float mtp, float *ttime) { int n, /* simple loop count */ nblocks, /* number of packets blocks */ bn, /* block number to read */ percent, /* what percentage of file has been transmitted */ ffd; /* file to send file descriptor */ unsigned long msec; /* milliseconds of transfer */ off_t bytes, /* bytes which has been sent */ offset; /* bytes already sent */ float thruput; /* network thruput */ char packet[OVERSIZE], /* data packet to send */ tmp[MAXLEN], /* temporary string */ fname[MAXLEN], /* file name and compress info */ *reply; /* reply string */ time_t sec0,sec1,sec2; /* unix time */ struct timeval tv1,tv2; #if !defined(SOLARIS2) && !defined(IRIX) struct timezone tz; #endif extern int quiet, /* quiet mode flag */ packet_size; /* size of a packet in bytes */ msec=0; offset=0; /* fallback */ if (packet_size<1) packet_size=512; if (ttime) *ttime=0; strcpy(fname,iso_name); if (*type) { strcat(fname," ("); strcat(fname,type); strcat(fname,")"); } if (!quiet && !verbose) printf("sending... \r"); fflush(stdout); /* real sending and no local testing? */ if (sockfd) { /* real file to send? ==> ask for resend */ if (*file) { sock_putline(sockfd,"RESEND"); reply=getreply(sockfd); /* correct answer? */ if (!str_beq(reply,"500 ") && !str_beq(reply,"502 ")) { /* error occured? */ if (!str_beq(reply,"230 ")) { if (quiet<3) { errno=0; snprintf(MAXS(tmp),"server error: %s",&reply[4]); message("",'F',tmp); } return(-1); } sscanf(&reply[4],"%lld",&offset); } } /* prepare sending of data */ sock_putline(sockfd,"DATA"); reply=getreply(sockfd); /* file already transmitted? */ if (str_beq(reply,"531 ")) { snprintf(MAXS(tmp), "file %s has been already transmitted - ignored.",iso_name); if (quiet<2) message("",'W',tmp); return(1); } /* server reply ok? */ if (!str_beq(reply,"302 ")) { if (quiet<3) { snprintf(MAXS(tmp),"corrupt server reply: %s",&reply[4]); errno=0; message("",'F',tmp); } return(-1); } } /* open file */ if (*file) { ffd=open(file,O_RDONLY,0); if (ffd<0 || lseek(ffd,offset,SEEK_SET)<0) { if (quiet<3) { snprintf(MAXS(tmp),"error reading %s",iso_name); message("",'E',tmp); } return(-1); } } else ffd=fileno(stdin); /* resend active? */ if (offset) { snprintf(MAXS(tmp),"resuming %s at byte %lld",iso_name,offset); if (quiet<2) message("",'I',tmp); } if (quiet==1) { snprintf(MAXS(tmp),"begin transfer of %s with %lld bytes",fname,size); message("",'I',tmp); } /* get time normal */ #if defined(SOLARIS2) || defined(IRIX) #ifdef _SVID_GETTOD gettimeofday(&tv1); #else gettimeofday(&tv1,NULL); #endif #else gettimeofday(&tv1,&tz); #endif sec1=0; sec0=time(0); /* send the file data in packets */ bytes=0; size=size-offset; nblocks=size/packet_size; for (bn=1; bn<=nblocks; bn++) { if (readn(ffd,packet,packet_size)sec1) { fprintf(stderr,"%s%s: %3d%% (%lld of %lld kB)\r", tinfo,fname,percent, (bytes+offset-1)/1024+1,(size+offset-1)/1024+1); fflush(stderr); sec1=sec2; } } /* limit maximum thruput */ if (mtp) while (bytes/(time(0)-sec0+0.001)>mtp*1024) sleep(1); } /* send the last bytes */ if ((n=size-nblocks*packet_size) > 0) { if (readn(ffd,packet,n)9999) snprintf(MAXS(tmp), "transfer of %s completed: %.1f kB/s",fname,thruput/1024); else snprintf(MAXS(tmp), "transfer of %s completed: %d byte/s",fname,(int)thruput); message("",'I',tmp); } else { fprintf(stderr,"%s%s: 100%% (",tinfo,fname); if (bytes>9999) fprintf(stderr,"%lld kB, ",bytes/1024); else fprintf(stderr,"%lld byte, ",bytes); if (thruput>9999) fprintf(stderr,"%.1f kB/s) \n",thruput/1024); else fprintf(stderr,"%u byte/s) \n",(int)thruput); fflush(stderr); } } if (ttime) *ttime=(float)msec; /* transfer ok? */ if (sockfd && !str_beq(getreply(sockfd),"201 ")) { if (quiet<3) { snprintf(MAXS(tmp),"transfer failed for %s",iso_name); errno=0; message("",'E',tmp); } return(-1); } return(0); } sendfile-2.1b/src/reply.h0000640000175100001440000000037110251136250015116 0ustar framstagusers/* * reply - send string conforming to NVT telnet standard * * INPUT: rc - reply code * * terminates program on fatal error * * Copyright © 1995 Ulli Horlacher * This file is covered by the GNU General Public License */ void reply(int); sendfile-2.1b/src/pstring.c0000640000175100001440000000756510251136250015460 0ustar framstagusers/* * File: pstring.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: 1995-08-11 Framstag initial version * 1999-03-13 Framstag added pstr_addpstring() * * Functions to handle Pascal like strings. * Look at string.h for a list of the functions. * Strings start by definition at pstr.length[1] * * Copyright © 1995,1999 Ulli Horlacher * This file is covered by the GNU General Public License */ #include #include #include /* #include */ #include "pstring.h" /* * pstr_create - create a pstring * * INPUT: size - size of pstring in bytes * * RETURN: the new pstring */ pstr_t *pstr_create(int size) { pstr_t *pstr; /* pstring pointer */ char *string; /* the string contents */ /* allocate memory */ if ((pstr=(pstr_t *)malloc(sizeof(pstr_t))) == NULL) return(NULL); if ((string=(char *)malloc(size+1)) == NULL) return(NULL); /* form the new pstring */ /* size and length are of type sizeof(char) ! */ pstr->size=size; pstr->length=0; pstr->string=string; return(pstr); } /* * pstr_delete - delete a pstring * * INPUT: pstr - pstring to delete */ void pstr_delete(pstr_t *pstr) { /* Freiheit fuer die Gummibaerchen! */ free(pstr->string); free(pstr); } /* * pstr_addchar - add a char to a pstring * * INPUT: c - the char to add * pstr - the pstring to add to * * OUTPUT: pstr - the pstring * * RETURN: 0 if ok, -1 if failed */ int pstr_addchar(pstr_t *pstr, char c) { /* no more space for appending a char? */ if (pstr->length >= pstr->size) return(-1); /* increment the pstring length information */ pstr->length += 1; /* add the char, what else? :-) */ pstr->string[pstr->length]=c; return(0); } /* * pstr_assign - assign one pstring to another (p1<-p2) * * INPUT: p1 - destination pstring * p1 - source pstring * * OUTPUT: p1 - assigned pstring * * RETURN: 0 if ok, -1 if failed */ int pstr_assign(pstr_t *p1, pstr_t *p2) { /* is p1 big enough for p2? */ if (p2->length > p1->size) return(-1); /* copy the string */ memcpy(p1->string,p2->string,p2->length+1); /* copy the length information */ p1->length = p2->length; return(0); } /* * pstr_addstring - add a string to a pstring * * INPUT: s - string to add * pstr - the pstring to add to * * OUTPUT: pstr - the pstring * * RETURN: 0 if ok, -1 if failed */ int pstr_addstring(pstr_t *pstr, const char *s) { int plen, /* length of pstring */ slen; /* length of string */ /* get the lengths */ slen=strlen(s); plen=pstr->length; /* does it fit into pstring? */ if (plen+slen > pstr->size) return(-1); /* copy the string */ memcpy(pstr->string+plen+1,s,slen); /* adjust the length information */ pstr->length += slen; return(0); } /* * pstr_addpstring - add a pstring to a pstring * * INPUT: s1 - pstring to add * s0 - the pstring to add to * * OUTPUT: the resulting pstring s0 * * RETURN: 0 if ok, -1 if failed */ int pstr_addpstring(pstr_t *s0, const pstr_t *s1) { /* does it fit into s0? */ if (s0->length+s1->length > s0->size) return(-1); /* copy the string */ memcpy(s0->string+s0->length+1,s1->string,s1->length); /* adjust the length information */ s0->length += s1->length; return(0); } /* * pstr_print - print a pstring * * INPUT: pstr - pstring to print */ void pstr_print(pstr_t *pstr) { int i; /* simple loop counter */ /* print char by char */ for (i=1; i <= pstr->length; i++) printf("%c",pstr->string[i]); } /* * test main routine for debugging purposes, not used * void main() { pstr_t *p1,*p2; char *blubb="blabla"; p1=pstr_create(100); p2=pstr_create(20); pstr_addchar(p1,'x'); pstr_addstring(p1,"123"); pstr_addstring(p2,"abcd"); pstr_addstring(p1,blubb); pstr_assign(p2,p1); pstr_delete(p1); pstr_print(p2); printf("\n"); } */ sendfile-2.1b/src/sendfile.c0000644000175100001440000023220511025466672015574 0ustar framstagusers/* * File: sendfile.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Rainer Bawidamann (widi@sol.wohnheim.uni-ulm.de) * Martin Buck (Martin-2.Buck@student.uni-ulm.de) * Heiko Schlichting (heiko@fu-berlin.de) * Christoph 'GNUish' Goern (goern@janus.beuel.rhein.de) * Stefan Scholl (stesch@parsec.inka.de) * Michael Neumayer (eumel@42.org) * Martin Schulze * Ulf Fischer * * History: * * 1995-08-11 Framstag initial version * 1995-08-12 Framstag elm alias support * 1995-09-10 Framstag added delete and resend function * 1996-02-06 Framstag added ATTR EXE * 1996-02-07 Framstag check for already compressed files * 1996-02-20 Framstag follow forward address if given * 1996-02-21 widi better Solaris-2 support * 1996-02-22 Framstag added bouncing (forwarding) of files * 1995-02-23 mbuck bug fixes for getting $HOME * 1995-02-27 Framstag added quiet options * 1995-03-08 Framstag catch up signals in cleanup() * 1995-03-17 Framstag set umask (for tmp-files) * 1995-03-23 Framstag added percentage output * 1995-03-24 Framstag $TMPDIR replaces $HOME for tmp-files * 1996-03-28 Framstag extended search for support programs * 1996-04-02 Framstag added forward address to COMMENT * 1996-04-06 Framstag changed transaction message format * added overwrite option * 1996-04-10 Framstag better usage text * 1996-04-12 Framstag added pgp support * 1996-04-16 Framstag better pgp signature creation * 1996-04-17 Framstag new error handling for open_connection * 1996-04-18 Framstag verbose mode displays system() commands * allowed multiple IDs for pgp encryption * 1996-04-20 Framstag added pgp IDEA encryption option * 1996-04-24 Framstag changed bouncing option syntax * 1996-05-08 Framstag fixed bug when bouncing * 1996-05-10 Framstag allowed multiple forwards * 1996-05-14 Framstag moved send_data() to net.c * 1996-05-21 Framstag fixed bug when sending archive * 1996-05-23 Framstag added check for writeable tmp-files * added -P option (read from stdin) * 1996-08-13 Framstag fixed wrong "(compressed)" output * 1996-09-04 Heiko some fixes for IRIX * 1996-09-11 Heiko fixed redirection comment bug * 1996-11-19 Framstag fix for broken AIX include-files * 1997-01-04 Framstag moved check_forward() to address.c * 1997-01-20 Framstag fixed bug with TEXT=charset attribute * 1997-01-20 GNUish modified to move to gnu-style * 1997-01-25 Framstag added -X option (extended headers) * better usage text * better pgp parsing * 1997-02-01 Framstag set default quiet mode 1 on dump ttys * 1997-02-14 GNUish added long options * 1997-02-23 Framstag modified str_* function names * extended with TYPE=MIME * 1997-02-24 Framstag sprintf() --> snprintf() * 1997-03-24 stesch fixed buffering bug with -X option * 1997-05-15 Framstag added -c option usage text * 1997-05-16 Framstag added file type guessing * 1997-05-17 Framstag better file type guessing * 1997-06-04 Framstag added SF_TMPDIR * 1997-06-15 Framstag added -T option for file reading test * added new line output in cleanexit() * 1997-06-17 Framstag added packet_size config option * 1997-06-30 Framstag better file type guessing * 1997-07-04 Framstag auto dection of pgp ID for encryption * 1997-08-20 Framstag new syntax with option -a=name-of-archive * 1997-08-21 Framstag better handling of reply code 202 * 1997-12-05 Eumel fixed file type handling bug * 1997-12-11 Framstag added bzip2 support * 1997-12-14 Framstag fixed bug when sending to /dev/null * 1997-12-15 Framstag added link speed test for auto-compression * 1997-12-19 Framstag added -W option * 1998-01-05 Framstag reactivated outgoing logging * 1998-01-17 Framstag check SAFT-URL for alternative tcp port * 1998-01-22 Framstag check compression method when bouncing * 1998-02-27 Framstag fixed small bug in guess_ftype * more verbose transfer statistics * 1998-03-01 Framstag changed /dev/null testing recipient to :NULL: * 1998-03-07 Framstag better detection of non-interactive mode * added -i option for more transfer information * 1998-03-08 Framstag fixed outlog deletion bug * 1998-03-16 Framstag fixed error loop bug in cleanup() * 1998-03-20 Framstag fixed archive+overwrite bug * 1998-08-21 Framstag added maximum thruput option * 1998-09-23 Framstag continue sending on tar errors * 1998-11-05 Framstag do not compress files less than 1 KB * 1998-11-12 Framstag print "spooled" information with size * fixed spool+archive+overwrite bug * 1999-08-03 Framstag gzip is default compression, back again * 2001-01-10 Framstag fopen() --> rfopen() * 2001-02-04 Framstag added secure mktmpdir() * 2002-05-29 Framstag added -Z packet-size option * 2002-08-04 Framstag system(tar) --> spawn(tar) * (no shell involved any more) * 2002-08-04 Framstag removed all shell trap code * (unnecessary because of rmtmpdir()) * 2002-12-05 Framstag faster IO when reading from stdin * 2005-05-30 Framstag fixed timeout bug * (when preprocessing huge files) * added -z option * dont compress with :NULL: recipient * 2005-05-31 Framstag added largefile support * 2005-06-06 Maide added multiprotocol cababilities * 2008-06-16 Joey prevent buffer overflow for getopt-strings * Ulf NULL pointer dereference bugfix in verbose mode * Framstag readded -z option (got lost somehow) * * The sendfile client of the sendfile package. * Sends one or more files to the sendfiled of the destination system. * * Copyright © 1995-2008 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* autoconf header */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "string.h" /* extended string functions */ #include "net.h" /* the network routines */ #include "io.h" /* socket and file IO extensions */ #include "message.h" /* information, warning and error messages */ #include "spool.h" /* operations on files in the sendfile spool */ #include "utf7.h" /* UTF-7 coding */ #include "address.h" /* address checking */ #define IOB 4096 /* IO buffer length */ #if defined(HAVE_GETOPT_H) #include #else int getopt(int, char * const *, const char *); extern int opterr; extern int optind; extern int optopt; extern char *optarg; #endif #if defined(SOLARIS2) int gethostname(char *, int); #endif #if defined(LINUX) int gethostname(char *, size_t); #endif #ifndef AIX3 #ifndef CONVEXOS FILE *popen(const char *, const char *); #endif int pclose(FILE *); #endif #ifdef NEXT int shutdown(int, int); #endif #if defined(AIX3) || defined(ULTRIX) # include "bsd.h" #endif /* print short help usage text */ int usage(); /* clean termination routine */ void cleanexit(); /* delete tmp-file and send LOG command to local server */ void cleanup(); /* encrypt a file with pgp */ void pgp_encrypt(int, char *, char *); /* create detached pgp signature file and send SIGN header command */ void pgp_sign(const char *, const char *, int); /* create and open outgoing spool header file */ FILE *outspool(const char *, const char *, char *); /* start local spool daemon for outgoing files */ void start_spooldaemon(char *); /* create temporary user outgoing log file */ void outlog(char *, char *, char *, char *); /* forward a file with complete header from stdin */ void forward(char *, float); /* read a header line from stdin */ void get_header(const char *, char *); /* guess file type */ char guess_ftype(const char *, char *); /* check if link to host is fast enough */ int linkspeed(const char *, int, char **); /* note the link speed for later processing */ void notespeed(const char *, unsigned long, float); /* list files in outgoing spool */ int list_spool(); /* print information about spooled file */ void spooled_info(const char *, const char *, int); /* global variables */ int pgppass=0, /* flag if the pgp password is set as an env variable */ verbose=0, /* flag for verbose mode */ xonf=1, /* exit on fatalerror flag */ client=1, /* flag to determine client or server */ quiet=0, /* quiet mode flag */ test=0, /* flag for file reading testing (send to /dev/null) */ outlogging=0, /* flag logging outgoing files */ packet_size=0; /* size of a packet in bytes */ char *prg, /* name of the game */ *pgpvm, /* pgp verbose mode string */ *tmpdir, /* directory for temporary files */ *dontcompress[99], /* list of file extensions which are not compressible */ pw_name[FLEN], /* own user name */ localhost[FLEN], /* name of the local host */ outlogtmp[MAXLEN], /* user temporary outgoing log file */ userspool[MAXLEN], /* user spool directory */ tar_bin[MAXLEN], /* the tar binary */ gzip_bin[MAXLEN], /* the gzip binary */ bzip2_bin[MAXLEN], /* the bzip2 binary */ zprg[MAXLEN], /* the compress programm (either gzip or bzip2) */ pgp_bin[MAXLEN], /* the pgp binary */ stdintmp[MAXLEN], /* name of stdin temporary file */ tartmp[MAXLEN], /* name of tar temporary file */ ziptmp[MAXLEN], /* name of gzipped temporary file */ texttmp[MAXLEN], /* name of text temporary file in NVT telnet format */ pgptmp[MAXLEN]; /* name of pgp temporary file */ int main(int argc, char *argv[]) { int i,n, /* simple loop count */ pid, /* current proccess id */ status, /* return codes */ bytes, /* number of bytes for stdin IO */ sockfd, /* socket file descriptor */ opt, /* option to test for */ fn, /* file number in argv */ tfn, /* total file number sent */ stdinf, /* read file from stdin */ ch, /* character to read in from file */ lanspeed, /* speed in kB/s which defines what is in the LAN */ pgpcrypt, /* pgp public key or IDEA encryption */ del, /* flag for deleting previous sent files */ tar, /* flag for sending files as tar archive */ zip, /* flag for sending files as zip archive */ exe, /* flag for sending executable */ pgp, /* flag for pgp encoding */ guess, /* flag for file type guessing */ text, /* flag for sending text file */ mime, /* flag for sending mime file */ source, /* flag for sending source code file */ spool, /* flag for do outgoing spooling */ list, /* flag for listing files in outgoing spool */ info, /* flag for information mode */ bounce, /* flag for bouncing files */ extended, /* flag for extended command parsing */ spooling, /* flag for spooling allowed */ overwrite, /* flag for overwriting already sent files */ do_compress; /* flag for really do compressing */ /* long long int */ off_t size, /* size of file to send */ orgsize; /* original file size uncompressed */ float mtp, /* maximum thruput limit */ tsize, /* total size of all sent files */ attime, /* actual transfer time */ tttime, /* total transfer time */ thruput; /* total net throughput */ char *cp, /* simple string pointer */ *argp, /* argument string pointer */ *pop, /* pgp option string pointer */ *fnp, /* file name pointer */ *type, /* type of file transfer */ *compress, /* the compression methode */ **sad, /* spawn argument descriptor */ mode, /* guessed file mode */ to[2*FLEN], /* user@host from argv */ file[FLEN], /* name of file to send */ tinfo[FLEN], /* transfer information */ sdfn[FLEN], /* spool data file name */ shfn[FLEN], /* spool header file name */ rto[2*FLEN], /* user@host from spool header file */ ftype[FLEN], /* file type mode */ archive[FLEN], /* name of archive file */ where[FLEN], /* where is userspool or sendfile.cf */ aopt[FLEN], /* alias options */ recipient[FLEN], /* recipient at serverhost */ bouncearg[DLEN], /* bouncing files argument */ sizes[FLEN], /* original and compressed file size */ user[FLEN], /* local user name */ date[DLEN], /* date of file */ host[FLEN], /* name of serverhost */ pgpopt[FLEN], /* options for pgp */ pgprid[FLEN], /* pgp recipient id */ pgpsign[FLEN], /* pgp signature option */ redirect[MAXLEN], /* redirected comment */ cmd[MAXLEN], /* cmd string for system-call */ line[MAXLEN], /* one line of text */ reply[MAXLEN], /* reply from the server */ tmp[MAXLEN], /* temporary string */ iobuf[IOB], /* IO buffer */ comment[MAXLEN], /* file comment */ outgoing[MAXLEN], /* outgoing spool directory */ oshfn[MAXLEN], /* outgoing spool header file name */ osdfn[MAXLEN], /* outgoing spool data file name */ filelist[OVERSIZE], /* list of files for tar command */ force_compress[MAXLEN]; /* force compress with special programm */ const char *cft[]= /* file types which are not compressible (output from file(1) command */ { "compress","zip","zoo","frozen","gif","jpg","jpeg","mpg","mpeg","" }; FILE *shf, /* spool header file */ *oshf, /* outgoing spool header file */ *inf, /* input file */ *outf; /* output file */ struct passwd *pwe; /* password entry */ struct stat finfo; /* information about a file */ char utf_name[LEN_UNI], /* name in UTF-7 format */ iso_name[LEN_ISO]; /* name in ISO Latin-1 format */ struct hostlist *hls, /* host list start */ *hlp; /* host list pointer */ struct outfilelist *oflp; /* outgoing file list pointer */ /* HAVE_GETOPTLONG_H is dead code for sendfile! */ #if defined(HAVE_GETOPTLONG_H) static struct option long_options[] = { { "version", 0, 0, 'V' }, { "help", 0, 0, 'h' }, { "delete", 0, 0, 'd' }, { "text", 0, 0, 't' }, { "spool", 0, 0, 'S' }, { "quiet", 0, 0, 'q' }, { "real-quiet", 0, 0, 'Q' }, { "source", 0, 0, 's' }, { "mime", 0, 0, 'm' }, { "verbose", 0, 0, 'v' }, { "uncompressed", 0, 0, 'u' }, { "overwrite", 0, 0, 'o' }, { "comment", 1, 0, 'c' }, { "extended", 1, 0, 'X' }, { "archive", 1, 0, 'a' }, { "bounce", 1, 0, 'b' }, { "stdin", 0, 0, 'P' }, { "pgp-sign", 0, 0, 'ps' }, { "pgp-encrypt", 1, 0, 'p' } #ifdef ENABLE_MULTIPROTOCOL { "ipv4-only", 0, 0, '4' }, { "ipv6-only", 0, 0, '6' }, #endif }; int long_index = 0; #endif mtp=0; tfn=0; del=0; tar=0; zip=0; exe=0; pgp=0; text=0; spool=0; quiet=0; mime=0; list=0; info=0; guess=0; tsize=0; source=0; bounce=0; sockfd=0; stdinf=0; tttime=0; thruput=0; verbose=0; extended=0; spooling=0; pgpcrypt=0; lanspeed=100; overwrite=0; do_compress=0; *aopt=0; *host=0; *date=0; *zprg=0; *where=0; *tinfo=0; *comment=0; *archive=0; *redirect=0; *filelist=0; *pgprid=0; *pgpopt=0; *pgpsign=0; *force_compress=0; dontcompress[0]=""; type="BINARY"; compress=S_GZIP; oshf=NULL; pid=(int)getpid(); prg=argv[0]; if ((cp=strrchr(prg,'/'))) prg=cp+1; /* switch off buffering for STDIN for -X option */ setvbuf(stdin, NULL, _IONBF, 0); if (getenv("PGPPASS")) { pgppass=1; pgpvm="+verbose=0"; } else { pgppass=0; pgpvm="+verbose=1"; } /* scann the command line on options */ #if defined(HAVE_GETOPTLONG_H) #ifndef ENABLE_MULTIPROTOCOL while ((opt=getopt_long(argc, argv, "Vh?dtmSqQsvuoc:X:a:b:p:", long_options, &long_index)) > 0) #else while ((opt=getopt_long(argc, argv, "Vh?dtmSqQsvuoc:X:a:b:p:46", long_options, &long_index)) > 0) #endif #else #ifndef ENABLE_MULTIPROTOCOL while ((opt=getopt(argc,argv,"ivVTgtsuqoMQPdSlzh?a:c:p:b:m:X:C:W:Z:")) > 0) #else while ((opt=getopt(argc,argv,"ivVTgtsuqoMQPdSlzh?a:c:p:b:m:X:C:W:Z:46")) > 0) #endif #endif { switch (opt) { case ':': case 'h': case '?': exit(usage()); case 'd': del=1; break; case 'g': guess=1; break; case 't': text=1; break; case 'T': test=1; break; case 'S': spool=1; break; case 'l': list=1; break; case 'i': info++; break; case 'q': quiet++; break; case 'Q': quiet=2; break; case 'P': stdinf=1; break; case 's': source=1; break; case 'M': mime=1; break; case 'm': mtp=atof(optarg); if (mtp<0) mtp=0; break; case 'v': verbose++; break; case 'u': compress=""; break; case 'C': if (*optarg == '=') strcpy(force_compress,optarg+1); else strcpy(force_compress,optarg); break; case 'o': overwrite=1; break; case 'c': if (*optarg == '=') strcpy(comment,optarg+1); else strcpy(comment,optarg); break; case 'a': tar=1; strcpy(archive,optarg); break; case 'A': zip=1; strcpy(archive,optarg); break; case 'b': bounce=1; strcpy(bouncearg,optarg); break; case 'X': extended=1; strcpy(host,optarg); break; case 'W': if (*optarg == '=') strcpy(where,optarg+1); else strcpy(where,optarg); break; case 'Z': if (*optarg == '=') packet_size=atoi(optarg+1); else packet_size=atoi(optarg); break; case 'p': pgp=1; snprintf(tmp,FLEN-1,"%s\n%s",pgpopt,optarg); strcpy(pgpopt,tmp); break; case 'V': message(prg,'I',"version "VERSION" revision "REVISION); exit(0); case 'z': strcpy(force_compress,"gzip"); #ifdef ENABLE_MULTIPROTOCOL case '4': addressFamily = PF_INET; break; case '6': addressFamily = PF_INET6; break; #endif } } /* too few arguments? */ if (argc-optind<2 && !extended && !list && !*where) { if (argc-optind<1) exit(usage()); errno=0; message(prg,'F',"too few arguments: " "you must specify at least a file name and recipient"); } /* non-interactive usage without a tty? */ if (!quiet) { cp=getenv("TERM"); if (!cp || !*cp || strstr("tty|dumb",cp)) quiet=1; } /* incompatible options? */ if (test && spool) { errno=0; message(prg,'F',"you cannot specify :NULL: and -S option together"); } if (extended) { if (strchr(host,'@')) { errno=0; message(prg,'F',"you must specify only a host name with the -X option"); } if (del||text||spool||stdinf||source||mime||overwrite||tar||bounce||pgp|| *comment) { if (quiet<2) message(prg,'W',"you cannot use any other option with " "the extended header option - ignored"); del=text=spool=stdinf=source=mime=overwrite=tar=bounce=pgp=0; *comment=0; } } if (bounce) { if (!(str_eq(bouncearg,"k=y") || str_eq(bouncearg,"k=n"))) { errno=0; message(prg,'F',"wrong bouncing argument"); } if (source||mime||text||tar||del|stdinf) if (quiet<2) message(prg,'W',"you cannot use any other option " "when bouncing a file - ignored"); text=source=mime=tar=del=stdinf=0; compress=""; } if (del) { if (source||mime||text||tar||overwrite||stdinf||pgp||*comment) if (quiet<2) message(prg,'W',"you cannot use any other option " "when deleting a file - ignored"); text=source=mime=tar=stdinf=0; compress=""; } if (guess) { if (source||mime||text||tar) if (quiet<2) message(prg,'W',"you cannot use source, text, mime or " "archive option when guessing the file " "type - ignored"); text=source=mime=tar=0; } if (stdinf) { if (tar) if (quiet<2) message(prg,'W',"you cannot send stdin as an archive file; " "-a option will be ignored"); tar=0; } if (tar&&zip) { errno=0; message(prg,'F',"you cannot use the -a and -A archive options together"); } if (tar||zip) { if (source) if (quiet<2) message(prg,'W',"option SOURCE is not allowed when " "sending in archive format - ignored"); if (mime) if (quiet<2) message(prg,'W',"option MIME is not allowed when " "sending in archive format - ignored"); if (text) if (quiet<2) message(prg,'W',"option TEXT is not allowed when " "sending in archive format - ignored"); text=source=mime=0; } /* correct archive option? */ if (*archive) { if (*archive == '=') { strcpy(tmp,archive+1); strcpy(archive,tmp); } else { errno=0; message(prg,'F',"you have not specified an archive " "name with -a=name-of-archive"); } } /* correct comment? */ if (*comment && argc-optind>2 && !tar) { errno=0; message(prg,'F',"you can only comment a single file"); } /* protect all tmp-files */ umask(~(S_IRUSR|S_IWUSR)); /* support programs defaults */ memset(tar_bin,0,sizeof(tar_bin)); memset(pgp_bin,0,sizeof(pgp_bin)); memset(gzip_bin,0,sizeof(gzip_bin)); memset(bzip2_bin,0,sizeof(bzip2_bin)); strcpy(tar_bin,TAR); strcpy(pgp_bin,PGP); strcpy(gzip_bin,GZIP); strcpy(bzip2_bin,BZIP2); /* look for environment variables */ if ((cp=getenv("SF_TAR"))) strncpy(tar_bin,cp,sizeof(tar_bin)-1); if ((cp=getenv("SF_PGP"))) strncpy(pgp_bin,cp,sizeof(pgp_bin)-1); if ((cp=getenv("SF_GZIP"))) strncpy(gzip_bin,cp,sizeof(gzip_bin)-1); if ((cp=getenv("SF_BZIP2"))) strncpy(bzip2_bin,cp,sizeof(bzip2_bin)-1); /* do the support programs really exist? */ if (access(tar_bin,X_OK)<0) strcpy(tar_bin,"tar"); if (access(pgp_bin,X_OK)<0) strcpy(pgp_bin,"pgp"); if (access(gzip_bin,X_OK)<0) strcpy(gzip_bin,"gzip"); if (access(bzip2_bin,X_OK)<0) strcpy(bzip2_bin,"bzip2"); /* determine which compress programm to use */ if (*force_compress) { compress=""; if (strstr(force_compress,"gzip")) compress=S_GZIP; if (strstr(force_compress,"bzip2")) compress=S_BZIP2; if (!*compress) { snprintf(MAXS(tmp),"unsupported compression program %s",force_compress); errno=0; message(prg,'F',tmp); } strcpy(zprg,force_compress); } else if (*compress) { #if 0 snprintf(MAXS(tmp),"%s --help 2>&1",bzip2_bin); if ((pp=popen(tmp,"r"))) { while (fgetl(line,pp)) { if (strstr(line,"usage:")) { strcpy(zprg,bzip2_bin); break; } } pclose(pp); } /* is bzip2 available? */ if (!spool && whereis(bzip2_bin)) { strcpy(zprg,bzip2_bin); compress=S_BZIP2; } if (!*zprg) *bzip2_bin=0; snprintf(MAXS(tmp),"%s --help 2>&1",gzip_bin); if ((pp=popen(tmp,"r"))) { while (fgetl(line,pp)) if (strstr(line,"usage:")) break; pclose(pp); } if (strstr(line,"usage:")) { if (!*zprg) strcpy(zprg,gzip_bin); } else *gzip_bin=0; #endif /* is gzip available? */ if (whereis(gzip_bin) && !*zprg) { strcpy(zprg,gzip_bin); compress=S_GZIP; } if (!*zprg) { compress=""; if (quiet<2) message(prg,'W',"no compression program found - sending uncompressed"); } } /* get the local host name */ if (gethostname(localhost,FLEN-1)<0) strcpy(localhost,"localhost"); /* extended header feature = read everything from stdin? */ if (extended) { forward(host,mtp); exit(0); } /* get own user name, recipient name and host and alias options */ destination(argc,argv,user,recipient,host,aopt); /* printf("recipient: %s\nhost: %s\noptions: %s\n",recipient,host,aopt); */ /* name the local host */ if (str_eq(host,"127.0.0.1") || str_eq(host,"0")) strcpy(host,localhost); if (*aopt) { snprintf(MAXS(cmd),"%s %s ",argv[0],aopt); for(i=1;ipw_name); tmpdir=mktmpdir(verbose); /* check pgp options */ if (pgp) { pop=pgpopt; /* conventional IDEA encryption? */ if (str_eq(pop,"\nc")) { pgpcrypt='c'; compress=""; } else { /* check other pgp options */ while (*pop) { pop++; /* pgp encryption? */ if (*pop=='e') { pgpcrypt='e'; compress=""; pop++; snprintf(MAXS(pgprid),"%s@%s",recipient,host); /* is there a recipient id? */ if (*pop>'\n') { if (*pop=='=') strcpy(pgprid,++pop); /* cut off any more options */ if ((cp=strchr(pgprid,'\n'))) { *cp=0; pop=strchr(pop,'\n'); } else *pop=0; } /* if (!*pgprid) { errno=0; message(prg,'F',"you have to specify a pgp recipient-ID " "when encrypting"); } */ continue; } /* pgp signature? */ if (*pop=='s') { strcpy(pgpsign," "); pop++; /* is there a signature id? */ if (*pop>'\n') { if (*pop=='=') pop++; snprintf(MAXS(pgpsign),"-u '%s",pop); /* cut off any more options */ if ((cp=strchr(pgpsign,'\n'))) { *cp=0; pop=strchr(pop,'\n'); } else *pop=0; strcat(pgpsign,"'"); } continue; } /* wrong pgp options */ errno=0; snprintf(MAXS(tmp),"wrong pgp option, see 'man %s'",prg); message(prg,'F',tmp); } } } /* set various file names */ snprintf(MAXS(userspool),SPOOL"/%s",pw_name); snprintf(MAXS(outlogtmp),"%s/.sendfile_%d.log",userspool,pid); snprintf(MAXS(tartmp),"%s/sendfile.tar",tmpdir); snprintf(MAXS(ziptmp),"%s/sendfile.zip",tmpdir); snprintf(MAXS(pgptmp),"%s/sendfile.pgp",tmpdir); snprintf(MAXS(texttmp),"%s/sendfile.txt",tmpdir); snprintf(MAXS(stdintmp),"%s/sendfile.tmp",tmpdir); /* where are the files/directories ? */ if (*where) { if (str_eq(where,"config") || str_eq(where,"sendfile.cf")) { if (quiet) printf(CONFIG"\n"); else message(prg,'I',"the global configuration file is: "CONFIG); } else if (str_eq(where,"spool")) { if (quiet) printf(SPOOL"\n"); else message(prg,'I',"the spool directory is: "SPOOL); } else if (str_eq(where,"userspool")) { if (quiet) printf("%s\n",userspool); else { snprintf(MAXS(tmp),"the user spool directory is: %s",userspool); message(prg,'I',tmp); } } else { snprintf(MAXS(tmp),"%s is an unknown -W argument",where); errno=0; message(prg,'E',tmp); if (quiet<2) message(prg,'I',"you may specify -W=config, -W=spool, or " "-W=userspool"); } if (argc-optind<1) exit(0); } /* check tmp files */ unlink(tartmp); unlink(ziptmp); unlink(texttmp); unlink(pgptmp); unlink(stdintmp); if (stat(tartmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",tartmp); message(prg,'F',tmp); } if (stat(ziptmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",ziptmp); message(prg,'F',tmp); } if (stat(texttmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",texttmp); message(prg,'F',tmp); } if (stat(pgptmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",pgptmp); message(prg,'F',tmp); } if (stat(stdintmp,&finfo)==0) { snprintf(MAXS(tmp), "tmp-file %s does already exist and cannot be deleted",stdintmp); message(prg,'F',tmp); } /* parse the global config-file */ if ((inf=rfopen(CONFIG,"r"))) { while (fgetl(line,inf)) { /* prepare line to be parsed */ if ((cp=strchr(line,'#'))) *cp=0; if ((cp=strchr(line,'='))) *cp=' '; str_tolower(str_trim(line)); /* is there an option and an argument? */ if ((argp=strchr(line,' '))) { *argp=0; argp++; if (str_eq(line,"packet") && packet_size==0) { packet_size=atoi(argp); continue; } if (str_eq(line,"lanspeed")) { lanspeed=atoi(argp); if (lanspeed<0) lanspeed=0; continue; } if (str_eq(line,"log")) { if (str_eq(argp,"out") || str_eq(argp,"both")) outlogging=1; continue; } if (str_eq(line,"spooling")) { if (str_eq(argp,"nostart")) spooling=1; if (str_eq(argp,"on")) spooling=2; continue; } if (str_eq(line,"dontcompress")) { if (*argp) { /* save the whole string in element #0 */ if (!(dontcompress[0]=strdup(argp))) message(prg,'F',"out of memory"); /* parse and split the list (tricky, eh? :-) ) */ for (n=1,cp=strtok(dontcompress[0],", \t"); cp && n<99; n++,cp=strtok(NULL,", \t")) { /*printf("sfconf: >%s<\n",cp); */ dontcompress[n]=cp; } dontcompress[n]=""; /* last element must terminate the list! */ } continue; } } } fclose(inf); } /* spooling allowed? */ if ((spool || list) && !spooling) { errno=0; message(prg,'F',"outgoing spooling of files is not allowed on this system"); } /* list files in outgoing spool */ if (list) exit(list_spool()); /* set tcp packet length */ if (packet_size<1) packet_size=PACKET; if (verbose && !spool && !del) { snprintf(MAXS(tmp),"packet size = %d bytes",packet_size); message(prg,'I',tmp); } /* enable simple interrupt handler */ signal(SIGTERM,cleanexit); signal(SIGABRT,cleanexit); signal(SIGQUIT,cleanexit); signal(SIGHUP,cleanexit); signal(SIGINT,cleanexit); /* file as stdin data stream? */ if (stdinf) { /* write stdin to tmp-file */ if (!(outf=rfopen(stdintmp,"w"))) { snprintf(MAXS(tmp),"cannot open tmp-file %s",stdintmp); message(prg,'F',tmp); } /* while ((ch=getchar())!=EOF) putc(ch,outf); */ while ((bytes=read(fileno(stdin),iobuf,IOB))) { if (bytes<0) message(prg,'F',"error while reading from stdin"); if (write(fileno(outf),iobuf,bytes)!=bytes) { snprintf(MAXS(tmp),"error while writing stdin to %s",stdintmp); message(prg,'F',tmp); } } fclose(outf); } /* determine the file type */ type="BINARY"; if (text) type="TEXT="CHARSET; if (mime) type="MIME"; if (source) type="SOURCE"; /* no testing mode */ if (!test) { /* prepare sending or spooling */ if (!spool) { /* look for correct SAFT server and open connection */ sockfd=saft_connect("file",recipient,user,host,redirect); /* compression mode wanted? */ if (*compress) do_compress=1; if (do_compress && !*force_compress) do_compress=linkspeed(host,lanspeed,&compress); /* test if server can handle bzip2 */ if (do_compress && *zprg && strstr(zprg,"bzip2")) { sendcommand(sockfd,"TYPE BINARY COMPRESSED=BZIP2",reply); if (!str_beq(reply,"200 ") && *gzip_bin && !*force_compress) { compress=S_GZIP; strcpy(zprg,gzip_bin); } else compress=S_BZIP2; } } else /* outgoing spooling */ { /* does the outgoing spool exist? */ strcpy(outgoing,SPOOL"/OUTGOING"); if (stat(outgoing,&finfo)<0 || !S_ISDIR(finfo.st_mode)) { snprintf(MAXS(tmp),"spool directory %s does not exist",outgoing); message(prg,'F',tmp); } /* and does it have the correct protection? */ if (!((finfo.st_mode&S_ISVTX) && (finfo.st_mode&S_IRWXO))) { snprintf(MAXS(tmp), "spool directory %s has wrong protection (must have 1777)", outgoing); message(prg,'F',tmp); } /* name the local host */ if (str_eq(host,"127.0.0.1") || str_eq(host,"0")) strcpy(host,localhost); } } /* bouncing files? */ if (bounce) { /* does the spool directory exist? */ if (chdir(userspool)<0) { snprintf(MAXS(tmp),"cannot access spool directory %s",userspool); message(prg,'F',tmp); } /* main loop over the spool file names */ for (fn=optind; fn%s",BZIP2,sdfn,GZIP,ziptmp); else snprintf(MAXS(cmd),"%s -d < %s > %s",BZIP2,sdfn,ziptmp); } else snprintf(MAXS(cmd),"%s -dc %s > %s",GZIP,sdfn,ziptmp); /* execute shell-command and close spool header file on error */ if (vsystem(cmd)) { snprintf(MAXS(tmp),"cannot recompress spool file #%s",argv[fn]); message(prg,'E',tmp); fclose(inf); break; } } continue; /* read next line from spool header file */ } /* store size for later processing */ if (str_beq(line,"SIZE ")) { sscanf(line,"SIZE %lld %lld",&size,&orgsize); strcpy(sizes,line+5); } /* is there already a comment line? */ if (str_beq(line,"COMMENT")) { if (*redirect) snprintf(MAXS(line),"%s+AA0ACg-%s",comment,redirect); else { snprintf(MAXS(tmp), "%s+AA0ACg-forward+ACA-from+ACA-%s",line,comment); strcpy(line,tmp); } if (spool) fprintf(oshf,"%s\n",line); else sendcommand(sockfd,line,NULL); *comment=0; continue; } /* all other header lines */ if (spool) fprintf(oshf,"%s\n",line); else sendheader(sockfd,line); } /* if file has been already closed there is an error (see above) */ if (fclose(shf)) { if (spool) fclose(oshf); continue; } /* send comment if not already done */ if (*comment) { iso2utf(tmp,"forward from "); snprintf(MAXS(line),"COMMENT %s%s",tmp,comment); if (*redirect) { snprintf(MAXS(tmp),"\r\n%s",redirect); iso2utf(comment,tmp); strcat(line,comment); } if (spool) fprintf(oshf,"%s\n",line); else sendcommand(sockfd,line,NULL); } /* check the file size */ if (stat(ziptmp,&finfo)==0) { size=finfo.st_size; snprintf(MAXS(sizes),"%lld %lld",size,orgsize); snprintf(MAXS(line),"SIZE %s",sizes); sendcommand(sockfd,line,NULL); } else { if (stat(sdfn,&finfo)<0 || size!=finfo.st_size) { snprintf(MAXS(tmp), "spool file #%s has wrong size count - ignored",argv[fn]); errno=0; message(prg,'E',tmp); if (spool) fclose(oshf); continue; } } /* copy spool file to outgoing */ if (spool) { fclose(oshf); strcpy(osdfn,oshfn); osdfn[strlen(osdfn)-1]='d'; if (fcopy(sdfn,osdfn,S_IRUSR|S_IWUSR)<0) { unlink(oshfn); unlink(osdfn); } else { if (str_eq(bouncearg,"k=n")) { unlink(shfn); unlink(sdfn); } strcpy(tmp,oshfn); oshfn[strlen(oshfn)-1]='h'; rename(tmp,oshfn); spooled_info(iso_name,osdfn,do_compress); } } else /* forward the spool data file */ { if (stat(ziptmp,&finfo)==0) { status=send_data(sockfd,size,ziptmp,tinfo,file,"",mtp,&attime); unlink(ziptmp); } else status=send_data(sockfd,size,sdfn,tinfo,file,"",mtp,&attime); /* summarize transfer statistics */ if (attime) { tfn++; tsize+=size; tttime+=attime; } if (status==0) { /* log data */ outlog(recipient,host,file,sizes); notespeed(host,size,attime); /* if not keep file delete the spool files */ if (str_eq(bouncearg,"k=n")) { unlink(shfn); unlink(sdfn); } } } } } else if (tar||zip) { /* sending tar or zip archive */ /* translate the archive name to UTF-7 */ iso2utf7(utf_name,archive,0); /* build spawn descriptor */ sad=(char**)(malloc(sizeof(char*)*(argc-optind+4))); if (!sad) message(prg,'F',"out of memory"); sad[0]=tar_bin; sad[1]="cf"; sad[2]=tartmp; for (n=3; n-2 %s",zprg,tartmp,ziptmp); if (verbose) { snprintf(MAXS(tmp),"shell-call: %s",cmd); message(prg,'I',tmp); } if (vsystem(cmd)) message(prg,'F',"cannot compress archive file"); strcpy(file,ziptmp); } /* pgp encryption? */ if (pgpcrypt) pgp_encrypt(pgpcrypt,pgprid,file); /* pgp signature to add? */ if (*pgpsign) pgp_sign(pgpsign,file,sockfd); /* get the file size */ if (stat(file,&finfo)<0) message(prg,'F',"cannot access tmp file"); size=finfo.st_size; snprintf(MAXS(sizes),"%lld %lld",size,orgsize); /* write to outgoing spool? */ if (spool) { /* overwrite archive file? */ if (overwrite && (hls=scanoutspool(pw_name))) { /* create correct to-string */ if (strchr(argv[argc-1],'*')) snprintf(MAXS(to),"%s",argv[argc-1]); else snprintf(MAXS(to),"%s@%s",recipient,host); /* search for file in outgoing spool */ for (hlp=hls; hlp; hlp=hlp->next) { for (oflp=hlp->flist; oflp; oflp=oflp->next) { /* matching file name? */ if (simplematch(oflp->fname,utf_name,0)) { /* matching recipient? */ snprintf(MAXS(rto),"%s@%s",oflp->to,hlp->host); if (simplematch(rto,to,0)) { unlink(oflp->oshfn); oflp->oshfn[strlen(oflp->oshfn)-1]='d'; unlink(oflp->oshfn); } } } } } /* open outgoing spool header file */ if ((oshf=outspool(pw_name,outgoing,oshfn))==NULL) message(prg,'F',"cannot create outgoing spool file"); /* TAB as whitespace is needed here, because scanspool insists on it */ fprintf(oshf,"FROM\t%s\n",user); fprintf(oshf,"TO\t%s@%s\n",recipient,host); fprintf(oshf,"FILE\t%s\n",utf_name); if (*compress) { if (str_eq(compress,S_GZIP)) fprintf(oshf,"TYPE\tBINARY COMPRESSED\n"); else fprintf(oshf,"TYPE\tBINARY COMPRESSED=%s\n",compress); } else if (pgpcrypt) { fprintf(oshf,"TYPE\tBINARY CRYPTED\n"); } else fprintf(oshf,"TYPE\tBINARY\n"); fprintf(oshf,"SIZE\t%s\n",sizes); fprintf(oshf,"ATTR\tTAR\n"); } else { /* send header lines */ snprintf(MAXS(tmp),"FILE %s",utf_name); /* deactivate exit on 4xx error to test for timeout */ client=0; sendcommand(sockfd,tmp,reply); client=1; /* saft server still online? (check timeout) */ if (str_beq(reply,"429 ")) { sockfd=saft_connect("file",recipient,user,host,redirect); snprintf(MAXS(tmp),"FILE %s",utf_name); sendcommand(sockfd,tmp,reply); } if (!test && !str_beq(reply,"200 ") && quiet<2) message(prg,'W',"remote site does not support file names"); if (overwrite) { if (str_beq(reply,"200 ")) sendcommand(sockfd,"DEL",reply); snprintf(MAXS(tmp),"FILE %s",utf_name); sendcommand(sockfd,tmp,reply); } if (*compress) { if (str_eq(compress,S_GZIP)) snprintf(MAXS(tmp),"TYPE BINARY COMPRESSED"); else snprintf(MAXS(tmp),"TYPE BINARY COMPRESSED=%s",compress); sendcommand(sockfd,tmp,reply); if (!test && !str_beq(reply,"200 ") && quiet<2) { errno=0; message(prg,'F',"remote site does not support compressed files"); } } else if (pgpcrypt) { sendcommand(sockfd,"TYPE BINARY CRYPTED",reply); if (!test && !str_beq(reply,"200 ") && quiet<2) { errno=0; message(prg,'F',"remote site does not support encrypted files"); } } else { sendcommand(sockfd,"TYPE BINARY",reply); if (!test && !str_beq(reply,"200 ") && quiet<2) message(prg,'W',"remote site does not support binary files"); } snprintf(MAXS(tmp),"SIZE %s",sizes); sendheader(sockfd,tmp); sendcommand(sockfd,"ATTR TAR",reply); if (!test && !str_beq(reply,"200 ") && quiet<2) { errno=0; message(prg,'F',"remote site does not support archive file type"); } } /* comment to send? */ if (*comment || *redirect) { *line=0; if (*comment) strcat(line,comment); if (*redirect) { if (*line) { snprintf(MAXS(tmp),"%s\r\n%s",line,redirect); strcpy(line,tmp); } else strcpy(line,redirect); } iso2utf(tmp,line); if (spool) fprintf(oshf,"COMMENT\t%s\n",tmp); else { snprintf(MAXS(line),"COMMENT %s",tmp); sendcommand(sockfd,line,NULL); } } /* send the file data */ if (spool) { fclose(oshf); strcpy(osdfn,oshfn); osdfn[strlen(osdfn)-1]='d'; if (fcopy(file,osdfn,S_IRUSR|S_IWUSR)<0) { unlink(oshfn); unlink(osdfn); } else { strcpy(tmp,oshfn); oshfn[strlen(oshfn)-1]='h'; rename(tmp,oshfn); spooled_info(archive,osdfn,do_compress); } } else { strcpy(tmp,"archive"); if (*compress) strcat(tmp," compressed"); if (pgpcrypt) strcat(tmp," crypted"); if (send_data(sockfd,size,file,"",archive,tmp,mtp,&attime)==0) { /* summarize transfer statistics */ if (attime) { tfn++; tsize+=size; tttime+=attime; } /* do some logging */ outlog(recipient,host,utf_name,sizes); notespeed(host,size,attime); } } } else /* sending or deleting single files */ { /* main loop over the file names */ for (fn=optind; fnnext) { for (oflp=hlp->flist; oflp; oflp=oflp->next) { /* matching file name? */ if (simplematch(oflp->fname,utf_name,0)) { /* matching recipient? */ snprintf(MAXS(rto),"%s@%s",oflp->to,hlp->host); if (simplematch(rto,to,0)) { unlink(oflp->oshfn); oflp->oshfn[strlen(oflp->oshfn)-1]='d'; unlink(oflp->oshfn); if (del) { del=2; utf2iso(0,NULL,file,NULL,oflp->fname); snprintf(MAXS(tmp), "deleted from outgoing spool: '%s' for %s ", file,rto); if (quiet<2) message(prg,'I',tmp); } } } } } } if (del) continue; /* open outgoing spool header file */ if ((oshf=outspool(pw_name,outgoing,oshfn))==NULL) message(prg,'F',"cannot create outgoing spool file"); fprintf(oshf,"FROM\t%s\n",user); fprintf(oshf,"TO\t%s@%s\n",recipient,host); fprintf(oshf,"FILE\t%s\n",utf_name); /*if (del || overwrite) fprintf(oshf,"DEL\n");*/ } else /* send header lines */ { /* send file name */ snprintf(MAXS(tmp),"FILE %s",utf_name); sendcommand(sockfd,tmp,reply); if (!test && !str_beq(reply,"200 ") && quiet<2) message(prg,'W',"remote site does not support file names"); /* delete file? */ if (overwrite) sendcommand(sockfd,"DEL",NULL); if (del) { if (sendheader(sockfd,"DEL")) { if (quiet<2) message(prg,'W',"remote site cannot delete files"); } else { snprintf(MAXS(tmp),"'%s' deleted",iso_name); if (quiet<2) message(prg,'I',tmp); } continue; } } /* is the file readable? */ if (stat(file,&finfo)<0) { snprintf(MAXS(tmp),"cannot access '%s'",file); message(prg,'E',tmp); if (spool) { fclose(oshf); unlink(oshfn); } continue; } /* is it a regular file? */ if (!S_ISREG(finfo.st_mode)) { errno=0; snprintf(MAXS(tmp),"%s is not a regular file, skipping",file); message(prg,'E',tmp); if (spool) { fclose(oshf); unlink(oshfn); } continue; } /* is it a executable? */ if (finfo.st_mode&S_IXUSR) exe=1; else exe=0; /* no file mode set? guess the file type */ mode=guess_ftype(file,ftype); if (!guess) mode=0; /* get the original file size */ strftime(date,20,"%Y-%m-%d %H:%M:%S",gmtime(&finfo.st_mtime)); #ifdef HPUX /* dirty hack around HPUX strftime bug */ date[17]=0; strcat(date,"00"); #endif /* text or source mode? */ if (text || source || mode=='t' || mode=='s') { /* open and test file to send and open tmp-file */ inf=rfopen(file,"r"); outf=rfopen(texttmp,"w"); if (!inf) { snprintf(MAXS(tmp),"cannot open '%s'",file); message(prg,'E',tmp); if (spool) { fclose(oshf); unlink(oshfn); } continue; } if (!outf) message(prg,'F',"cannot open tmp-file"); /* convert file to NVT format */ do { ch=fgetc(inf); if (ch!=EOF) { if (ch=='\n') fprintf(outf,"\r\n"); else fputc(ch,outf); } } while (!feof(inf)); fclose(inf); fclose(outf); strcpy(file,texttmp); } /* get the original file size */ stat(file,&finfo); orgsize=finfo.st_size; /* compression mode wanted? */ if (*compress) do_compress=1; /* check if file is compressible */ if (do_compress && !*force_compress) { /* do not compress too small files */ if (finfo.st_size < 1024) do_compress=0; /* determine file type */ /* loop over all non-compressible file type strings */ for (n=0;do_compress && *cft[n];n++) { /* is this file a not compressible one? */ snprintf(MAXS(tmp),"*%s*",cft[n]); if (simplematch(ftype,tmp,1)) do_compress=0; } } /* compressed mode? */ if (do_compress) { /* compress tmp-file */ if (!quiet) printf("compressing... \r"); fflush(stdout); snprintf(MAXS(cmd),"%s < '%s' > %s",zprg,file,ziptmp); if (verbose) { snprintf(MAXS(tmp),"shell-call: %s",strchr(cmd,';')+1); message(prg,'I',tmp); } if (vsystem(cmd)) { snprintf(MAXS(tmp),"cannot compress %s",file); message(prg,'E',tmp); if (spool) { fclose(oshf); unlink(oshfn); } continue; } strcpy(file,ziptmp); } else size=orgsize; /* pgp encryption? */ if (pgpcrypt) pgp_encrypt(pgpcrypt,pgprid,file); /* pgp signature to add? */ if (*pgpsign) pgp_sign(pgpsign,file,sockfd); /* get the file size */ if (stat(file,&finfo)<0) message(prg,'F',"cannot access tmp file"); size=finfo.st_size; snprintf(MAXS(sizes),"%lld %lld",size,orgsize); /* printf("DEBUG: size=%lld orgsize=%lld sizes=%s\n",size,orgsize,sizes); exit(0); */ /* determine the file type */ type="BINARY"; if (guess) { if (mode=='s') type="SOURCE"; if (mode=='t') type="TEXT="CHARSET; } else if (mime) type="MIME"; else if (source) type="SOURCE"; else if (text) type="TEXT="CHARSET; /* write to outgoing spool? */ if (spool) { if (do_compress) { if (str_eq(compress,S_GZIP)) fprintf(oshf,"TYPE\tBINARY COMPRESSED\n"); else fprintf(oshf,"TYPE\tBINARY COMPRESSED=%s\n",compress); } else if (pgpcrypt) fprintf(oshf,"TYPE\t%s CRYPTED\n",type); else fprintf(oshf,"TYPE\t%s\n",type); fprintf(oshf,"SIZE\t%s\n",sizes); fprintf(oshf,"DATE\t%s\n",date); if (exe) fprintf(oshf,"ATTR\tEXE\n"); else fprintf(oshf,"ATTR\tNONE\n"); } else /* send the header information */ { if (do_compress) { if (str_eq(compress,S_GZIP)) snprintf(MAXS(line),"TYPE %s COMPRESSED",type); else snprintf(MAXS(line),"TYPE %s COMPRESSED=%s",type,compress); } else if (pgpcrypt) snprintf(MAXS(line),"TYPE %s CRYPTED",type); else snprintf(MAXS(line),"TYPE %s",type); sendcommand(sockfd,line,reply); if (!test && !str_beq(reply,"200 ") && quiet<2) { errno=0; snprintf(MAXS(tmp),"remote site does not support file of %s",line); message(prg,'F',tmp); } snprintf(MAXS(tmp),"SIZE %s",sizes); sendheader(sockfd,tmp); snprintf(MAXS(tmp),"DATE %s",date); if (sendheader(sockfd,tmp) && quiet<2) message(prg,'W',"remote site does not support dates"); if (exe) sendcommand(sockfd,"ATTR EXE",NULL); else sendcommand(sockfd,"ATTR NONE",NULL); } /* comment to send? */ if (*comment || *redirect) { *line=0; if (*comment) strcat(line,comment); if (*redirect) { if (*line) { snprintf(MAXS(tmp),"%s\r\n%s",line,redirect); strcpy(line,tmp); } else strcpy(line,redirect); } iso2utf(tmp,line); if (spool) fprintf(oshf,"COMMENT\t%s\n",tmp); else { snprintf(MAXS(line),"COMMENT %s",tmp); sendcommand(sockfd,line,NULL); } } /* send the file data */ if (spool) { fclose(oshf); strcpy(osdfn,oshfn); osdfn[strlen(osdfn)-1]='d'; if (fcopy(file,osdfn,S_IRUSR|S_IWUSR)<0) { unlink(oshfn); unlink(osdfn); } else { strcpy(tmp,oshfn); oshfn[strlen(oshfn)-1]='h'; rename(tmp,oshfn); spooled_info(iso_name,osdfn,do_compress); } } else { strcpy(tmp,type); if ((cp=strchr(tmp,'='))) *cp=0; str_tolower(tmp); if (do_compress) strcat(tmp," compressed"); if (pgpcrypt) strcat(tmp," crypted"); if (send_data(sockfd,size,file,tinfo,iso_name,tmp,mtp,&attime)==0) { /* summarize transfer statistics */ if (attime) { tfn++; tsize+=size; tttime+=attime; } /* do some logging */ outlog(recipient,host,utf_name,sizes); notespeed(host,size,attime); } } } } /* start spool daemon or close the connection */ if (spool) { if (del) { if (del<2 && quiet<2) message(prg,'W',"no matching files found in outgoing spool"); } else { if (spooling==2) start_spooldaemon(localhost); } } else { sendcommand(sockfd,"QUIT",NULL); close(sockfd); } /* print total transfer statistics */ if (tsize && info && tfn>1 && quiet<2) { thruput=tsize*1000/tttime; if (tsize/1024>9999) snprintf(MAXS(tmp),"%d files sent with %.1f MB",tfn,tsize/1024/1024); else if (tsize>9999) snprintf(MAXS(tmp),"%d files sent with %.1f kB",tfn,tsize/1024); else snprintf(MAXS(tmp),"%d files sent with %d byte",tfn,(int)tsize); if (thruput>9999) snprintf(MAXS(line),"%s at %.1f kB/s",tmp,thruput/1024); else snprintf(MAXS(line),"%s at %d byte/s",tmp,(int)thruput); message("",'I',line); } /* delete tmp-files */ cleanup(); exit(0); } /* * cleanexit - clean termination routine * * A very simple interrupt handler */ void cleanexit() { printf("\r\n"); cleanup(); exit(0); } /* * cleanup - delete tmp files and send LOG command to local server */ void cleanup() { int sockfd; /* socket file descriptor */ char line[MAXLEN], /* one line of text */ reply[MAXLEN], /* reply string from server */ server[FLEN]; /* saft server */ /* ignore all relevant signals */ signal(SIGTERM,SIG_IGN); signal(SIGABRT,SIG_IGN); signal(SIGQUIT,SIG_IGN); signal(SIGHUP,SIG_IGN); signal(SIGINT,SIG_IGN); if (verbose<2) verbose=0; *reply=0; #ifndef DEBUG rmtmpdir(tmpdir); if (outlogging) { /* inform local saft server about outgoing log file */ if (access(outlogtmp,R_OK)==0 && !test && #ifndef ENABLE_MULTIPROTOCOL (sockfd=open_connection("127.0.0.1",SAFT))>=0) { #else (sockfd=open_connection("127.0.0.1",SERVICE))>=0) { #endif /* check local saft server */ sock_getline(sockfd,reply); if (str_beq(reply,"220 ") && strstr(reply,"SAFT")) { /* send LOG command */ snprintf(MAXS(line),"LOG %s %s",pw_name,outlogtmp); sock_putline(sockfd,line); sock_getline(sockfd,reply); str_trim(reply); /* emergency exit */ if (*reply=='4') { unlink(outlogtmp); exit(0); } /* forward address to real saft server? */ if (str_beq(reply,"510 ")) { strcpy(server,strrchr(reply,' ')+1); /* close current connection */ sendcommand(sockfd,"QUIT",NULL); shutdown(sockfd,2); /* connect real saft server */ #ifndef ENABLE_MULTIPROTOCOL if (!test && (sockfd=open_connection(server,SAFT))>=0) { #else if (!test && (sockfd=open_connection(server,SERVICE))>=0) { #endif sock_getline(sockfd,reply); if (str_beq(reply,"220 ") && strstr(reply,"SAFT")) { /* send LOG command */ snprintf(MAXS(line),"LOG %s %s",pw_name,outlogtmp); sock_putline(sockfd,line); sock_getline(sockfd,reply); str_trim(reply); /* emergency exit */ if (*reply=='4') { unlink(outlogtmp); exit(0); } } } } } /* close the connection */ sendcommand(sockfd,"QUIT",NULL); shutdown(sockfd,2); } } unlink(outlogtmp); #endif } /* * pgp_encrypt - encrypt a file with pgp * * INPUT: pgpcrypt - public key or IDEA encryption * pgprid - pgp recipient id * file - input file name * * OUTPUT: file - output file name */ void pgp_encrypt(int pgpcrypt, char *pgprid, char *file) { char *cp, /* simple character pointer */ cmd[OVERSIZE], /* the command for system() */ line[MAXLEN]; /* one text line */ struct stat finfo; /* information about a file */ FILE *inf; /* input file */ inf=NULL; if (!quiet) message(prg,'I',"call to pgp..."); /* look for matching pgp-IDs */ if (strlen(pgprid)>1) { snprintf(MAXS(cmd),"%s -kvf %s > %s 2>/dev/null",pgp_bin,pgprid,pgptmp); vsystem(cmd); if (stat(pgptmp,&finfo)<0 || finfo.st_size==0 || !(inf=rfopen(pgptmp,"r"))) { errno=0; message(prg,'F',"call to pgp failed"); } while (fgetl(line,inf) && !strstr(line,"matching key")); fclose(inf); if ((cp=strchr(line,'.'))) *cp=0; if (!str_eq(line,"1 matching key found")) { if (!quiet) { snprintf(MAXS(line),"ambigous pgp-ID '%s'",pgprid); message(prg,'W',line); inf=rfopen(pgptmp,"r"); while (fgetl(line,inf)) printf("%s",line); fclose(inf); } *pgprid=0; } } else *pgprid=0; /* pgp needs user input? */ if (pgpcrypt=='c' || !*pgprid) { snprintf(MAXS(cmd),"%s +armor=off -f%c < %s > %s", pgp_bin,pgpcrypt,shell_quote(file),pgptmp); if (vsystem(cmd) || stat(pgptmp,&finfo)<0 || finfo.st_size==0) { errno=0; message(prg,'F',"call to pgp failed"); } printf("\n"); /* pgp needs no user input */ } else { snprintf(MAXS(cmd),"%s +armor=off -fe %s < %s > %s 2>/dev/null", pgp_bin,pgprid,shell_quote(file),pgptmp); if (vsystem(cmd) || stat(pgptmp,&finfo)<0 || finfo.st_size==0) { errno=0; message(prg,'F',"call to pgp failed (wrong pgp user id?)"); } } strcpy(file,pgptmp); } /* * pgp_sign - create detached pgp signature file and send SIGN header line * * INPUT: pgpsign - pgp user id * infile - input file name * sockfd - socket descriptor */ void pgp_sign(const char *pgpsign, const char *infile, int sockfd) { int check; /* check if sig is ok */ char *cp, /* simple string pointer */ tmp[MAXLEN], /* temporary string */ sign[MAXLEN], /* signature */ line[MAXLEN], /* one line of text */ cmd[2*MAXLEN]; /* the command for popen() */ FILE *pipe; /* input file descriptor */ check=0; *sign=0; if (!quiet && !pgppass) message(prg,'I',"call to pgp..."); snprintf(MAXS(cmd),"%s %s -fsba %s < %s", pgp_bin,pgpvm,pgpsign,shell_quote(infile)); if (verbose) { snprintf(MAXS(tmp),"shell-call: %s",cmd); message(prg,'I',tmp); } if (!(pipe=popen(cmd,"r"))) message(prg,'F',"call to pgp (signature) failed"); /* read signature file in NVT format */ while (fgetl(line,pipe)) { if ((cp=strchr(line,'\n'))) *cp=0; if (str_eq(line,"-----BEGIN PGP MESSAGE-----")) check+=1; if (str_eq(line,"-----END PGP MESSAGE-----")) check+=2; strcat(sign,line); strcat(sign,"\r\n"); } pclose(pipe); if (!pgppass) printf("\n"); if (check!=3) message(prg,'F',"call to pgp (signature) failed"); iso2utf(tmp,sign); snprintf(MAXS(sign),"SIGN %s",tmp); if (sockfd) sendcommand(sockfd,sign,NULL); } /* * outspool - create and open outgoing spool header file * * INPUT: user - own user name * outgoing - outgoing spool directory * * OUTPUT: oshf - outgoing spool header file name * * RETURN: FILE pointer if ok, NULL if failed * * This function does not use a locking or a atomar test&create function * because this would not work with NFS. To avoid race conditions (remember: * a spool daemon is normally running, too!) a tmp-header file is created. */ FILE *outspool(const char *user, const char *outgoing, char *oshf) { struct stat finfo; /* information about a file */ struct timeval tv; #if !defined(SOLARIS2) && !defined(IRIX) struct timezone tz; #endif /* get time structure */ #if defined(SOLARIS2) || defined(IRIX) # ifdef _SVID_GETTOD gettimeofday(&tv); # else gettimeofday(&tv,NULL); # endif #else gettimeofday(&tv,&tz); #endif /* build (tmp) header file name */ snprintf(oshf,MAXLEN-1,"%s/%s_%d.t",outgoing,user,(int)tv.tv_usec); /* does the file already exist? */ if (stat(oshf,&finfo)==0) return(NULL); return(rfopen(oshf,"w")); } /* * reply - dummy function, only needed for linking */ void reply(int x) { } /* * start_spooldaemon - start local spool daemon for outgoing files * * INPUT: localhost - name of the local host */ void start_spooldaemon(char *localhost) { int sockfd; /* socket file descriptor */ char *host, /* name of local SAFT server */ reply[MAXLEN], /* reply string from remote server */ tmp[MAXLEN], /* temporary string */ line[MAXLEN]; /* one line of text */ /* open connection to the own server */ #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection(localhost,SAFT); #else sockfd=open_connection(localhost,SERVICE); #endif if (sockfd==-1) snprintf(MAXS(tmp),"cannot create a network socket " "- cannot start local spool daemon"); if (sockfd==-2) snprintf(MAXS(tmp),"cannot open connection to %s " "- cannot start local spool daemon",localhost); if (sockfd==-3) snprintf(MAXS(tmp),"%s is unknown (name server down?) " "- cannot start local spool daemon",localhost); if (sockfd==-4) snprintf(MAXS(tmp),"out of memory " "- cannot start local spool daemon"); if (sockfd<0) { errno=0; message(prg,'F',tmp); } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { errno=0; #ifndef ENABLE_MULTIPROTOCOL snprintf(MAXS(tmp),"No SAFT server on port %d at %s " "- cannot start local spool daemon",SAFT,localhost); #else snprintf(MAXS(tmp),"No SAFT server on port %s at %s " "- cannot start local spool daemon",SERVICE,localhost); #endif message(prg,'F',tmp); } sendcommand(sockfd,"START SPOOLDAEMON",reply); str_trim(reply); /* forward to local SAFT-server set? */ if (str_beq(reply,"510 ") && (host=strrchr(reply,' '))) { host++; /* close current connection */ sendcommand(sockfd,"QUIT",NULL); shutdown(sockfd,2); /* open connection to the own SAFT server */ #ifndef ENABLE_MULTIPROTOCOL sockfd=open_connection(host,SAFT); #else sockfd=open_connection(host,SERVICE); #endif if (sockfd==-1) snprintf(MAXS(tmp),"cannot create a network socket " "- cannot start local spool daemon"); if (sockfd==-2) snprintf(MAXS(tmp),"cannot open connection to %s " "- cannot start local spool daemon",host); if (sockfd==-3) snprintf(MAXS(tmp),"%s is unknown (name server down?) " "- cannot start local spool daemon",host); if (sockfd==-4) snprintf(MAXS(tmp),"out of memory " "- cannot start local spool daemon"); if (sockfd<0) { errno=0; message(prg,'F',tmp); } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { errno=0; #ifndef ENABLE_MULTIPROTOCOL snprintf(MAXS(tmp),"No SAFT server on port %d at %s " "- cannot start local spool daemon",SAFT,host); #else snprintf(MAXS(tmp),"No SAFT server on port %s at %s " "- cannot start local spool daemon",SERVICE,host); #endif message(prg,'F',tmp); } sendheader(sockfd,"START SPOOLDAEMON"); sendheader(sockfd,"QUIT"); } } /* * outlog - create temporary user outgoing log file * * INPUT: from - own user name * to - recipient user name * host - recipient host name * file - file name * sizes - original and compressed file size */ void outlog(char *to, char *host, char *file, char *sizes) { char currentdate[FLEN]; /* current date */ FILE *outf; /* output file */ time_t timetick; /* unix time (in seconds) */ if (outlogging && strcmp(host,localhost) && strcmp(host,"localhost") && (outf=rfopen(outlogtmp,"a"))) { /* get current date */ timetick=time(NULL); strftime(currentdate,20,"%Y-%m-%d %H:%M:%S",localtime(&timetick)); /* write to log file */ fprintf(outf,"FROM\t%s\nTO\t%s@%s\nDATE\t%s\nFILE\t%s\nSIZES\t%s\n\n", pw_name,to,host,currentdate,file,sizes); fclose(outf); } return; } /* * forward - forward a file with complete header from stdin * * INPUT: host - host to send to * mtp - maximum thruput */ void forward(char *host, float mtp) { int sockfd; /* socket file descriptor */ off_t size; /* size of the file */ float ttime; char *arg, /* SAFT command argument */ from[FLEN], /* sender user name */ recipient[FLEN], /* recipient at serverhost */ line[MAXLEN], /* one line of text */ tmp[MAXLEN]; /* temporary string */ size=0; *line=*recipient=*from=0; get_header("FROM",from); get_header("TO",recipient); /* look for correct SAFT server and open connection */ sockfd=saft_connect("file",recipient,from,host,tmp); /* loop over the other header lines */ while (fgetl(line,stdin)) { str_trim(line); if (str_neq_nocase("DATA",line,strlen(line))) break; if (str_neq_nocase("RESEND",line,strlen(line))) { errno=0; message(prg,'F',"the RESEND command is not supported with the -X option"); } /* look for SIZE command */ if ((arg=strchr(line,' '))) { if (str_neq_nocase("SIZE",line,4)) sscanf(arg+1,"%lld",&size); } /* send this SAFT command */ sendheader(sockfd,line); } if (!size) { errno=0; message(prg,'F',"SIZE command is missing"); } send_data(sockfd,size,"","","STDIN","",mtp,&ttime); } /* * get_header - read a header line from stdin * * INPUT: cmd - command type * * OUTPUT: arg - the command argument */ void get_header(const char *cmd, char *arg){ char *cp, /* a simple character pointer */ line[MAXLEN], /* one line of text */ tmp[MAXLEN]; /* temporary string */ /* read one header line */ fgetl(line,stdin); str_trim(line); /* split command and argument */ if (strlen(line)>3 && (cp=strchr(line,' '))) { *cp=0; strcpy(arg,cp+1); str_toupper(line); } if (!str_eq(cmd,line)) { errno=0; line[MAXLEN-80]=0; snprintf(MAXS(tmp), "illegal SAFT command \"%s\", \"%s\" was expected",line,cmd); message(prg,'F',tmp); } } /* * guess_ftype - guess file type * * INPUT: file - file name with path * * OUTPUT: type - file type as long string * * RETURN: b for binary, s for source, t for text * * Remark: you MUST call stat(file) and check the return value before * calling guess_ftype(), because of symlink loop detection. */ char guess_ftype(const char *file, char *type) { int i; char *cp, **cpp, tmp[MAXLEN], /* temporary string */ cmd[MAXLEN]; /* the command for popen() */ FILE *pipe; /* input file descriptor */ static const char *set[]= /* source extension type array */ { "Makefile","Makefile.", ".c",".f",".f77",".for",".f90",".p",".pas",".java",".h",".ada",".pl",".sl", ".cc",".tcl",".tk",".ps","" }; static char *tet[]= /* text extension type array */ { "README",".txt","" }; static char *sft[]= /* source file type array */ { "source","shell","program","command","script", "perl","pascal"," c ","c++","java","fortran","" }; static const char *tft[]= /* text file type array */ { "text","ASCII","english","" }; static const char *bft[]= /* binary file type array */ { "data","archive","zip","stripped","" }; static char *cet[]= /* compressed extension type array */ { ".zip",".z",".zoo",".gz",".bz",".bz2",".tgz",".rpm", ".mp3",".gif",".jpg",".tif",".tiff",".png",".avi",".mpeg","" }; /* first look for known file names and extensions */ /* source types */ for (i=0;*set[i];i++) { if (*set[i]=='.') { if ((cp=strrchr(file,'.'))) if str_eq(cp,set[i]) return('s'); } else { if str_eq(file,set[i]) return('s'); } } /* text types */ for (i=0;*tet[i];i++) { if (*tet[i]=='.') { if ((cp=strrchr(file,'.'))) if str_eq(cp,tet[i]) return('t'); } else { if str_eq(file,tet[i]) return('t'); } } /* compressed binary types */ if (*dontcompress[0]) cpp=dontcompress; /* list from sendfile.cf */ else cpp=cet; for (i=0;*cpp[i];i++) { /*printf(">%s<\n",cpp[i]);*/ if ((cp=strrchr(file,'.')) && str_eq(cp,cpp[i])) { strcpy(type,"already compressed"); return('b'); } } /* next, try with file command */ /* read output from file command */ snprintf(MAXS(cmd),"file %s",shell_quote(file)); if ((pipe=vpopen(cmd,"r")) && fgetl(tmp,pipe)) { pclose(pipe); /* get type string */ if (str_beq(tmp,file)) strcpy(type,tmp+strlen(file)); else strcpy(type,tmp); if ((cp=strchr(type,'\n'))) *cp=0; if (verbose) { snprintf(MAXS(tmp),"%s is of type %s",file,type); message(prg,'I',tmp); } /* look for characteristic substrings */ str_tolower(type); for (i=0;*bft[i];i++) if (strstr(type,bft[i])) return('b'); for (i=0;*sft[i];i++) if (strstr(type,sft[i])) return('s'); for (i=0;*tft[i];i++) if (strstr(type,tft[i])) return('t'); } /* default type is binary */ return('b'); } /* * linkspeed - check if link to host is fast enough * * INPUT: host - remote host to send to * lanspeed - min. speed for LAN in kB/s * compress - the compression method * * OUTPUT: compress - empty compression method if fast link found * * RETURN: 1 for slow, 0 for faster than lanspeed */ int linkspeed(const char *host, int lanspeed, char **compress) { int speed; /* found speed */ char msg[MAXLEN], /* message output string */ speeddir[MAXLEN], /* directory with speed info files */ hostfile[MAXLEN]; /* file with speed for remote host */ FILE *inf; /* input file */ struct stat finfo; /* information about a file */ speed=0; /* local host IS fast! :-) */ if (str_eq(host,localhost) || str_eq(host,"localhost")) { if (verbose) message(prg,'I',"disabling compressing for localhost"); *compress=""; return(0); } /* on too low lanspeed value we suppose a slow link */ if (lanspeed<1) return(1); /* create speeds dir if necessary */ snprintf(MAXS(speeddir),"%s/speeds",userspool); if (stat(speeddir,&finfo)<0 || !S_ISDIR(finfo.st_mode)) { unlink(speeddir); if (mkdir(speeddir,S_IRUSR|S_IWUSR|S_IXUSR)<0) return(1); chmod(speeddir,S_IRUSR|S_IWUSR|S_IXUSR); } snprintf(MAXS(hostfile),"%s/%s",speeddir,host); /* if host file is missing return slow link */ if (!(inf=rfopen(hostfile,"r"))) return(1); fscanf(inf,"%d",&speed); fclose(inf); if (speednext) { printf("\n"); for (oflp=hlp->flist; oflp; oflp=oflp->next) { utf2iso(0,NULL,file,NULL,oflp->fname); printf("%s@%s : %s (%lld KB)\n", oflp->to,hlp->host,file,(oflp->size+512)/1024); } } /* printf("\n(To delete these files use: %s -Sd )\n",prg); */ return(0); } /* * spooled_info - print information about spooled file * * INPUT: file - original file name * sdf - spool data file name * compressed - compressed flag */ void spooled_info(const char *file, const char *sdf, int compressed) { int size; char tmp[MAXLEN]; /* temporary string */ struct stat finfo; /* information about a file */ if (quiet>1) return; if (stat(sdf,&finfo)<0) { snprintf(MAXS(tmp),"cannot access spool file %s",sdf); message(prg,'E',tmp); return; } size=(finfo.st_size+512)/1024; if (compressed) snprintf(MAXS(tmp),"'%s' spooled (%d KB [compressed])",file,size); else snprintf(MAXS(tmp),"'%s' spooled (%d KB)",file,size); message(prg,'I',tmp); } /* * usage - print short help usage text */ int usage() { /* HAVE_GETOPTLONG_H is dead code for sendfile! */ #if defined(HAVE_GETOPTLONG_H) fprintf(stderr,"usage: %s [OPTIONS] file [...] user[@host]\n",prg); fprintf(stderr," or: %s [OPTIONS] -a archivename file-or-directory [...] user[@host]\n",prg); fprintf(stderr,"options:\n"); fprintf(stderr," -a, --archive sends file-or-director(s) as\n archivename to user[@host]\n"); fprintf(stderr," -s, --source send file(s) in source mode\n"); fprintf(stderr," -t, --text send file(s) in text mode\n"); fprintf(stderr," -d, --delete delete previous sent file(s)\n"); fprintf(stderr," -c, --comment comment a single file\n"); fprintf(stderr," -o, --overwrite overwrite already sent file(s) with same name\n"); fprintf(stderr," -b, --bounce resend file(s) to user[@host]\n"); fprintf(stderr," -u, --uncompressed send file(s) uncompressed\n"); fprintf(stderr," -v, --verbose verbose mode\n"); fprintf(stderr," -q, --quiet quiet mode 1: no transfer messages or questions\n"); fprintf(stderr," -Q, --real-quiet quiet mode 2: no transfer\n information and warning messages\n"); fprintf(stderr," -P, --stdin read data stream from stdin\n normaly this is a pipe\n"); /* fprintf(stderr," -X, --extended this uses the extended\n header feature, this implies -P\n"); */ fprintf(stderr," -V, --version show version\n"); fprintf(stderr," -h, --help print this help\n"); fprintf(stderr," -ps, --pgp-sign pgp-sign the file\n"); fprintf(stderr," -pe=ID, --pgp-encrypt pgp-encrypt the file\n\n"); #ifdef ENABLE_MULTIPROTOCOL fprintf(stderr," -4, --ipv4-only explicitly force ipv4 connections\n"); fprintf(stderr," -6, --ipv6-only explicitly force ipv6 connections\n"); #endif fprintf(stderr,"Default mode: send file(s) in binary mode and compressed.\n"); fprintf(stderr,"For a full description of all options, see 'man %s'.\n\n",prg); fprintf(stderr,"Example: %s rabbit.gif beate@juhu.lake.de\n\n",prg); #endif fprintf(stderr,"\n"); fprintf(stderr,"usage: %s [OPTIONS] file [...] user[@host]\n",prg); fprintf(stderr," or: %s [OPTIONS] -a=archive-name file-or-directory [...] user[@host]\n",prg); fprintf(stderr,"options: -s send file(s) in source mode\n"); fprintf(stderr," -t send file(s) in text mode\n"); fprintf(stderr," -g send file(s) in guessed mode (does not work in every case!)\n"); fprintf(stderr," -d delete previously sent file(s)\n"); fprintf(stderr," -o overwrite file(s) with the same name\n"); fprintf(stderr," -u send file(s) uncompressed\n"); fprintf(stderr," -v verbose mode\n"); fprintf(stderr," -q quiet mode 1: no transfer messages or questions\n"); fprintf(stderr," -Q quiet mode 2: no transfer, information or warning messages\n"); fprintf(stderr," -P read file from stdin (this is usually a pipe)\n"); fprintf(stderr," -S spool file(s) for later processing\n"); fprintf(stderr," -l list file(s) in outgoing spool\n"); fprintf(stderr," -V show version\n"); fprintf(stderr," -z force compression (with gzip)\n"); fprintf(stderr," -m LIMIT maximum thruput at LIMIT KB/s\n"); fprintf(stderr," -a=name send all files in one archive\n"); fprintf(stderr," -c='comment' add a one line text comment to a single file\n"); fprintf(stderr," -ps pgp-sign\n"); fprintf(stderr," -pe[=ID] pgp-encrypt [for ID]\n"); #ifdef ENABLE_MULTIPROTOCOL fprintf(stderr," -4 explicitly force ipv4 connections\n"); fprintf(stderr," -6 explicitly force ipv6 connections\n"); #endif fprintf(stderr,"example: %s rabbit.gif beate@juhu.lake.de\n",prg); fprintf(stderr,"see also: sfconf\n"); /* fprintf(stderr,"Default mode: send file(s) in binary mode and compressed.\n"); fprintf(stderr,"For a full description of all options, see 'man %s'.\n",prg); */ return(2); } sendfile-2.1b/src/message.h0000640000175100001440000000077610765530564015440 0ustar framstagusers/* * File: message.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: 1995-08-12 Framstag initial version * 2008-03-12 Framstag exit on fatalerror flag * * Header-file for the VMS-like message routine. * * Copyright © 1995,2008 Ulli Horlacher * This file is covered by the GNU General Public License */ /* print information, warning and error messages on stderr */ void message(char *, char, const char *); /* cleanup routine before exit */ void cleanup(); sendfile-2.1b/src/Makefile.in0000640000175100001440000002512310251132201015651 0ustar framstagusers# Makefile.in generated automatically by automake 1.1l from Makefile.am # Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ target_alias = @target_alias@ build_alias = @build_alias@ host_triplet = @host@ target_triplet = @target@ build_triplet = @build@ host_alias = @host_alias@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ PACKAGE = @PACKAGE@ SYSTEM = @SYSTEM@ CC = @CC@ VERSION = @VERSION@ REVISION = @REVISION@ AUTOMAKE_OPTIONS = gnits MAINT_CHARSET = latin1 INCLUDES = -I- noinst_HEADERS = globals.h address.h net.h config.h.in \ reply.h string.h bsd.h io.h peername.h \ message.h pstring.h spool.h utf7.h EXTRA_DIST = snprintf.c bin_PROGRAMS = sendfile sendmsg receive utf7encode libexec_PROGRAMS = sendfiled sendfile_SOURCES = sendfile.c message.c utf7.c pstring.c string.c io.c \ net.c spool.c address.c sendmsg_SOURCES = sendmsg.c message.c utf7.c pstring.c string.c io.c \ net.c address.c receive_SOURCES = receive.c message.c utf7.c pstring.c string.c io.c \ spool.c getdate.c sendfiled_SOURCES = sendfiled.c message.c utf7.c pstring.c string.c io.c \ net.c spool.c peername.c reply.c utf7encode_SOURCES = utf7encode.c message.c utf7.c pstring.c string.c mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = .././src/config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I.././src CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ sendfile_OBJECTS = sendfile.o message.o utf7.o pstring.o string.o io.o \ net.o spool.o address.o sendfile_LDADD = $(LDADD) sendfile_LDFLAGS = sendmsg_OBJECTS = sendmsg.o message.o utf7.o pstring.o string.o io.o \ net.o address.o sendmsg_LDADD = $(LDADD) sendmsg_LDFLAGS = receive_OBJECTS = receive.o message.o utf7.o pstring.o string.o io.o \ spool.o getdate.o receive_LDADD = $(LDADD) receive_LDFLAGS = utf7encode_OBJECTS = utf7encode.o message.o utf7.o pstring.o string.o utf7encode_LDADD = $(LDADD) utf7encode_LDFLAGS = sendfiled_OBJECTS = sendfiled.o message.o utf7.o pstring.o string.o \ io.o net.o spool.o peername.o reply.o sendfiled_LDADD = $(LDADD) sendfiled_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(LDFLAGS) -o $@ HEADERS = $(noinst_HEADERS) DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) \ $(TEXINFOS) $(MANS) $(EXTRA_DIST) TAR = tar SOURCES = $(sendfile_SOURCES) $(sendmsg_SOURCES) $(receive_SOURCES) $(utf7encode_SOURCES) $(sendfiled_SOURCES) OBJECTS = $(sendfile_OBJECTS) $(sendmsg_OBJECTS) $(receive_OBJECTS) $(utf7encode_OBJECTS) $(sendfiled_OBJECTS) default: all .SUFFIXES: .SUFFIXES: .c .o $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL) cd $(top_srcdir) && automake --gnits src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) $(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list="$(bin_PROGRAMS)"; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-binPROGRAMS: list="$(bin_PROGRAMS)"; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done mostlyclean-libexecPROGRAMS: clean-libexecPROGRAMS: test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS) distclean-libexecPROGRAMS: maintainer-clean-libexecPROGRAMS: install-libexecPROGRAMS: $(libexec_PROGRAMS) $(NORMAL_INSTALL) $(mkinstalldirs) $(libexecdir) @list="$(libexec_PROGRAMS)"; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(libexecdir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$p $(libexecdir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-libexecPROGRAMS: list="$(libexec_PROGRAMS)"; for p in $$list; do \ rm -f $(libexecdir)/`echo $$p|sed '$(transform)'`; \ done .c.o: $(COMPILE) -c $< mostlyclean-compile: rm -f *.o core clean-compile: distclean-compile: rm -f *.tab.c maintainer-clean-compile: $(sendfile_OBJECTS): .././src/config.h sendfile: $(sendfile_OBJECTS) $(sendfile_DEPENDENCIES) $(LINK) $(sendfile_LDFLAGS) $(sendfile_OBJECTS) $(sendfile_LDADD) $(LIBS) $(sendmsg_OBJECTS): .././src/config.h sendmsg: $(sendmsg_OBJECTS) $(sendmsg_DEPENDENCIES) $(LINK) $(sendmsg_LDFLAGS) $(sendmsg_OBJECTS) $(sendmsg_LDADD) $(LIBS) $(receive_OBJECTS): .././src/config.h receive: $(receive_OBJECTS) $(receive_DEPENDENCIES) $(LINK) $(receive_LDFLAGS) $(receive_OBJECTS) $(receive_LDADD) $(LIBS) $(utf7encode_OBJECTS): .././src/config.h utf7encode: $(utf7encode_OBJECTS) $(utf7encode_DEPENDENCIES) $(LINK) $(utf7encode_LDFLAGS) $(utf7encode_OBJECTS) $(utf7encode_LDADD) $(LIBS) $(sendfiled_OBJECTS): .././src/config.h sendfiled: $(sendfiled_OBJECTS) $(sendfiled_DEPENDENCIES) $(LINK) $(sendfiled_LDFLAGS) $(sendfiled_OBJECTS) $(sendfiled_LDADD) $(LIBS) tags: TAGS ID: $(HEADERS) $(SOURCES) here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) tags=; \ here=`pwd`; \ list="$(SUBDIRS)"; for subdir in $$list; do \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ done; \ test -z "$(ETAGS_ARGS)$(SOURCES)$(HEADERS)$$tags" \ || cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $(SOURCES) $(HEADERS) -o $$here/TAGS mostlyclean-tags: clean-tags: distclean-tags: rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = src distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done address.o address.lo: address.c config.h globals.h string.h net.h utf7.h \ pstring.h message.h address.h getdate.o getdate.lo: getdate.c io.o io.lo: io.c config.h globals.h io.h net.h string.h message.h message.o message.lo: message.c globals.h message.h string.h config.h net.o net.lo: net.c config.h globals.h string.h message.h net.h io.h peername.o peername.lo: peername.c peername.h string.h config.h \ globals.h pstring.o pstring.lo: pstring.c pstring.h receive.o receive.lo: receive.c config.h globals.h message.h utf7.h \ pstring.h io.h string.h spool.h reply.o reply.lo: reply.c config.h globals.h string.h sendfile.o sendfile.lo: sendfile.c config.h globals.h string.h net.h \ io.h message.h spool.h utf7.h pstring.h address.h sendfiled.o sendfiled.lo: sendfiled.c config.h globals.h reply.h \ peername.h string.h spool.h net.h io.h utf7.h pstring.h sendmsg.o sendmsg.lo: sendmsg.c config.h globals.h string.h net.h io.h \ message.h utf7.h pstring.h address.h spool.o spool.lo: spool.c config.h globals.h spool.h utf7.h pstring.h \ message.h string.h reply.h string.o string.lo: string.c string.h config.h globals.h utf7.o utf7.lo: utf7.c string.h config.h globals.h utf7.h pstring.h utf7encode.o utf7encode.lo: utf7encode.c config.h globals.h message.h \ utf7.h pstring.h string.h info: dvi: check: all $(MAKE) installcheck: install-exec: install-binPROGRAMS install-libexecPROGRAMS $(NORMAL_INSTALL) $(MAKE) install-exec-hook install-data: $(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-binPROGRAMS uninstall-libexecPROGRAMS all: $(PROGRAMS) $(HEADERS) Makefile install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install installdirs: $(mkinstalldirs) $(bindir) $(libexecdir) mostlyclean-generic: test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: rm -f Makefile $(DISTCLEANFILES) rm -f config.cache config.log stamp-h test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-binPROGRAMS mostlyclean-libexecPROGRAMS \ mostlyclean-compile mostlyclean-tags \ mostlyclean-generic clean: clean-binPROGRAMS clean-libexecPROGRAMS clean-compile clean-tags \ clean-generic mostlyclean distclean: distclean-binPROGRAMS distclean-libexecPROGRAMS \ distclean-compile distclean-tags distclean-generic \ clean rm -f config.status maintainer-clean: maintainer-clean-binPROGRAMS \ maintainer-clean-libexecPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ install-binPROGRAMS mostlyclean-libexecPROGRAMS \ distclean-libexecPROGRAMS clean-libexecPROGRAMS \ maintainer-clean-libexecPROGRAMS uninstall-libexecPROGRAMS \ install-libexecPROGRAMS mostlyclean-compile distclean-compile \ clean-compile maintainer-clean-compile tags mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ installcheck install-exec install-data install uninstall all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean install-exec-hook: $(RM) $(bindir)/utf7decode @ln -s $(bindir)/utf7encode $(bindir)/utf7decode # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sendfile-2.1b/src/snprintf.c0000640000175100001440000012166710251136250015635 0ustar framstagusers/* * snprintf.c - a portable implementation of snprintf * * AUTHOR * Mark Martinec , April 1999. * * Copyright 1999, Mark Martinec. All rights reserved. * * TERMS AND CONDITIONS * This program is free software; you can redistribute it and/or modify * it under the terms of the "Frontier Artistic License" which comes * with this Kit. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Frontier Artistic License for more details. * * You should have received a copy of the Frontier Artistic License * with this Kit in the file named LICENSE.txt . * If not, I'll be glad to provide one. * * FEATURES * - careful adherence to specs regarding flags, field width and precision; * - good performance for large string handling (large format, large * argument or large paddings). Performance is similar to system's sprintf * and in several cases significantly better (make sure you compile with * optimizations turned on, tell the compiler the code is strict ANSI * if necessary to give it more freedom for optimizations); * - return value semantics per ISO/IEC 9899:1999 ("ISO C99"); * - written in standard ISO/ANSI C - requires an ANSI C compiler. * * SUPPORTED CONVERSION SPECIFIERS AND DATA TYPES * * This snprintf only supports the following conversion specifiers: * s, c, d, u, o, x, X, p (and synonyms: i, D, U, O - see below) * with flags: '-', '+', ' ', '0' and '#'. * An asterisk is supported for field width as well as precision. * * Length modifiers 'h' (short int), 'l' (long int), * and 'll' (long long int) are supported. * NOTE: * If macro SNPRINTF_LONGLONG_SUPPORT is not defined (default) the * length modifier 'll' is recognized but treated the same as 'l', * which may cause argument value truncation! Defining * SNPRINTF_LONGLONG_SUPPORT requires that your system's sprintf also * handles length modifier 'll'. long long int is a language extension * which may not be portable. * * Conversion of numeric data (conversion specifiers d, u, o, x, X, p) * with length modifiers (none or h, l, ll) is left to the system routine * sprintf, but all handling of flags, field width and precision as well as * c and s conversions is done very carefully by this portable routine. * If a string precision (truncation) is specified (e.g. %.8s) it is * guaranteed the string beyond the specified precision will not be referenced. * * Length modifiers h, l and ll are ignored for c and s conversions (data * types wint_t and wchar_t are not supported). * * The following common synonyms for conversion characters are supported: * - i is a synonym for d * - D is a synonym for ld, explicit length modifiers are ignored * - U is a synonym for lu, explicit length modifiers are ignored * - O is a synonym for lo, explicit length modifiers are ignored * The D, O and U conversion characters are nonstandard, they are supported * for backward compatibility only, and should not be used for new code. * * The following is specifically NOT supported: * - flag ' (thousands' grouping character) is recognized but ignored * - numeric conversion specifiers: f, e, E, g, G and synonym F, * as well as the new a and A conversion specifiers * - length modifier 'L' (long double) and 'q' (quad - use 'll' instead) * - wide character/string conversions: lc, ls, and nonstandard * synonyms C and S * - writeback of converted string length: conversion character n * - the n$ specification for direct reference to n-th argument * - locales * * It is permitted for str_m to be zero, and it is permitted to specify NULL * pointer for resulting string argument if str_m is zero (as per ISO C99). * * The return value is the number of characters which would be generated * for the given input, excluding the trailing null. If this value * is greater or equal to str_m, not all characters from the result * have been stored in str, output bytes beyond the (str_m-1) -th character * are discarded. If str_m is greater than zero it is guaranteed * the resulting string will be null-terminated. * * NOTE that this matches the ISO C99, OpenBSD, and GNU C library 2.1, * but is different from some older and vendor implementations, * and is also different from XPG, XSH5, SUSv2 specifications. * For historical discussion on changes in the semantics and standards * of snprintf see printf(3) man page in the Linux programmers manual. * * Routines asprintf and vasprintf return a pointer (in the ptr argument) * to a buffer sufficiently large to hold the resulting string. This pointer * should be passed to free(3) to release the allocated storage when it is * no longer needed. If sufficient space cannot be allocated, these functions * will return -1 and set ptr to be a NULL pointer. These two routines are a * GNU C library extensions (glibc). * * Routines asnprintf and vasnprintf are similar to asprintf and vasprintf, * yet, like snprintf and vsnprintf counterparts, will write at most str_m-1 * characters into the allocated output string, the last character in the * allocated buffer then gets the terminating null. If the formatted string * length (the return value) is greater than or equal to the str_m argument, * the resulting string was truncated and some of the formatted characters * were discarded. These routines present a handy way to limit the amount * of allocated memory to some sane value. * * AVAILABILITY * http://www.ijs.si/software/snprintf/ * * REVISION HISTORY * 1999-04 V0.9 Mark Martinec * - initial version, some modifications after comparing printf * man pages for Digital Unix 4.0, Solaris 2.6 and HPUX 10, * and checking how Perl handles sprintf (differently!); * 1999-04-09 V1.0 Mark Martinec * - added main test program, fixed remaining inconsistencies, * added optional (long long int) support; * 1999-04-12 V1.1 Mark Martinec * - support the 'p' conversion (pointer to void); * - if a string precision is specified * make sure the string beyond the specified precision * will not be referenced (e.g. by strlen); * 1999-04-13 V1.2 Mark Martinec * - support synonyms %D=%ld, %U=%lu, %O=%lo; * - speed up the case of long format string with few conversions; * 1999-06-30 V1.3 Mark Martinec * - fixed runaway loop (eventually crashing when str_l wraps * beyond 2^31) while copying format string without * conversion specifiers to a buffer that is too short * (thanks to Edwin Young for * spotting the problem); * - added macros PORTABLE_SNPRINTF_VERSION_(MAJOR|MINOR) * to snprintf.h * 2000-02-14 V2.0 (never released) Mark Martinec * - relaxed license terms: The Artistic License now applies. * You may still apply the GNU GENERAL PUBLIC LICENSE * as was distributed with previous versions, if you prefer; * - changed REVISION HISTORY dates to use ISO 8601 date format; * - added vsnprintf (patch also independently proposed by * Caolan McNamara 2000-05-04, and Keith M Willenson 2000-06-01) * 2000-06-27 V2.1 Mark Martinec * - removed POSIX check for str_m<1; value 0 for str_m is * allowed by ISO C99 (and GNU C library 2.1) - (pointed out * on 2000-05-04 by Caolan McNamara, caolan@ csn dot ul dot ie). * Besides relaxed license this change in standards adherence * is the main reason to bump up the major version number; * - added nonstandard routines asnprintf, vasnprintf, asprintf, * vasprintf that dynamically allocate storage for the * resulting string; these routines are not compiled by default, * see comments where NEED_V?ASN?PRINTF macros are defined; * - autoconf contributed by Caolan McNamara * 2000-10-06 V2.2 Mark Martinec * - BUG FIX: the %c conversion used a temporary variable * that was no longer in scope when referenced, * possibly causing incorrect resulting character; * - BUG FIX: make precision and minimal field width unsigned * to handle huge values (2^31 <= n < 2^32) correctly; * also be more careful in the use of signed/unsigned/size_t * internal variables - probably more careful than many * vendor implementations, but there may still be a case * where huge values of str_m, precision or minimal field * could cause incorrect behaviour; * - use separate variables for signed/unsigned arguments, * and for short/int, long, and long long argument lengths * to avoid possible incompatibilities on certain * computer architectures. Also use separate variable * arg_sign to hold sign of a numeric argument, * to make code more transparent; * - some fiddling with zero padding and "0x" to make it * Linux compatible; * - systematically use macros fast_memcpy and fast_memset * instead of case-by-case hand optimization; determine some * breakeven string lengths for different architectures; * - terminology change: 'format' -> 'conversion specifier', * 'C9x' -> 'ISO/IEC 9899:1999 ("ISO C99")', * 'alternative form' -> 'alternate form', * 'data type modifier' -> 'length modifier'; * - several comments rephrased and new ones added; * - make compiler not complain about 'credits' defined but * not used; */ /* Define HAVE_SNPRINTF if your system already has snprintf and vsnprintf. * * If HAVE_SNPRINTF is defined this module will not produce code for * snprintf and vsnprintf, unless PREFER_PORTABLE_SNPRINTF is defined as well, * causing this portable version of snprintf to be called portable_snprintf * (and portable_vsnprintf). */ /* #define HAVE_SNPRINTF */ /* Define PREFER_PORTABLE_SNPRINTF if your system does have snprintf and * vsnprintf but you would prefer to use the portable routine(s) instead. * In this case the portable routine is declared as portable_snprintf * (and portable_vsnprintf) and a macro 'snprintf' (and 'vsnprintf') * is defined to expand to 'portable_v?snprintf' - see file snprintf.h . * Defining this macro is only useful if HAVE_SNPRINTF is also defined, * but does does no harm if defined nevertheless. */ /* #define PREFER_PORTABLE_SNPRINTF */ /* Define SNPRINTF_LONGLONG_SUPPORT if you want to support * data type (long long int) and length modifier 'll' (e.g. %lld). * If undefined, 'll' is recognized but treated as a single 'l'. * * If the system's sprintf does not handle 'll' * the SNPRINTF_LONGLONG_SUPPORT must not be defined! * * This is off by default as (long long int) is a language extension. */ /* #define SNPRINTF_LONGLONG_SUPPORT */ /* Define NEED_SNPRINTF_ONLY if you only need snprintf, and not vsnprintf. * If NEED_SNPRINTF_ONLY is defined, the snprintf will be defined directly, * otherwise both snprintf and vsnprintf routines will be defined * and snprintf will be a simple wrapper around vsnprintf, at the expense * of an extra procedure call. */ /* #define NEED_SNPRINTF_ONLY */ /* Define NEED_V?ASN?PRINTF macros if you need library extension * routines asprintf, vasprintf, asnprintf, vasnprintf respectively, * and your system library does not provide them. They are all small * wrapper routines around portable_vsnprintf. Defining any of the four * NEED_V?ASN?PRINTF macros automatically turns off NEED_SNPRINTF_ONLY * and turns on PREFER_PORTABLE_SNPRINTF. * * Watch for name conflicts with the system library if these routines * are already present there. * * NOTE: vasprintf and vasnprintf routines need va_copy() from stdarg.h, as * specified by C99, to be able to traverse the same list of arguments twice. * I don't know of any other standard and portable way of achieving the same. * With some versions of gcc you may use __va_copy(). You might even get away * with "ap2 = ap", in this case you must not call va_end(ap2) ! * #define va_copy(ap2,ap) ap2 = ap */ /* #define NEED_ASPRINTF */ /* #define NEED_ASNPRINTF */ /* #define NEED_VASPRINTF */ /* #define NEED_VASNPRINTF */ /* Define the following macros if desired: * SOLARIS_COMPATIBLE, SOLARIS_BUG_COMPATIBLE, * HPUX_COMPATIBLE, HPUX_BUG_COMPATIBLE, LINUX_COMPATIBLE, * DIGITAL_UNIX_COMPATIBLE, DIGITAL_UNIX_BUG_COMPATIBLE, * PERL_COMPATIBLE, PERL_BUG_COMPATIBLE, * * - For portable applications it is best not to rely on peculiarities * of a given implementation so it may be best not to define any * of the macros that select compatibility and to avoid features * that vary among the systems. * * - Selecting compatibility with more than one operating system * is not strictly forbidden but is not recommended. * * - 'x'_BUG_COMPATIBLE implies 'x'_COMPATIBLE . * * - 'x'_COMPATIBLE refers to (and enables) a behaviour that is * documented in a sprintf man page on a given operating system * and actually adhered to by the system's sprintf (but not on * most other operating systems). It may also refer to and enable * a behaviour that is declared 'undefined' or 'implementation specific' * in the man page but a given implementation behaves predictably * in a certain way. * * - 'x'_BUG_COMPATIBLE refers to (and enables) a behaviour of system's sprintf * that contradicts the sprintf man page on the same operating system. * * - I do not claim that the 'x'_COMPATIBLE and 'x'_BUG_COMPATIBLE * conditionals take into account all idiosyncrasies of a particular * implementation, there may be other incompatibilities. */ /* ============================================= */ /* NO USER SERVICABLE PARTS FOLLOWING THIS POINT */ /* ============================================= */ #define PORTABLE_SNPRINTF_VERSION_MAJOR 2 #define PORTABLE_SNPRINTF_VERSION_MINOR 2 #if defined(NEED_ASPRINTF) || defined(NEED_ASNPRINTF) || defined(NEED_VASPRINTF) || defined(NEED_VASNPRINTF) # if defined(NEED_SNPRINTF_ONLY) # undef NEED_SNPRINTF_ONLY # endif # if !defined(PREFER_PORTABLE_SNPRINTF) # define PREFER_PORTABLE_SNPRINTF # endif #endif #if defined(SOLARIS_BUG_COMPATIBLE) && !defined(SOLARIS_COMPATIBLE) #define SOLARIS_COMPATIBLE #endif #if defined(HPUX_BUG_COMPATIBLE) && !defined(HPUX_COMPATIBLE) #define HPUX_COMPATIBLE #endif #if defined(DIGITAL_UNIX_BUG_COMPATIBLE) && !defined(DIGITAL_UNIX_COMPATIBLE) #define DIGITAL_UNIX_COMPATIBLE #endif #if defined(PERL_BUG_COMPATIBLE) && !defined(PERL_COMPATIBLE) #define PERL_COMPATIBLE #endif #if defined(LINUX_BUG_COMPATIBLE) && !defined(LINUX_COMPATIBLE) #define LINUX_COMPATIBLE #endif #include #include #include #include #include #include #include #ifdef isdigit #undef isdigit #endif #define isdigit(c) ((c) >= '0' && (c) <= '9') /* For copying strings longer or equal to 'breakeven_point' * it is more efficient to call memcpy() than to do it inline. * The value depends mostly on the processor architecture, * but also on the compiler and its optimization capabilities. * The value is not critical, some small value greater than zero * will be just fine if you don't care to squeeze every drop * of performance out of the code. * * Small values favor memcpy, large values favor inline code. */ #if defined(__alpha__) || defined(__alpha) # define breakeven_point 2 /* AXP (DEC Alpha) - gcc or cc or egcs */ #endif #if defined(__i386__) || defined(__i386) # define breakeven_point 12 /* Intel Pentium/Linux - gcc 2.96 */ #endif #if defined(__hppa) # define breakeven_point 10 /* HP-PA - gcc */ #endif #if defined(__sparc__) || defined(__sparc) # define breakeven_point 33 /* Sun Sparc 5 - gcc 2.8.1 */ #endif /* some other values of possible interest: */ /* #define breakeven_point 8 */ /* VAX 4000 - vaxc */ /* #define breakeven_point 19 */ /* VAX 4000 - gcc 2.7.0 */ #ifndef breakeven_point # define breakeven_point 6 /* some reasonable one-size-fits-all value */ #endif #define fast_memcpy(d,s,n) \ { register size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memcpy((d), (s), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ register char *dd; register const char *ss; \ for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } } #define fast_memset(d,c,n) \ { register size_t nn = (size_t)(n); \ if (nn >= breakeven_point) memset((d), (int)(c), nn); \ else if (nn > 0) { /* proc call overhead is worth only for large strings*/\ register char *dd; register const int cc=(int)(c); \ for (dd=(d); nn>0; nn--) *dd++ = cc; } } /* prototypes */ #if defined(NEED_ASPRINTF) int asprintf (char **ptr, const char *fmt, /*args*/ ...); #endif #if defined(NEED_VASPRINTF) int vasprintf (char **ptr, const char *fmt, va_list ap); #endif #if defined(NEED_ASNPRINTF) int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...); #endif #if defined(NEED_VASNPRINTF) int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap); #endif #if defined(HAVE_SNPRINTF) /* declare our portable snprintf routine under name portable_snprintf */ /* declare our portable vsnprintf routine under name portable_vsnprintf */ #else /* declare our portable routines under names snprintf and vsnprintf */ #define portable_snprintf snprintf #if !defined(NEED_SNPRINTF_ONLY) #define portable_vsnprintf vsnprintf #endif #endif #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...); #if !defined(NEED_SNPRINTF_ONLY) int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap); #endif #endif /* declarations */ static char credits[] = "\n\ @(#)snprintf.c, v2.2: Mark Martinec, \n\ @(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\ @(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n"; #if defined(NEED_ASPRINTF) int asprintf(char **ptr, const char *fmt, /*args*/ ...) { va_list ap; size_t str_m; int str_l; *ptr = NULL; va_start(ap, fmt); /* measure the required size */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); va_end(ap); assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ *ptr = (char *) malloc(str_m = (size_t)str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2; va_start(ap, fmt); str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); va_end(ap); assert(str_l2 == str_l); } return str_l; } #endif #if defined(NEED_VASPRINTF) int vasprintf(char **ptr, const char *fmt, va_list ap) { size_t str_m; int str_l; *ptr = NULL; { va_list ap2; va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ va_end(ap2); } assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ *ptr = (char *) malloc(str_m = (size_t)str_l + 1); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); assert(str_l2 == str_l); } return str_l; } #endif #if defined(NEED_ASNPRINTF) int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) { va_list ap; int str_l; *ptr = NULL; va_start(ap, fmt); /* measure the required size */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap); va_end(ap); assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { *ptr = (char *) malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2; va_start(ap, fmt); str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); va_end(ap); assert(str_l2 == str_l); } } return str_l; } #endif #if defined(NEED_VASNPRINTF) int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) { int str_l; *ptr = NULL; { va_list ap2; va_copy(ap2, ap); /* don't consume the original ap, we'll need it again */ str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/ va_end(ap2); } assert(str_l >= 0); /* possible integer overflow if str_m > INT_MAX */ if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1; /* truncate */ /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */ if (str_m == 0) { /* not interested in resulting string, just return size */ } else { *ptr = (char *) malloc(str_m); if (*ptr == NULL) { errno = ENOMEM; str_l = -1; } else { int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap); assert(str_l2 == str_l); } } return str_l; } #endif /* * If the system does have snprintf and the portable routine is not * specifically required, this module produces no code for snprintf/vsnprintf. */ #if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF) #if !defined(NEED_SNPRINTF_ONLY) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { va_list ap; int str_l; va_start(ap, fmt); str_l = portable_vsnprintf(str, str_m, fmt, ap); va_end(ap); return str_l; } #endif #if defined(NEED_SNPRINTF_ONLY) int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) { #else int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) { #endif #if defined(NEED_SNPRINTF_ONLY) va_list ap; #endif size_t str_l = 0; const char *p = fmt; /* In contrast with POSIX, the ISO C99 now says * that str can be NULL and str_m can be 0. * This is more useful than the old: if (str_m < 1) return -1; */ #if defined(NEED_SNPRINTF_ONLY) va_start(ap, fmt); #endif if (!p) p = ""; while (*p) { if (*p != '%') { /* if (str_l < str_m) str[str_l++] = *p++; -- this would be sufficient */ /* but the following code achieves better performance for cases * where format string is long and contains few conversions */ const char *q = strchr(p+1,'%'); size_t n = !q ? strlen(p) : (q-p); if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, p, (n>avail?avail:n)); } p += n; str_l += n; } else { const char *starting_p; size_t min_field_width = 0, precision = 0; int zero_padding = 0, precision_specified = 0, justify_left = 0; int alternate_form = 0, force_sign = 0; int space_for_positive = 1; /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored. */ char length_modifier = '\0'; /* allowed values: \0, h, l, L */ char tmp[32];/* temporary buffer for simple numeric->string conversion */ const char *str_arg; /* string address in case of string argument */ size_t str_arg_l; /* natural field width of arg without padding and sign */ unsigned char uchar_arg; /* unsigned char argument value - only defined for c conversion. N.B. standard explicitly states the char argument for the c conversion is unsigned */ size_t number_of_zeros_to_pad = 0; /* number of zeros to be inserted for numeric conversions as required by the precision or minimal field width */ size_t zero_padding_insertion_ind = 0; /* index into tmp where zero padding is to be inserted */ char fmt_spec = '\0'; /* current conversion specifier character */ str_arg = credits;/* just to make compiler happy (defined but not used)*/ str_arg = NULL; starting_p = p; p++; /* skip '%' */ /* parse flags */ while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '\'') { switch (*p) { case '0': zero_padding = 1; break; case '-': justify_left = 1; break; case '+': force_sign = 1; space_for_positive = 0; break; case ' ': force_sign = 1; /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */ #ifdef PERL_COMPATIBLE /* ... but in Perl the last of ' ' and '+' applies */ space_for_positive = 1; #endif break; case '#': alternate_form = 1; break; case '\'': break; } p++; } /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */ /* parse field width */ if (*p == '*') { int j; p++; j = va_arg(ap, int); if (j >= 0) min_field_width = j; else { min_field_width = -j; justify_left = 1; } } else if (isdigit((int)(*p))) { /* size_t could be wider than unsigned int; make sure we treat argument like common implementations do */ unsigned int uj = *p++ - '0'; while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); min_field_width = uj; } /* parse precision */ if (*p == '.') { p++; precision_specified = 1; if (*p == '*') { int j = va_arg(ap, int); p++; if (j >= 0) precision = j; else { precision_specified = 0; precision = 0; /* NOTE: * Solaris 2.6 man page claims that in this case the precision * should be set to 0. Digital Unix 4.0, HPUX 10 and BSD man page * claim that this case should be treated as unspecified precision, * which is what we do here. */ } } else if (isdigit((int)(*p))) { /* size_t could be wider than unsigned int; make sure we treat argument like common implementations do */ unsigned int uj = *p++ - '0'; while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0'); precision = uj; } } /* parse 'h', 'l' and 'll' length modifiers */ if (*p == 'h' || *p == 'l') { length_modifier = *p; p++; if (length_modifier == 'l' && *p == 'l') { /* double l = long long */ #ifdef SNPRINTF_LONGLONG_SUPPORT length_modifier = '2'; /* double l encoded as '2' */ #else length_modifier = 'l'; /* treat it as a single 'l' */ #endif p++; } } fmt_spec = *p; /* common synonyms: */ switch (fmt_spec) { case 'i': fmt_spec = 'd'; break; case 'D': fmt_spec = 'd'; length_modifier = 'l'; break; case 'U': fmt_spec = 'u'; length_modifier = 'l'; break; case 'O': fmt_spec = 'o'; length_modifier = 'l'; break; default: break; } /* get parameter value, do initial processing */ switch (fmt_spec) { case '%': /* % behaves similar to 's' regarding flags and field widths */ case 'c': /* c behaves similar to 's' regarding flags and field widths */ case 's': length_modifier = '\0'; /* wint_t and wchar_t not supported */ /* the result of zero padding flag with non-numeric conversion specifier*/ /* is undefined. Solaris and HPUX 10 does zero padding in this case, */ /* Digital Unix and Linux does not. */ #if !defined(SOLARIS_COMPATIBLE) && !defined(HPUX_COMPATIBLE) zero_padding = 0; /* turn zero padding off for string conversions */ #endif str_arg_l = 1; switch (fmt_spec) { case '%': str_arg = p; break; case 'c': { int j = va_arg(ap, int); uchar_arg = (unsigned char) j; /* standard demands unsigned char */ str_arg = (const char *) &uchar_arg; break; } case 's': str_arg = va_arg(ap, const char *); if (!str_arg) str_arg_l = 0; /* make sure not to address string beyond the specified precision !!! */ else if (!precision_specified) str_arg_l = strlen(str_arg); /* truncate string if necessary as requested by precision */ else if (precision == 0) str_arg_l = 0; else { /* memchr on HP does not like n > 2^31 !!! */ const char *q = memchr(str_arg, '\0', precision <= 0x7fffffff ? precision : 0x7fffffff); str_arg_l = !q ? precision : (q-str_arg); } break; default: break; } break; case 'd': case 'u': case 'o': case 'x': case 'X': case 'p': { /* NOTE: the u, o, x, X and p conversion specifiers imply the value is unsigned; d implies a signed value */ int arg_sign = 0; /* 0 if numeric argument is zero (or if pointer is NULL for 'p'), +1 if greater than zero (or nonzero for unsigned arguments), -1 if negative (unsigned argument is never negative) */ int int_arg = 0; unsigned int uint_arg = 0; /* only defined for length modifier h, or for no length modifiers */ long int long_arg = 0; unsigned long int ulong_arg = 0; /* only defined for length modifier l */ void *ptr_arg = NULL; /* pointer argument value -only defined for p conversion */ #ifdef SNPRINTF_LONGLONG_SUPPORT long long int long_long_arg = 0; unsigned long long int ulong_long_arg = 0; /* only defined for length modifier ll */ #endif if (fmt_spec == 'p') { /* HPUX 10: An l, h, ll or L before any other conversion character * (other than d, i, u, o, x, or X) is ignored. * Digital Unix: * not specified, but seems to behave as HPUX does. * Solaris: If an h, l, or L appears before any other conversion * specifier (other than d, i, u, o, x, or X), the behavior * is undefined. (Actually %hp converts only 16-bits of address * and %llp treats address as 64-bit data which is incompatible * with (void *) argument on a 32-bit system). */ #ifdef SOLARIS_COMPATIBLE # ifdef SOLARIS_BUG_COMPATIBLE /* keep length modifiers even if it represents 'll' */ # else if (length_modifier == '2') length_modifier = '\0'; # endif #else length_modifier = '\0'; #endif ptr_arg = va_arg(ap, void *); if (ptr_arg != NULL) arg_sign = 1; } else if (fmt_spec == 'd') { /* signed */ switch (length_modifier) { case '\0': case 'h': /* It is non-portable to specify a second argument of char or short * to va_arg, because arguments seen by the called function * are not char or short. C converts char and short arguments * to int before passing them to a function. */ int_arg = va_arg(ap, int); if (int_arg > 0) arg_sign = 1; else if (int_arg < 0) arg_sign = -1; break; case 'l': long_arg = va_arg(ap, long int); if (long_arg > 0) arg_sign = 1; else if (long_arg < 0) arg_sign = -1; break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': long_long_arg = va_arg(ap, long long int); if (long_long_arg > 0) arg_sign = 1; else if (long_long_arg < 0) arg_sign = -1; break; #endif } } else { /* unsigned */ switch (length_modifier) { case '\0': case 'h': uint_arg = va_arg(ap, unsigned int); if (uint_arg) arg_sign = 1; break; case 'l': ulong_arg = va_arg(ap, unsigned long int); if (ulong_arg) arg_sign = 1; break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': ulong_long_arg = va_arg(ap, unsigned long long int); if (ulong_long_arg) arg_sign = 1; break; #endif } } str_arg = tmp; str_arg_l = 0; /* NOTE: * For d, i, u, o, x, and X conversions, if precision is specified, * the '0' flag should be ignored. This is so with Solaris 2.6, * Digital UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl. */ #ifndef PERL_COMPATIBLE if (precision_specified) zero_padding = 0; #endif if (fmt_spec == 'd') { if (force_sign && arg_sign >= 0) tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; /* leave negative numbers for sprintf to handle, to avoid handling tricky cases like (short int)(-32768) */ #ifdef LINUX_COMPATIBLE } else if (fmt_spec == 'p' && force_sign && arg_sign > 0) { tmp[str_arg_l++] = space_for_positive ? ' ' : '+'; #endif } else if (alternate_form) { if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X') ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = fmt_spec; } /* alternate form should have no effect for p conversion, but ... */ #ifdef HPUX_COMPATIBLE else if (fmt_spec == 'p' /* HPUX 10: for an alternate form of p conversion, * a nonzero result is prefixed by 0x. */ #ifndef HPUX_BUG_COMPATIBLE /* Actually it uses 0x prefix even for a zero value. */ && arg_sign != 0 #endif ) { tmp[str_arg_l++] = '0'; tmp[str_arg_l++] = 'x'; } #endif } zero_padding_insertion_ind = str_arg_l; if (!precision_specified) precision = 1; /* default precision is 1 */ if (precision == 0 && arg_sign == 0 #if defined(HPUX_BUG_COMPATIBLE) || defined(LINUX_COMPATIBLE) && fmt_spec != 'p' /* HPUX 10 man page claims: With conversion character p the result of * converting a zero value with a precision of zero is a null string. * Actually HP returns all zeroes, and Linux returns "(nil)". */ #endif ) { /* converted to null string */ /* When zero value is formatted with an explicit precision 0, the resulting formatted string is empty (d, i, u, o, x, X, p). */ } else { char f[5]; int f_l = 0; f[f_l++] = '%'; /* construct a simple format string for sprintf */ if (!length_modifier) { } else if (length_modifier=='2') { f[f_l++] = 'l'; f[f_l++] = 'l'; } else f[f_l++] = length_modifier; f[f_l++] = fmt_spec; f[f_l++] = '\0'; if (fmt_spec == 'p') str_arg_l += sprintf(tmp+str_arg_l, f, ptr_arg); else if (fmt_spec == 'd') { /* signed */ switch (length_modifier) { case '\0': case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, int_arg); break; case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, long_arg); break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,long_long_arg); break; #endif } } else { /* unsigned */ switch (length_modifier) { case '\0': case 'h': str_arg_l+=sprintf(tmp+str_arg_l, f, uint_arg); break; case 'l': str_arg_l+=sprintf(tmp+str_arg_l, f, ulong_arg); break; #ifdef SNPRINTF_LONGLONG_SUPPORT case '2': str_arg_l+=sprintf(tmp+str_arg_l,f,ulong_long_arg);break; #endif } } /* include the optional minus sign and possible "0x" in the region before the zero padding insertion point */ if (zero_padding_insertion_ind < str_arg_l && tmp[zero_padding_insertion_ind] == '-') { zero_padding_insertion_ind++; } if (zero_padding_insertion_ind+1 < str_arg_l && tmp[zero_padding_insertion_ind] == '0' && (tmp[zero_padding_insertion_ind+1] == 'x' || tmp[zero_padding_insertion_ind+1] == 'X') ) { zero_padding_insertion_ind += 2; } } { size_t num_of_digits = str_arg_l - zero_padding_insertion_ind; if (alternate_form && fmt_spec == 'o' #ifdef HPUX_COMPATIBLE /* ("%#.o",0) -> "" */ && (str_arg_l > 0) #endif #ifdef DIGITAL_UNIX_BUG_COMPATIBLE /* ("%#o",0) -> "00" */ #else /* unless zero is already the first character */ && !(zero_padding_insertion_ind < str_arg_l && tmp[zero_padding_insertion_ind] == '0') #endif ) { /* assure leading zero for alternate-form octal numbers */ if (!precision_specified || precision < num_of_digits+1) { /* precision is increased to force the first character to be zero, except if a zero value is formatted with an explicit precision of zero */ precision = num_of_digits+1; precision_specified = 1; } } /* zero padding to specified precision? */ if (num_of_digits < precision) number_of_zeros_to_pad = precision - num_of_digits; } /* zero padding to specified minimal field width? */ if (!justify_left && zero_padding) { int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) number_of_zeros_to_pad += n; } break; } default: /* unrecognized conversion specifier, keep format string as-is*/ zero_padding = 0; /* turn zero padding off for non-numeric convers. */ #ifndef DIGITAL_UNIX_COMPATIBLE justify_left = 1; min_field_width = 0; /* reset flags */ #endif #if defined(PERL_COMPATIBLE) || defined(LINUX_COMPATIBLE) /* keep the entire format string unchanged */ str_arg = starting_p; str_arg_l = p - starting_p; /* well, not exactly so for Linux, which does something inbetween, * and I don't feel an urge to imitate it: "%+++++hy" -> "%+y" */ #else /* discard the unrecognized conversion, just keep * * the unrecognized conversion character */ str_arg = p; str_arg_l = 0; #endif if (*p) str_arg_l++; /* include invalid conversion specifier unchanged if not at end-of-string */ break; } if (*p) p++; /* step over the just processed conversion specifier */ /* insert padding to the left as requested by min_field_width; this does not include the zero padding in case of numerical conversions*/ if (!justify_left) { /* left padding with blank or zero */ int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, (zero_padding?'0':' '), (n>avail?avail:n)); } str_l += n; } } /* zero padding as requested by the precision or by the minimal field width * for numeric conversions required? */ if (number_of_zeros_to_pad <= 0) { /* will not copy first part of numeric right now, * * force it to be copied later in its entirety */ zero_padding_insertion_ind = 0; } else { /* insert first part of numerics (sign or '0x') before zero padding */ int n = zero_padding_insertion_ind; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, str_arg, (n>avail?avail:n)); } str_l += n; } /* insert zero padding as requested by the precision or min field width */ n = number_of_zeros_to_pad; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, '0', (n>avail?avail:n)); } str_l += n; } } /* insert formatted string * (or as-is conversion specifier for unknown conversions) */ { int n = str_arg_l - zero_padding_insertion_ind; if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memcpy(str+str_l, str_arg+zero_padding_insertion_ind, (n>avail?avail:n)); } str_l += n; } } /* insert right padding */ if (justify_left) { /* right blank padding to the field width */ int n = min_field_width - (str_arg_l+number_of_zeros_to_pad); if (n > 0) { if (str_l < str_m) { size_t avail = str_m-str_l; fast_memset(str+str_l, ' ', (n>avail?avail:n)); } str_l += n; } } } } #if defined(NEED_SNPRINTF_ONLY) va_end(ap); #endif if (str_m > 0) { /* make sure the string is null-terminated even at the expense of overwriting the last character (shouldn't happen, but just in case) */ str[str_l <= str_m-1 ? str_l : str_m-1] = '\0'; } /* Return the number of characters formatted (excluding trailing null * character), that is, the number of characters that would have been * written to the buffer if it were large enough. * * The value of str_l should be returned, but str_l is of unsigned type * size_t, and snprintf is int, possibly leading to an undetected * integer overflow, resulting in a negative return value, which is illegal. * Both XSH5 and ISO C99 (at least the draft) are silent on this issue. * Should errno be set to EOVERFLOW and EOF returned in this case??? */ return (int) str_l; } #endif sendfile-2.1b/src/string.h0000640000175100001440000000463410251136250015277 0ustar framstagusers/* * File: string.h * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: * * 1995-08-12 Framstag initial version * 1996-02-29 Framstag added streq and strneq macros * 1996-05-05 Framstag merged streq and strneq * 1997-01-16 GNUish added strerror * 1997-02-11 GNUish include_next replaced * 1997-02-23 Framstag renamed str* functions to str_* * added str_beq_nocase and str_neq_nocase * 2000-12-10 Framstag added sfgetl() (substitution for fgets()) * 2005-05-31 Framstag new snprintf() from * * Header-file of the extended string functions for the sendfile package, * which are not found in the standard C library. * * Copyright © 1995-2005 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" #include /* Try to emulate GNUs include_next here */ /* #if defined(HAVE_STRING_H) #include "/usr/include/string.h" #else int strncasecmp(const char *, const char *, int); #endif */ /* This seems to be true on SunOS 4.1.4 */ #ifndef NULL #define NULL (void *) 0 #endif #if !defined(HAVE_STRERROR) char *strerror(int); #endif /* trim white spaces */ char *str_trim(char *); /* transform string to upper case */ char *str_toupper(char *); /* transform string to lower case */ char *str_tolower(char *); /* match a simple pattern */ int simplematch(char *, char *, int); /* string begin equal test */ int str_beq(const char *, const char *); /* string equal test until length n, ignoring case */ int str_neq_nocase(const char *, const char *, int); /* string begin equal test, ignoring case */ int str_beq_nocase(const char *, const char *); /* string equal test */ #define str_eq(s1,s2) (strcmp((s1),(s2)) == 0) /* #define streq(s1,s2) (strncmp((s1),(s2),(strlen(s1) #include "snprintf.h" /* int snprintf(char *buf, size_t len, const char *format,...); int vsnprintf(char *buf, size_t len, const char *format, va_list ap); */ #else /* This is a GNU extention to the libc */ #if __GLIBC__ > 1 extern int snprintf __P ((char *, size_t, __const char *, ...)); #endif #endif #define MAXS(s) s,sizeof(s)-1 /* secure version of gets() : read a text line from a stream */ char *sfgetl(char *, int, FILE *); #define fgetl(s,f) sfgetl(s,sizeof(s),f) sendfile-2.1b/src/pstring.h0000640000175100001440000000203210251136250015445 0ustar framstagusers/* * File: pstring.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * History: 1995-08-12 Framstag initial version * 1999-03-13 Framstag added pstr_addpstring() * * Header-file for the Pascal like pstring functions. * Strings start by definition at pstr.length[1] * * Copyright © 1995,1999 Ulli Horlacher * This file is covered by the GNU General Public License */ typedef struct { int size; /* absolute length in bytes */ int length; /* used string length in bytes */ char *string; /* the string itself without any terminating symbol */ } pstr_t; /* create a pstring */ pstr_t *pstr_create(int); /* delete a pstring */ void pstr_delete(pstr_t *); /* add a char to a pstring */ int pstr_addchar(pstr_t *, char); /* assign one pstring to another (p1<-p2) */ int pstr_assign(pstr_t *, pstr_t *); /* add a string to a pstring */ int pstr_addstring(pstr_t *, const char *); /* add a pstring to a pstring */ int pstr_addpstring(pstr_t *, const pstr_t *); /* print a pstring */ void pstr_print(pstr_t *); sendfile-2.1b/src/address.c0000640000175100001440000005601310251136250015407 0ustar framstagusers/* * File: address.c * * Author: Ulli Horlacher (framstag@rus.uni-stuttgart.de) * * Contrib.: Stefan Zehl (sec@42.org) * * History: * * 1995-08-12 Framstag initial version * 1995-11-07 Framstag added URL addressing * 1995-11-15 Framstag added sendfile alias file * 1995-12-13 Framstag correct bug when reading alias file * 1996-04-30 Framstag checking elm alias only if configured * 1997-01-04 Framstag renamed from destination.c to address.c * added check_forward() * 1997-01-22 Framstag added connect-test to generic saft address * 1997-02-23 Framstag modified str_* function names * 1997-02-24 Framstag sprintf() -> snprintf() * 1997-03-18 Framstag better URL parsing * 1997-11-22 Framstag added saft2rfc822() * better SAFT URL parsing in check_forward() * 1997-11-27 Framstag accept also saft.domain/user pseudo URLs * (idea by Eumel, thanx!) * 1998-01-04 Framstag fixed bug in saft2rfc822() * 1998-01-13 Sec look for generic saft.domain address * 1998-01-17 Framstag check SAFT-URL for alternative tcp port * 1998-01-20 Framstag check_forward() works now better with sendfiled * 1998-01-25 Framstag better check_forward() * (accept user name without host) * 1998-03-07 Framstag added finger_saft_port() * 1998-03-11 Framstag aliases is now in $HOME/.sendfile/ * 1998-07-11 Framstag aliases may have an entry for CLI arguments * 1998-08-26 Framstag allow port names, too (framstag@bofh:saft) * 1998-12-13 Framstag fixed port determination bug * 1999-08-07 Framstag fixed redirect message collecting bug * "forward address found" is now a Info * 2005-06-06 Maide added multiprotocol cababilities * 2005-06-06 Maide replaced numeric ports with service string * 2005-06-06 Maide made finger_saft_port return port or service * string instead of numeric port value * 2005-06-06 Maide added out of memory error message * * Various address routines for sendfile.c and sendmsg.c * * Copyright © 1995-1999 Ulli Horlacher * This file is covered by the GNU General Public License */ #include "config.h" /* various #defines */ #include #include #include #include #include #include #include #include #include #include #include "string.h" /* Extended string functions */ #include "io.h" /* misc IO routines */ #include "net.h" /* the network routines */ #include "utf7.h" /* UTF-7 coding */ #include "message.h" /* information, warning and error messages */ #include "address.h" /* address routines */ #if defined(SOLARIS2) int gethostname(char *, int); #endif #if defined(LINUX) int gethostname(char *, size_t); int symlink(const char *, const char *); #endif /* check an alias file */ int check_alias(char *, char *, char *, char *); /* test if there is a forward address set */ int check_forward(int, char *, char *, char *); /* finger user@host and look for user SAFT port */ #ifndef ENABLE_MULTIPROTOCOL int finger_saft_port(char *, char *); #else char* finger_saft_port(char *, char *); #endif extern int client, /* flag to determine client or server */ verbose, /* flag for verbose mode */ quiet; /* quiet mode flag */ extern char *prg; /* name of the game */ /* * destination - get recipient user and host * * INPUT: argc - shell argument count * argv - the shell arguments * * OUTPUT: user - own user login and real name * recipient - recipient user name * host - recipient host name * aopt - alias options */ void destination(int argc, char **argv, char *user, char *recipient, char *host, char *aopt) { char *cp, /* simple char pointer */ *at, /* @ character in recepient@host */ *larg, /* last argument */ gecos[FLEN], /* user real name */ tmp[MAXLEN], /* tmp string */ line[MAXLEN], /* one text line */ localhost[FLEN], /* name of the local host */ userconfig[MAXLEN], /* user configuration directory */ aliasfile[MAXLEN]; /* the alias file */ FILE *inf; /* input file */ struct passwd *pwe; /* password entry */ struct stat finfo; /* file information */ /* get the own user name */ if ((pwe=getpwuid(getuid())) == NULL) message(prg,'F',"could not determine own user name"); /* translate the real name to UTF-7 and add it */ iso2utf(gecos,pwe->pw_gecos); if ((cp=strchr(gecos,','))) *cp=0; snprintf(user,FLEN-1,"%s %s",pwe->pw_name,gecos); /* check user configuration directory */ snprintf(MAXS(userconfig),"%s/.sendfile",pwe->pw_dir); snprintf(MAXS(tmp),SPOOL"/%s/config",pwe->pw_name); if (stat(userconfig,&finfo)<0 && stat(tmp,&finfo)==0) symlink(tmp,userconfig); /* trick: argc == 0, when message reply mode */ if (argc==0) { if (gethostname(localhost,FLEN-1)<0) strcpy(localhost,"localhost"); snprintf(MAXS(tmp),"%s/msg@%s",userconfig,localhost); if ((inf=rfopen(tmp,"r")) && fgetl(line,inf)) { if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strchr(line,'@'))) { *cp=0; snprintf(host,FLEN-1,"%s",cp+1); } snprintf(recipient,FLEN-1,"%s",line); } fclose(inf); return; } /* trick: argc < 0, when called from quak */ if (argc<0) larg=argv[-argc]; else larg=argv[argc-1]; *host=0; /* user@host specified? */ if ((at=strchr(larg,'@'))) { /* store recipient name and host */ *recipient=0; strncat(recipient,larg,at-larg); strcpy(host,at+1); /* SAFT-URL specified? */ } else if (str_neq_nocase(larg,"saft",4) && strchr(larg,'/')) { if (str_neq_nocase(larg,"saft://",7)) larg+=7; cp=strrchr(larg,'/'); if (!cp || strchr(larg,'@')) message(prg,'F',"illegal SAFT-URL"); strcpy(recipient,cp+1); *cp=0; while ((cp=strchr(larg,'/'))) *cp='.'; strcpy(host,larg); /* local user or alias specified */ } else { strcpy(recipient,larg); /* check the sendfile alias file */ snprintf(MAXS(aliasfile),"%s/aliases",userconfig); if (check_alias(aliasfile,recipient,host,aopt)<0) { #ifdef RESPECT_MAIL_ALIASES /* check the elm alias file */ snprintf(MAXS(aliasfile),"%s/.elm/aliases.text",pwe->pw_dir); if (check_alias(aliasfile,recipient,host,aopt)<0) { #endif /* store local recipient name and local host */ /* trick: argc <= 0, when called from quak */ if (argc<=0) strcpy(recipient,argv[-argc]); else strcpy(recipient,argv[argc-1]); strcpy(host,"127.0.0.1"); #ifdef RESPECT_MAIL_ALIASES } #endif } } /*if (!*port) *port=SAFT;*/ } /* * check_alias - check an alias file * * INPUT: aliasfile - the alias file * recipient - recipient alias name * * OUTPUT: recipient - recipient user name * host - recipient host name * aopt - alias options */ int check_alias(char *aliasfile, char *recipient, char *host, char *aopt) { char *cp, /* a character pointer */ line[MAXLEN], /* one line of the alias file */ address[MAXLEN]; /* address from the alias */ FILE *inf; /* input file to read */ /* if there is an alias file, open it (what else? :-) ) */ inf=rfopen(aliasfile,"r"); if (inf==NULL) return(-1); *address=0; if (aopt) *aopt=0; /* loop over all lines */ while (fgetl(line,inf)) { /* trim line */ if ((cp=strchr(line,'\n'))) *cp=0; if ((cp=strchr(line,'#'))) *cp=0; str_trim(line); if (!*line) continue; /* save the address and options */ cp=strchr(line,' '); if (cp) *cp=0; else continue; strcpy(address,cp+1); if ((cp=strchr(address,' '))) { *cp=0; if (aopt) snprintf(aopt,FLEN-1,"%s",cp+1); } /* is it the correct alias, we are ready */ if (str_eq(recipient,line)) break; *address=0; if (aopt) *aopt=0; } fclose(inf); /* alias found? */ if (*address) { /* convert SAFT to mail address */ if (str_beq_nocase(address,"saft://")) saft2rfc822(address); /* store recipient name and host */ cp=strchr(address,'@'); if (cp) { *cp=0; strcpy(host,cp+1); } else strcpy(host,"0"); strcpy(recipient,address); return(0); } return(-1); } /* * check_forward - test if there is a forward address set * * INPUT: sockfd - socket file descriptor * recipient - recipient user name * host - host to connect * redirect - redirect comment * * OUTPUT: recipient - new recipient user name * host - new host to connect * redirect - new redirect comment * * RETURN: 1 if a forward is set, 0 if not, -1 on error */ int check_forward(int sockfd, char *recipient, char *host, char *redirect) { char *cp,*at, /* simple string pointer */ *adr, /* address in forwarding reply string */ *reply, /* reply string from server */ tmp[MAXLEN]; /* temporary string */ /* get reply from server */ reply=getreply(sockfd); str_trim(reply); /* forward address set? */ if (str_beq(reply,"510 ")) { adr=strrchr(reply,' ')+1; /* convert SAFT to mail address */ if (str_beq_nocase(adr,"saft://")) saft2rfc822(adr); if (quiet<2) message(prg,'I',"forward address found"); if (*redirect) { strcpy(tmp,redirect); snprintf(redirect,MAXLEN-1,"%s\r\nredirected by %s@%s", tmp,recipient,host); } else { snprintf(redirect,MAXLEN-1,"redirected by %s@%s",recipient,host); } /* save new recipient and host name */ if ((at=strchr(adr,'@'))) { *at=0; strcpy(host,at+1); } strcpy(recipient,adr); return(1); } /* illegal answer */ if (!str_beq(reply,"200 ")) { snprintf(MAXS(tmp),"server error: %s",reply+4); errno=0; if (client) message(prg,'F',tmp); strcpy(redirect,reply+4); if ((cp=strrchr(redirect,'.'))) *cp=0; return(-1); } return(0); } #ifndef ENABLE_MULTIPROTOCOL /* * saft_connect - look for correct SAFT server and open connection * * INPUT: type - file or message * recipient - recipient user name * user - local user name * host - host to connect * redirect - redirect comment * * OUTPUT: recipient - new recipient user name * host - new host to connect * redirect - redirect comment * * RETURN: socket file descriptor; -1 on error */ int saft_connect(const char *type, char *recipient, char *user, char *host, char *redirect) { int port, /* tcp port to connect */ sockfd, /* socket file descriptor */ hopcount; /* count for forwarding addresses */ char *cp, /* simple character pointer */ answer[FLEN], /* answer string */ tmp[MAXLEN], /* temporary string */ ahost[MAXLEN], /* alternate host */ line[MAXLEN]; /* one line of text */ extern int client; /* flag to determine client or server mode */ struct servent *sinfo;/* service info */ port=SAFT; hopcount=0; *answer=0; /* get port number */ if ((cp=strchr(host,':'))) { cp++; if (*cp>'9') { if ((sinfo=getservbyname(cp,"tcp"))) port=ntohs(sinfo->s_port); } else port=atoi(cp); } /* try to connect to the recipient's server */ for (hopcount=1; hopcount<11; hopcount++) { /* if the finger-port is specified get real port from there */ if (port==79 || !port) { if ((cp=strchr(host,':'))) *cp=0; snprintf(MAXS(tmp),"opening connection to finger://%s/%s",host,recipient); if (quiet<2) message(prg,'I',tmp); port=finger_saft_port(recipient,host); if (port<1) { errno=0; message(prg,'F',"no SAFT port information"); } snprintf(tmp,FLEN-1,"%s:%d",host,port); strcpy(host,tmp); } /* initiate the SAFT-connection to the server */ snprintf(MAXS(tmp),"opening connection to saft://%s/%s",host,recipient); if (quiet<2) message(prg,'I',tmp); sockfd=open_connection(host,port); if (port==SAFT) { /* host has no ip-address, but we can try more ... */ if (sockfd==-3 && str_eq(type,"file")) { if (client) { snprintf(MAXS(tmp),"%s has no internet-address",host); if (quiet<2) message(prg,'W',tmp); } /* try generic saft-address for this host/domain */ if (port==SAFT) { snprintf(MAXS(ahost),"saft.%s",host); if (client) { if(gethostbyname(ahost)){ if (!quiet) { printf("try sending to %s@%s ? ",recipient,ahost); fgetl(answer,stdin); } else *answer='y'; } else *answer='n'; } if (tolower(*answer)!='n' || !client) { strcpy(host,ahost); if (client) { snprintf(MAXS(tmp),"opening connection to %s@%s",recipient,host); if (quiet<2) message(prg,'I',tmp); } sockfd=open_connection(host,port); } } } /* try user SAFT port on connection failure */ if (sockfd==-2 && str_eq(type,"file")) { if (verbose) { snprintf(MAXS(tmp),"cannot connect to SAFT port %d on %s", port,host); message(prg,'E',tmp); } port=finger_saft_port(recipient,host); if (port>0 && port!=SAFT) { snprintf(MAXS(tmp),"%s has no system SAFT server, " "trying user SAFT server on port %d",host,port); if (quiet<2) message(prg,'W',tmp); sockfd=open_connection(host,port); } else port=SAFT; } } if (sockfd==-1) snprintf(MAXS(tmp),"cannot create a network socket"); if (sockfd==-2) snprintf(MAXS(tmp),"cannot open connection to %s",host); if (sockfd==-3) snprintf(MAXS(tmp),"%s is unknown",host); if (sockfd<0) { if (client) { errno=0; message(prg,'F',tmp); } else return(-1); } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { snprintf(MAXS(tmp),"No SAFT server on port %d at %s",port,host); if ((cp=strrchr(tmp,':'))) *cp=0; if (client) { errno=0; message(prg,'F',tmp); } else { strcpy(redirect,tmp); return(-1); } } /* send constant header lines */ snprintf(MAXS(tmp),"FROM %s",user); sendheader(sockfd,tmp); snprintf(MAXS(tmp),"TO %s",recipient); sock_putline(sockfd,tmp); /* is there a forward set? */ if (check_forward(sockfd,recipient,host,redirect)) { /* close current connection */ sock_putline(sockfd,"QUIT"); getreply(sockfd); shutdown(sockfd,2); continue; } /* sendfile connection? */ if (str_eq(type,"file")) { if (verbose) message(prg,'I',"testing remote server"); /* test if server can receive files */ sock_putline(sockfd,"FILE test"); if (check_forward(sockfd,recipient,host,redirect)) { /* close current connection */ sock_putline(sockfd,"QUIT"); getreply(sockfd); shutdown(sockfd,2); continue; } } /* connection is successfull */ break; } if (hopcount>10) { strcpy(tmp,"maximum hopcount reached (forward loop?)"); if (client) { errno=0; message(prg,'F',tmp); } else { strcpy(redirect,tmp); return(-1); } } return(sockfd); } /* * finger_saft_port - finger user@host and look for user SAFT port * * INPUT: user - user login name * * OUTPUT: host - host to connect * * RETURN: user saft port on success, -1 on failure */ int finger_saft_port(char *user, char *host) { int port, /* user SAFT tcp port */ sockfd; /* socket file descriptor */ char *cp, /* character pointer */ line[MAXLEN]; /* one line of text */ port=-1; *line=0; /* connect to the finger port of the remote host */ sockfd=open_connection(host,79); if (sockfd>0) { sock_putline(sockfd,user); while (sock_getline(sockfd,line)>=0) { str_trim(line); if (str_beq_nocase(line,"saftport") && (cp=strchr(line,'='))) { port=atoi(cp+1); break; } } shutdown(sockfd,2); } return(port); } #else /* ENABLE_MULTIPROTOCOL */ /* * saft_connect - look for correct SAFT server and open connection * * INPUT: type - file or message * recipient - recipient user name * user - local user name * host - host to connect * redirect - redirect comment * * OUTPUT: recipient - new recipient user name * host - new host to connect * redirect - redirect comment * * RETURN: socket file descriptor; -1 on error */ int saft_connect(const char *type, char *recipient, char *user, char *host, char *redirect) { int sockfd, /* socket file descriptor */ hopcount; /* count for forwarding addresses */ char* service = NULL; /* service or port to connect to */ int needsFree = 0; /* do we need to call free(service)? */ char *cp, /* simple character pointer */ answer[FLEN], /* answer string */ tmp[MAXLEN], /* temporary string */ ahost[MAXLEN], /* alternate host */ line[MAXLEN]; /* one line of text */ extern int client; /* flag to determine client or server mode */ service=SERVICE; hopcount=0; *answer=0; /* get port number */ if (*host == '[') { if ((cp=strchr(host,']'))) { cp++; if (*cp == ':') { cp++; service = cp; } } } else { if ((cp=strchr(host,':'))) { cp++; service = cp; } } /* try to connect to the recipient's server */ for (hopcount=1; hopcount<11; hopcount++) { /* if the finger-port is specified get real port from there */ if (strcasecmp(service, "finger") == 0 || strcmp(service, "79") == 0) { if (*host == '[') { if ((cp=strchr(host,']'))) { cp++; if (*cp == ':') { *cp=0; } } } else { if ((cp=strchr(host,':'))) *cp=0; } snprintf(MAXS(tmp),"opening connection to finger://%s/%s",host,recipient); if (quiet<2) message(prg,'I',tmp); service=finger_saft_port(recipient,host); if (service==NULL) { errno=0; message(prg,'F',"no SAFT port information"); } else needsFree = 1; snprintf(tmp,FLEN-1,"%s:%s",host,service); strcpy(host,tmp); } /* initiate the SAFT-connection to the server */ snprintf(MAXS(tmp),"opening connection to saft://%s/%s",host,recipient); if (quiet<2) message(prg,'I',tmp); sockfd=open_connection(host,service); if (strcasecmp(service, SERVICE) == 0 || strcmp(service, PORT_STRING) == 0) { /* host has no ip-address, but we can try more ... */ if (sockfd==-3 && str_eq(type,"file")) { if (client) { snprintf(MAXS(tmp),"%s has no internet-address",host); if (quiet<2) message(prg,'W',tmp); } /* try generic saft-address for this host/domain */ if (strcasecmp(service, SERVICE) == 0 || strcmp(service, PORT_STRING) == 0) { snprintf(MAXS(ahost),"saft.%s",host); if (client) { if(gethostbyname2(ahost, addressFamily)){ if (!quiet) { printf("try sending to %s@%s ? ",recipient,ahost); fgetl(answer,stdin); } else *answer='y'; } else *answer='n'; } if (tolower(*answer)!='n' || !client) { strcpy(host,ahost); if (client) { snprintf(MAXS(tmp),"opening connection to %s@%s",recipient,host); if (quiet<2) message(prg,'I',tmp); } sockfd=open_connection(host,service); } } } /* try user SAFT port on connection failure */ if (sockfd==-2 && str_eq(type,"file")) { if (verbose) { snprintf(MAXS(tmp),"cannot connect to SAFT port %s on %s", service,host); message(prg,'E',tmp); } service=finger_saft_port(recipient,host); if (service != NULL) needsFree = 1; if (service != NULL && strcasecmp(service, SERVICE) != 0 && strcmp(service, PORT_STRING) != 0) { snprintf(MAXS(tmp),"%s has no system SAFT server, " "trying user SAFT server on port %s",host,service); if (quiet<2) message(prg,'W',tmp); sockfd=open_connection(host,service); } else service=SERVICE; needsFree = 0; } } if (sockfd==-1) snprintf(MAXS(tmp),"cannot create a network socket"); if (sockfd==-2) snprintf(MAXS(tmp),"cannot open connection to %s",host); if (sockfd==-3) snprintf(MAXS(tmp),"%s is unknown",host); if (sockfd==-4) snprintf(MAXS(tmp),"out of memory"); if (sockfd<0) { if (client) { errno=0; message(prg,'F',tmp); } else { if (needsFree) free(service); return(-1); } } /* no remote server or protocol error? */ sock_getline(sockfd,line); if (!str_beq(line,"220 ") || !strstr(line,"SAFT")) { snprintf(MAXS(tmp),"No SAFT server on port %s at %s",service,host); if ((cp=strrchr(tmp,':'))) *cp=0; if (client) { errno=0; message(prg,'F',tmp); } else { strcpy(redirect,tmp); if (needsFree) free(service); return(-1); } } /* send constant header lines */ snprintf(MAXS(tmp),"FROM %s",user); sendheader(sockfd,tmp); snprintf(MAXS(tmp),"TO %s",recipient); sock_putline(sockfd,tmp); /* is there a forward set? */ if (check_forward(sockfd,recipient,host,redirect)) { /* close current connection */ sock_putline(sockfd,"QUIT"); getreply(sockfd); shutdown(sockfd,2); continue; } /* sendfile connection? */ if (str_eq(type,"file")) { if (verbose) message(prg,'I',"testing remote server"); /* test if server can receive files */ sock_putline(sockfd,"FILE test"); if (check_forward(sockfd,recipient,host,redirect)) { /* close current connection */ sock_putline(sockfd,"QUIT"); getreply(sockfd); shutdown(sockfd,2); continue; } } /* connection is successfull */ break; } if (hopcount>10) { strcpy(tmp,"maximum hopcount reached (forward loop?)"); if (client) { errno=0; message(prg,'F',tmp); } else { strcpy(redirect,tmp); if (needsFree) free(service); return(-1); } } if (needsFree) free(service); return(sockfd); } /* * finger_saft_port - finger user@host and look for user SAFT port * * INPUT: user - user login name * * OUTPUT: host - host to connect * * RETURN: user saft port on success, -1 on failure */ char* finger_saft_port(char *user, char *host) { int sockfd; /* socket file descriptor */ char *cp, /* character pointer */ *port, /* user SAFT tcp port */ line[MAXLEN]; /* one line of text */ port=NULL; *line=0; /* connect to the finger port of the remote host */ sockfd=open_connection(host,"finger"); if (sockfd>0) { sock_putline(sockfd,user); while (sock_getline(sockfd,line)>=0) { str_trim(line); if (str_beq_nocase(line,"saftport") && (cp=strchr(line,'='))) { port=strdup(cp+1); break; } } shutdown(sockfd,2); } return(port); } #endif /* ENABLE_MULTIPROTOCOL */ /* * saft2rfc822 - SAFT URL to RFC822 mail address translation * * INPUT: adr - SAFT URL * * OUTPUT: adr - SAFT address in RFC822 format * * RETURN: 0 on success, -1 on failure */ int saft2rfc822(char *adr) { char *cp, /* simple char pointer */ *user, /* user name */ host[MAXLEN]; /* host name */ if (!str_beq_nocase(adr,"saft://")) return(-1); strcpy(host,adr+7); cp=strchr(host,'/'); if (!cp) return(-1); *cp=0; user=cp+1; sprintf(adr,"%s@%s",user,host); return(0); }