HERE;
}
/*
* Übersicht über POST-Parameter, die entgegen genommen werden:
*'data-src' = file|input|font
-> file => 'data-file' (dateiupload)
-> form => 'data-form' = hex[0]|oct|bin|dec
'data-input' = auf Länge checken und format
-> font => 'data-text' = auf gute Zeichen checken ([a-zA-Z0-9 ])
*'format' = PNG|SVG
*'dimension-src' = width|height|diameter
-> width => dimension-width
-> height => dimension-height jeweils auf int checken
-> diameter => dimension-diameter
*'alignment' => hor-[rtl|ltr]-[l|r] | ver-[btt|ttb]-[u|o]
komponenten = imagebg|tapebg|punched|notpunched|feedholes
*'show-'+[komponenten] (nur toggle an/aus)
*'color-'+[komponenten] => #RRGGBB
*'lucency-'+[komponenten] => AA
*'empty-start', 'empty-end' => int
*/
if(empty($_POST)) {
// so einfach ist das.
print '
Parameter fehlen
';
exit; // ;)
}
function get($var) {
// kleine Helperfunktion
return isset($_POST[$var]) ? $_POST[$var] : false;
}
function my_ctype_digit($string) {
// meine Implementierung dieser netten Funkion
return preg_match('/^[0-9]+$/', $string);
}
// Sofort tötende Fehler. Anzuwenden bei brutalen Fehlern, die nicht
// auf Fehleingabe im Formular berufen (Angriffsgefahr)
function print_fatal($text) {
print "
Falsche Benutzung!
\n";
print '
'.$text."
\n";
print "
Dieser Fehler wäre nicht aufgetreten, hätten sie das Formular benutzt.
";
exit;
}
// das große Fehlerarray.
$errors = array();
// das nicht-tödliche Warnungsarray
$warnings = array();
// mit allen Fehlern beenden
function exit_errors() {
global $ajax,$errors,$warnings;
print "
Fehler in den angegeben Daten
";
foreach($warnings as $error) {
print '
'.$error."
\n";
}
foreach($errors as $error) {
print '
'.$error."
\n";
}
if($ajax) {
print "
Gehen sie zurück zum Formular und korrigieren sie ihre Fehleingaben.
Klicken sie dann nochmals auf Generieren.
';
}
exit;
}
// Schritt 0: Ausgabeverzeichnis pruefen
if(!file_exists($output_dir)) {
if(is_writeable($output_dir)) {
mkdir($output_dir);
} else
$errors[] = "Ausgabeverzeichnis $output_dir nicht anlegbar!";
}
// Schritt 1: Eingaben entgegennehmen und validieren
// 1/6: Punch-Daten
$input_source = get('data-src');
switch($input_source) {
case 'file': // Dateiupload. Tja. Datei direkt dem Programm übergeben. Vorher
// Größe checken. Also mal los:
if($ajax) {
// wenn Ajax benutzt wird, wird die Datei noch nicht hochgeladen.
break; // also erst anschließend machbar.
}
if(!isset($_FILES['data-file'])) {
$errors[] = "Keine Datei hochgeladen, obwohl Dateiupload als Datenquelle ausgewählt war!";
} elseif($_FILES['data-file']['size'] > 500*1024) {
$errors[] = "Die hochgeladene Datei ist größer als ein 500kb. Derart große
Lochstreifen sind aus Perfomancegründen nicht erlaubt. Laden sie
sich das Visualisierungsprogramm runter und erstellen sie lokal
ihre Mammutlochstreifen.";
} elseif($_FILES['data-file']['size'] == 0) {
$warnings[] = "Die hochgeladene Datei ist leer (0 Bytes Inhalt). Das gibt keinen sonderlich
spannenden Lochstreifen...";
}
$original_filename = $_FILES['data-file']['name']; // fuer den Report weiter unten
$input_filename = $_FILES['data-file']['tmp_name'];
// usw.
break;
case 'input': // Daten direkt eingetippt. Na dann...
$text = get('data-input');
$form = get('data-form');
$input_binary = '';
$parts = preg_split("/\s+|\n+/", $text);
foreach($parts as $x => $byte) {
if(!strlen($byte)) continue; // nur whitespace, Abfall durch das preg_split.
// Alle Formen zu dezimal umwandeln.
if($form == 'bin')
$byte = bindec($byte);
elseif($form == 'hex')
$byte = hexdec($byte);
elseif($form == 'oct')
$byte = octdec($byte);
elseif($form == 'hex0')
$byte = hexdec(substr($byte,2)); // 0x wegschneiden.
elseif($form != 'dec') {
$errors[] = "Fehler: Ungültige Datenform $form!";
break;
}
if(!is_numeric($byte)) {
$errors[] = "Fehler: Byte $x mit dem Wert $byte ist keine entsprechende
Zahl des Types $form. Vielleicht haben sie nicht das
passende Format eingestellt, in dem sie ihre Daten eingegeben haben?";
break;
}
$input_binary .= chr($byte); // <- the PHP way | the Perl way -> pack('C', $byte);
} // foreach
if(strlen($input_binary) > 1024*1024) {
$errors[] = 'Sie haben über eine Millionen Bytes eingetippt! Derart große
Lochstreifen sind aus Perfomancegründen nicht erlaubt. Laden sie
sich das Visualisieurngsprogramm runter und erstellen sie ihren
Monsterstreifen lokal.';
break;
} elseif(strlen($input_binary) == 0) {
$errors[] = 'Sie haben keine Daten eingegeben, obwohl direkte Byteeingabe als
Datenquelle ausgewählt wurde!';
break;
}
// so, jetzt liegts als $input_binary vor.
break;
case 'font': // Text, der gepuncht werden soll
$text = get('data-text');
if(!preg_match('/^[a-zA-Z0-9 ]+$/', $text)) {
$warnings[] = 'Im Text befinden sich nichtdruckbare Zeichen. Nur Buchstaben und Zahlen
können dargestellt werden, keine anderen Zeichen.';
}
if(strlen($text) == 0) {
$errors[] = 'Sie haben keinen Text eingegeben, obwohl Textgenerierung als Datenquelle
ausgewählt wurde!';
}
if(strlen($text) > 1000) {
$errors[] = 'Der Text ist mit über 1000 Zeichen eindeutig zu lang.
Aus Perfomancegründen ist das nicht erlaubt. Laden sie sich die
entsprechenden Programme runter und erstellen sie ihren Streifen lokal.';
}
// irgendwas mit dem Text machen.
// und als $input_binary fertig machen.
$file_generator = proc_open($font_generator_program, array(
// descriptor array (0=stdin, 1=stdout, 2=stderr, like sh)
0 => array('pipe', 'r'), // Programm wird von STDIN lesen
1 => array('pipe', 'w'), // und zu STDOUT schreiben
2 => array('pipe', 'w'), // und zu STDERR auch schreiben
), $font_pipes, NULL , NULL );
if(is_resource($file_generator)) {
fwrite($font_pipes[0], $text);
fclose($font_pipes[0]); // nichts mehr zu schreiben
$input_binary = stream_get_contents($font_pipes[1]);
//$stderr = stream_get_contents($pipes[2]);
proc_close($file_generator);
} else
$input_binary = "funktionierte nicht :("; // hier was sinnhafteres
break;
default: $errors[] = "Ungültige Datenquelle! Es konnten keine Daten entgegengenommen werden!";
}
// 2/6: Formatfragen.
$format = strtolower(get('format'));
if($format != 'png' && $format != 'svg') {
$errors[] = "Ungültiges Ausgabeformat $format! Erlaubt sind nur PNG und SVG!";
}
// 3/6: Dimensionen
$dsrc = get('dimension-src');
if($dsrc == 'width' || $dsrc == 'height' || $dsrc == 'diameter') {
$size = get("dimension-$dsrc");
if(!my_ctype_digit($size)) {
$errors[] = "Die Größenangabe zu den Dimensionen, die der Lochstreifen annehmen soll,
ist fehlerhaft: $size ist keine positive ganze Dezimazahl!";
} elseif($dsrc == 'diameter' && $size > 100) {
$errors[] = "Der Durchmesser eines Loches ist mit 100 pxieln zu groß, ein so großes Bild
darf aus Perfomancegründen nicht generiert werden. Bitte kleineren Wert
einstellen.";
} elseif($size > 1000*100) {
$errors[] = "Die Größenangabe von über 100.000 Pixel ist viel zu groß. Bitte kleineren Wert
einstellen.";
}
// alles klar. $size und $dsrc
} else
$errors[] = "Es wurde keine Größenangabe zum Lochstreifen gemacht!";
// 4/6: Ausrichtung des Lochstreifens
$alignment = get('alignment');
if(preg_match('/^(hor)-(rtl|ltr)-([ou])$|^(ver)-(btt|ttb)-([lr])$/', $alignment, $m)) {
// so, jetzt mal zusammenpuzzeln...
// $m[0] == hor | ver
// $m[1] == rtl | ltr | btt | ttb
// $m[2] == u | o | l | r
// Problem: In CLI ist es auch nicht vollstaendig implementiert... -.-
} else
$errors[] = "Ungültige Ausrichtung des Lochstreifens: $alignment war nicht in der Auswahl!";
// 5/6: Den ganzen komponentenweiten Kram
$comp = array('imagebg', 'tapebg', 'punched', 'notpunched', 'feedholes');
$comp_visibility = array(); $comp_color = array();
$comp_translation = array('Bildhintergrund', 'Lochstreifen', 'Löcher', 'Nicht-Löcher', 'Führungslöcher');
foreach($comp as $x => $component) {
$comp_visibility[$x] = get("show-$component") ? 1 : 0;
$color = substr(get("color-$component"), 1); // das "#" wegstrippen
$lucency = get("lucency-$component");
if(!preg_match('/^[0-9a-fA-F]{6}$/', $color)) {
$errors[] = "Die Farbangabe $color für den Komponenten $component ist keine korrekte Hexadezimalfarbangabe.";
continue;
} elseif(!preg_match('/^[0-9a-fA-F]{2}$/', $lucency)) {
$errors[] = "Die Transparenzangabe $lucency für den Komponenten $component ist nicht korrekt.";
continue;
}
$comp_color[$x] = "#${color}${lucency}";
}
// 6/6: Empty-start, Empty-End
$empty_start = get('empty-start');
$empty_end = get('empty-end');
if(!my_ctype_digit($empty_start))
$errors[] = "Die Anzahl leerer Startbytes ist keine positive ganze Zahl ($empty_start)";
if(!my_ctype_digit($empty_end))
$errors[] = "Die Anzahl leerer Endbytes ist keine positive ganze Zahl ($empty_end)";
// fertig.
// Fehler ausgeben und beenden.
if(!empty($errors)) {
exit_errors();
}
// keine Fehler aufgetreten und in Ajax-Mode: "ok" zurückgeben
if($ajax) {
echo "ok";
exit;
}
// Wenn wir hier sind, gehts schon mal weiter.
echo '
Lochstreifengenerator
';
if(!empty($warnings)) {
// es gibt Warnungen...
echo '
Es sind Probleme aufgetaucht, die allerdings nicht wirklich schlimm sind, der
Lochstreifen wurde trotzdem generiert:
";
print "\nReturn Value $return_value\n";
}
// checken ob was gemacht wurde.
if(!is_file($image_filename)) {
print "
Gewünschtes Bild konnte nicht erstellt werden!
";
exit; // dann brauchts auch kein Report und so. Der braucht nämlich die Datei.
}
} else
print '
Konnte Generatorprozess nicht starten!
';
// + Übersichtsseite machen, erst mal in String, und ausgeben.
$dir_url = dirname($_SERVER['PHP_SELF']);
$image_url = "$dir_url/$image_filename";
$report_file = $output_dir.'/'.$output_hash.'.htm';
$report_url = "$dir_url/$report_file";
$filesize = DataSizeFormat(filesize($image_filename));
$report = "
Der folgende Lochstreifen wurde am ".date('m.d.Y')." um ".date('H:i:s')." Uhr von dem
Besucher mit der IP-Adresse $_SERVER[REMOTE_ADDR] generiert. Die erstellte Datei vom
Typ ".strtoupper($format)." ist $filesize groß";
if($format == 'png') {
$imagesize = GetImageSize($image_filename);
$report .= ", sie hat die Ausmaße von $imagesize[0] x $imagesize[1] Pixel.
\n";
$report .= "
Das Bild wurde gespeichert unter der Adresse $image_url
und kann z.B. zur Weiterverwendung runtergeladen werden. Es sieht so aus:
";
} else {
$report .= ".
Das Bild wurde unter der Adresse $image_url gespeichert.
Mit einem modernen Browser (Nicht Internet Explorer) können sie sich die SVG-Datei durch
Anklicken des Linkes anschauen. Laden sie sich (ansonten) die Datei runter und öffnen sie
es mit einem Vektorgrafikprogramm, z.B. mit dem frei erhältlichen Inkscape.
";
}
// Discmailer ;-)
$report .= "
Bitte beachten sie: Die Verfügbarkeit des Bildes auf diesem Server gehört nicht in den
\"Dienstleistungsumfang\" des Generierungsprogramms. Das heißt, dass sie durch Eingeben ihrer
Daten zugestimmt haben, dass diese mit dem Bild nach freiem Ermessen des Administrators gespeichert
werden und willkürlich gelöscht werden können. Es besteht kein Anspruch auf selbst zeitlich
begrenztes Hosting! Wenn sie das Bild im Internet verfügbar machen wollen, können sie es z.B.
auf kostenlosen Bilderhostern hochladen. Suchen sie dazu mit der Suchmaschine ihres Vertrauens
nach so etwas wie z.B. \"image hosting\"
";
$report .= "
Die Daten
";
// Daten als HEX aufbereiten
if($input_source == 'file')
$input_binary = file_get_contents($input_filename);
$report_input_source = array(
'file' => "als eine Datei mit dem Namen $original_filename hochgeladen",
'input' => "$form-kodiert eingetippt",
'font' => "als zu generierende Schrift eingetippt, zugrunde lag der Text $text"
);
$report .= "
Die Daten, die dem generierten Lochstreifen zugrundeliegen, wurden vom Benutzer
$report_input_source[$input_source]. Im folgenden wird ein Hexdump der ".strlen($input_binary)."
Bytes angegeben, mit denen letztendlich der Lochstreifen generiert wurde. Mit geeigneten
Hilfmitteln (z.B. einem Hexeditor) können sie aus den Daten eine Binärdatei erstellen.";
$report .= "
";
for($x=0; $x $c) {
$report .= "
$comp_translation[$x] ($c): ".
($comp_visibility[$x] ? "sichtbar, und zwar mit der Farbe $comp_color[$x] (Format #RRGGBBAA)"
: "nicht sichtbar (deaktiviert)");
}
$report .= "";
$report .= "
Außerdem wurden $empty_start leere Startbytes und $empty_end leere Endbytes eingestellt.
Die eingestellte Rotation des Lochstreifens wird durch das folgende Bild verdeutlicht:
Die Größe des Lochstreifens wurde von der Dimension $dsrc abhängig gemacht und auf
$size eingestellt.
";
$report .= "
Generierung
";
$report .= "
Mit dem Kommandozeilentool führ(t)en folgende Parameter zu der Generierung eines derart
gewünschten Lochstreifens:
$exec_params Durch Eingabe dieser Parameter mit den oben angezeigten Eingabedaten müsste jederzeit
das gleiche Bild reproduzierbar sein.
";
$report .= ""; // debugging...
$report .= "
Das Generieren des Lochstreifens nahm die folgende Zeit in Anspruch:
$stderr
Dabei steht real für die wirklich vergangene Zeit, die der Benutzer warten musste,
bevor er seinen Lochstreifen bekam, user für die tatsächliche Zeit, die das Programm
aktiv war (Abweichungen zu real können dadurch begründet sein, dass der Server noch
andere Sachen gleichzeit machte) und system für die Zeit, in der der Server wirklich
ernsthaft über den Lochstreifen nachgedacht hat ;-)
";
//// REPORT zuende. Jetzt erst mal ausdrucken.
if(!$verbose) echo "fertig
\n"; // als Antwort auf die "wird nun generiert..."-Ausgaben weit oben.
echo "
Mit dem generierten Bild wurde eine Urkunde erstellt, in der alle Parameter, Daten und sonstige
interessante Dinge festgehalten sind. Es folgt nur dessen Inhalt:
";
echo "
"; // ;)
echo $report;
echo "
";
echo "
Diese \"Urkunde\" wurde mit dem Bild zusammen gespeichert. Sie ist unter einer ähnlichen Adresse
wie das Bild erreichbar, und zwar unter $report_url.