Diese 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 <SYSTEM>
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:

<empfangsname> <username> | <programm>

<username> muß ein lokaler Username sein. <programm> 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=|<programm>" 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 <stesch@parsec.inka.de>

---------------------------------------------------------------------------

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 <stesch@parsec.inka.de>


---------------------------------------------------------------------------

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.

