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 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.