#!/usr/bin/perl -T
###########################################################################
#
# jsMarket
#
# Beliebig konfigurierbarer Anzeigenmarkt
#
###########################################################################
# Letzte Änderung:        17. März 2011
# Autor:                  Jürg Sommer <jsommer@cgicorner.ch>
###########################################################################
use strict;
use Time::Local;
use CGI::Carp qw(fatalsToBrowser set_message);
BEGIN {
	sub handle_errors {
		my $msg = shift;
		print <<HTMLtext
		<html><head><title>jsMarket - 500 Interner Server Fehler</title><style>
		body {font-family:Tahoma,Arial,Helvetica,sans-serif; color:#000000; font-size:10pt; background:#FFFFFF;} h1 {font-size:16pt; color:#1155AA;} .red {color:#FF0000; font-weight:bold;} .info { background:#EEEEEE; margin-left: 60px; }
		</style></head><body><h1>HTTP Error 500</h1>
		<span class="red">HTTP Fehler 500 - Interner Serverfehler</span><br />Es ist ein Fehler aufgetreten. Wir werden die St&ouml;rung baldm&ouml;glichst beheben und entschuldigen uns f&uuml;r die Unannehmlichkeit.<br />		Sollte dieses Problem weiterhin auftreten, so bitten wir sie, den Administrator zu kontaktieren.<br /><br />
		<span class="red">HTTP Error 500 - Internal Server Error</span><br />An error occurred when you requested this page. We will work to correct the problem and apologize for the inconvenience.<br />If this problem persists, please contact the administrator<br /><br />
		<span class="red">HTTP Erreur 500 - server erreur</span><br />Une erreur s&acute;est produite dans cette page. Nous chercherons &agrave; r&eacute;gler ce probl&egrave;me le plus vite possible. Veuillez nous excuser pour cette inconv&eacute;nience.<br />Si se probl&egrave;me persiste, contactez le webmaster.
		<br /><br /><br /><br /><div class="info">Additional information:<br /><b>$msg</b></div></body></html>
HTMLtext
	}
	set_message(\&handle_errors);
}


###########################################################################
# Variablen
###########################################################################
my (%FORM, %COOKIE, %DATA, %CONFIG);
my (@cat, %TEXTLENGTH, %NUMFIELDS, %ERROR, %ad, %adSearch, $id, $id2, %images, @TEMPLATE);
my ($tmp, $i, @splitArray, @tmpArray, $status, $fileIO, $count, $count1, $srchString, $sysMsg);
my (%timeZone, $serverTime, $mailDate, $mailDate2, $dmmmmyyyyDate, $dmmmmyyyyDate2, $todayUNIX, $yyyymmddDate);

my $COMPCGIURL="";															# Script-URL und Pfad bestimmen
if ($ENV{"SERVER_PORT"} == 443) {
	$COMPCGIURL="https://";
} else {
	$COMPCGIURL="http://";
}
$COMPCGIURL.=$ENV{'HTTP_HOST'}.$ENV{'SCRIPT_NAME'};

my $version="1.08 BETA";															# interne Versionsnummer
my $lastMod="17. März 2011";											# letztes Änderungsdatum

# Legt die Versandart für Mails fest
# TRUE:  Versand via sendmail
# FALSE: Alle Mails werden als .eml gespeichert (für Debugging)
my $mailVersand="TRUE";

# URL für Online Versions-Check - Weitere Informationen siehe Installations-Anleitung
my $tmplastmod=$lastMod;
$tmplastmod=~ s/\s/%20/g;
my $CheckNewVersionURL="http://www.cgicorner.ch/cgi-bin/vercheck/vercheck.cgi?product=jsmarket&amp;version=$version&amp;lastmod=$tmplastmod";

my $configFile="config.pl";
my $delDebug=0;																	# Löschprotokollierung, DEBUGGING only, sollte nur durch cgicorner.ch aktiviert werden.
&readConfig;																		# Konfiguration einlesen
&readForm;																			# Formular-Daten einlesen
&readDataFile;																	# Daten-Datei einlesen
&createDrawSecCode;															# Funktionen für Secure-Code und Thumbnails

&setTimeZones;
&setMailTime;																		# Zeit für Mail setzen

if ($DATA{"lastRun"} ne $todayUNIX) {						# beim ersten Aufruf des Tages --> alte Inserate löschen
	$DATA{"lastRun"}=$todayUNIX;
	if (&lockFile($CONFIG{"dataFile"})) {
		&saveDataFile;
		unlockFile($CONFIG{"dataFile"});
	}
	if ($delDebug) {															# Löschprotokollierung (Debug only)
		open(DELLOG,">".&secureFilename("del_".time().".log"));
		print DELLOG $COMPCGIURL."\n";
		print DELLOG $mailDate."\n\n";
	}
	#&deleteAndReorderOldAds;
	if ($delDebug) {															# Löschprotokollierung (Debug only)
		close(DELLOG);
	}
	opendir($tmp, ".");														# Temp-Dateien älter 24 Stunden löschen
	while ($i = readdir($tmp)) {
		if ($i =~ m/^tmp_/) {
			if (-M $i > 1) {
				unlink(&secureFilename($i));
			}
		}
	}

}

my $messageID="<$mailDate2.".&makeBoundary(14)."\@$ENV{HTTP_HOST}>";
my $boundary="------------".&makeBoundary(26);


###########################################################################
# ADMIN: Administration
###########################################################################
if ($FORM{"action"} eq "admin") {
	&HTMLbegin;
	print "<h1>Login</h1>\n";
	if ($FORM{"error"} eq "WrongPass") {					# Log-Eintrag wegen falschem Passwort
		print "<span class=\"red\">Login failed! Benutzername und/oder Kennwort falsch<br />Achtung: fehlerhafte Login-Versuche werden protokolliert!</span><br /><br />\n";
		&errorLog("login failed (wrong pass)\nUser: $FORM{user}\nPass: $FORM{pass}\nASID: $FORM{ASID}\nIP:   $ENV{REMOTE_ADDR}");
	} elsif ($FORM{"error"} eq "WrongReferer") {	# Log-Eintrag wegen falschem Referer
		print "<span class=\"red\">Was erwarten Sie jetzt? Ich begl&uuml;ckw&uuml;nsche Sie zu Ihrer Freizeit. Haben Sie nichts besseres zu tun, als hier Versuche zu starten?<br />Wenn Sie diesen Dienst nutzen wollen, so verwenden Sie ihn bitte wie vorgesehen...</span><br /><br />\n";
		&errorLog("login failed (wrong referer)\nUser: $FORM{user}\nPass: $FORM{pass}\nASID: $FORM{ASID}\nIP:   $ENV{REMOTE_ADDR}");
	} elsif ($FORM{"error"} eq "WrongReferer1") {	# Log-Eintrag wegen falschem Referer
		print "<span class=\"red\">Login failed!<br />Es konnte nicht festgestellt werden, von welcher Seite aus der Login erfolgte. Sie m&uuml;ssen in Ihrem Browser/Firewall die Referer-&Uuml;bermittlung aktivieren. Lesen Sie dazu bitte <a href=\"http://www.cgicorner.ch/download/jsstyle-referer.shtml\" target=\"_blank\">cgicorner.ch - unterdr&uuml;ckter Referer</a>.</span><br /><br />\n";
		&errorLog("login failed (wrong referer)\nUser: $FORM{user}\nPass: $FORM{pass}\nASID: $FORM{ASID}\nIP:   $ENV{REMOTE_ADDR}");
	}
	print <<HTMLtext;
	<form action="$COMPCGIURL" method="post">
	<input type="hidden" name="action" value="main" alt="." />
	<input type="hidden" name="frompage" value="login" alt="." />
	<table border="0" cellspacing="0" cellpadding="1">
		<tr>
			<td colspan="5" class="blue">&nbsp;&nbsp;<b>Bitte geben Sie Ihre Benutzerdaten ein</b></td>
		</tr>
		<tr>
			<td rowspan="5" class="greyleft">&nbsp;&nbsp;</td>
			<td class="grey">&nbsp;</td>
			<td class="grey">&nbsp;</td>
			<td class="grey">&nbsp;</td>
			<td class="greyright" rowspan="5">&nbsp;&nbsp;</td>
		</tr>
		<tr>
			<td rowspan="3" class="grey"><img src="$CONFIG{imgDir}$CONFIG{keysImg}" alt=""/></td>
			<td class="grey">Benutzername&nbsp;&nbsp;&nbsp;&nbsp;</td>
			<td class="grey"><input type="text" name="user" class="var160" value="$COOKIE{UserName}" alt="." /></td>
		</tr>
		<tr>
			<td class="grey">Passwort</td>
			<td class="grey"><input type="password" name="pass" class="var160" value="$COOKIE{Password}" alt="." /></td>
		</tr>
		<tr>
			<td class="grey">&nbsp;</td>
			<td class="grey"><input type="submit" value="Anmelden" class="button" alt="." /></td>
		</tr>
		<tr>
			<td class="greybottom" colspan="3">&nbsp;</td>
		</tr>
		</table>
	</form>
HTMLtext
	if (-e "update.cgi") {
		print "<span class=\"red\">Achtung: Die Datei <code>update.cgi</code> befindet sich noch auf dem Server! Mit dieser Datei sind &Auml;nderungen der Konfiguration durch unberechtigte Drittpersonen m&ouml;glich. L&ouml;schen Sie diese Datei aus Sicherheitsgr&uuml;nden von Ihrem Server.</span><br /><br />";
	}
	if (-e "jsdiag.cgi") {
		print "<span class=\"red\">Achtung: Die Datei <code>jsdiag.cgi</code> befindet sich noch auf dem Server! Mit dieser Datei sind &Auml;nderungen der Konfiguration durch unberechtigte Drittpersonen m&ouml;glich. L&ouml;schen Sie diese Datei aus Sicherheitsgr&uuml;nden von Ihrem Server.</span><br /><br />";
	}
	if ($mailVersand eq "FALSE") {
		print "<p class=\"red\">Achtung: \$mailVersand ist auf FALSE gesetzt (Debugging-Mode), es werden keine E-Mails versendet!</p>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# MAIN: Hauptmenü
###########################################################################
if ($FORM{"action"} eq "main") {
	if ($FORM{"frompage"} eq "login") {						# Wenn via Hauptseite --> Passwort checken
		$FORM{"pass1"}=$FORM{"pass"};
		$FORM{"pass"}=crypt($FORM{"pass"},"js".$FORM{"pass"}) if ($FORM{"pass"} ne "");
		if (($FORM{"user"} eq $CONFIG{"user"}) and ($FORM{"pass"} eq $CONFIG{"pass"})) {
			$DATA{"ASID"}=time;												# ASID generieren
			$FORM{"ASID"}=$DATA{"ASID"};
			if (&lockFile($CONFIG{"dataFile"})) {
				&saveDataFile;
				&unlockFile($CONFIG{"dataFile"});
			}
			print "Set-Cookie: UserName=".&jsCrypt($FORM{"user"},"COOKIEcrypt")."; expires=".&mygmtime($serverTime+(86400*30)).";\n";
			print "Set-Cookie: Password=".&jsCrypt($FORM{"pass1"},"COOKIEcrypt")."; expires=".&mygmtime($serverTime+(1800)).";\n";
		} else {
			&forbidden("WrongPass");
		}
		if ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i) {
			&forbidden("WrongReferer1");
		}
	} else {
		if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
			&forbidden("WrongReferer");
		}
	}
	&HTMLbegin;
	$sysMsg="";
	if ($CONFIG{"pass"} eq "") {									# Kein Passwort gesetzt
		$sysMsg="<br /><span class=\"red\"><b>Sicherheitsrisiko: Noch kein Admin-Passwort gesetzt!</b></span>\n";
	}
	print <<HTMLtext;
	<h1>Hauptmen&uuml;</h1>
	<table width="100%" border="0">
		<tr valign="top">
			<td width="250"><a href="$COMPCGIURL?action=logindata&amp;ASID=$FORM{ASID}">Login-Daten &auml;ndern</a></td>
			<td>Benutzername und Passwort f&uuml;r Login in den Administrationsbereich &auml;ndern.$sysMsg</td>
		</tr>
		<tr>
			<td colspan="2">&nbsp;</td>
		</tr>
		<tr valign="top">
			<td width="250"><a href="$COMPCGIURL?action=settings&amp;ASID=$FORM{ASID}">Einstellungen &auml;ndern</a></td>
			<td>Systemeinstellungen und Dateipfade &auml;ndern.</td>
		</tr>
		<tr>
			<td colspan="2">&nbsp;</td>
		</tr>
		<tr valign="top">
			<td width="250"><a href="$COMPCGIURL?action=cat&amp;ASID=$FORM{ASID}">Kategorien</a></td>
			<td>Marktplatz-Kategorien konfigurieren</td>
		</tr>
		<tr>
			<td colspan="2">&nbsp;</td>
		</tr>
		<tr valign="top">
			<td width="250"><a href="$COMPCGIURL?action=adminads&amp;ASID=$FORM{ASID}">Eintr&auml;ge</a></td>
			<td>Eintr&auml;ge ansehen, editieren und l&ouml;schen</td>
		</tr>
		<tr>
			<td colspan="2">&nbsp;</td>
		</tr>
		<tr valign="top">
			<td width="250"><a href="$COMPCGIURL?action=backup&amp;ASID=$FORM{ASID}">Backup</a></td>
			<td>Datendateien sichern</td>
		</tr>
		<tr>
			<td colspan="2">&nbsp;</td>
		</tr>
	</table>
HTMLtext
	&HTMLend;
	exit(0);
}


###########################################################################
# LOGINDATA: Benutzername und Passwort für Login ändern
###########################################################################
if ($FORM{"action"} eq "logindata") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	print "<h1>Login Daten &auml;ndern</h1>\n";
	print "<form action=\"$COMPCGIURL\" method=\"post\">\n";
	print &hiddenField("ASID",  "$FORM{ASID}");
	print &hiddenField("action","logindatasave");
	print "<table border=\"0\">\n";
	print &inputField("Benutzername",              "User",  $CONFIG{"user"},   "", "160var");
	print &inputField("Neues Passwort",            "Pass1", $CONFIG{"X"},      "", "160varpass");
	print &inputField("Neues Passwort (nochmals)", "Pass2", $CONFIG{"X"},      "", "160varpass");
	print &inputField("&nbsp;",                    "",      "Passwort ändern", "", "button");
	print "</table></form>";
	&HTMLend;
	exit(0);
}


###########################################################################
# LOGINDATASAVE: Benutzername und Passwort für Login ändern (speichern)
###########################################################################
if ($FORM{"action"} eq "logindatasave") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	if ($FORM{"Pass1"} eq $FORM{"Pass2"}) {
		$CONFIG{"pass"}="";
		$CONFIG{"pass"}=crypt($FORM{"Pass1"},"js".$FORM{"Pass1"}) if ($FORM{"Pass1"} ne "");
		$CONFIG{"user"}=$FORM{"User"};
		if (&lockFile($configFile)) {
			&saveConfig;
			print "<h1><a href=\"$COMPCGIURL?action=logindata&amp;ASID=$FORM{ASID}\">Login Daten &auml;ndern</a> &gt; Daten gespeichert</h1>";
			print "<p>Die neuen Login-Daten wurden <b>erfolgreich</b> gespeichert.</p>";
			&unlockFile($configFile);
		} else {
			print "<h1><a href=\"$COMPCGIURL?action=logindata&amp;ASID=$FORM{ASID}\">Login Daten &auml;ndern</a> &gt; Daten nicht gespeichert</h1>";
			print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&amp;file=$configFile\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
			print "<p><a href=\"$COMPCGIURL?action=logindata&ASID=$FORM{ASID}\">[ zur&uuml;ck ]</a></p>";
		}
	} else {
		print "<h1><a href=\"$COMPCGIURL?action=logindata&ASID=$FORM{ASID}\">Login Daten &auml;ndern</a> &gt; Daten nicht gespeichert</h1>";
		print "<p>Die neuen Login-Daten wurden <b>nicht</b> gespeichert, da Passwort und Passwortbest&auml;tigung nicht identisch waren.</p>\n";
		print "<p><a href=\"$COMPCGIURL?action=logindata&ASID=$FORM{ASID}\">[ zur&uuml;ck ]</a></p>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# SETTINGS: System Einstellungen
###########################################################################
if ($FORM{"action"} eq "settings") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	print "<h1>System Einstellungen &auml;ndern</h1>\n";
	print "<form action=\"$COMPCGIURL\" method=\"post\">\n";
	print &hiddenField("action",   "settingssave");
	print &hiddenField("ASID",     $FORM{"ASID"});
	print &hiddenField("frompage", "settings");
	print &hiddenField("fromtext", "System Einstellungen &amp;auml;ndern");
	print "<table border=\"0\">\n";
	print &inputField("Pfad zu sendmail",                           "sendmail", $CONFIG{"sendmail"}, "[UNIX-Pfad]",    "300var");
	$tmp=sprintf("%04.4d",$timeZone{"auto"}*100);
	if ($tmp > 0) {
		$tmp="+".$tmp;
	}
	my $timeNames="[auto] ".$timeZone{"T".$tmp};
	my $timeValues="99";
	for ($i=-12;$i<=12;$i++) {										# alle Zeitzonen verarbeiten
		$tmp=sprintf("%04.4d",$i*100);							# Zeitzone als +0300 darstellen
		if ($i >= 0) {
			$tmp="+".$tmp;
		}
		$timeValues.="§§".$i;
		$timeNames.="§§".$timeZone{"T".$tmp};
	}
	print &dropDown("GMT Zeitzone","gmTimeZ",$timeNames,$timeValues,"","var300");
	print &inputField("Korr. Serverzeit gegen&uuml;ber GMT",        "timeZone", $CONFIG{"timeZone"}, "[Stunden]; nur bei Fehlkonfiguration des Servers","300var");
	print &yesNoRadio("Sommerzeit erzwingen",                       "summerTim","Nein§§Ja (nur bei Servern in Zeitzone ohne Sommerzeit)","0§§1","","");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Daten-Datei (tempor&auml;r)",                "dataFile", $CONFIG{"dataFile"}, "[UNIX-Pfad]",    "300var");
	print &inputField("Error-Datei",                                "errorFile",$CONFIG{"errorFile"},"[UNIX-Pfad]",    "300var");
	print &inputField("Copyright",                                  "copyright",$CONFIG{"copyright"},"",               "300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("CSS f&uuml;r Administrationsbereich",        "CSS",      $CONFIG{"CSS"},      "[UNIX-Pfad]","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("allg. Bilderverzeichnis",                    "imgDir",   $CONFIG{"imgDir"},   "[Browser-Path] mit abschliessendem /","300var");
	print &inputField("Administrationslogo",                        "admiLogo", $CONFIG{"admiLogo"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("Trennlinie",                                 "lineGIF",  $CONFIG{"lineGIF"},  "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("zum Hauptmen&uuml; GIF (aktiv)",             "backGifA", $CONFIG{"backGifA"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("zum Hauptmen&uuml; GIF (inaktiv)",           "backGifI", $CONFIG{"backGifI"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("nach oben GIF (aktiv)",                      "topGifA",  $CONFIG{"topGifA"},  "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("nach oben GIF (inaktiv)",                    "topGifI",  $CONFIG{"topGifI"},  "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("nach unten GIF (aktiv)",                     "bottGifA", $CONFIG{"bottGifA"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("nach unten GIF (inaktiv)",                   "bottGifI", $CONFIG{"bottGifI"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("Login-GIF",                                  "loginGIF", $CONFIG{"loginGIF"}, "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("Logout-GIF",                                 "logoutGIF",$CONFIG{"logoutGIF"},"[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("Schl&uuml;ssel (Login)",                     "keysImg",  $CONFIG{"keysImg"},  "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print &inputField("Delete-GIF",                                 "deleImg",  $CONFIG{"deleImg"},  "[Browserpfad], relativ zum allg. Bilderverz.","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Bei neuem Eintrag Mail an",                  "newMail",  $CONFIG{"newMail"},  "leer=kein Mail","300var");
	print &inputField("Template: Admin-Info Mail",                  "admiMail", $CONFIG{"admiMail"}, "[UNIX-Pfad]","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &dropDown("Validierung E-Mail Adresse notwendig","valMail","Nein§§Ja, durch Benutzer§§Ja, durch Administrator§§Ja, durch Benutzer und Administrator","N§§Y§§A§§B","","var300");
	print &inputField("Flood-Sperre (Inserate von selber IP)",      "floodSek", $CONFIG{"floodSek"}, "in Sekunden / 0=keine Flood-Sperre","300var");
	print &yesNoRadio("Flood-Sperre auch f&uuml;r Kontakt/Weiterempf.", "floodMai",   "ja§§nein","Y§§N","","");
	print &yesNoRadio("Nach Inserat erfassen/editieren",            "adDest",   "Inserate&uuml;bersicht§§Inserate-Detail (nur wenn keine Validierung erforderlich, sonst &Uuml;bersicht)","L§§V","","");
	print &inputField("Nicht val. Inserate nach X Tagen l&ouml;schen","nValDel",$CONFIG{"nValDel"},  "0=wie validierte Inserate","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &yesNoRadio("BB-Code in Inseraten erlauben",              "bbCode",   "erlaubt§§verboten","Y§§N","","");
	$tmp="";
	eval {
		require GD;
	};
	if ($@) {
		$tmp=" <span class=\"red\">GD-Modul nicht vorhanden. Option darf nicht aktiviert werden!</span>";
	}
	print &dropDown("Secure-Code (Missbrauchsschutz)","secCode","deaktiviert§§nur Mails (Kontakt und Weiterempfehlen)§§nur bei Inserate-Erfassung§§aktiviert f&uuml;r Mails und Inserate-Erfassung","N§§M§§I§§Y","","var300");
	print &inputField("Secure-Code Hintergrund",                    "secCodeI", $CONFIG{"secCodeI"}, "UNIX-Pfad","300var");
	print &inputField("Secure-Code Hintergrund-Farbe",              "secCodC1", $CONFIG{"secCodC1"}, "Hex-Code \#aabbcc","300var");
	print &inputField("Secure-Code Schrift-Farbe",                  "secCodC2", $CONFIG{"secCodC2"}, "Hex-Code \#aabbcc","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Kategorien-Datei",                           "catFile",  $CONFIG{"catFile"},  "[UNIX-Pfad]","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Marktplatz-Bilder (Upload)",                 "imgUplB",  $CONFIG{"imgUplB"},  "[Browserpfad]","300var");
	print &inputField("Marktplatz-Bilder (Upload)",                 "imgUplU",  $CONFIG{"imgUplU"},  "[UNIX-Pfad]","300var");
	print &yesNoRadio("zu grosse Marktplatz-Bilder",                "imgRSiz",  "ablehnen§§verkleinern (ben&ouml;tigt GD-Modul$tmp)", "N§§Y","","");
	print &inputField("maximale Bildgr&ouml;sse in Bytes",          "imgSize",  $CONFIG{"imgSize"},  "[Bytes] 0=keine Einschr&auml;nkung","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &yesNoRadio("Dateiuploads erlauben",                      "fileUpl",  "ja§§nein", "Y§§N","","");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Template: Validation Mail",                  "valiMail", $CONFIG{"valiMail"}, "[UNIX-Pfad]","300var");
	print &inputField("Template: Contact Mail",                     "contMail", $CONFIG{"contMail"}, "[UNIX-Pfad]","300var");
	print &inputField("Template: Weiterempfehlen Mail",             "recoMail", $CONFIG{"recoMail"}, "[UNIX-Pfad]","300var");
	print &inputField("Template: Passwort Reset Mail",              "pareMail", $CONFIG{"pareMail"}, "[UNIX-Pfad]","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Fehlertext: nicht alle Pflichtfelder",       "errRequ",  $CONFIG{"errRequ"},  "","300var");
	print &inputField("Fehlertext: Text zu lang",                   "errLong",  $CONFIG{"errLong"},  "","300var");
	print &inputField("Fehlertext: fehlerhafte Mailadresse",        "errMail",  $CONFIG{"errMail"},  "","300var");
	print &inputField("Fehlertext: Bild zu gross/kein Bild",        "errImgS",  $CONFIG{"errImgS"},  "","300var");
	print &inputField("Fehlertext: Text in numerischem Feld",       "errText",  $CONFIG{"errText"},  "","300var");
	print &inputField("Fehlertext: ung&uuml;ltige Eingabe",         "errIlle",  $CONFIG{"errIlle"},  "","300var");
	print &inputField("Fehlertext: Datei gesperrt",                 "errFile",  $CONFIG{"errFile"},  "","300var");
	print &inputField("Fehlertext: Flood-Sperre",                   "errFloo",  $CONFIG{"errFloo"},  "","300var");
	print &inputField("Fehlertext: aktuelles Feld ist Pflichtfeld", "errFReq",  $CONFIG{"errFReq"},  "","300var");
	print &inputField("Fehlertext: aktuelles Feld ist numerisch",   "errFNum",  $CONFIG{"errFNum"},  "","300var");
	print &inputField("Fehlertext: aktuelles Feld nur Mail",        "errFMai",  $CONFIG{"errFMai"},  "","300var");
	print &inputField("Fehlertext: aktuelles Feld Text zu lang",    "errFLon",  $CONFIG{"errFLon"},  "","300var");
	print &inputField("Fehlertext: ung&uuml;ltige Eingabe in akt. Feld", "errFIll",  $CONFIG{"errFIll"},  "","300var");
	print &inputField("Fehlertext: aktuelles Feld Bild zu gross",   "errFImg",  $CONFIG{"errFImg"},  "","300var");
	print &inputField("Fehlertext: Secure-Code falsch/fehlerhaft",  "errSCod",  $CONFIG{"errSCod"},  "","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Meldung: Inserat erfasst, aktiv",            "sysAdAc",  $CONFIG{"sysAdAc"},  "","300var");
	print &inputField("Meldung: Inserat erf., Benutzer-Validierung","sysValR",  $CONFIG{"sysValR"},  "","300var");
	print &inputField("Meldung: Inserat erf., Admin-Validierung",   "sysValA",  $CONFIG{"sysValA"},  "","300var");
	print &inputField("Meldung: Inserat erf., Usr+Adm-Validierung", "sysValB",  $CONFIG{"sysValB"},  "","300var");
	print &inputField("Meldung: Mailadresse validiert",             "sysVali",  $CONFIG{"sysVali"},  "","300var");
	print &inputField("Meldung: Mailadresse validiert, Adm.Valid.", "sysVaAR",  $CONFIG{"sysVaAR"},  "","300var");
	print &inputField("Meldung: Inserat nicht gefunden",            "sysValE",  $CONFIG{"sysValE"},  "","300var");
	print &inputField("Meldung: nicht alle Felder (Kontakt)",       "sysCont",  $CONFIG{"sysCont"},  "","300var");
	print &inputField("Meldung: E-Mail versendet (Kontakt)",        "sysCoOK",  $CONFIG{"sysCoOK"},  "","300var");
	print &inputField("Meldung: Inserat gel&ouml;scht",             "sysADel",  $CONFIG{"sysADel"},  "","300var");
	print &inputField("Meldung: Passwort falsch",                   "sysWPas",  $CONFIG{"sysWPas"},  "","300var");
	print &inputField("Meldung: E-Mail Adresse falsch (Passwort)",  "sysMail",  $CONFIG{"sysMail"},  "","300var");
	print &inputField("Meldung: Eingaben falsch (Passwort)",        "sysPare",  $CONFIG{"sysPare"},  "","300var");
	print &inputField("Meldung: Passwort ge&auml;ndert (Passwort)", "sysPass",  $CONFIG{"sysPass"},  "","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("Suche: enth&auml;lt",                        "srchCon",  $CONFIG{"srchCon"},  "","300var");
	print &inputField("Suche: zwischen ... und ...",                "srchBet",  $CONFIG{"srchBet"},  "","300var");
	print "<tr><td colspan=\"2\">&nbsp;</td></tr>\n";
	print &inputField("&nbsp;", "", "Einstellungen speichern", "","300button");
	print "</table>\n</form>\n";
	&HTMLend;
	exit(0);
}


###########################################################################
# SETTINGSSAVE: Einstellungen speichern
###########################################################################
if ($FORM{"action"} eq "settingssave") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	foreach (keys(%FORM)) {
		if (($_ ne "ASID") and ($_ ne "action") and ($_ ne "frompage") and ($_ ne "fromtext")) {
			$CONFIG{$_}=$FORM{$_};
		}
	}
	&HTMLbegin;
	print "<h1><a href=\"$COMPCGIURL?action=$FORM{frompage}&amp;ASID=$FORM{ASID}\">$FORM{fromtext}</a> &gt; Einstellungen speichern</h1>\n";
	if (&lockFile($configFile)) {
		&saveConfig;
		&unlockFile($configFile);
		print "<p>Einstellungen <b>erfolgreich</b> gespeichert.</p>\n";
	} else {
		print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&amp;file=$configFile\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# CAT: Kategorien konfigurieren
###########################################################################
if ($FORM{"action"} eq "cat") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	if ($FORM{"cat"} eq "") {											# keine Kategorie ausgewählt
		print "<h1>Kategorien konfigurieren</h1>";
		if (-e $CONFIG{"catFile"}) {								# Kategorie-Datei existiert
			print "<table width=\"100%\" border=\"0\">";
			open(CAT,&secureFilename($CONFIG{"catFile"})); # vorhandene Kategorien einlesen
			while (<CAT>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				@splitArray=split(/\t/);
				if ($splitArray[1] eq "") {							# keine Links ohne Text
					$splitArray[1]="[unnamed]";
				}
				print "<tr><td><a href=\"$COMPCGIURL?ASID=$FORM{ASID}&amp;action=$FORM{action}&amp;cat=$splitArray[0]\">$splitArray[1]</a></td><td>Link zum Marktplatz: <a href=\"$COMPCGIURL?action=viewcat&amp;cat=$splitArray[0]\" target=\"_blank\">$COMPCGIURL?action=viewcat&amp;cat=$splitArray[0]</a>";
				print "&nbsp;&nbsp;&nbsp;<a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&amp;file=$splitArray[2]\" target=\"_blank\"><span class=\"red\">[ Dateisperre aufheben ]</span></a>" if (-e $splitArray[2].".lock");
				print "</td></tr>\n";
				push @tmpArray, "<option value=\"$splitArray[0]\">$splitArray[1]</option>\n";
			}
			close(CAT);
			print "</table>";
		}
		print "<br /><h2>neue Kategorie hinzuf&uuml;gen:</h2>\n<form action=\"$COMPCGIURL\" method=\"get\">";
		print &hiddenField("ASID",$FORM{"ASID"});
		print &hiddenField("action",$FORM{"action"});
		print "Neue Kategorie basierend auf:<br /><select name=\"based\" class=\"var300\"><option value=\"\" selected>[ leer ]</option>\n";
		foreach (@tmpArray) {
			print "$_";
		}
		print "</select> <input type=\"hidden\" name=\"cat\" value=\"".time()."\"/> <input type=\"submit\" value=\"Kategorie erstellen\" class=\"button\"/></form>";
	} else {																			# Kategorie ausgewählt
		print "<h1><a href=\"$COMPCGIURL?ASID=$FORM{ASID}&amp;action=cat\">Kategorien konfigurieren</a> &gt; Kategorie editieren</h1>";
		if ($FORM{"based"} ne "") {
			&getCat($FORM{"based"});									# neue Kategorie basiert auf bestehender
		} else {
			&getCat($FORM{"cat"});										# Kategoriedaten einlesen
		}
		$cat[24]=zeilenUmbruch($cat[24],"§§",1);
		$cat[25]=zeilenUmbruch($cat[25],"§§",1);
		print "<form action=\"$COMPCGIURL\" method=\"post\">\n";
		print &hiddenField("ASID",$FORM{"ASID"});
		print &hiddenField("action","catsave");
		print &hiddenField("cat",$FORM{"cat"});
		# Kategorie Konfiguration
		print <<HTMLtext;
		<table width="100%" border="0">
		<tr valign="top"><td class="blue200">Name der Kategorie</td><td class="grey"><input type="text" name="catName" value="$cat[1]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Inserate Daten Datei</td><td class="grey"><input type="text" name="insFile" value="$cat[2]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Eintr&auml;ge pro Seite</td><td class="grey"><input type="text" name="entPage" value="$cat[13]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Default Anzeigedauer</td><td class="grey"><input type="text" name="defDays" value="$cat[7]" class="var300"/> in Tagen</td></tr>
		<tr valign="top"><td class="blue200">Maximale Anzeigendauer</td><td class="grey"><input type="text" name="maxDays" value="$cat[6]" class="var300"/> in Tagen (0=unbeschr&auml;nkt)</td></tr>
		<tr valign="top"><td class="blue200">Validierung notwendig</td><td class="grey"><select name="valMail" class="var300"><option value="">[ Standardeinstellung ]</option><option value="N"
HTMLtext
		print " selected" if ($cat[22] eq "N");
		print ">Nein</option><option value=\"Y\"";
		print " selected" if ($cat[22] eq "Y");
		print ">Ja, durch Benutzer</option><option value=\"A\"";
		print " selected" if ($cat[22] eq "A");
		print ">Ja, durch Administrator</option><option value=\"B\"";
		print " selected" if ($cat[22] eq "B");
		print <<HTMLtext;
		>Ja, durch Benutzer und Adminstrator</option></select></td></tr>
		<tr valign="top"><td class="blue200">Mail: Admin-Info Mailadr.</td><td class="grey"><input type="text" name="mailAdmi" value="$cat[20]" class="var300"/> leer=Standard ($CONFIG{"newMail"})</td></tr>
		<tr valign="top"><td class="blue200">sortieren</td><td class="grey"><select name="ordWhen" class="var300"><option value="">nur manuell (Parameter)</option><option value="day"
HTMLtext
		print " selected" if ($cat[29] eq "day");
		print ">einmal pro Tag</option><option value=\"live\"";
		print " selected" if ($cat[29] eq "live");
		print <<HTMLtext;
		>bei jedem Aufruf</option></select></td></tr>
		<tr valign="top"><td class="blue200">Sortiert nach</td><td class="grey"><input type="text" name="ordField" value="$cat[30]" class="var300"/> mehrere Felder durch ; getrennt. Nur relevant, wenn oben Sortierung aktiviert</td></tr>
		<tr valign="top"><td class="blue200">Anzeigen-Counter</td><td class="grey"><select name="adCount" class="var300"><option value="N">deaktiviert</option><option value="Y"
HTMLtext
		print " selected" if ($cat[31] eq "Y");
		$tmp="";
		eval {
			require GD;
		};
		if ($@) {
			$tmp=" <span class=\"red\">GD-Modul nicht vorhanden. Option darf nicht aktiviert werden!</span>";
		}
		print <<HTMLtext;
		>aktiviert</option></select></td></tr>
		<tr valign="top"><td class="blue200">Felder Adminbereich</td><td class="grey"><input type="text" name="adFields" value="$cat[33]" class="var300"/> Felder (getrennt mit ;), die im Adminbereich bei Eintr&auml;ge verwalten zus&auml;tzlich angezeigt werden.</td></tr>
		<tr valign="top"><td colspan="2">&nbsp;</td></tr>
		<tr valign="top"><td class="blue" colspan="2">Felddefinitionen / Einschr&auml;nkungen</td></tr>
		<tr valign="top"><td class="blue200">Pflichtfelder</td><td class="grey"><input type="text" name="pflicht" value="$cat[10]" class="var300"/> durch ; getrennt (title;valid;password;email sind immer Pflichtfelder)</td></tr>
		<tr valign="top"><td class="blue200">Textbegrenzungen</td><td class="grey"><input type="text" name="maxLenght" value="$cat[11]" CLASS="var300"> Feldname=L&auml;nge, getrennt mit Strichpunkt, z.B. Feld1=10;Feld2=50</td></tr>
		<tr valign="top"><td class="blue200">E-Mail Felder</td><td class="grey"><input type="text" name="mailField" value="$cat[12]" class="var300"/> durch ; getrennt</td></tr>
		<tr valign="top"><td class="blue200">numerische Felder</td><td class="grey"><input type="text" name="numField" value="$cat[15]" class="var300"> durch ; getrennt</td></tr>
		<tr valign="top"><td class="blue200">numerische Einschr&auml;nkungen</td><td class="grey"><table border="0" cellspacing="0" cellpadding="0"><tr valign="top"><td class="grey"><textarea name="numRest" class="fix300" rows="5" cols="50">$cat[24]</textarea></td><td class="grey">&nbsp;feldname~operator~wert<br />&nbsp;z.B. anzahl~&lt;~15<br />&nbsp;G&uuml;ltige Operatoren: &lt;, &lt;=, =, &gt;, &gt;=<br />&nbsp;Eine Einschr&auml;nkung pro Zeile</td></tr></table></td></tr>
		<tr valign="top"><td class="blue200">Text Einschr&auml;nkungen</td><td class="grey"><table border="0" cellspacing="0" cellpadding="0"><tr valign="top"><td class="grey"><textarea name="txtRest" class="fix300" rows="5" cols="50">$cat[25]</textarea></td><td class="grey">&nbsp;feldname~typ~wert<br />&nbsp;z.B. title~=~.{5}<br />&nbsp;G&uuml;ltige Typen: = (muss enthalten), =i (muss enthalten; Gross-/Kleinschreibung ignorieren),<br />&nbsp;! (darf nicht enthalten), !i (darf nicht enthalten; Gross-/Kleinschreibung ignorieren) <br />&nbsp;<a href="$COMPCGIURL?action=regex&amp;ASID=$FORM{ASID}" target="_blank">Perl-Regex</a> / Eine Einschr&auml;nkung pro Zeile</td></tr></table></td></tr>
		<tr valign="top"><td class="blue200">Maximale Bildgr&ouml;sse</td><td class="grey"><input type="text" name="maxISize" value="$cat[8]" class="var300"/> in Pixel [Breite]x[H&ouml;he] (0=unbeschr&auml;nkt)</td></tr>
		<tr valign="top"><td class="blue200">Thumbnail-Gr&ouml;sse</td><td class="grey"><input type="text" name="maxTmbS" value="$cat[9]" class="var300"> in Pixel [Breite]x[H&ouml;he] (leer=kein Thumbnail) $tmp</td></tr>
		<tr valign="top"><td class="blue200">Alternative Thumbnails</td><td class="grey"><input type="checkbox" name="uAltTmb" value="checked" $cat[32] /> verwende normales Bild, falls kein Thumbnail existiert (HTTP-Resize)</td></tr>
		<tr valign="top"><td colspan="2">&nbsp;</td></tr>
		<tr valign="top"><td class="blue" colspan="2">Templates</td></tr>
		<tr valign="top"><td class="blue200">Eingabe-Formular</td><td class="grey"><input type="text" name="formTemp" value="$cat[3]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Detailansicht</td><td class="grey"><input type="text" name="viewTemp" value="$cat[4]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">&Uuml;bersicht/Suchergebnis</td><td class="grey"><input type="text" name="listTemp" value="$cat[5]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Kontaktformular</td><td class="grey"><input type="text" name="contTemp" value="$cat[14]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Weiterempfehlen-Form.</td><td class="grey"><input type="text" name="recoTemp" value="$cat[17]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Such-Formular</td><td class="grey"><input type="text" name="srchTemp" value="$cat[16]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Passwort-Abfrage</td><td class="grey"><input type="text" name="passTemp" value="$cat[26]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Passwort-R&uuml;cksetzen</td><td class="grey"><input type="text" name="pareTemp" value="$cat[27]" class="var300"/></td></tr>
		<tr valign="top"><td class="blue200">Mail: Kontakt</td><td class="grey"><input type="text" name="mailCont" value="$cat[18]" class="var300"/> leer=Standard ($CONFIG{"contMail"})</td></tr>
		<tr valign="top"><td class="blue200">Mail: Weiterempfehlung</td><td class="grey"><input type="text" name="mailReco" value="$cat[19]" class="var300"/> leer=Standard ($CONFIG{"recoMail"})</td></tr>
		<tr valign="top"><td class="blue200">Mail: Validierung</td><td class="grey"><input type="text" name="mailVali" value="$cat[21]" class="var300"/> leer=Standard ($CONFIG{"valiMail"})</td></tr>
		<tr valign="top"><td class="blue200">Mail: Admin-Info</td><td class="grey"><input type="text" name="mailAdIn" value="$cat[23]" class="var300"/> leer=Standard ($CONFIG{"admiMail"})</td></tr>
		<tr valign="top"><td class="blue200">Mail: Passwort-Reset</td><td class="grey"><input type="text" name="mailPare" value="$cat[28]" class="var300"/> leer=Standard ($CONFIG{"pareMail"})</td></tr>
		<tr valign="top"><td colspan="2">&nbsp;</td></tr>
		<tr valign="top"><td>&nbsp;</td><td><input type="submit" value="Speichern" class="button300"/> <b><a href="$COMPCGIURL?action=catsave&amp;ASID=$FORM{ASID}&amp;cat=$FORM{cat}&amp;delete=yes">[ Kategorie l&ouml;schen ]</a></b></td></tr>
		</table></form>
HTMLtext
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# CATSAVE: Kategorien speichern
###########################################################################
if ($FORM{"action"} eq "catsave") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	$status=0;
	if (-e $CONFIG{"catFile"}) {									# vorhandene Kategorien in @cat einlesen
		open(CAT,&secureFilename($CONFIG{"catFile"}));
		@cat=<CAT>;
		close(CAT);
		@cat=sort @cat;
	}
	$FORM{"numRest"}=zeilenUmbruch($FORM{"numRest"},"§§");
	$FORM{"txtRest"}=zeilenUmbruch($FORM{"txtRest"},"§§");
	&HTMLbegin;
	print "<h1><a href=\"$COMPCGIURL?ASID=$FORM{ASID}&amp;action=cat\">Kategorien konfigurieren</a> &gt; <a href=\"$COMPCGIURL?ASID=$FORM{ASID}&amp;action=cat&amp;cat=$FORM{cat}\">Kategorie editieren</a> &gt; speichern</h1>";
	if (&lockFile($CONFIG{"catFile"})) {
		open(CATOUT,">".&secureFilename($CONFIG{"catFile"})); # Ausgabedatei schreiben
		foreach (@cat) {
			chomp;
			$_ =~ s/[\r\n]//g;
			if ($_ =~ m/^$FORM{"cat"}\t/) {						# Kategorie gefunden
				$status++;
				if ($FORM{"delete"} ne "yes") {					# editieren, sofern nicht löschen ausgewählt
					print CATOUT "$FORM{cat}\t$FORM{catName}\t$FORM{insFile}\t$FORM{formTemp}\t$FORM{viewTemp}\t$FORM{listTemp}\t$FORM{maxDays}\t$FORM{defDays}\t$FORM{maxISize}\t$FORM{maxTmbS}\t$FORM{pflicht}\t$FORM{maxLenght}\t$FORM{mailField}\t$FORM{entPage}\t$FORM{contTemp}\t$FORM{numField}\t$FORM{srchTemp}\t$FORM{recoTemp}\t$FORM{mailCont}\t$FORM{mailReco}\t$FORM{mailAdmi}\t$FORM{mailVali}\t$FORM{valMail}\t$FORM{mailAdIn}\t$FORM{numRest}\t$FORM{txtRest}\t$FORM{passTemp}\t$FORM{pareTemp}\t$FORM{mailPare}\t$FORM{ordWhen}\t$FORM{ordField}\t$FORM{adCount}\t$FORM{uAltTmb}\t$FORM{adFields}\n";
				}
			} else {																	# anderer Eintrag --> 1:1 übernehmen
				print CATOUT "$_\n";
			}
		}
		if ($status < 1) {													# Eintrag bis jetzt noch nicht gefunden --> neuer Eintrag erstellen
			print CATOUT "$FORM{cat}\t$FORM{catName}\t$FORM{insFile}\t$FORM{formTemp}\t$FORM{viewTemp}\t$FORM{listTemp}\t$FORM{maxDays}\t$FORM{defDays}\t$FORM{maxISize}\t$FORM{maxTmbS}\t$FORM{pflicht}\t$FORM{maxLenght}\t$FORM{mailField}\t$FORM{entPage}\t$FORM{contTemp}\t$FORM{numField}\t$FORM{srchTemp}\t$FORM{recoTemp}\t$FORM{mailCont}\t$FORM{mailReco}\t$FORM{mailAdmi}\t$FORM{mailVali}\t$FORM{valMail}\t$FORM{mailAdIn}\t$FORM{numRest}\t$FORM{txtRest}\t$FORM{passTemp}\t$FORM{pareTemp}\t$FORM{mailPare}\t$FORM{ordWhen}\t$FORM{ordField}\t$FORM{adCount}\t$FORM{uAltTmb}\t$FORM{adFields}\n";
		}
		close(CATOUT);
		&unlockFile($CONFIG{"catFile"});
		if ($FORM{"delete"} eq "yes") {
			print "<p>Die Kategorie mit der ID $FORM{cat} wurde erfolgreich gel&ouml;scht.</p>";
		}
		if (($FORM{"delete"} ne "yes") and ($status < 1)) {
			print "<p>Die Kategorie <b>$FORM{catName}</b> (ID: $FORM{cat}) wurde erfolreich erstellt.</p>";
		}
		if (($FORM{"delete"} ne "yes") and ($status > 0)) {
			print "<p>Die Kategorie <b>$FORM{catName}</b> (ID: $FORM{cat}) wurde erfolgreich gespeichert.</p>";
		}
	} else {
		print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&amp;file=$CONFIG{catFile}\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# ADMINADS: Einträge ansehen
###########################################################################
if ($FORM{"action"} eq "adminads") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	if ($FORM{"cat"} eq "") {											# keine Kategorie ausgewählt
		print "<h1>Eintr&auml;ge editieren</h1>";
		if (-e $CONFIG{"catFile"}) {								# vorhandene Kategorien einlesen
			open(CAT,&secureFilename($CONFIG{"catFile"}));
			while (<CAT>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				@splitArray=split(/\t/);
				print "<a href=\"$COMPCGIURL?ASID=$FORM{ASID}&amp;action=$FORM{action}&amp;cat=$splitArray[0]\">$splitArray[1]</a><br />\n";
			}
			close(CAT);
		}
	} else {																			# Kategorie gewählt
		&getCat($FORM{"cat"});											# Kategoriedaten einlesen
		print "<h1><a href=\"$COMPCGIURL?action=adminads&amp;ASID=$FORM{ASID}\">Eintr&auml;ge editieren</a> &gt; &Uuml;bersicht \"$cat[1]\"</h1>";
		if (($FORM{"delete"} ne "") and (-e $cat[2])) {	# Eintrag löschen
			if (&lockFile($cat[2])) {
				open(INPUT,&secureFilename($cat[2]));
				open(OUTPUT,">".&secureFilename($cat[2].".tmp"));
				while (<INPUT>) {
					print OUTPUT $_ if ($_ !~ m/^$FORM{"delete"}\t/);
				}
				close(INPUT);
				close(OUTPUT);
				unlink &secureFilename($cat[2]);
				rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
				&unlockFile($cat[2]);
			} else {
				print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&file=$cat[2]\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
			}
		}
		print "<form action=\"$COMPCGIURL\" method=\"post\">\n";
		print &hiddenField("ASID", $FORM{"ASID"});
		print &hiddenField("action", $FORM{"action"});
		print &hiddenField("cat", $FORM{"cat"});
		$FORM{"search1"}=$FORM{"search"};
		$FORM{"search1"}=~ s/</&lt;/g;
		$FORM{"search1"}=~ s/>/&gt;/g;
		$FORM{"search1"}=~ s/\"/&quot;/g;
		print "<p><input type=\"text\" name=\"search\" value=\"".$FORM{"search1"}."\" class=\"var160\" /> <input type=\"submit\" value=\"Suche\" class=\"button\" /></form></p>\n";
		print "<table border=\"0\">\n";
		print "<tr><td><b>ID</b></td><td><b>Titel</b></td><td><b>Name</b></td><td><b>E-Mail</b></td>";
		@splitArray=split(/;/,$cat[33]);
		foreach (@splitArray) {
			print "<td><b>$_</b></td>";
		}
		print "<td><b>validiert</b>&nbsp;&nbsp;&nbsp;&nbsp;</td><td>&nbsp;</td></tr>";
		if (-e $cat[2]) {
			open(DATA,&secureFilename($cat[2]));
			while (<DATA>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				if (($FORM{"search"} ne "") and ($_ !~ m/$FORM{"search"}/i)) { # Suchfilter prüfen
					next;
				}
				if ($tmp eq "") {												# Farben wechseln
					$tmp=" class=\"grey\"";
				} else {
					$tmp="";
				}
				&parseAd($_);														# Eintrag einlesen
				print "<tr><td$tmp>$ad{id}&nbsp;&nbsp;&nbsp;&nbsp;</td><td$tmp><a href=\"$COMPCGIURL?action=admineditad&amp;ASID=$FORM{ASID}&amp;cat=$FORM{cat}&amp;id=$ad{id}\">$ad{title}</a>&nbsp;&nbsp;&nbsp;&nbsp;</td><td$tmp>$ad{name}&nbsp;&nbsp;&nbsp;&nbsp;</td><td$tmp><a href=\"mailto:$ad{email}\">$ad{email}</a>&nbsp;&nbsp;&nbsp;&nbsp;</td>";
				@splitArray=split(/;/,$cat[33]);
				foreach (@splitArray) {
					print "<td$tmp>$ad{$_}</td>";
				}
				print "<td$tmp>";
				$status=substr($ad{"validated"},0,1);
				if ($status eq "Y") {
					print "Ja";
				} elsif ($status eq "N") {
					print "Nein";
				} elsif ($status eq "A") {
					print "erst durch Admin";
				} elsif ($status eq "U") {
					print "erst durch Benutzer";
				}
				print "</td><td$tmp><a href=\"$COMPCGIURL?action=adminads&amp;ASID=$FORM{ASID}&amp;cat=$FORM{cat}&amp;delete=$ad{id}\" title=\"Eintrag l&ouml;schen\"><img src=\"$CONFIG{imgDir}$CONFIG{deleImg}\" alt=\"Eintrag l&ouml;schen\" border=\"0\"> Eintrag l&ouml;schen</a>&nbsp;</td></tr>";
			}
			close(DATA);
		}
		print "</table>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# ADMINEDITAD: Eintrag editieren
###########################################################################
if ($FORM{"action"} eq "admineditad") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	&getCat($FORM{"cat"});												# Eintrag einlesen
	@splitArray=split(/;/,$cat[11]);							# Textlängen einlesen
	foreach (@splitArray) {
		@tmpArray=split(/=/);
		$TEXTLENGTH{$tmpArray[0]}=$tmpArray[1];			# Textlängen bestimmen
	}
	print "<h1><a href=\"$COMPCGIURL?action=adminads&amp;ASID=$FORM{ASID}\">Eintr&auml;ge editieren</a> &gt; <a href=\"$COMPCGIURL?action=adminads&amp;ASID=$FORM{ASID}&amp;cat=$FORM{cat}\">&Uuml;bersicht \"$cat[1]\"</a> &gt; Eintrag editieren</h1>\n";
	$fileIO=0;
	open(INPUT,&secureFilename($cat[2]));
	if ($FORM{"do"} ne "") {
		if (&lockFile($cat[2])) {
			open(DATA,">".&secureFilename($cat[2].".tmp"));
			$fileIO=1;
		} else {
			print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&file=$cat[2]\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
		}
	}
	while (<INPUT>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		if ($_ =~ m/^$FORM{"id"}\t/) {							# Eintrag gefunden
			if ($fileIO) {														# Editieren ausgewählt und Datei schreibbereit
				$id=$FORM{"id"};
				if ($FORM{"newfield"} ne "") {
					$FORM{$FORM{"newfield"}}=$FORM{"newfieldvalue"};
				}
				$_ =~ m/\tpassword=(.*?)\t/;						# altes Passwort bestimmen
				if ($1 ne $FORM{"password"}) {					# Passwort hat sich geändert oder ist neu --> Hash erstellen
					$FORM{"password"}=crypt($FORM{"password"},"crypt");
				}
				&addAd;																	# Eintrag speichern
				%ad=%FORM;
				foreach (keys(%ad)) {										# Zeilenumbrüche einfügen
					$ad{$_}=&zeilenUmbruch($ad{$_},"§§",1);
				}
				delete($ad{"newfieldvalue"});
				delete($ad{"newfield"});
				delete($ad{"cat"});
				delete($ad{"ASID"});
				delete($ad{"action"});
				delete($ad{"do"});
				print "<span class=\"red\">Eintrag editiert</span>";
			} else {
				&parseAd($_,"NLonly");									# Eintrag einlesen
				print DATA "$_\n";											# unverändert in Datei speichern
			}
		} else {
			if ($fileIO) {														# anderer Eintrag --> 1:1 wieder in Datei schreiben (sofern editieren)
				print DATA "$_\n";
			}
		}
	}
	close(INPUT);
	if ($fileIO) {																# editieren
		close(DATA);
		unlink &secureFilename($cat[2]);
		rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
		&unlockFile($cat[2])
	}
	print "<form action=\"$COMPCGIURL\" method=\"post\">";
	print &hiddenField("action",$FORM{"action"});
	print &hiddenField("ASID",$FORM{"ASID"});
	print &hiddenField("cat",$FORM{"cat"});
	print "<table width=\"100%\" border=\"0\">";
	print "<tr><td class=\"blue200\"><b>ID</b></td><td class=\"grey\"><input type=\"hidden\" name=\"id\" value=\"$ad{id}\" class=\"var300\">$ad{id}</td></tr>\n";
	foreach (sort keys(%ad)) {										# alle Werte alphabetisch sortiert ausgeben
		if (($_ eq "date") or ($_ eq "validated")) {
			next;
		} if (($TEXTLENGTH{$_} > 100) or ($ad{$_} =~ m/\n/)) {
			print "<tr valign=\"top\"><td class=\"blue200\"><b>$_</b></td><td class=\"grey\"><textarea name=\"$_\" rows=\"5\" cols=\"40\" class=\"fix300\">$ad{$_}</textarea></td></tr>\n" if ($_ ne "id");
		} else {
			print "<tr><td class=\"blue200\"><b>$_</b></td><td class=\"grey\"><input type=\"text\" name=\"$_\" value=\"$ad{$_}\" class=\"var300\"/></td></tr>\n" if ($_ ne "id");
		}
	}
	$tmp=substr($ad{"validated"},1,10);
	print "<tr><td class=\"blue200\">Status Validierung</td><td class=\"grey\"><select name=\"validated\" class=\"var300\">\n<option value=\"N\"$tmp";
	print " selected" if (substr($ad{"validated"},0,1) eq "N");
	print ">noch nicht validiert</option>\n<option value=\"Y\"";
	print " selected" if (substr($ad{"validated"},0,1) eq "Y");
	print ">validiert</option>\n<option value=\"U\"$tmp";
	print " selected" if (substr($ad{"validated"},0,1) eq "U");
	print ">validiert durch Benutzer, aber nicht durch Admin</option>\n<option value=\"A\"$tmp";
	print " selected" if (substr($ad{"validated"},0,1) eq "A");
	print ">validiert durch Admin, aber nicht durch Benutzer</option></select></td></tr>\n";
	print "<tr><td class=\"blue200\"><input type=\"text\" name=\"newfield\" class=\"var160\"></td><td class=\"grey\"><input type=\"text\" name=\"newfieldvalue\" class=\"var300\"/></td></tr>\n";
	print "<tr><td class=\"blue200\">&nbsp;</td><td class=\"grey\"><input type=\"submit\" name=\"do\" value=\"Eintrag editieren\" class=\"button300\"/> <a href=\"$COMPCGIURL?action=adminads&amp;cat=$FORM{cat}&amp;delete=$FORM{id}&amp;ASID=$FORM{ASID}\"><b>[ Eintrag l&ouml;schen ]</b></a>&nbsp;&nbsp;&nbsp;<a href=\"$COMPCGIURL?action=viewad&amp;cat=$FORM{cat}&amp;id=$FORM{id}\" target=\"_blank\"><b>[ Eintrag in Original-Layout ansehen ]</b></a></td></tr>\n";
	print "</table></form>";
	&HTMLend;
	exit(0);
}


###########################################################################
# UNLOCKFILE: Datei gewaltsam entsperren
###########################################################################
if ($FORM{"action"} eq "unlockfile") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	print "<h1>Dateisperre aufheben</h1><p>Jeder Schreibzugriff auf eine Datendatei erzeugt eine Dateisperre, um Datenverlust zu vermeiden. In Ausnahmef&auml;llen (z.B. Absturz des Scripts) kann diese Dateisperre m&ouml;glicherweise nicht mehr aufgehoben werden.</p><p>Mit diesem Men&uuml; kann die Datei manuell wieder f&uuml;r weitere Schreibzugriffe freigegeben werden.</p><p>Bitte beachten Sie: die Dateisperre ist in der Regel gewollt. Zuerst sollte immer versucht werden, den Vorgang nochmals zu wiederholen. Erst dann sollte die Datei gewaltsam entsperrt werden.</p>";
	if ($FORM{"file"} ne "") {
		if (-e $FORM{"file"}.".lock") {
			unlink &secureFilename($FORM{"file"}.".lock");
			print "<p><b>Die Datei <code>$FORM{file}</code> wurde wieder f&uuml;r Schreibzugriffe freigegeben!</b></p>";
		} else {
			print "<p class=\"red\">Die Datei <code>$FORM{file}</code> ist zwischenzeitlich nicht mehr gesperrt!</p>";
		}
	} else {
		print "<p class=\"red\">Es wurde kein Dateiname zum entsperren &uuml;bergeben!</p>";
	}
	print "<p><a href=\"#\" onClick=\"window.close()\">[ Fenster schliessen ]</a></p>";
	&HTMLend;
	exit(0);
}


###########################################################################
# LOGOUT: Abmelden
###########################################################################
if ($FORM{"action"} eq "logout") {
	print "Set-Cookie: Password=; expires=0;\n";
	&HTMLbegin;
	if (&lockFile($CONFIG{"dataFile"})) {
		$DATA{"ASID"}="";
		&saveDataFile;
		print "<h1>Logged out</h1>\n";
		print "<p>Besten Dank f&uuml;r Ihren Besuch. Sie sind jetzt abgemeldet.</p>\n";
		print "<p><a href=\"$COMPCGIURL?action=admin\">[ zum Login ]</a></p>";
		&unlockFile($CONFIG{"dataFile"});
	} else {
		print "<p class=\"red\">Datei f&uuml;r Schreibzugriffe gesperrt! Versuchen Sie es bitte erneut. <a href=\"$COMPCGIURL?action=unlockfile&amp;ASID=$FORM{ASID}&amp;file=$CONFIG{DataFile}\" target=\"_blank\">Klicken Sie hier um die Datei gewaltsam zu entsperren</a></p>";
		print "<p><a href=\"$COMPCGIURL?action=main&amp;ASID=$FORM{ASID}\">[ zur&uuml;ck ]</a></p>";
	}
	&HTMLend;
	exit(0);
}


###########################################################################
# REGEX: Regular-Expressions Erklärung
###########################################################################
if ($FORM{"action"} eq "regex") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	print <<HTMLtext;
	<h1>Regular Expressions in K&uuml;rze</h1>
	<p>Perl Regular-Expressions dienen der Mustererkennung von Text-Feldern. Weiterf&uuml;hrende Informationen findet man z.B. unter <a href="http://de.wikipedia.org/wiki/Regul%E4re_Ausdr%FCcke" target="_blank">http://de.wikipedia.org/wiki/Regul&auml;re_Ausdr&uuml;cke</a>. Nachfolgend sollten die wichtigsten Funktionen aufgef&uuml;hrt werden:</p>
	<table width="100%" border="0">
	<tr valign="top">
		<td class="blue" width="300">.</td>
		<td class="grey">Beliebiges Zeichen</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\d</td>
		<td class="grey">Ziffer (0-9), auch schreibbar als [0-9]</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\D</td>
		<td class="grey">Keine Ziffer (alles ausser 0-9), auch schreibbar als [^0-9]</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\w</td>
			<td class="grey">Alphanumerische Zeichen inkl. _ und Zahlen aber <i>ohne Umlaute</i>, auch schreibbar als [a-zA-z0-9_]</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\W</td>
		<td class="grey">Nicht-Alphanumerisches Zeichen, auch schreibbar als [^a-zA-Z0-9_]</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\s</td>
		<td class="grey">Leerzeichen und andere White-Spaces (\\n \\r \\t \\f [FormFeed]), auch schreibbar als [ \\t\\r\\n\\f]</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\S</td>
		<td class="grey">Kein Leerzeichen, auch schreibbar als [^ \\t\\r\\n\\f]</td>
	</tr>
	<tr valign="top">
		<td class="blue">^</td>
		<td class="grey">Beginn des Strings</td>
	</tr>
	<tr valign="top">
		<td class="blue">\$</td>
		<td class="grey">String-Ende</td>
	</tr>
	<tr valign="top">
		<td class="blue">[]</td>
		<td class="grey">Auswahlm&ouml;glichkeiten einzelner Zeichen / ODER</td>
	</tr>
	<tr valign="top">
		<td class="blue">(abc|def)</td>
		<td class="grey">Auswahlm&ouml;glichkeiten mehrer Zeichen / ODER (abc oder def)</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\. \\[ \\] \\( \\) \\{ \\} \\? \+</td>
		<td class="grey">Die Zeichen . [ ] ( ) { } ? +</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\n \\t \\r \\f</td>
		<td class="grey">haben ihre normale Bedeutung (Zeilenumbruch, Tabulator, Carriage-Return, Form-Feed</td>
	</tr>
</table><br /><br />
Zudem gibt es noch spezielle Tags f&uuml;r Mengenangaben, wie oft ein Zeichen hintereinander vorkommen muss.
<table width="100%" border="0">
	<tr valign="top">
		<td class="blue" width="300">?</td>
		<td class="grey">Kein- oder einmal, {0,1}</td>
	</tr>
	<tr valign="top">
		<td class="blue">*</td>
		<td class="grey">Keinmal bis beliebig oft {0,}</td>
	</tr>
	<tr valign="top">
		<td class="blue">+</td>
		<td class="grey">Ein- oder mehrmal {1,}</td>
	</tr>
	<tr valign="top">
		<td class="blue">{7}</td>
		<td class="grey">siebenmal</td>
	</tr>
	<tr valign="top">
		<td class="blue">{3,5}</td>
		<td class="grey">Drei- bis f&uuml;nfmal</td>
	</tr>
	<tr valign="top">
		<td class="blue">{4,}</td>
		<td class="grey">Viermal oder mehr</td>
	</tr>
	</table><br /><br />
	In ein paar praktischen Beispielen kann das wie folgt aussehen:
	<table width="100%" border="0">
	<tr valign="top">
		<td class="blue" width="300">.{5}</td>
		<td class="grey">Wert muss 5 beliebige Zeichen enthalten</td>
	</tr>
	<tr valign="top">
		<td class="blue">Hans.*Muster</td>
		<td class="grey">Muss die zwei W&ouml;rter "Hans" und "Muster" enthalten (zuerst Hans, dann Muster, dazwischen darf sich beliebiger Text befinden)</td>
	</tr>
	<tr valign="top">
		<td class="blue">(Meer|Strand|Sand)</td>
		<td class="grey">Muss mindestens eines der erw&auml;hnten W&ouml;rter beinhalten</td>
	</tr>
	<tr valign="top">
		<td class="blue">\\d{3}\\s\\d{2}\\s\\d{2}</td>
		<td class="grey">Muss eine Kombination wie "099 99 99" enthalten (Telefonnummer, Block mit 3, 2 und 2 Zahlen, dazwischen jeweils ein Leerzeichen</td>
	</tr>
	<tr valign="top">
		<td class="blue">[12]?\\d?\\d\\.[12]?\\d?\\d\\.[12]?\\d?\\d</td>
		<td class="grey">Muss eine IP-Adresse enthalten</td>
	</tr>
	<tr valign="top">
		<td class="blue">^Ich.*!\$</td>
		<td class="grey">Text muss mit "Ich" beginnen und "!" enden</td>
	</tr>
</table>
<p><a href="#" onClick="window.close()">[ Fenster schliessen ]</a></p>
HTMLtext
	&HTMLend;
	exit(0);
}


###########################################################################
# BACKUP: Datendateien sichern
###########################################################################
if ($FORM{"action"} eq "backup") {
	if (($FORM{"ASID"} ne $DATA{"ASID"}) or ($ENV{"HTTP_REFERER"} !~ m/$COMPCGIURL/i)) {
		&forbidden("WrongReferer");
	}
	&HTMLbegin;
	print "<h1>Backup</h1>";
	print "<p>Mit der nachfolgenden Funktion k&ouml;nnen alle Inserate-Dateien von jsMarket gesichert werden. Um die Dateien wiederherzustellen, kann die Datei einfach wieder an ihren urspr&uuml;nglichen Ort kopiert werden.</p>\n";
	print "<p>Wichtig: dieser Men&uuml;punkt sichert keine Konfiguration, Templates und Bilder zu Inseraten. F&uuml;r einen vollst&auml;ndigen Backup der jsMarket-Installation kopieren Sie am besten das komplette jsmarket-Verzeichnis im cgi-bin sowie den marketimages-Ordner via FTP auf Ihren PC.</p>\n";
	if ($FORM{"backup"} ne "") {
		if ($FORM{"suffix"} ne "") {
			$FORM{"suffix"}=".".$FORM{"suffix"};			# Wenn Suffix angegeben via Punkt trennen
		}
		print "<p><b>Starte Datensicherung...</b></p>\n";
		open(CAT,&secureFilename($CONFIG{"catFile"}));	# Kategoriedatei verarbeiten
		while (<CAT>) {
			chomp;
			$_ =~ s/[\r\n]//g;												# Zeilenumbrüche entfernen
			@splitArray=split(/\t/);
			if ($FORM{"path"} ne "") {								# in anderes Verzeichnis: Pfade ersetzen und Suffix anhängen
				$tmp=$splitArray[2];
				$tmp=~ s/[\\\/]/-/g;
				$tmp=$FORM{"path"}."/".$tmp.$FORM{"suffix"};
			} else {																	# in selbes Verzeichnis: Suffix anhängen
				$tmp=$splitArray[2].$FORM{"suffix"};
			}
			&moveFile($splitArray[2], $tmp, "copy");
			print "Sichere Datei: \"$splitArray[2]\" -&gt; \"$tmp\"<br />";
		}
		close(CAT);
		print "<p class=\"red\">Datensicherung erfolgreich abgeschlossen!</p>\n";
	}


	print "<form action=\"$COMPCGIURL\" method=\"post\">\n";
	print &hiddenField("ASID",$FORM{"ASID"});
	print &hiddenField("action",$FORM{"action"});
	print &hiddenField("backup","yes");
	print <<HTMLtext;
	<table border="0" width="100%">
	<tr valign="top">
		<td class="blue" width="200">Datei-Suffix</td>
		<td class="grey"><input type="text" name="suffix" value="$yyyymmddDate" class="var300"/> (wird dem Dateinamen angeh&auml;ngt)</td>
	</tr>
	<tr valign="top">
		<td class="blue" width="200">Speicherort</td>
		<td class="grey"><input type="text" name="path" value="" class="var300"/> (leer = selbes Verzeichnis wie Datendatei)</td>
	</tr>
	<tr valign="top">
		<td class="blue" width="200">&nbsp;</td>
		<td class="grey"><input type="submit" value="Backup starten" class="button300"/></td>
	</tr>
	</table>
HTMLtext
	print "</form>\n";
	&HTMLend;
	exit(0);
}


###########################################################################
# ADDAD: Neues Inserat hinzufügen
###########################################################################
if ($FORM{"action"} eq "addad") {
	foreach (keys(%FORM)) {												# Zeilenumbrüche in \n
		$FORM{$_} = &zeilenUmbruch($FORM{$_},"\n");
		if (($_ =~ m/^image\d*$/) or ($_ =~ m/^FILE_.*$/)) {	# Zeilenumbrüche aus Bild entfernen
			$FORM{$_} =~ s/\s//g;
		}
	}
	$sysMsg="";
	$status=0;																		# per Default Fehler (=Eingabemaske)
	&getCat($FORM{"cat"});												# Liest die Konfiguration in @cat ein.
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	if ($FORM{"do"} eq "save") {									# Inserat speichern
		$status=1;																	# per Default alles OK
		######## PFLICHTFELDER ########
		@splitArray=split(/;/,$cat[10].";title;password;email;name");
		foreach (@splitArray) {
			if (($FORM{$_} eq "") and ($_ ne "")) {		# Pflichtfeld ist leer --> Errorcode setzen
				$status=2;
				$ERROR{$_}=$CONFIG{"errFReq"}						# Fehlertext definieren (Feldabhängig)
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errRequ"};
			$status=0;
		}
		######## MAX. TEXTLAENGEN ########
		@splitArray=split(/;/,$cat[11]);						# Textlängen einlesen
		foreach (@splitArray) {
			@tmpArray=split(/=/);
			$TEXTLENGTH{$tmpArray[0]}=$tmpArray[1];		# Textlängen bestimmen
		}
		foreach (keys(%TEXTLENGTH)) {								# Check auf maximale Textlängen
			if (length($FORM{$_}) > $TEXTLENGTH{$_}) {	# Text zu lang --> Errorcode setzen
				$status=2;
				$ERROR{$_}=$CONFIG{"errFLon"}							# Fehlertext definieren (Feldabhängig)
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errLong"};
			$status=0;
		}
		######## ALPHANUMERISCHE EINSCHRAEKUNGEN ########
		if ($cat[25] ne "") {
			@tmpArray=split(/§§/,$cat[25]);
			foreach (@tmpArray) {
				@splitArray=split(/~/, $_, 3);
				if ($FORM{$splitArray[0]} ne "") {
					$tmp=0;
					if ((($splitArray[1] eq "=") and ($FORM{$splitArray[0]} =~ m/$splitArray[2]/)) or
						(($splitArray[1] eq "=i") and ($FORM{$splitArray[0]} =~ m/$splitArray[2]/i)) or
						(($splitArray[1] eq "!") and ($FORM{$splitArray[0]} !~ m/$splitArray[2]/)) or
						(($splitArray[1] eq "!i") and ($FORM{$splitArray[0]} !~ m/$splitArray[2]/i))) {
						$tmp=1;
					}
					if ($tmp == 0) {
						$status=2;
						$ERROR{$splitArray[0]}=$CONFIG{"errFIll"};	# Fehlertext definieren (Feldabhängig)
					}
				}
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errIlle"};
			$status=0;
		}
		######## NUMERISCHE FELDER ########
		@splitArray=split(/;/,$cat[15]);
		foreach (@splitArray) {
			$FORM{$_}=~ s/,/\./g;
			$FORM{$_}=~ s/\'//g;
			$FORM{$_}=~ s/^\+//g;
			$FORM{$_}=~ s/\s//g;
			if (($FORM{$_} !~ m/^-?\d*\.?\d*$/) and ($_ ne "")) {	# Numerisches Feld ungültig --> Errorcode setzen
				$status=2;
				$ERROR{$_}=$CONFIG{"errFNum"}						# Fehlertext definieren (Feldabhängig)
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errText"};
			$status=0;
		}
		######## NUMERISCHE EINSCHRAENKUNGEN ########
		if ($cat[24] ne "") {
			@tmpArray=split(/§§/,$cat[24]);
			foreach (@tmpArray) {
				@splitArray=split(/~/, $_, 3);
				if ($FORM{$splitArray[0]} ne "") {
					if ((($splitArray[1] eq ">") and ($FORM{$splitArray[0]} <= $splitArray[2])) or
						(($splitArray[1] eq ">=") and ($FORM{$splitArray[0]} < $splitArray[2])) or
						(($splitArray[1] eq "=") and ($FORM{$splitArray[0]} != $splitArray[2])) or
						(($splitArray[1] eq "<=") and ($FORM{$splitArray[0]} > $splitArray[2])) or
						(($splitArray[1] eq "<") and ($FORM{$splitArray[0]} >= $splitArray[2]))) {
						$status=2;
						$ERROR{$splitArray[0]}=$CONFIG{"errFIll"};	# Fehlertext definieren (Feldabhängig)
					}
				}
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errIlle"};
			$status=0;
		}
		######## E-MAIL FELDER ########
		@splitArray=split(/;/,$cat[12].";email");
		foreach (@splitArray) {
			if ((&invalidMail($FORM{$_},0)) and ($_ ne "")) {	# E-Mail Feld ungültig --> Errorcode setzen
				$status=2;
				$ERROR{$_}=$CONFIG{"errFMai"}						# Fehlertext definieren (Feldabhängig)
			}
		}
		if ($status == 2) {													# Errorcode gesetzt --> Meldung ausgeben, nicht speichern
			$sysMsg.=$CONFIG{"errMail"};
			$status=0;
		}
		######## SECURE-CODE ########
		if ((($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "I")) and (($FORM{"scid"} eq "") or ($FORM{"seccode"} eq "") or ($DATA{"SC".$FORM{"scid"}} ne $FORM{"seccode"}))) {
			$sysMsg.=$CONFIG{"errSCod"};							# Secure-Code erforderlich aber nicht vorhanden oder falsch
			$status=0;
		}
		######## BILDER ########
		foreach (keys(%FORM)) {
			if (($_ =~ m/^image\d*$/) and ($FORM{$_} ne "")) { # aktuelles Feld ist ein Bild-Feld und nicht leer
				@tmpArray=getImageSize("tmp_".$FORM{$_});	# Bildformat und -grösse bestimmen
				($tmpArray[101],$tmpArray[102])=split(/x/,$cat[8]);
				# Bild zu gross: versuche es, zu verkleinern, falls entsprechende Funktion aktiviert.
				if (($tmpArray[0] > 0) and ($tmpArray[1] > 0) and ((($tmpArray[0] > $tmpArray[101]) and ($tmpArray[101] > 0)) or (($tmpArray[1] > $tmpArray[102]) and ($tmpArray[102] > 0))) and ($FORM{$_} =~ m/\.jpe?g$/i) and ($CONFIG{"imgRSiz"} eq "Y")) {
					@tmpArray=split(/x/, $cat[8]);
					if ($tmpArray[0] == 0) {
						$tmpArray[0]=9999;
					}
					if ($tmpArray[1] == 0) {
						$tmpArray[1]=9999;
					}
					&makeThumb("tmp_".$FORM{$_},"tmp_".$FORM{$_},$tmpArray[0],$tmpArray[1]);
					@tmpArray=getImageSize("tmp_".$FORM{$_});	# Bildformat und -grösse bestimmen
					($tmpArray[101],$tmpArray[102])=split(/x/,$cat[8]);
				}
				if (($tmpArray[0] == 0) or ($tmpArray[1] == 0) or (($tmpArray[0] > $tmpArray[101]) and ($tmpArray[101] > 0)) or (($tmpArray[1] > $tmpArray[102]) and ($tmpArray[102] > 0)) or ((-s "tmp_".$FORM{$_} > $CONFIG{"imgSize"}) and ($CONFIG{"imgSize"} > 0))) {
					# Kein gültiges Bild oder zu gross --> Meldung ausgeben, nicht speichern
					$sysMsg.=$CONFIG{"errImgS"};
					$ERROR{$_}=$CONFIG{"errFImg"};				# Fehlertext definieren (Feldabhängig)
					&moveFile("tmp_".$FORM{$_},"","delete");	# Bild wieder löschen
					$FORM{$_}="";
					$status=0;
				}
			}
		}
		######## PASSWORT BESTEHENDES INSERAT ########
		if (($status > 0) and ($FORM{"id"} ne "")) {
			if (-e &secureFilename($cat[2])) {
				open(DATA,&secureFilename($cat[2]));		# Datei öffnen und Inserat suchen
				while (<DATA>) {
					chomp;
					$_ =~ s/[\r\n]//g;
					if ($_ =~ m/^$FORM{"id"}\t/) {				# Eintrag gefunden
						$_ =~ m/\tpassword=(.*?)\t/;				# altes Passwort bestimmen
						if ($1 ne $FORM{"password1"}) {			# Passwort stimmt nicht --> Fehler
							&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=sysValE");
							exit;
						}
						last;
					}
				}
				close(DATA);
			} else {																	# Daten-Datei für Kategorie existiert nicht
				&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=sysValE");
				exit;
			}
		}
		######## FLOOD-SPERRE ########
		if ((!(time-$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}}>$CONFIG{"floodSek"}))	and ($FORM{"id"} eq "")) {
			$sysMsg.=$CONFIG{"errFloo"};
			$status=0;
		}
		######## GUELTIKEITSDAUER PRUEFEN UND ANPASSEN ########
		if (($FORM{"valid"} > $cat[6]) and ($cat[6] > 0)) {
			$FORM{"valid"} = $cat[6];									# Maximale Gültigkeit überschritten --> auf Maximum setzen
		}
		if (($FORM{"valid"} == 0) and ($cat[6] > 0)) {
			$FORM{"valid"} = $cat[6]; 								# Maximale Gültigkeit überschritten --> auf Maximum setzen
		}
		if ($FORM{"valid"} eq "") {									# keine Gültigkeitsdauer --> auf Default setzen
			$FORM{"valid"} = $cat[7];
		}
		###########################################################################
		if ($status > 0) {													# Alles OK --> Eintrag speichern
			if ($FORM{"id"} eq "") {									# ID bestimmen
				$id=$serverTime;
			} else {
				$id=$FORM{"id"};
			}
			foreach (sort { lc($a) cmp lc($b) } keys(%FORM)) {
				# Bilder ins richtige Verzeichnis verschieben und Thumbnails erstellen
				if (($_ =~ m/^image\d*$/) and ($FORM{$_} ne "")) {
					$tmp=$_;
					@tmpArray=split(/x/, $cat[9]);
					if ((($tmpArray[0] > 0) or ($tmpArray[1] > 0)) and ($FORM{$tmp} =~ m/\.jpe?g$/i)) {
						if ($tmpArray[0] == 0) {
							$tmpArray[0]=9999;
						}
						if ($tmpArray[1] == 0) {
							$tmpArray[1]=9999;
						}
						# Thumbnail von JPG erstellen
						&makeThumb("tmp_".$FORM{$tmp},$CONFIG{"imgUplU"}."/".$id."_tmb_".$FORM{$tmp},$tmpArray[0],$tmpArray[1]);
					}
					# Datei in Upload-Ordner verschieben
					&moveFile("tmp_".$FORM{$tmp},$CONFIG{"imgUplU"}."/".$id."_".$FORM{$tmp});
					$FORM{$tmp}=$id."_".$FORM{$tmp};
				}
				# Dateien ins richtige Verzeichnis verschieben
				if (($_ =~ m/^FILE_.*$/) and ($FORM{$_} ne "")) {
					$tmp=$_;
					# Datei in Upload-Ordner verschieben
					&moveFile("tmp_".$FORM{$tmp},$CONFIG{"imgUplU"}."/".$id."_".$FORM{$tmp});
					$FORM{$tmp}=$id."_".$FORM{$tmp};
				}
				# Servergespeicherte Bilder wieder integrieren
				if (($FORM{$_} =~ m/^($id|tmp_)/) and ($_ =~ m/^SRV_(image\d*)$/) and ($FORM{$1} eq "")) {
					$tmp=$1;
					$FORM{$tmp} = $FORM{$_};
					if ($FORM{$tmp} =~ m/^tmp_/) {
						$FORM{$tmp}=~ s/^tmp(_.*)$/$id$1/;
						rename &secureFilename($CONFIG{"imgUplU"}."/tmp".$1), &secureFilename($CONFIG{"imgUplU"}."/".$id.$1);
						$tmp=$1;
						@tmpArray=split(/x/, $cat[9]);
						if ((($tmpArray[0] > 0) or ($tmpArray[1] > 0)) and ($tmp =~ m/\.jpe?g$/i)) {
							if ($tmpArray[0] == 0) {
								$tmpArray[0]=9999;
							}
							if ($tmpArray[1] == 0) {
								$tmpArray[1]=9999;
							}
							&makeThumb($CONFIG{"imgUplU"}."/".$id.$tmp, $CONFIG{"imgUplU"}."/".$id."_tmb".$tmp,$tmpArray[0],$tmpArray[1]);
						}
					}
					delete($FORM{$_});
				}
				# Servergespeicherte Dateien wieder integrieren
				if (($FORM{$_} =~ m/^($id|tmp_)/) and ($_ =~ m/^SRV_(FILE_.*$)$/) and ($FORM{$1} eq "")) {
					$tmp=$1;
					$FORM{$tmp} = $FORM{$_};
					if ($FORM{$tmp} =~ m/^tmp_/) {
						$FORM{$tmp}=~ s/^tmp(_.*)$/$id$1/;
						rename &secureFilename($CONFIG{"imgUplU"}."/tmp".$1), &secureFilename($CONFIG{"imgUplU"}."/".$id.$1);
						$tmp=$1;
					}
					delete($FORM{$_});
				}
			}
			if ($cat[22] ne "") {											# Wenn Validierung für diese Kategorie besoders geregelt --> Einstellung übernehmen
				$CONFIG{"valMail"}=$cat[22];
			}
			if (($CONFIG{"valMail"} ne "N") and ($id eq $serverTime)) { # neues Inserat und Validierung notwendig
				$id2=int(rand(100000));									# zweite ID für Admin-Validierung
				$FORM{"validated"}="N".$id2;
				if ($CONFIG{"valMail"} eq "Y") {				# Validierung durch Benutzer notwendig
					&sendValidationMail;									# Mail zur Validierung der Mailadresse senden
					$sysMsg="sysValR";										# Meldetext ausgeben
				} elsif ($CONFIG{"valMail"} eq "A") {		# Validierung durch Administrator notwendig, Meldetext ausgeben
					$sysMsg="sysValA";
				} elsif ($CONFIG{valMail} eq "B") {			# Validierung durch Benutzer und Administrator notwendig
					&sendValidationMail;									# Mail zur Validierung der Mailadresse senden
					$sysMsg="sysValB";										# Meldetext ausgeben
				}
			} else {																	# keine Validierung notwendig: Eintrag sofort aktivieren
				$FORM{"validated"}="Y";
				$sysMsg="sysAdAc";
			}
			if (&lockFile($cat[2])) {
				rename &secureFilename($cat[2]), &secureFilename($cat[2].".tmp");
				open(DATA,">".&secureFilename($cat[2]));
				if ($FORM{"id"} eq "") {								# Inserat hinzufügen, sofern neu
					$FORM{"password"}=crypt($FORM{"password"},"crypt");
					&addAd;
				}
				open(INPUT,&secureFilename($cat[2].".tmp"));	# restliche Inserate unten anhängen
				while (<INPUT>) {
					chomp;
					$_ =~ s/[\r\n]//g;
					if ($_ =~ m/^$id\t/) {								# Inserat ersetzen (edit)
						$_ =~ m/\tpassword=(.*?)\t/;				# altes Passwort bestimmen
						if ($1 ne $FORM{"password"}) {			# Passwort hat sich geändert oder ist neu --> Hash erstellen
							$FORM{"password"}=crypt($FORM{"password"},"crypt");
						}
						if (($_ !~ m/\temail=$FORM{email}\t/) and (($CONFIG{"valMail"} eq "Y") or ($CONFIG{"valMail"} eq "B"))) {
							$FORM{"validated"}="A";
							&sendValidationMail;							# Mail zur Validierung der Mailadresse senden
							$sysMsg="sysValR";								# Meldetext ausgeben
						}
						&addAd;
					} else {
						print DATA $_."\n";
					}
				}
				close(INPUT);
				close(DATA);
				unlink &secureFilename($cat[2].".tmp");
				&unlockFile($cat[2]);
				if ($CONFIG{"floodSek"} > 0) {					# Flood-Sperre gesetzt --> IP eintragen
					$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}}=time;
					if (&lockFile($CONFIG{"dataFile"})) {
						&saveDataFile;
						&unlockFile($CONFIG{"dataFile"});
					}
				}
				if (($CONFIG{"adDest"} eq "V") and ($sysMsg eq "sysAdAc")) {	# Inserate-Detailseite zeigen
					&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$id&sysMsg=$sysMsg&email=$FORM{email}");
				} else {																# Inserate-Übersicht zeigen
					&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=$sysMsg&email=$FORM{email}");
				}
			} else {																	# Datei gesperrt --> Fehlermeldung ausgeben
				$status=0;
				$sysMsg=$CONFIG{"errFile"};
			}
		} else {																		# Inserat hat Fehler: korrekte Bilder trotzdem verschieben
			foreach (reverse sort keys(%FORM)) {
				if (($_ =~ m/^(image\d*)$/) and ($FORM{"SRV_". $1} eq "") and ($FORM{$_} ne "")) {
					$tmp=$_;
					&moveFile("tmp_".$FORM{$tmp},$CONFIG{"imgUplU"}."/tmp_".$FORM{$tmp});
					$FORM{$tmp}="tmp_".$FORM{$tmp};
				}
				if (($FORM{$_} =~ m/^($id|tmp_)/) and ($_ =~ m/^SRV_(image\d*)$/) and ($FORM{$1} eq "")) { # Servergespeicherte Bilder wieder integrieren
					$tmp=$1;
					$FORM{$tmp} = $FORM{$_};
					if ($FORM{$tmp} =~ m/^tmp_/) {
						if ($id > 0) {
							$FORM{$tmp}=~ s/^tmp(_.*)$/$id$1/;
							rename &secureFilename($CONFIG{"imgUplU"}."/tmp".$1), &secureFilename($CONFIG{"imgUplU"}."/".$id.$1);
							$tmp=$1;
							@tmpArray=split(/x/, $cat[9]);
							if ((($tmpArray[0] > 0) or ($tmpArray[1] > 0)) and ($FORM{$tmp} =~ m/\.jpe?g$/i)) {
								if ($tmpArray[0] == 0) {
									$tmpArray[0]=9999;
								}
								if ($tmpArray[1] == 0) {
									$tmpArray[1]=9999;
								}
								&makeThumb($CONFIG{"imgUplU"}."/".$id.$tmp, $CONFIG{"imgUplU"}."/".$id."_tmb".$tmp,$tmpArray[0],$tmpArray[1]);
							}
						}
					}
					delete($FORM{$_});
				}
				if (($_ =~ m/^(FILE_.*)$/) and ($FORM{"SRV_". $1} eq "") and ($FORM{$_} ne "")) {
					$tmp=$_;
					&moveFile("tmp_".$FORM{$tmp},$CONFIG{"imgUplU"}."/tmp_".$FORM{$tmp});
					$FORM{$tmp}="tmp_".$FORM{$tmp};
				}
				if (($FORM{$_} =~ m/^($id|tmp_)/) and ($_ =~ m/^SRV_(FILE_.*)$/) and ($FORM{$1} eq "")) { # Servergespeicherte Dateien wieder integrieren
					$tmp=$1;
					$FORM{$tmp} = $FORM{$_};
					if ($FORM{$tmp} =~ m/^tmp_/) {
						if ($id > 0) {
							$FORM{$tmp}=~ s/^tmp(_.*)$/$id$1/;
							rename &secureFilename($CONFIG{"imgUplU"}."/tmp".$1), &secureFilename($CONFIG{"imgUplU"}."/".$id.$1);
							$tmp=$1;
						}
					}
					delete($FORM{$_});
				}
			}
		}
	}
	if ($status == 0) {														# Eingabemaske
		if ($FORM{"do"} eq "edit") {								# ID übergeben
			open(DATA,&secureFilename($cat[2]));			# Datei öffnen und Inserat suchen
			while (<DATA>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				if ($_ =~ m/^$FORM{id}\t/) {						# Eintrag gefunden
					&parseAd($_,"NLonly");								# Eintrag einlesen
					if ((($ad{"password"} eq $FORM{"password"}) or ($ad{"password"} eq crypt($FORM{"password"},"crypt"))) and ($ad{"validated"} eq "Y")) {
						%FORM=%ad;													# Passwort stimmt --> Eintrag laden
						$FORM{"password1"}=$FORM{"password"};
						$FORM{"cat"}=$cat[0];								# $FORM{"cat"} wieder abfüllen
					} else {															# Passwort falsch --> ID verwerfen
						&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}&sysMsg=sysWPas");
					}
					last;
				}
			}
			close(DATA);
		}
		print "Content-type: text/html\n\n";
		if ($FORM{"valid"} eq "") {									# Default Gültigkeitsdauer einlesen
			$FORM{"valid"} = $cat[7];
		}
		if (-e $cat[3]) {
			open(TEMPLATE,&secureFilename($cat[3]));
			while (<TEMPLATE>) {
				$_ =~ s/<!--SYSTEMMESSAGE-->/$sysMsg/gi;
				$_ =~ s/<!--cat-->/$cat[0]/gi;
				$_ =~ s/<!--catname-->/$cat[1]/gi;
				$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
				$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
				$_ =~ s/<!--action-->/$FORM{"action"}/gi;
				$_ =~ s/<!--scriptVersion-->/$version/gi;
				$_ =~ s/<!--imgpath-->/$CONFIG{"imgUplB"}/gi;
				$_ =~ s/<!--scid-->/$serverTime/gi;
				$_ =~ s/<!--field:([^>:]+):(.+?)-->/substr($FORM{$1},0,$2)/egi;
				$_ =~ s/<!--field:(.*?)-->/$FORM{$1}/gi;
				$_ =~ s/<!--fieldh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
				$_ =~ s/<!--fehler:(.*?)-->/$ERROR{$1}/gi;
				$_ =~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%FORM)/egi;
				if ($_ =~ m/<!--scyes-->/i) {						# Zeile enthält scyes
					if (($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "I")) {	# SecureCode aktiviert...
						$_=~ s/<!--scyes-->//gi;						# ...Tag entfernen
					} else {															# SecureCode nicht aktiviert...
						$_="";															# ...komplette Zeile entfernen
					}
				}
				if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
					&includeFile($1);
				}
				if ($FORM{"id"} ne "") {								# editieren --> Link zum Löschen anzeigen
					$_ =~ s/<!--editad//gi;
					$_ =~ s/editad-->//gi;
				}
				print $_;
			}
			close(TEMPLATE);
		}
	}
	exit(0);
}


###########################################################################
# EDITAD: Inserat editieren
###########################################################################
if ($FORM{"action"} eq "editad") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	open(FILE,&secureFilename($cat[2]));
	while (<FILE>) {
		if ($_ =~ m/^$FORM{"id"}\t/) {
			$status++;
			&parseAd($_);
			last;
		}
	}
	close(FILE);
	if ($status < 1) {														# Inserat nicht gefunden --> zurück zur Hauptseite
		&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}");
	}
	print "Content-type: text/html\n\n";
	if (-e $cat[26]) {
		open(TEMPLATE,&secureFilename($cat[26]));
		while (<TEMPLATE>) {
			$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^sys/);
			$_ =~ s/<!--cat-->/$cat[0]/gi;
			$_ =~ s/<!--catname-->/$cat[1]/gi;
			$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
			$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
			$_ =~ s/<!--scriptVersion-->/$version/gi;
			$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
			$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
			$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
			$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
			$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
			$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
			if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
				&includeFile($1);
			}
			print $_;
		}
		close(TEMPLATE);
	}
	exit(0);
}


###########################################################################
# PASSRESET: Passwort zurücksetzen
###########################################################################
if ($FORM{"action"} eq "passreset") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	open(FILE,&secureFilename($cat[2]));
	while (<FILE>) {
		if ($_ =~ m/^$FORM{id}\t/) {
			$status++;
			&parseAd($_);
			$id=checksum($_);
			last;
		}
	}
	close(FILE);
	if ($status < 1) {														# Inserat nicht gefunden --> zurück zur Hauptseite
		&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}");
	}
	$FORM{"email"} =~ s/>$//;											# > am Ende einer Mailadresse löschen

	if ($FORM{"do"} eq "sendmail") {							# Passwort per Mail versenden
		if (lc($ad{email}) ne lc($FORM{"email"})) {	# E-Mail Adresse stimmt nicht
			&sendURL("$COMPCGIURL?action=editad&cat=$FORM{cat}&id=$FORM{id}&sysMsg=sysMail");
		}
		# Mail mit Reset-Code versenden
		if ($mailVersand eq "TRUE") {
			$ENV{"PATH"} = "/bin:/usr/bin:/usr/sbin";
			open MAIL, "| ".&secureFilename($CONFIG{"sendmail"})." -oi -t" or die "Sendmail konnte nicht geöffnet werden";
		} else {
			open(MAIL,">mail.eml") || die "Kann EML-Datei nicht schreiben! Error : $!\n";
		}
		if ($cat[28] ne "") {													# Spezielles Template für diese Rubrik definiert
			$CONFIG{"pareMail"}=$cat[28];
		}
		open(FILE,&secureFilename($CONFIG{"pareMail"}));
		while (<FILE>) {
			chomp;
			$_ =~ s/[\r\n]//g;
			$_ =~ s/<!--date-->/$mailDate/gi;
			$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
			$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
			$_ =~ s/<!--scriptVersion-->/$version/gi;
			$_ =~ s/<!--id-->/$FORM{"id"}/gi;
			$_ =~ s/<!--cat-->/$cat[0]/gi;
			$_ =~ s/<!--catname-->/$cat[2]/gi;
			$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
			$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
			$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
			$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
			$_ =~ s/<!--messageid-->/$messageID/gi;
			$_ =~ s/<!--boundary-->/$boundary/gi;
			$_ =~ s/<!--code-->/$id/gi;
			if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
				&includeFile($1);
			}
			print MAIL "$_\n";
		}
		close(FILE);
		close(MAIL);
	}

	if ($FORM{"do"} eq "setpass") {								# Angaben prüfen und ggf. Passwort ändern
		$status=0;																	# am Anfang ist alles ok...
		if (lc($ad{email}) ne lc($FORM{"email"})) {	# E-Mail Adresse stimmt nicht
			$FORM{"sysMsg"}="sysMail";
			$status++;
		}
		if (($FORM{"password"} ne $FORM{"password1"}) or ($FORM{"password"} eq "")) {
			$FORM{"sysMsg"}="sysPare";								# Passwort stimmt nicht überein oder ist leer
			$status++;
		}
		if ($FORM{"code"} ne $id) {									# Code stimmt nicht
			$FORM{"sysMsg"}="sysPare";
			$status++;
		}
		if ($status == 0) {
			if (&lockFile($cat[2])) {
				open(INPUT,&secureFilename($cat[2]));
				open(OUTPUT,">".&secureFilename($cat[2].".tmp"));
				while (<INPUT>) {
					if ($_ =~ m/^$FORM{id}\t/) {							# Inserat gefunden
						$id2=crypt($FORM{"password"},"crypt");	# Passwort neu setzen
						$_ =~ s/\tpassword=.*?\t/\tpassword=$id2\t/;
					}
					print OUTPUT $_;
				}
				close(INPUT);
				close(OUTPUT);
				unlink &secureFilename($cat[2]);
				rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
				&unlockFile($cat[2]);
				&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}&sysMsg=sysPass");
			}
		}
	}

	# Formular anzeigen
	print "Content-type: text/html\n\n";
	if (-e $cat[27]) {
		open(TEMPLATE,&secureFilename($cat[27]));
		while (<TEMPLATE>) {
			$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^sys/);
			$_ =~ s/<!--cat-->/$cat[0]/gi;
			$_ =~ s/<!--catname-->/$cat[1]/gi;
			$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
			$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
			$_ =~ s/<!--scriptVersion-->/$version/gi;
			$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
			$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
			$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
			$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
			$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
			$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
			if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
				&includeFile($1);
			}
			print $_;
		}
		close(TEMPLATE);
	}
	exit(0);
}


###########################################################################
# DELETEAD: Inserat löschen
###########################################################################
if ($FORM{"action"} eq "deletead") {
	$status=0;
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	if (&lockFile($cat[2])) {
		open(INPUT,&secureFilename($cat[2]));
		open(OUTPUT,">".&secureFilename($cat[2].".tmp"));
		while (<INPUT>) {
			if ($_ =~ m/^$FORM{"id"}\t/) {						# Inserat gefunden
				&parseAd($_);														# Inserat einlesen
				if ((($ad{"password"} eq $FORM{"password"}) or ($ad{"password"} eq crypt($FORM{"password"},"crypt")))) {
					$status=1;														# Passwort stimmt --> löschen
				} else {																# Passwort falsch --> Fehler, Inserat nicht löschen
					$status=2;
					print OUTPUT $_;
				}
			} else {																	# andere Zeilen 1:1 übernehmen
				print OUTPUT $_;
			}
		}
		close(INPUT);
		close(OUTPUT);
		unlink &secureFilename($cat[2]);
		rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
		if ($status == 0) {													# Status 0 --> Inserat nicht gefunden
			$sysMsg="sysValE";
		} elsif ($status == 1) {										# Status 1 --> Inserat gelöscht
			$sysMsg="sysADel";
		} elsif ($status == 2) {										# Status 2 --> Passwort falsch
			$sysMsg="sysWPas";
		}
		&unlockFile($cat[2]);
		&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=$sysMsg");
	} else {
		&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=errFile");
	}
}


###########################################################################
# VIEWCAT: Kategorie Übersicht ansehen
###########################################################################
if ($FORM{"action"} eq "viewcat") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	if (($cat[29] eq "live") and ($cat[30] ne "") and ($FORM{"orderby"} eq "")) {
		$FORM{"orderby"}=$cat[30];									# Sortierung im Kategorie; kein Parameter --> anwenden
	}
	if ($FORM{"from"} < 1) {											# von/bis bestimmen
		$FORM{"from"} = 1;
	}
	$FORM{"to"}=$FORM{"from"}+$cat[13];
	@splitArray=split(/;/,$cat[15]);							# numerische Felder bestimmen
	foreach (@splitArray) {
		$NUMFIELDS{$_}++;
	}
	if ($FORM{"do"} eq "search") {								# Suchabfrage bestimmen
		&compressSearch;														# Suchergebnisse verdichten
		@splitArray=split(/\s/,$CONFIG{"srchBet"});
		foreach (sort keys(%FORM)) {
			if (($_ eq "action") or ($_ eq "do") or ($_ eq "cat") or ($_ eq "from") or ($_ eq "to") or ($_ eq "orderby") or ($FORM{$_} eq "")) {
				next;
			}
			if ($_ =~ m/^(.*)(VON|BIS)$/) {
				$tmp=$1;
				$srchString.="'$tmp' >= '$FORM{$_}', " if ($_ =~ m/VON$/);
				$srchString.="'$tmp' <= '$FORM{$_}', " if ($_ =~ m/BIS$/);
			} else {
				if ($NUMFIELDS{$_} > 0) {
					if ($FORM{$_} =~ m/^[<>]/) {
						$srchString.="'".$_."'".$FORM{$_}.", ";
					} elsif ($FORM{$_} =~ m/^(-?\d*?)-(-?\d*)$/) {
						$srchString.="'$_' $splitArray[0] $1 $splitArray[1] $2, ";
					} else {
						$srchString.="'$_'=$FORM{$_}, ";
					}
				} else {
					$srchString.="'$_' $CONFIG{srchCon} '$FORM{$_}', ";
				}
			}
		}
		$srchString=~ s/, $//;
	}

	$count=0;																			# Zähler Anzahl Inserate
	open(DATA,&secureFilename($cat[2]));
	while (<DATA>) {
		$_ =~ s/[\r\n]//g;
		$tmp=0;
		if ($FORM{"do"} eq "search") {							# Suche: passt Eintrag?
			if (&checkSearch($_)) {
				$tmp++;
			}
		} else {																		# keine Suche: OK, wenn validiert
			$tmp++ if ($_ =~ m/\tvalidated=Y\t/);
		}
		# $tmp: 1=Inserat zum anzeigen / 0=Inserat nicht zum anzeigen (nicht validiert oder entspricht nicht Suche)
		if ($tmp) {
			$count++;																	# Anzahl Inserate erhöhen
			if (($FORM{"do"} eq "search") and ($FORM{"orderby"} eq "") and ($count > $FORM{"to"})) {
				next;																		# nur Suche aber keine Sortierung, Nur maximale Ergebnisse behandeln....
			}
			if (($FORM{"do"} eq "search") or ($FORM{"orderby"} ne "")) {	# Suche oder Sortierung: Schlüssel festlegen
				$tmp="S";
				@splitArray=split(/[,;]/,$FORM{"orderby"});	# Sortierschlüssel splitten
				foreach $status (@splitArray) {
					if ($_ =~ m/\t$status=(.*?)\t/) {
						if ($NUMFIELDS{$status}) {
							$tmp.=sprintf("%10.10d",$1);			# numerisch: erste 10 Zeichen für Sortierung beachten und führende 0
						} else {
							$status=$1;
							if ($status =~ m/^(\d{2})\.(\d{2})\.(\d{4})$/) {	# Datumsfeld (01.01.2006)
								$tmp.=sprintf("%-30.30s",$3.$2.1);	# alphanumerisch Datum: JJJJMMTT
							} else {
								$tmp.=sprintf("%-30.30s",lc($status));	# alphanumerisch: erste 30 Zeichen für Sortierung beachten
							}
						}
					}
					$tmp.="          ";
				}
				$_ =~ m/^(.*?)\t/;
				$tmp.=sprintf("-%11.11d-%11.11d",$count, $1);	# Zähler und ID am Schluss anfügen
				$adSearch{$tmp}=$_;
			}
		}
	}
	close(DATA);
	$FORM{"number"}=$count;												# Anzahl Inserate
	$CONFIG{$FORM{"sysMsg"}}=~ s/<!--email-->/$FORM{"email"}/g;
	$status=0;																		# Status: 0=Header / 1=Template für Eintrage parsen / 2=Einträge ausgeben / 3=Footer
	$count=0;
	print "Content-type: text/html\n\n";
	open(TEMPLATE,&secureFilename($cat[5]));
	while (<TEMPLATE>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^sys/);
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--catname-->/$cat[1]/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--numAds-->/$FORM{"number"}/gi;
		$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
		$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
		$_ =~ s/<!--srchString-->/$srchString/gi;
		if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
			&includeFile($1);
		}
		if ($_ =~ m/<!--prevlink:(.*?)-->/) {				# Navigationslinks
			if ($FORM{"from"} > 1) {
				$FORM{"prevlink"}="<a href=\"$COMPCGIURL?from=".($FORM{"from"}-$cat[13]);
				foreach (keys(%FORM)) {
					$FORM{"prevlink"}.="&amp;$_=$FORM{$_}" if (($_ ne "from") and ($_ ne "to") and ($_ ne "prevlink") and ($_ ne "nextlink") and ($_ ne "number") and ($_ ne "sysMsg") and ($FORM{$_} ne ""));
				}
				$FORM{"prevlink"}.="\">$1</a>";
			} else {
				$FORM{"prevlink"}="";
			}
			$_ =~ s/<!--prevlink:.*?-->/$FORM{"prevlink"}/gi;
		}
		if ($_ =~ m/<!--nextlink:(.*?)-->/) {
			if ($FORM{"number"} >= $FORM{"to"}) {
				$FORM{"nextlink"}="<a href=\"$COMPCGIURL?from=$FORM{to}";
				foreach (keys(%FORM)) {
					$FORM{"nextlink"}.="&amp;$_=$FORM{$_}" if (($_ ne "from") and ($_ ne "to") and ($_ ne "prevlink") and ($_ ne "nextlink") and ($_ ne "number") and ($_ ne "sysMsg") and ($FORM{$_} ne ""));
				}
				$FORM{"nextlink"}.="\">$1</a>";
			} else {
				$FORM{"nextlink"} = "";
			}
			$_ =~ s/<!--nextlink:.*?-->/$FORM{"nextlink"}/i;
		}
		if ($_ =~ m/<!--directlink:(.*?)-->/) {	# Link direkt zu einer Seite
			$tmp = &directLink($1);
			$_ =~ s/<!--directlink:.*?-->/$tmp/i;
		}
		if ($_ =~ m/<!--ifSearch:.*?-->/i) {				# Link im Suchen
			if ($FORM{"do"} eq "search") {
				$_ =~ s/<!--ifSearch:(.*?)-->/$1/i;
			} else {
				$_ =~ s/<!--ifSearch:.*?-->//i;
			}
		}
		if ($_ =~ m/<!--startList-->/i) {
			$status++;
		}
		if ($_ =~ m/<!--endList-->/i) {
			$status++;
		}
		if ($status == 1) {
			push @TEMPLATE, $_;
		} else {
			$_ =~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%FORM)/egi;
			$_ =~ s/<!--(start|end)List-->//g;
			print "$_\n";
		}
		if ($status == 2) {
			if (($FORM{"do"} eq "search") or ($FORM{"orderby"} ne ""))	{	# Anzeige Suchergebnis oder Sortierung
				foreach (sort {$a cmp $b} (keys(%adSearch))) {
					$count++;
					if (($FORM{"from"} <= $count) and ($FORM{"to"} > $count)) {
						&parseAd($adSearch{$_},"","Y");
						&showAd;														# Inserat anzeigen
					} elsif ($FORM{"to"} < $count) {
						last;
					}
				}
				close(FILE);
			} else {																	# normale Kategorieanzeige
				open(FILE,&secureFilename($cat[2]));
				while (<FILE>) {
					if ($_ !~ m/\tvalidated=Y\t/) {				# Inserat nicht validiert --> überspringen
						next;
					}
					$count++;
					if (($FORM{"from"} <= $count) and ($FORM{"to"} > $count)) {
						&parseAd($_,"","Y");
						&showAd;														# Inserat anzeigen
					} elsif ($FORM{"to"} < $count) {
						last;
					}
				}
				close(FILE);
			}
			$status++;
		}
	}
	close(TEMPLATE);
	exit(0);
}


###########################################################################
# VIEWAD: Eintrag ansehen
###########################################################################
if ($FORM{"action"} eq "viewad") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	$status=0;
	open(INPUT,&secureFilename($cat[2]));
	while (<INPUT>) {
		if ($_ =~ m/^$FORM{"id"}\t/) {
			$status++;
			&parseAd($_,"","Y");
			last;
		}
	}
	close(INPUT);
	if ($status < 1) {														# Inserat nicht gefunden --> zurück zur Hauptseite
		&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}");
	}
	if (($cat[31] eq "Y") and ($ad{"counterip"} ne $ENV{"REMOTE_ADDR"})) {	# wenn Counter aktiviert und andere IP
		if (&lockFile($cat[2])) {
			open(INPUT,&secureFilename($cat[2]));
			open(OUTPUT,">".&secureFilename($cat[2].".tmp"));
			while (<INPUT>) {
				if ($_ =~ m/^$FORM{"id"}\t/) {						# diese ID
					if ($_ !~ m/\tcounterip=$ENV{"REMOTE_ADDR"}\t/) {	# Counter erhöhen, wenn nicht gleiche IP
						$ad{"counter"}++;										# Counter erhöhen
						if ($_ =~ m/\tcounter=/) {					# hat bereits eine Counter-ID --> erhöhen
							$_=~ s/\tcounter=\d*\t/\tcounter=$ad{"counter"}\t/g;
						} else {
							chomp;
							$_ =~ s/[\r\n]//g;
							$_.="counter=$ad{counter}\t\n";
						}
						if ($_ =~ m/\tcounterip=/) {				# hat bereits eine Counter-IP --> ändern
							$_=~ s/\tcounterip=.*?\t/\tcounterip=$ENV{"REMOTE_ADDR"}\t/g;
						} else {
							chomp;
							$_ =~ s/[\r\n]//g;
							$_.="counterip=".$ENV{"REMOTE_ADDR"}."\t\n";
						}
					}
				}
				print OUTPUT $_;
			}
			close(INPUT);
			close(OUTPUT);
			unlink &secureFilename($cat[2]);
			rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
			&unlockFile($cat[2]);
		}
	}
	print "Content-type: text/html\n\n";
	&setMailTime($ad{"id"}+($ad{"valid"}*24*60*60));
	if ($ad{"valid"}) {
		$ad{"expiredate"}=$dmmmmyyyyDate2;
	} else {
		$ad{"expiredate"}="---";
	}
	my $searchParams="";
	foreach (keys(%FORM)) {
		$searchParams.="&".$_."=".$FORM{$_} if (($_ ne "action") and ($_ ne "orderby") and ($_ ne "cat") and ($_ ne "id") and ($_ ne "from") and ($_ ne "nextlink") and ($_ ne "prevlink"));
	}
	if ($searchParams ne "") {
		$searchParams.="&do=search";
	}
	open(TEMPLATE,&secureFilename($cat[4]));
	while (<TEMPLATE>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
			&includeFile($1);
		}
		$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^sys/);
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--id-->/$FORM{"id"}/gi;
		$_ =~ s/<!--catname-->/$cat[1]/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--orderby-->/$FORM{"orderby"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--scid-->/$serverTime/gi;
		$_ =~ s/<!--field:rimage(.*?)-->/$ad{"image".$1}/gi;
		if (($_ =~ m/<!--field:image(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {
			$_ =~ s/<!--field:image(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$ad{"image".$1}\"$2 alt=\"$ad{"image".$1}\" \/>/gi;
		}
		if (($_ =~ m/<!--field:timage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails
			$_ = &thumbImageAsHTML($1, $2, $_, 0);
		}
		if (($_ =~ m/<!--field:rtimage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails als RAW-Code
			$_ = &thumbImageAsHTML($1, $2, $_, 1);
		}
		$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
		$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
		$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
		$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
		$_ =~ s/<!--contact-->/$COMPCGIURL?action=contact&amp;cat=$FORM{"cat"}&id=$FORM{"id"}/gi;
		$_ =~ s/<!--recommend-->/$COMPCGIURL?action=recommend&amp;cat=$FORM{"cat"}&amp;id=$FORM{"id"}/gi;
		$_ =~ s/<!--editurl-->/$COMPCGIURL?action=addad&amp;cat=$FORM{"cat"}&amp;id=$FORM{"id"}&amp;do=edit/gi;	# compatible mode, not longer supported
		$_ =~ s/<!--mainurl-->/$COMPCGIURL?action=viewcat&amp;cat=$FORM{"cat"}&amp;orderby=$FORM{"orderby"}&amp;from=$FORM{"from"}$searchParams/gi;
		$_ =~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%ad)/egi;
		$_ =~ s/<!--editad-->/$COMPCGIURL?action=editad&amp;cat=$FORM{"cat"}&amp;id=$FORM{"id"}/gi;
		print "$_\n";
	}
	close(TEMPLATE);
	exit(0);
}


###########################################################################
# CONTACT: Inserent kontaktieren
###########################################################################
if ($FORM{"action"} eq "contact") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	$status=0;
	open(FILE,&secureFilename($cat[2]));
	while (<FILE>) {
		if ($_ =~ m/^$FORM{"id"}\t/) {							# Inserat suchen und einlesen
			$status++;
			&parseAd($_);
			last;
		}
	}
	close(FILE);
	if ($status < 1) {														# Inserat nicht gefunden --> zurück zum Eintrag
		&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}");
	}
	if ($FORM{"do"} ne "") {
		if (($FORM{"message"} eq "") or ($FORM{"name"} eq "") or ($FORM{"email"} eq "") or (&invalidMail($FORM{"email"},0)) or ($FORM{"subject"} eq "")) {
			$FORM{sysMsg}="sysCont"; 									# nicht alle Pflichtfelder
		} elsif ((($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "M")) and (($FORM{"scid"} eq "") or ($FORM{"seccode"} eq "") or ($DATA{"SC".$FORM{"scid"}} ne $FORM{"seccode"}))) {
			$FORM{sysMsg}="errSCod"; 									# Secure-Code erforderlich aber nicht vorhanden oder falsch
		} elsif (($CONFIG{"floodMai"} eq "Y") and ($CONFIG{"floodSek"} > 0) and (time-$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}} < $CONFIG{"floodSek"})) {
			$FORM{sysMsg}="errFloo"; 									# Flood-Sperre unterschritten
		} else {
			if ($mailVersand eq "TRUE") {
				$ENV{"PATH"} = "/bin:/usr/bin:/usr/sbin";
				open MAIL, "| ".&secureFilename($CONFIG{"sendmail"})." -oi -t" or die "Sendmail konnte nicht geöffnet werden";
			} else {
				open(MAIL,">mail.eml") || die "Kann EML-Datei nicht schreiben! Error : $!\n";
			}
			if ($cat[18] ne "") {											# spezielles Kontaktmail für diese Rubrik definiert
				$CONFIG{"contMail"}=$cat[18];
			}
			open(FILE,&secureFilename($CONFIG{"contMail"}));
			while (<FILE>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				$_ =~ s/<!--date-->/$mailDate/gi;
				$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
				$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
				$_ =~ s/<!--action-->/$FORM{"action"}/gi;
				$_ =~ s/<!--scriptVersion-->/$version/gi;
				$_ =~ s/<!--id-->/$FORM{"id"}/gi;
				$_ =~ s/<!--cat-->/$cat[0]/gi;
				$_ =~ s/<!--catname-->/$cat[2]/gi;
				if ($_ =~ m/<!--form:(image\d*|FILE_.*)-->/) {	# Dateien und Bilder als Anhang
					$tmp=$1;
					@tmpArray=getImageSize("tmp_".$FORM{$tmp});	# Bildformat und -grösse bestimmen
					if (((@tmpArray[0] < 1) or ($tmpArray[1] < 1)) and ($tmp =~ m/^image/)) {	# ungültiges Bild bei einem image-Feld
						unlink "tmp_".$FORM{$tmp};
					}
					$tmpArray[90]=&attachment($tmp);
					$_ =~ s/<!--.*?-->/$tmpArray[90]/gi;
				}
				$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
				$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
				$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
				$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
				$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
				$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
				$_ =~ s/<!--detailurl-->/$COMPCGIURL?action=viewad&amp;cat=$cat[0]&amp;id=$FORM{id}/gi;
				$_ =~ s/<!--messageid-->/$messageID/gi;
				$_ =~ s/<!--boundary-->/$boundary/gi;
				print MAIL "$_\n";
			}
			close(FILE);
			close(MAIL);
			foreach (keys(%FORM)) {
				if ($_ =~ m/(image\d*|FILE_.*)/) {	# Dateien wieder löschen
					unlink &secureFilename("tmp_".$FORM{$1});
				}
			}
			if (($CONFIG{"floodMai"} eq "Y") and ($CONFIG{"floodSek"} > 0)) {	# Flood-Sperre updaten
				$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}}=time;
				if (&lockFile($CONFIG{"dataFile"})) {
					&saveDataFile;
					&unlockFile($CONFIG{"dataFile"});
				}
			}
			$sysMsg="sysCoOK";
			&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}&sysMsg=$sysMsg");
		}
	}
	print "Content-type: text/html\n\n";
	open(TEMPLATE,&secureFilename($cat[14]));
	while (<TEMPLATE>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
			&includeFile($1);
		}
		$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^(sys|err)/);
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--catname-->/$cat[1]/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--field:rimage(\d*)-->/$ad{"image".$1}/gi;
		if (($_ =~ m/<!--field:image(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {
			$_ =~ s/<!--field:image(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$ad{"image".$1}\"$2 alt=\"$ad{"image".$1}\" \/>/gi;
		}
		if (($_ =~ m/<!--field:timage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails
			$_ = &thumbImageAsHTML($1, $2, $_, 0);
		}
		if (($_ =~ m/<!--field:rtimage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails als RAW-Code
			$_ = &thumbImageAsHTML($1, $2, $_, 1);
		}
		$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
		$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
		$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
		$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
		$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
		$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
		$_ =~ s/<!--if:field:(.*?)§(.*?)-->/&ifQuery($1,$2,\%ad)/egi;
		$_ =~ s/<!--if:form:(.*?)§(.*?)-->/&ifQuery($1,$2,\%FORM)/egi;
		$_ =~ s/<!--contact-->/$COMPCGIURL?action=contact&amp;cat=$FORM{"cat"}&amp;id=$FORM{"id"}/gi;
		$_ =~ s/<!--recommend-->/$COMPCGIURL?action=recommend&amp;cat=$FORM{"cat"}&amp;id=$FORM{"id"}/gi;
		$_ =~ s/<!--detailurl-->/$COMPCGIURL?action=viewad&amp;cat=$cat[0]&amp;id=$FORM{"id"}/gi;
		$_ =~ s/<!--scid-->/$serverTime/gi;
		if ($_ =~ m/<!--scyes-->/i) {								# Zeile enthält scyes
			if (($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "M")) {	# SecureCode aktiviert...
				$_=~ s/<!--scyes-->//gi;								# ...Tag entfernen
			} else {																	# SecureCode nicht aktiviert...
				$_="";																	# ...komplette Zeile entfernen
			}
		}
		print "$_\n";
	}
	close(TEMPLATE);
	exit(0);
}


###########################################################################
# RECOMMEND: Inserat an Drittperson weiterempfehlen
###########################################################################
if ($FORM{"action"} eq "recommend") {
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	foreach (keys(%FORM)) {												# Zeilenumbrüche immer nach \n wandeln
		$FORM{$_}=&zeilenUmbruch($FORM{$_},"\n");
	}
	$status=0;
	open(FILE,&secureFilename($cat[2]));
	while (<FILE>) {
		if ($_ =~ m/^$FORM{"id"}\t/) {							# Inserat suchen und einlesen
			$status++;
			&parseAd($_);
			last;
		}
	}
	close(FILE);
	if ($status < 1) {														# Inserat nicht gefunden --> zurück zum Eintrag
		&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}");
	}
	if ($FORM{"do"} ne "") {
		if (($FORM{"message"} eq "") or ($FORM{"rcptname"} eq "") or (&invalidMail($FORM{"rcptmail"},1)) or ($FORM{"sendname"} eq "") or (&invalidMail($FORM{"sendmail"},1)) or ($FORM{"subject"} eq "")) {
			$FORM{"sysMsg"}="sysCont"; 								# nicht alle Pflichtfelder
		} elsif ((($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "M")) and (($FORM{"scid"} eq "") or ($FORM{"seccode"} eq "") or ($DATA{"SC".$FORM{"scid"}} ne $FORM{"seccode"}))) {
			$FORM{sysMsg}="errSCod"; 									# Secure-Code erforderlich aber nicht vorhanden oder falsch
		} elsif (($CONFIG{"floodMai"} eq "Y") and ($CONFIG{"floodSek"} > 0) and (time-$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}} < $CONFIG{"floodSek"})) {
			$FORM{sysMsg}="errFloo"; 									# Flood-Sperre unterschritten
		} else {
			if ($mailVersand eq "TRUE") {
				$ENV{"PATH"} = "/bin:/usr/bin:/usr/sbin";
				open MAIL, "| ".&secureFilename($CONFIG{"sendmail"})." -oi -t" or die "Sendmail konnte nicht geöffnet werden";
			} else {
				open(MAIL,">mail.eml") || die "Kann EML-Datei nicht schreiben! Error : $!\n";
			}
			if ($cat[19] ne "") {											# Spezielles Weiterempfehlungsmail für diese Rubrik definiert
				$CONFIG{"recoMail"}=$cat[19];
			}
			open(FILE,&secureFilename($CONFIG{"recoMail"}));
			while (<FILE>) {
				chomp;
				$_ =~ s/[\r\n]//g;
				$_ =~ s/<!--date-->/$mailDate/gi;
				$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
				$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
				$_ =~ s/<!--action-->/$FORM{"action"}/gi;
				$_ =~ s/<!--scriptVersion-->/$version/gi;
				$_ =~ s/<!--id-->/$FORM{"id"}/gi;
				$_ =~ s/<!--cat-->/$cat[0]/gi;
				$_ =~ s/<!--catname-->/$cat[2]/gi;
				$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
				$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
				$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
				$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
				$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
				$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
				$_ =~ s/<!--detailurl-->/$COMPCGIURL?action=viewad&amp;cat=$cat[0]&amp;id=$FORM{"id"}/gi;
				$_ =~ s/<!--messageid-->/$messageID/gi;
				$_ =~ s/<!--boundary-->/$boundary/gi;
				print MAIL "$_\n";
			}
			close(FILE);
			close(MAIL);
			if (($CONFIG{"floodMai"} eq "Y") and ($CONFIG{"floodSek"} > 0)) {	# Flood-Sperre updaten
				$DATA{"IPFLOOD_".$ENV{"REMOTE_ADDR"}}=time;
				if (&lockFile($CONFIG{"dataFile"})) {
					&saveDataFile;
					&unlockFile($CONFIG{"dataFile"});
				}
			}
			$sysMsg="sysCoOK";
			&sendURL("$COMPCGIURL?action=viewad&cat=$FORM{cat}&id=$FORM{id}&sysMsg=$sysMsg");
		}
	}
	print "Content-type: text/html\n\n";
	open(TEMPLATE,&secureFilename($cat[17]));
	while (<TEMPLATE>) {
		chomp;
		if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
			&includeFile($1);
		}
		$_ =~ s/<!--SYSTEMMESSAGE-->/$CONFIG{$FORM{"sysMsg"}}/gi if ($FORM{"sysMsg"} =~ m/^(sys|err)/);
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--catname-->/$cat[1]/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--field:rimage(\d*)-->/$ad{"image".$1}/gi;
		if (($_ =~ m/<!--field:image(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {
			$_ =~ s/<!--field:image(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$ad{"image".$1}\"$2 alt=\"$ad{"image".$1}\" \/>/gi;
		}
		if (($_ =~ m/<!--field:timage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails
			$_ = &thumbImageAsHTML($1, $2, $_, 0);
		}
		if (($_ =~ m/<!--field:rtimage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails als RAW-Code
			$_ = &thumbImageAsHTML($1, $2, $_, 1);
		}
		$_ =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
		$_ =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
		$_ =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
		$_ =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
		$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
		$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
		$_ =~ s/<!--contact-->/$COMPCGIURL?action=contact&cat=$FORM{"cat"}&id=$FORM{"id"}/gi;
		$_ =~ s/<!--recommend-->/$COMPCGIURL?action=recommend&cat=$FORM{"cat"}&id=$FORM{"id"}/gi;
		$_ =~ s/<!--detailurl-->/$COMPCGIURL?action=viewad&cat=$cat[0]&id=$FORM{"id"}/gi;
		$_ =~ s/<!--scid-->/$serverTime/gi;
		if ($_ =~ m/<!--scyes-->/i) {								# Zeile enthält scyes
			if (($CONFIG{"secCode"} eq "Y") or ($CONFIG{"secCode"} eq "M")) {	# SecureCode aktiviert...
				$_=~ s/<!--scyes-->//gi;								# ...Tag entfernen
			} else {																	# SecureCode nicht aktiviert...
				$_="";																	# ...komplette Zeile entfernen
			}
		}
		print "$_\n";
	}
	close(TEMPLATE);
	exit(0);
}


###########################################################################
# SEARCH: Suche starten
###########################################################################
if ($FORM{"action"} eq "search") {
	print "Content-type: text/html\n\n";
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	if (-e $cat[16]) {
		open(TEMPLATE,&secureFilename($cat[16]));
		while (<TEMPLATE>) {
			$_ =~ s/<!--cat-->/$cat[0]/gi;
			$_ =~ s/<!--catname-->/$cat[1]/gi;
			$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
			$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
			$_ =~ s/<!--action-->/$FORM{"action"}/gi;
			$_ =~ s/<!--scriptVersion-->/$version/gi;
			$_ =~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%FORM)/egi;
			$_ =~ s/<!--form:(.*?)-->/$FORM{$1}/gi;
			$_ =~ s/<!--formh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
			if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
				&includeFile($1);
			}
			print $_;
		}
		close(TEMPLATE);
	}
	exit(0);
}


###########################################################################
# VALIDATE: Eintrag validieren
###########################################################################
if ($FORM{"action"} eq "validate") {
	$status=0;
	&getCat($FORM{"cat"});												# Kategoriedaten einlesen
	if ($cat[5] eq "") {													# Kategorie nicht gefunden --> Fehler 404
		&notFound;
	}
	if ($cat[22] ne "") {													# Wenn Validierung für diese Kategorie besoders geregelt --> Einstellung übernehmen
		$CONFIG{"valMail"}=$cat[22];
	}
	if (&lockFile($cat[2])) {
		open(INPUT,&secureFilename($cat[2]));
		open(OUTPUT,">".&secureFilename($cat[2].".tmp"));
		while (<INPUT>) {
			if ($_ =~ m/^$FORM{"id"}\t.*validated=(.)(\d*)/) {	# Zeile gefunden --> Validierung kontrollieren
				$id=$1;
				$id2=$2;
				if (($FORM{"val"} eq "admin") and ($FORM{"id2"} eq $id2)) {
					$status++;														# Admin-Validierung
					if (($CONFIG{"valMail"} eq "N") or ($CONFIG{"valMail"} eq "A")) {
						$id="Y";														# Keine Validierung oder Validierung durch Admin notwendig --> aktivieren
						$id2="";
					}
					if ($CONFIG{"valMail"} eq "Y") {
						$id="A";
					} elsif (($CONFIG{"valMail"} eq "B") and ($id eq "U")) {
						$id="Y";														# Validierung durch User+Adm notwendig, Val. durch Usr OK --> aktivieren
						$id2="";
					} elsif (($CONFIG{"valMail"} eq "B") and (($id eq "A") or ($id eq "N"))) {
						$id="A"; 														# Validierung durch User+Adm notwendig, Keine Val. durch Usr --> Status A
					}
					$_ =~ s/\tvalidated=.\d*\t/\tvalidated=$id$id2\t/g;
				} elsif ($FORM{"val"} eq "") {					# Benutzer-Validierung
					$status++;
					if (($CONFIG{"valMail"} eq "N") or ($CONFIG{"valMail"} eq "Y")) {
						$id="Y";														# Keine Validierung oder Validierung durch User notwendig --> aktivieren
						$id2="";
					} elsif (($CONFIG{"valMail"} eq "B") and ($id eq "A")) {
						$id="Y";														# Validierung durch User+Adm notwendig, Val. durch Adm OK --> aktivieren
						$id2="";
					} elsif (($CONFIG{"valMail"} eq "B") and (($id eq "N") or ($id eq "U"))) {
						$id="U"; 														# Validierung durch User+Adm notwendig, Keine Val. durch Adm --> Status U
					}
					$_ =~ s/\tvalidated=.\d*\t/\tvalidated=$id$id2\t/g;
				}
			}
			print OUTPUT $_;
		}
		close(OUTPUT);
		close(INPUT);
		unlink &secureFilename($cat[2]);
		rename &secureFilename($cat[2].".tmp"), &secureFilename($cat[2]);
		if ($status) {															# Eintrag gefunden
			if ($id eq "Y") {
				$sysMsg="sysVali";
			} elsif (($id eq "U") or ($id eq "N")) {
				$sysMsg="sysVaAR";
			} elsif (($id eq "A")) {
				$sysMsg="sysValR";
			}
		} else {																		# Eintrag nicht gefunden
			$sysMsg="sysValE";
		}
		&unlockFile($cat[2]);
	} else {
		$sysMsg="errFile";
	}
	&sendURL("$COMPCGIURL?action=viewcat&cat=$FORM{cat}&sysMsg=$sysMsg");
}


###########################################################################
# SECCODE: Secure-Code anzeigen
###########################################################################
if ($FORM{"action"} eq "seccode") {
	if ($FORM{"id"} == 0) {												# Abbruch, wenn keine ID
		exit(1);
	}
	if ($DATA{"SC".$FORM{"id"}} > 0) {						# ID in Data-File --> verwenden
		$id=$DATA{"SC".$FORM{"id"}};
	} else {																			# nicht in Data-File --> generieren und speichern
		$id=sprintf("%5.5d",int(rand(100000)));
		$DATA{"SC".$FORM{"id"}}=$id;
		if (&lockFile($CONFIG{"dataFile"})) {
			&saveDataFile;
			&unlockFile($CONFIG{"dataFile"});
		}
	}
	&drawSecCode($id, $CONFIG{"secCodeI"}, $CONFIG{"secCodC1"}, $CONFIG{"secCodC2"});
	exit(0);
}


###########################################################################
# Übersicht
###########################################################################
if ($FORM{"action"} eq "") {
	print "Content-type: text/html\n\n";
	print "<html><head><title>Marktplatz</title>";
	# CSS
	open(CSS,&secureFilename($CONFIG{"CSS"}));
	print "<style type=\"text/css\">\n<!--\n";
	while (<CSS>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		print "$_\n";
	}
	close(CSS);
	print "-->\n</style>\n";
	# /CSS
	print "</head><body>";
	if (-e $CONFIG{"catFile"}) {
		open(CATFILE,&secureFilename($CONFIG{"catFile"}));
		foreach (<CATFILE>) {
			chomp;
			$_ =~ s/[\r\n]//g;
			@splitArray=split(/\t/);
			print "<b>$splitArray[1]</b><br />\n<a href=\"$COMPCGIURL?action=viewcat&amp;cat=$splitArray[0]\">$COMPCGIURL?action=viewcat&amp;cat=$splitArray[0]</a><br /><br />\n\n";
		}
		close(CATFILE);
	}
	print "</body></html>";
	exit(0);
}


###########################################################################
# 404 page not found
###########################################################################
&notFound;


###########################################################################
# Subroutinen
###########################################################################
sub readForm {					# Parameter in %FORM einlesen
	my ($buffer,@pairs,@pair,$i);
	if ($ENV{'REQUEST_METHOD'} eq "GET") {
		$buffer = $ENV{'QUERY_STRING'};
	} else {
		binmode(STDIN);
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	}
	$buffer=~ s/(>|%3E)$//gi;											# > am Ende löschen
	if ($buffer =~ m/------.*\n?.*Content/) {	# Mutlipart-Encoded
		&getUploadData($buffer);
	} else {
		@pairs = split(/&/, $buffer);
		foreach (@pairs) {
			@pair = split(/=/, $_, 2);
			for ($i=0;$i<2;$i++) {
				$pair[$i] =~ tr/+/ /;
				$pair[$i] =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			}
			$FORM{$pair[0]} = $pair[1];
		}
	}
	$buffer = $ENV{'HTTP_COOKIE'};								# Cookies auslesen
	@pairs = split(/; /,$buffer);
	foreach (@pairs) {
		@pair = split(/=/, $_, 2);
		$pair[1]=~ s/^\"//;													# Leerzeichen am Anfang und Ende entfernen
		$pair[1]=~ s/\"$//;
		$COOKIE{$pair[0]} = &jsDecrypt($pair[1],"COOKIEcrypt");
	}
	if ($FORM{"x"} =~ m/^\d+$/) {									# X- und Y-Variablen löschen (Image-Button)
		delete($FORM{"x"});
	}
	if ($FORM{"y"} =~ m/^\d+$/) {
		delete($FORM{"y"});
	}
}
###########################################################################
sub readConfig {				# Config-File in %CONFIG einlesen
	my (@pair);
	if (-e $configFile) {
		open(CONFIG,&secureFilename($configFile));
		while (<CONFIG>) {
			chomp;
			$_ =~ s/[\r\n]//g;
			(@pair) = split(/=/, $_, 2);
			$CONFIG{$pair[0]} = $pair[1] if ($pair[0] ne "#!");
		}
		close(CONFIG);
	}
}
###########################################################################
sub saveConfig {				# Speichert die Config-Datei
	open(CONFIG,">".&secureFilename($configFile));
	print CONFIG "#!\n";
	foreach (sort keys(%CONFIG)) {
		if (($CONFIG{$_} ne "") and ($_ ne "")) {
			$CONFIG{$_}=&zeilenUmbruch($CONFIG{$_},"§§");
			print CONFIG $_."=".$CONFIG{$_}."\n";
		}
	}
	close(CONFIG);
}
###########################################################################
sub zeilenUmbruch {			# wandelt Zeilenumbrüche in ein beliebiges Zeichen um
	my $returnValue=$_[0];
	if ($_[2]) {	# Zeilenumbruch wieder darstellen
			$returnValue=~ s/$_[1]/\n/g;
	} else {	# Zeilenumbruch in Zeichen umwandeln
		if ($returnValue =~ m/\n/) {
			$returnValue=~ s/\n/$_[1]/g;
			$returnValue=~ s/\r//g;
		} else {
			$returnValue=~ s/\r/$_[1]/g;
		}
	}
	return $returnValue;
}
###########################################################################
sub readDataFile {			# Data-File in %DATA einlesen
	my (@pair);
	if (-e $CONFIG{"dataFile"}) {
		open(DATA, &secureFilename($CONFIG{"dataFile"}));
		while (<DATA>) {
			chomp;
			$_ =~ s/[\r\n]//g;
			(@pair) = split(/=/, $_, 2);
			$DATA{$pair[0]} = $pair[1]  if ($pair[0] ne "#!");
		}
		close(DATA);
	}
}
###########################################################################
sub saveDataFile {			# Data-File speichern
	my $nowTime=time;
	open(DATA,">".&secureFilename($CONFIG{"dataFile"}));
	print CONFIG "#!\n";
	foreach (sort keys(%DATA)) {
		if (($_ =~ m/^IPFLOOD_/) and (time-$DATA{$_} > $CONFIG{"floodSek"})) {
			$DATA{$_}="";															# abgelaufene Flood-Sperre
		}
		if ($_ =~ m/^SC(\d+)$/) {
			if ($1 < $serverTime-(60*60*5)) {
				$DATA{$_}="";														# abgelaufener Secure-Code
			}
		}
		print DATA "$_=$DATA{$_}\n" if ($DATA{$_} ne "");
	}
	close(DATA);
}
###########################################################################
sub HTMLbegin {					# HTML-Header
	print "Content-type: text/html\n\n";
	print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n";
	print "<html>\n<head>\n<title>jsMarket - Administration</title>\n<meta http-equiv=\"content-type\" content=\"text/html;charset=iso-8859-1\">\n";
	# CSS
	open(CSS,&secureFilename($CONFIG{"CSS"}));
	print "<style type=\"text/css\">\n<!--\n";
	while (<CSS>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		print "$_\n";
	}
	close(CSS);
	print "-->\n</style>\n";
	# /CSS
	print "$_[0]";
	print "</head>\n<body>\n<a name=\"top\"></a>\n<img src=\"$CONFIG{imgDir}$CONFIG{admiLogo}\" alt=\"\"/><br />\n";
	print "<img width=\"100%\" height=\"2\" src=\"$CONFIG{imgDir}$CONFIG{lineGIF}\" alt=\"\"/>\n";
	print "<table width=\"100%\" border=\"0\"><tr><td>&nbsp;</td><td><div class=\"right\">";
	if (($FORM{"action"} eq "admin") or ($FORM{"action"} eq "logout") or ($FORM{"action"} eq "main")) {
		print "<img src=\"$CONFIG{imgDir}$CONFIG{backGifI}\" alt=\"zur&uuml;ck zum Hauptmen&uuml;\" title=\"zur&uuml;ck zum Hauptmen&uuml;\"/>\n";
	} else {
		print "<a href=\"$COMPCGIURL?action=main&amp;ASID=$FORM{ASID}\"><img src=\"$CONFIG{imgDir}$CONFIG{backGifA}\" border=\"0\" alt=\"zur&uuml;ck zum Hauptmen&uuml;\" title=\"zur&uuml;ck zum Hauptmen&uuml;\"/></a>\n";
	}
	print "<img src=\"$CONFIG{imgDir}$CONFIG{topGifI}\" alt=\"zum Anfang des Dokuments\" title=\"zum Anfang des Dokuments\"/><a href=\"#bottom\"><img src=\"$CONFIG{imgDir}$CONFIG{bottGifA}\" border=\"0\" alt=\"zum Ende des Dokuments\" title=\"zum Ende des Dokuments\"/></a>";
	if (($FORM{"action"} eq "admin") or ($FORM{"action"} eq "logout")) {
		print "<a href=\"$COMPCGIURL?action=admin\"><img src=\"$CONFIG{imgDir}$CONFIG{loginGIF}\" border=\"0\" alt=\"Anmelden\" title=\"Anmelden\"/></a>\n";
	} else {
		print "<a href=\"$COMPCGIURL?action=logout\"><img src=\"$CONFIG{imgDir}$CONFIG{logoutGIF}\" border=\"0\" alt=\"Abmelden\" title=\"Abmelden\"></a>\n";
	}
	print "</div></td></tr></table>\n\n";
}
###########################################################################
sub HTMLend {						# HTML-Schluss
	print "<br /><br /><br /><div class=\"right\">\n";
	if (($FORM{"action"} eq "admin") or ($FORM{"action"} eq "logout") or ($FORM{"action"} eq "main")) {
		print "<img src=\"$CONFIG{imgDir}$CONFIG{backGifI}\" alt=\"zur&uuml;ck zum Hauptmen&uuml;\" />\n";
	} else {
		print "<a href=\"$COMPCGIURL?action=main&amp;ASID=$FORM{ASID}\"><img src=\"$CONFIG{imgDir}$CONFIG{backGifA}\" border=\"0\" alt=\"zur&uuml;ck zum Hauptmen&uuml;\" /></a>\n";
	}
	print "<a href=\"#top\"><img src=\"$CONFIG{imgDir}$CONFIG{topGifA}\" border=\"0\" alt=\"zum Anfang des Dokuments\" /></a><img src=\"$CONFIG{imgDir}$CONFIG{bottGifI}\" alt=\"zum Ende des Dokuments\" />";
	if (($FORM{"action"} eq "admin") or ($FORM{"action"} eq "logout")) {
		print "<a href=\"$COMPCGIURL?action=admin\"><img src=\"$CONFIG{imgDir}$CONFIG{loginGIF}\" border=\"0\" alt=\"Anmelden\" /></a>\n";
	} else {
		print "<a href=\"$COMPCGIURL?action=logout\"><img src=\"$CONFIG{imgDir}$CONFIG{logoutGIF}\" border=\"0\" alt=\"Abmelden\" /></a>\n";
	}
	my $copyright=$CONFIG{"copyright"};
	$copyright=~ s/((mailto:)?[A-Z0-9\.\-]+\@[A-Z0-9\.\-]+\.[A-Z]+)/&encodeMail($1)/egi;
	print <<HTMLtext;
	<img width="100%" height="2" src="$CONFIG{imgDir}$CONFIG{lineGIF}" alt="" /></div>
	<table width="100%">
	<tr valign="top">
	<td><span class="copyright">$copyright</span></td>
	<td class="right"><span class="copyright"><a href="$CheckNewVersionURL" target="_blank" title="Online Versions-Check">Version $version</a><br/>Letzte &Auml;nderung: $lastMod</span></td>
	</tr></table>
	<a name="bottom"></a>&nbsp;</body></html>
HTMLtext
}
###########################################################################
sub forbidden {					# Access denided Fehlermeldung und Abbruch
	&sendURL("$COMPCGIURL?action=admin&".&formParams("action\terror")."error=$_[0]");
}
###########################################################################
sub sendURL {						# &sendURL("http://redirect.to");
	my $url=$_[0];
	$url =~ s/&amp;/&/g;
	print "Location: $url\n\n";
	exit(0);
}
###########################################################################
sub formParams {				# &formParams("wert1\twert2\twert3"); Alle Parameter ausser angegebene
	my $notValues=$_[0];
	$notValues="\t".$notValues."\t";
	my $formParam="";
	foreach (sort keys(%FORM)) {
		if ($notValues !~ m/\t$_\t/) {
			$formParam.= "$_=$FORM{$_}&amp;";
		}
	}
	return $formParam;
}
###########################################################################
sub mygmtime {					# GMT-Zeitformat für Cookies setzen
	my (@date, @months, @days,$timestr);
	(@date)=gmtime($_[0]);
	@months = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	@days = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
	$timestr = sprintf("%3s, %02d-%3s-%4d %02d:%02d:%02d GMT",$days[$date[6]],$date[3],$months[$date[4]],$date[5]+1900,$date[2],$date[1],$date[0]);
	return $timestr;
}
###########################################################################
sub inputField {				# print &inputField("Text","FeldName","FeldDefault","Ergänz.Text","FeldTyp");
	my (%felder, $inputFieldTMP);
	my $value=$_[2];
	$value =~ s/&/&amp;/g;
	$value =~ s/ä/&auml;/g;
	$value =~ s/ö/&ouml;/g;
	$value =~ s/ü/&uuml;/g;
	$value =~ s/Ä/&Auml;/g;
	$value =~ s/Ö/&Ouml;/g;
	$value =~ s/Ü/&Uuml;/g;
	$value =~ s/\"/&quot;/g;
	$value =~ s/</&lt;/g;
	$value =~ s/>/&gt;/g;
	$felder{"300var"}="type=\"text\" size=\"50\" class=\"var300\"";
	$felder{"300varpass"}="type=\"password\" size=\"50\" class=\"var300\"";
	$felder{"160var"}="type=\"text\" size=\"50\" class=\"var160\"";
	$felder{"160varpass"}="type=\"text\" size=\"50\" class=\"var160\"";
	$felder{"button"}="type=\"submit\" size=\"50\" class=\"button\"";
	$felder{"300button"}="type=\"submit\" size=\"50\" class=\"button300\"";
	$inputFieldTMP="<tr>\n<td>$_[0]&nbsp;&nbsp;&nbsp;</td>\n<td><input ".$felder{$_[4]}." ";
	$inputFieldTMP.="name=\"$_[1]\" " if ($_[1] ne "");
	$inputFieldTMP.="value=\"$value\" alt=\".\"/> $_[3]</td>\n</tr>\n";
	return $inputFieldTMP;
}
###########################################################################
sub yesNoRadio {					# Tabellenzeile mit Dropdown print &yesNoRadio("title","name","name1§§name2§§name3","value1§§value2§§value3","addText","css");
	my $title=$_[0];
	my $name=$_[1];
	my @names=split(/§§/,$_[2]);
	my @values=split(/§§/,$_[3]);
	my $addText=$_[4];
	my $style=$_[5];
	my $tmpI;
	my $yesNoRadioTMP="<tr><td>$title</td><td>";
	for ($tmpI=0;$tmpI<scalar(@names);$tmpI++) {
		$yesNoRadioTMP.="<input type=\"radio\" name=\"$name\" value=\"$values[$tmpI]\" class=\"$style\"";
		$yesNoRadioTMP.=" checked" if ($CONFIG{$name} eq $values[$tmpI]);
		$yesNoRadioTMP.=" />$names[$tmpI]&nbsp;&nbsp;&nbsp;&nbsp;\n";
	}
	$yesNoRadioTMP.="$addText</td></tr>\n";
	return $yesNoRadioTMP;
}
###########################################################################
sub dropDown {					# Tabellenzeile mit Dropdown print &dropDown("title","name","name1§§name2§§name3","value1§§value2§§value3","addText","css");
	my $title=$_[0];
	my $name=$_[1];
	my @names=split(/§§/,$_[2]);
	my @values=split(/§§/,$_[3]);
	my $addText=$_[4];
	my $style=$_[5];
	my $tmpI;
	my $dropdownTMP="<tr><td>$title</td><td><select name=\"$name\" class=\"$style\">";
	for ($tmpI=0;$tmpI<scalar(@names);$tmpI++) {
		$dropdownTMP.="<option value=\"$values[$tmpI]\"";
		$dropdownTMP.=" selected" if ($CONFIG{$name} eq $values[$tmpI]);
		$dropdownTMP.=">$names[$tmpI]</option>\n";
	}
	$dropdownTMP.="</select> $addText</td></tr>\n";
	return $dropdownTMP;
}
###########################################################################
# Function: &setTimeZones;
# Definiert Hash %timeZone und ermittelt die GMT-Zeitzone des Servers
sub setTimeZones {
	my (@localTimeArray, @gmTimeArray, $timeDiff);
	$timeZone{"T-1200"}="-1200 Eniwetok, Kwajalein";
	$timeZone{"T-1100"}="-1100 Midway-Islands, Samoa";
	$timeZone{"T-1000"}="-1000 Hawaii";
	$timeZone{"T-0900"}="-0900 Alaska";
	$timeZone{"T-0800"}="-0800 Pacific Time (Los Angeles, Seattle)";
	$timeZone{"T-0700"}="-0700 Mountain Time (Arizona, Denver)";
	$timeZone{"T-0600"}="-0600 Central Time (Chicago, Mexico City)";
	$timeZone{"T-0500"}="-0500 Eastern Time (Atlanta, New York)";
	$timeZone{"T-0400"}="-0400 Atlantic Time (Montreal, Santiago)";
	$timeZone{"T-0300"}="-0300 Brazilia, Buenos Aires, Greenland";
	$timeZone{"T-0200"}="-0200 Mid-Atlantic";
	$timeZone{"T-0100"}="-0100 Azores";
	$timeZone{"T+0000"}="-0000 Greenwich Mean Time (London)";
	$timeZone{"T+0100"}="+0100 Berlin, Bern, Madrid, Paris, Rome";
	$timeZone{"T+0200"}="+0200 Athen, Helsinki, Istanbul, Kairo";
	$timeZone{"T+0300"}="+0300 Bagdad, Moscow, Nairobi";
	$timeZone{"T+0400"}="+0400 Abu Dhabi, Baku, Muskat, Tiflis";
	$timeZone{"T+0500"}="+0500 Islamabad, New Delhi, Taschkent";
	$timeZone{"T+0600"}="+0600 Almaty, Astana, Dhakar";
	$timeZone{"T+0700"}="+0700 Bangkok, Hanoi,  Jakarta";
	$timeZone{"T+0800"}="+0800 Hong Kong, Peking, Singapore";
	$timeZone{"T+0900"}="+0900 Osaka, Sapporo, Seoul, Tokyo";
	$timeZone{"T+1000"}="+1000 Brisbane, Wladiwostok, Sydney";
	$timeZone{"T+1100"}="+1100 Magadan, Salomonen";
	$timeZone{"T+1200"}="+1200 Auckland, Fidschi, Wellington";
	(@gmTimeArray)=gmtime();
	(@localTimeArray)=localtime(time);
	$timeDiff=$localTimeArray[2]-$localTimeArray[8]-$gmTimeArray[2];
	$timeDiff+=24 if ($timeDiff < 0);
	$timeDiff-=24 if ($timeDiff > 12);
	$timeZone{"auto"}=$timeDiff;
	$timeZone{"autoSummer"}=$timeDiff+$localTimeArray[8]+$CONFIG{"summerTim"};
}
###########################################################################
# Function: &setMailTime
# Zeit für Mailversand in <$mailDate> setzen
sub setMailTime {
	my $timeValue=$_[0];
	my (@dateValues, @dateValues1, @engWochentag,@deuWochentag, @engMonate, @deuMonate, $stTmp);
	@engWochentag = qw(Sun Mon Tue Wed Thu Fri Sat);
	@engMonate = qw(&nbsp; Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
	@deuWochentag = qw(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag);
	@deuMonate = qw(&nbsp; Januar Februar März April Mai Juni Juli August September Oktober November Dezember);
	$stTmp=$CONFIG{"gmTimeZ"};
	$stTmp=$timeZone{"auto"} if ($CONFIG{"gmTimeZ"}==99);
	if ($timeValue > 0) {
		(@dateValues1) = localtime($timeValue);
		(@dateValues) = gmtime($timeValue+($CONFIG{"timeZone"}+$stTmp+$dateValues1[8]+$CONFIG{"summerTim"})*3600);
	} else {
		(@dateValues1) = localtime(time);
		(@dateValues) = gmtime(time+($CONFIG{"timeZone"}+$stTmp+$dateValues1[8]+$CONFIG{"summerTim"})*3600);
		$serverTime=timelocal($dateValues[0],$dateValues[1],$dateValues[2],$dateValues[3],$dateValues[4],$dateValues[5]);
	}
	$dateValues[90]=sprintf("%04.4d",($stTmp+$dateValues1[8]+$CONFIG{"summerTim"})*100);
	if ($dateValues[90] >= 0) {
		$dateValues[90]="+".$dateValues[90];
	}
	if ($dateValues[5] < 1900) {
		$dateValues[5]+=1900;
	}
	$dateValues[4]++;
	$dateValues[0]=sprintf("%2.2d", $dateValues[0]);
	$dateValues[1]=sprintf("%2.2d", $dateValues[1]);
	$dateValues[2]=sprintf("%2.2d", $dateValues[2]);
	$dateValues[3]=sprintf("%2.2d", $dateValues[3]);
	$dateValues[4]=sprintf("%2.2d", $dateValues[4]);
	if ($timeValue > 0) {
		$dmmmmyyyyDate2 = int($dateValues[3]).". ".$deuMonate[$dateValues[4]]." ".$dateValues[5];
	} else {
		$mailDate = $engWochentag[$dateValues[6]].", ".$dateValues[3]." ".$engMonate[$dateValues[4]]." ".$dateValues[5]." ".$dateValues[2].":".$dateValues[1].":".$dateValues[0]." ".$dateValues[90];
		$mailDate2=$dateValues[5].$dateValues[4].$dateValues[3].$dateValues[2].$dateValues[1].$dateValues[0];
		$dmmmmyyyyDate = int($dateValues[3]).". ".$deuMonate[$dateValues[4]]." ".$dateValues[5];
		$yyyymmddDate = sprintf("%04.4d%02.2d%02.2d", $dateValues[5], $dateValues[4], $dateValues[3]);
		$todayUNIX=timelocal(0,0,0,$dateValues[3],$dateValues[4]-1,$dateValues[5]);
	}
}
###########################################################################
sub getUploadData {			# Bild uploaden
	my ($status,@content,$name,$filename,$tmp);
	@content=split(/\n/,$_[0]);										# Zeilenweise aufsplitten
	$status=0;
	$name="";
	$filename="";
	foreach (@content) {													# übergebene Daten zeilenweise verarbeiten
		chomp;
		if ($status == 0) {													# Status 0 --> erwarte neue Eingaben / Eingaben in Datei speichern
			if ($_ =~ m/^------/) {										# Neues Feld
				if ($filename ne "") {									# $filename gesetzt --> Datei muss geschlossen werden.
					close(FILE);
					if ((($name !~ m/^image\d*$/) and ($name !~ m/^FILE_/)) or  (($name =~ m/^FILE_/) and ($CONFIG{"fileUpl"} ne "Y"))) {	# Uploaded Data nur in Feldern image* und FILE_* (FILE nur wenn Upload erlaubt) erlaubt. Sonst wieder löschen
						unlink &secureFilename("tmp_".$filename);
					}
				}
				$status=1;															# setze Status auf 1
			} else {																	# vorhandene Daten in Datei schreiben
				if ($filename ne "") {
					print FILE "$_\n";
				} else {
					$FORM{$name}.="\n$_";
				}
			}
		} elsif ($status == 1) {										# Status = 1 --> Name auslesen
			$_ =~ m/; name=\"(.*?)\"/;								# Name des Feldes auslesen
			$name=$1;
			$name=~ s/[\r\n]//g;
			if ($_ =~ m/filename=\"(.*?)\"/) {				# Dateiname übergeben?
				$filename=&fileNameOnly($1); 						# Pfad wegschneiden
			} else {
				$filename=""; 													# Dateiname leer lassen
			}
			$status=2;																# setze Status auf 2
		} elsif ($status == 2) {										# leere Zeile --> weglassen
			$status = 3;
		} elsif ($status == 3) {										# Status = 3 --> Inhalt verarbeiten
			if ($filename eq "") {										# Dateiname leer
				$tmp=$_;
				$tmp=~ s/[\r\n]//g;
				$FORM{$name} = $tmp;										# --> normales Feld
			} else {																	# Dateiname gesetzt
				$filename=~ s/[^A-Z0-9\_\-\.]//gi;				# Sonderzeichen aus Dateiname löschen
				open(FILE,"> tmp_".&secureFilename($filename));	# Dateiinhalt --> Binärdatei erstellen
				binmode(FILE);
				$FORM{$name}=$filename;									# Dateiname in Variable setzen
			}
			$status=0;
		}
	}
}
###########################################################################
sub fileNameOnly {			# Gibt Dateiname zurück &fileNameOnly("Dateiname inkl. Pfad");
	my $tmp=$_[0];
	$tmp=~ m/^.*[\\\/](.*)$/;
	return $1;
}
###########################################################################
sub getImageSize {			# Bildgrösse anhand des Dateitypes bestimmen
	my ($width,$height);
	if ($_[0] =~ m/\.gif$/i) {
		($width,$height)=getImageSizeGIF($_[0]);
	} elsif ($_[0] =~ m/\.jpe?g$/i) {
		($width,$height)=getImageSizeJPG($_[0]);
	} elsif ($_[0] =~ m/\.PNG$/i) {
		($width,$height)=getImageSizePNG($_[0]);
	}
	return ($width,$height);
}
###########################################################################
sub getImageSizeGIF {		# Bildgrösse von GIF-Dateien bestimmen
	my ($lf,$image,$width,$height,$s,@size);
	$lf=$/;
	undef $/;
	open(IMAGE, &secureFilename($_[0]));
	binmode(IMAGE);
	$image=<IMAGE> ;
	close(IMAGE);
	$/=$lf;
	if(!(substr($image,0,6) =~ m/GIF8[7,9]a/) || (length($s=substr($image, 6, 4))!=4)) {
		return;
	}
	(@size)=unpack("C"x4,$s);
	$width= $size[1]<<8|$size[0];
	$height= $size[3]<<8|$size[2];
	return ($width,$height);
}
###########################################################################
sub getImageSizeJPG {		# Bildgrösse von JPG-Dateien bestimmen
	my ($lf,$image,$width,$height,@size);
	$lf=$/;
	undef $/;
	open (IMAGE, &secureFilename($_[0]));
	binmode(IMAGE);
	$image=<IMAGE> ;
	close(IMAGE);
	$/=$lf;
	my $count=2 ;
	my $length=length($image);
	my $ch="" ;
	while (($ch ne "\xda") && ($count<$length)) {
		while (($ch ne "\xff") && ($count<$length)) {
			$ch=substr($image,$count,1);
			$count++;
		}
		while (($ch eq "\xff") && ($count<$length)) {
			$ch=substr($image,$count,1);
			$count++;
		}
		if ((ord($ch) >= 0xC0) && (ord($ch) <= 0xC3)) {
			$count+=3;
			(@size)=unpack("C"x4,substr($image,$count,4));
			$width=$size[2]<<8|$size[3];
			$height=$size[0]<<8|$size[1];
			return ($width,$height);
		} else {
			(@size)= unpack("C"x2,substr($image,$count,2));
			$count += $size[0]<<8|$size[1];
		}
	}
}
###########################################################################
sub getImageSizePNG {		# Bildgrösse von PNG-Dateien bestimmen
	my ($lf,$image,$width,$height,@size);
	$lf=$/;
	undef $/;
	open (IMAGE, &secureFilename($_[0]));
	binmode(IMAGE);
	$image=<IMAGE> ;
	close(IMAGE);
	$/=$lf;
	if ($image =~ /IHDR(.{8})/) {
		$image = $1;
		($width,$height) = unpack( "NN", $image);
	} else {
		print "Datei ist keine gueltige PNG Datei\n";
	}
	return ($width,$height);
}
###########################################################################
sub moveFile {					# Datei verschieben &moveFile("Quelle","Ziel","copy zum kopieren, delete zum löschen");
	if (($_[0] ne "") and (-e $_[0])) {
		if (lc($_[2]) eq "copy") {
			open(INPUT,&secureFilename($_[0]));
			open(OUTPUT,">".&secureFilename($_[1]));
			binmode(INPUT);
			binmode(OUTPUT);
			while (<INPUT>) {
				print OUTPUT $_;
			}
			close(INPUT);
			close(OUTPUT);
		} elsif ((lc($_[2]) eq "move") or ($_[2] eq "")) {
			rename &secureFilename($_[0]), &secureFilename($_[1]);
		} elsif (lc($_[2]) eq "delete") {
			unlink &secureFilename($_[0]);;
		}
	}
}
###########################################################################
sub getCat {						# Konfiguration in @cat einlesen. Parameter: Cat-ID
	my $srchcat=$_[0];
	if (-e $CONFIG{"catFile"}) {
		open(CAT,&secureFilename($CONFIG{"catFile"}));	# Kategoriedatei öffnen
		while (<CAT>) {
			if ($_ =~ m/^$srchcat\t/) {								# gewählte Kategorie gefunden
				chomp;
				$_=~ s/[\r\n]//g;
				@cat=split(/\t/);												# in @cat einlesen
				last;
			}
		}
		close(CAT);
	}
	$cat[8]=~ s/\s//g;														# keine Leerzeichen in Bildgrösse
	$cat[9]=~ s/\s//g;														# keine Leerzeichen in Thumbnail
}
###########################################################################
sub parseAd {						# Eintrag in %ad einlesen: &parseAd("String","NLonly","bbYes");
	my $lfParam=$_[1];
	my $bbYes=$_[2];
	if ($CONFIG{"bbCode"} ne "Y") {								# BB-Code muss im Adminbereich aktiviert sein
		$bbYes="";
	}
	my ($line, $tmp, @tmpArray1, @tmpArray2);
	undef(%ad);
	$ad{"ifImage"}=0;
	$line ="id=".$_[0];
	chomp($line);
	$line =~ s/[\r\n]//g;
	@tmpArray1=split(/\t/,$line);
	foreach $tmp (@tmpArray1) {
		@tmpArray2=split(/=/,$tmp,2);
		if ($lfParam eq "NLonly") {
			$tmpArray2[1]=~ s/§§/\n/g;
		} elsif ($lfParam eq "") {
			$tmpArray2[1]=~ s/§§/<br \/>\n/g;
		}
		if ($bbYes eq "Y") {												# BB-Code interpretieren, falls aktiviert
			$tmpArray2[1]=~ s/\[b\](.*?)\[\/b\]/<b>$1<\/b>/gi;
			$tmpArray2[1]=~ s/\[i\](.*?)\[\/i\]/<i>$1<\/i>/gi;
			$tmpArray2[1]=~ s/\[u\](.*?)\[\/u\]/<u>$1<\/u>/gi;
		}
		$ad{$tmpArray2[0]}=$tmpArray2[1];
		if ($tmpArray2[0] =~ m/^image\d*$/) {				# Bei Bild ifImage-Tag definieren
			$ad{"ifImage"}=1;
		}
	}
	&setMailTime($ad{"id"});
	$ad{"date"}=$dmmmmyyyyDate2;
}
###########################################################################
sub addAd {							# Inserat hinzufügen
	print DATA $id."\t";
	foreach (sort keys(%FORM)) {
		if ($_ =~ m/^html_/) {											# html_ nicht beachten
			next;
		}
		$FORM{$_}=~ s/[\t\r]//g;
		if (lc($FORM{"html_".$_}) ne "true") {
			$FORM{$_}=~ s/&/&amp;/g;
			$FORM{$_}=~ s/</&lt;/g;
			$FORM{$_}=~ s/>/&gt;/g;
		}
		$FORM{$_}=&zeilenUmbruch($FORM{$_},"§§");
		print DATA "$_=$FORM{$_}\t" if (($_ ne "action") and ($_ ne "do") and ($_ ne "cat") and ($_ ne "id") and ($_ ne "ASID") and ($_ ne "password1") and ($FORM{$_} ne ""));
	}
	print DATA "\n";
	if ($cat[20] ne "") {													# spezielle Einstellung für aktuelle Kategorie
		$CONFIG{"newMail"}=$cat[20];
	}
	if (($CONFIG{"newMail"} ne "") and ($FORM{"action"} ne "admineditad")) {
		&sendAdminMail; 														# Mail an Administrator bei Änderung
	}
}
###########################################################################
sub sendValidationMail {	# Mail für Validierung der Mailadresse versenden
	if ($mailVersand eq "TRUE") {
		$ENV{"PATH"} = "/bin:/usr/bin:/usr/sbin";
		open MAIL, "| ".&secureFilename($CONFIG{"sendmail"})." -oi -t" or die "Sendmail konnte nicht geöffnet werden";
	} else {
		open(MAIL,">mail.eml") || die "Kann EML-Datei nicht schreiben! Error : $!\n";
	}
	if ($cat[21] ne "") {													# spezielles Validierungsmail für diese Kategorie
		$CONFIG{"valiMail"}=$cat[21];
	}
	open(FILE,&secureFilename($CONFIG{"valiMail"}));
	while (<FILE>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		$_ =~ s/<!--date-->/$mailDate/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--id-->/$id/gi;
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--field:([^>:]+):(.+?)-->/substr($FORM{$1},0,$2)/egi;
		$_ =~ s/<!--field:(.*?)-->/$FORM{$1}/gi;
		$_ =~ s/<!--fieldh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
		$_ =~ s/<!--messageid-->/$messageID/gi;
		$_ =~ s/<!--boundary-->/$boundary/gi;
		print MAIL "$_\n";
	}
	close(FILE);
	close(MAIL);
}
###########################################################################
sub deleteAndReorderOldAds {	# alte Inserate löschen und neu sortieren
	my ($file, @catArray, $line, $errorLevel);
	opendir(IMAGES,&secureFilename($CONFIG{"imgUplU"}));	# alle Bilder einlesen
	while ($file = readdir(IMAGES)) {
		if (($file =~ m/^\d{5,}_/) or ($file =~ m/^tmp_/)) {
			$images{$file}++;
			if ($delDebug) {													# Löschprotokollierung
				print DELLOG "DELMARK: $file\n";
			}
		}
	}
	closedir(IMAGES);
	$errorLevel=0;
	if (-e $CONFIG{"catFile"}) {									# Kategoriendatei verarbeiten
		open(CAT,&secureFilename($CONFIG{"catFile"}));
		while (<CAT>) {
			chomp;
			$_ =~ s/[\r\n]//g;
			@catArray=split(/\t/);
			if ($catArray[29] ne "day") {							# Sortier-Parameter nur bei täglicher Sortierung übergeben
				$catArray[30]="";
			}
			$errorLevel+=&delReorderOldAdsPerCat($catArray[2], $catArray[15], $catArray[30]);
		}
		if ($errorLevel == 0) {
			foreach (keys(%images)) {						# verbleibende Bilder löschen
				unlink &secureFilename($CONFIG{"imgUplU"}."/".$_);
				if ($delDebug) {												# Löschprotokollierung
					print DELLOG "DODEL: $_\n";
				}
			}
		}
	}
}
###########################################################################
sub delReorderOldAdsPerCat {	# alte Inserate löschen und neu sortieren (eine Kategorie)
	my $catFile=$_[0];														# Daten-Datei
	my $catNumb=$_[1];														# numerische Felder
	my $catSort=$_[2];														# Sortier-Felder
	my (%adsHash, $i, @sort, $key, $tmp, $index);
	@sort=split(/[,;]/,$catSort);									# Split nach , oder ;
	if ($delDebug) {															# Löschprotokollierung
		print DELLOG "PROCESSCAT: $catFile\n";
	}
	if (&lockFile($catFile)) {										# Datei sperren
		$i=0;
		open(INPUT,&secureFilename($catFile));
		open(OUTPUT,">".&secureFilename($catFile).".tmp");
		while (<INPUT>) {
			$i++;
			chomp;
			#$_ =~ s/[\r\n]//g;
			if ($delDebug) {													# Löschprotokollierung
				print DELLOG "ADLINE: $_\n";
			}
			&parseAd($_);															# Eintrag auftrennen
			if (($ad{"validated"} ne "Y") and ($CONFIG{"nValDel"} > 0)) {	# Inserat nicht validiert und spezielles Ablaufdatum definiert --> überschreibe Ablaufdatum im Inserat
				$ad{"valid"}=$CONFIG{"nValDel"};
			}
			if (($ad{"id"}+($ad{"valid"}*60*60*24) > $todayUNIX) or ($ad{"valid"} == 0)) { # Eintrag noch gültig
				if ($catSort eq "") {										# keine Sortierung --> in Output-Datei schreiben
					print OUTPUT $_."\n";
				} else {																# Sortierung --> in Hash schreiben
					$index="";
					foreach $key (@sort) {
						$_=~ m/\t$key=(.*?)\t/;							#	Schlüsselfeld bestimmen
						$tmp=$1;
						if (";${catNumb};" =~ m/\;${key}\;/i) {	# numerisches Feld
							$index.=sprintf("%-6.6d",$tmp);		# Index festlegen: erste 6 Zeichen
						} else {	# Text Feld
							$index.=sprintf("%-30.30s",lc($tmp));	# Index festlegen: erste 30 Buchstaben
						}
					}
					$index.=sprintf("%-6.6d",$i);					# Eindeutige Kennung: erste 6 Zeichen
					$adsHash{$index}=$_;									# zu Hash hinzufügen
				}
				foreach (keys(%ad)) {
					if (($_ =~ m/^image\d*$/) and ($ad{$_} ne "")) {
						if ($delDebug) {										# Löschprotokollierung
							print DELLOG "UNDELMARK: $ad{$_}\n";
						}
						delete($images{$ad{$_}}); 					# Bild nicht löschen
						if ($ad{$_} =~ m/^(\d+)_(.*)$/) {		# Thumbnails ebenfalls erhalten
							delete($images{$1."_tmb_".$2});
							if ($delDebug) {										# Löschprotokollierung
								print DELLOG "UNDELMARK: ".$1."_tmb_".$2."\n";
							}
						}
					}
					if (($_ =~ m/^FILE_.*$/) and ($ad{$_} ne "")) {
						if ($delDebug) {										# Löschprotokollierung
							print DELLOG "UNDELMARK: $ad{$_}\n";
						}
						delete($images{$ad{$_}}); 					# Bild nicht löschen
					}
				}
			}
		}
		if ($catSort ne "") {												# Sortierung --> Hash in Datei schreiben
			foreach (sort { lc($a) cmp lc($b) } keys(%adsHash)) {	# zuerst alle Einträge >= Startbuchstaben schreiben
				print OUTPUT $adsHash{$_}."\n";
			}
		}
		close(OUTPUT);
		close(INPUT);
		&unlockFile($catFile);
		unlink &secureFilename($catFile);
		rename &secureFilename($catFile.".tmp"), &secureFilename($catFile);
		return 0;																		# Errorlevel 0: alles OK
	} else {
		return 1;																		# Errorlevel 1: Lock-Fehler
	}
}
###########################################################################
sub includeFile {				# Datei einbinden
	my ($jsstat);
	if (-e $_[0]) {
		# cgicorner.ch Add-On
		$jsstat="<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">\n<!--\nvar useFlash = navigator.mimeTypes &&\nnavigator.mimeTypes[\"application/x-shockwave-flash\"] &&\nnavigator.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin;\n//-->\n</SCRIPT>\n<SCRIPT LANGUAGE=\"VBScript\" TYPE=\"text/vbscript\">\n<!--\nOn error resume next\n useFlash = NOT IsNull(CreateObject(\"ShockwaveFlash.ShockwaveFlash\"))\n//-->\n</SCRIPT>\n<SCRIPT LANGUAGE=\"JavaScript\" TYPE=\"text/javascript\">\n<!--\nif(useFlash) flash=true;\n else flash=false;\n a=\"na\";\n f=\"na\";\nj=\"na\";\n r=\"_\"+escape(document.referrer)\n a=screen.width;\n b=navigator.appName\n if (b != \"Netscape\") {f=screen.colorDepth} else {f=screen.pixelDepth}\n j=navigator.javaEnabled()\n NS2Ch=0\n if (navigator.appName == \"Netscape\" && navigator.appVersion.charAt(0) == \"2\") {NS2Ch=1}\n if (NS2Ch == 0) {\n  r=\"Aufloes=\" + a + \"&Farbtie=\" + f + \"&Referer=\" + r + \"&JavaAkt=\" + j + \"&JavaScr=true&FlashAk=\" + flash;\n document.write(\"<img src='/cgi-bin/jsstat/jsstat.cgi?action=vl&desc=Marktplatz&\" + r +\"' WIDTH=1 HEIGHT=1 BORDER=0 ALT=''>\");\n}\n //-->\n</SCRIPT>\n<NOSCRIPT>\n<img src='/cgi-bin/jsstat/jsstat.cgi?action=vl&desc=Marktplatz&JavaScr=false' WIDTH=1 HEIGHT=1 BORDER=0 ALT=''>\n</NOSCRIPT>";
		# cgicorner.ch Add-On

		open(INCFILE,&secureFilename($_[0]));
		while (<INCFILE>) {
			$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
			$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
			$_ =~ s/<!--action-->/$FORM{"action"}/gi;
			$_ =~ s/<!--scriptVersion-->/$version/gi;
			$_ =~ s/<!--cat-->/$FORM{"cat"}/gi;
			# cgicorner.ch Add-On
			$_ =~ s/<!--aktfile-->/$COMPCGIURL?action=$FORM{"action"}/gi;
			$_ =~ s/<!--datum-->/$lastMod/gi;
			$_ =~ s/<!--datumencoded-->/$lastMod/gi;
			$_ =~ s/<!--printurl-->/$COMPCGIURL&action=$FORM{"action"}&cat=$FORM{"cat"}&id=$FORM{"id"}/gi;
			$_ =~ s/<!--jsstat-->/$jsstat/gi;
			# /cgicorner.ch Add-On
			if ($_ =~ m/<!--includeFile:(.*?)-->/gi) {
				&includeFile($1);
			}
			print $_;
		}
		close(INCFILE);
	}
}
###########################################################################
sub notFound {					# Error 404 ausgeben
	print "Content-type: text/html\n\n";
	print <<HTMLtext;
	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
	<html>
	<head>
	<title>jsMarket</title>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
	<style type="text/css">
	body			{font-family:Tahoma,Arial,Helvetica,sans-serif; color:#000000; font-size:10pt; background:#FFFFFF;}
	h1				{font-size:16pt; color:#1155AA;}
	.red			{color:#FF0000; font-weight:bold;}
	</style>
	</head>
	<body>
	<h1>HTTP Error 404</h1>
	<span class="red">HTTP Fehler 404 - Datei nicht gefunden</span><br/>
	Die von Ihnen angeforderte Datei konnte auf diesem Server leider nicht gefunden werden.<br/>
	Sollte dieses Problem weiterhin auftreten, so bitten wir sie, den Administrator zu kontaktieren.<br/><br/>
	<span class="red">HTTP Error 404 - File not found</span><br/>
	The requested file could not be found on this server.<br/>
	If this problem persists, please contact the administrator.<br/><br/>
	<span class="red">HTTP Erreur 404 - Fichier non trouv&eacute;</span><br/>
	Le fichier que vous avez demand&eacute; ne peut pas &ecirc;tre trouv&eacute; sur notre server.<br/>
	Si se problème persiste, contactez le webmaster.
	</body>
	</html>
HTMLtext
	exit(0);
}
###########################################################################
sub sendAdminMail {			# Nachricht an Admin bei neuem, geänderten Formular
	if ($mailVersand eq "TRUE") {
		$ENV{"PATH"} = "/bin:/usr/bin:/usr/sbin";
		open MAIL, "| ".&secureFilename($CONFIG{"sendmail"})." -oi -t" or die "Sendmail konnte nicht geöffnet werden";
	} else {
		open(MAIL,">mail1.eml") || die "Kann EML-Datei nicht schreiben! Error : $!\n";
	}
	if ($cat[23] ne "") {													# spezielle Template-Einstellung für diese Kategorie
		$CONFIG{"admiMail"}=$cat[23];
	}
	my $tmpStatus="";
	if ($FORM{"validated"} =~ m/^Y/) {						# Inserat aktiv
		$tmpStatus="Das Inserat ist aktiv";
	} elsif ($FORM{"validated"} =~ m/^N/) {
		if ($CONFIG{"valMail"} eq "Y") {						# Validierung durch Benutzer
			$tmpStatus="Das Inserat muss vom Benutzer noch validiert werden";
		} elsif ($CONFIG{"valMail"} eq "A") {				# Validierung durch Benutzer und Admin
			$tmpStatus="Das Inserat muss vom Administrator noch validiert werden";
		} elsif ($CONFIG{"valMail"} eq "B") {				# Validierung durch Benutzer und Admin
			$tmpStatus="Das Inserat muss vom Benutzer und vom Administrator noch validiert werden";
		}
	} elsif ($FORM{"validated"} =~ m/^A/) {
		$tmpStatus="Das Inserat muss vom Benutzer noch validiert werden";
	} elsif ($FORM{"validated"} =~ m/^U/) {
		$tmpStatus="Das Inserat muss vom Administrator noch validiert werden";
	}
	open(FILE,&secureFilename($CONFIG{"admiMail"}));
	while (<FILE>) {
		chomp;
		$_ =~ s/[\r\n]//g;
		$_ =~ s/<!--date-->/$mailDate/gi;
		$_ =~ s/<!--CGIURL-->/$COMPCGIURL/gi;
		$_ =~ s/<!--imgdir-->/$CONFIG{"imgDir"}/gi;
		$_ =~ s/<!--action-->/$FORM{"action"}/gi;
		$_ =~ s/<!--scriptVersion-->/$version/gi;
		$_ =~ s/<!--adminmail-->/$CONFIG{"newMail"}/gi;
		$_ =~ s/<!--id-->/$id/gi;
		$_ =~ s/<!--id2-->/$id2/gi;
		$_ =~ s/<!--cat-->/$cat[0]/gi;
		$_ =~ s/<!--field:([^>:]+):(.+?)-->/substr($FORM{$1},0,$2)/egi;
		$_ =~ s/<!--field:(.*?)-->/$FORM{$1}/gi;
		$_ =~ s/<!--fieldh:(.*?)-->/&newLine($FORM{$1}," ")/egi;
		$_ =~ s/<!--viewurl-->/$COMPCGIURL?action=viewad&id=$id&cat=$cat[0]/gi;
		$_ =~ s/<!--valurl-->/$COMPCGIURL?action=validate&id=$id&cat=$cat[0]&id2=$id2&val=admin/gi;
		$_ =~ s/<!--status-->/$tmpStatus/gi;
		$_ =~ s/<!--messageid-->/$messageID/gi;
		$_ =~ s/<!--boundary-->/$boundary/gi;
		print MAIL "$_\n";
	}
	close(FILE);
	close(MAIL);
}
###########################################################################
sub checkSearch {				# überprüfen, ob Inserat der Suche entspricht
	my $result=1;
	my ($tmp);
	&parseAd($_[0]);
	if ($ad{"validated"} eq "Y") {
		foreach (keys(%FORM)) {
			if ($result == 0) {												# Fehler --> Abbruch
				last;
			}
			if ($_ =~ m/^(.*)VON$/) {									# suche mit Felder wertVON und wertBIS
				$tmp=$1;
				if ($FORM{$_} ne "") {
					if ($ad{$tmp} < $FORM{$_}) {
						$result=0;
					}
				}
				if ($FORM{$tmp."BIS"} ne "") {
					if ($ad{$tmp} > $FORM{$tmp."BIS"}) {
						$result=0;
					}
				}
			} else {
				if (($_ eq "action") or ($_ eq "do") or ($_ eq "cat") or ($_ eq "from") or ($_ eq "to") or ($_ eq "orderby") or ($FORM{$_} eq "") or ($_ =~ m/BIS$/)) {
					next; 																# keine Such-, sondern Steuerfelder
				}
				if ($NUMFIELDS{$_} > 0) {								# numerisches Feld
					$FORM{$_}=~ s/\+//g;									# Plus Zeichen löschen
					if ($FORM{$_} =~ m/^>=(.*)$/) {				# Grösser Gleich
						if ($ad{$_} < $1) {
							$result=0;
						}
					} elsif ($FORM{$_} =~ m/^>(.*)$/) {		# Grösser
						if ($ad{$_} <= $1) {
							$result=0;
						}
					} elsif ($FORM{$_} =~ m/^<=(.*)$/) {	# Kleiner Gleich
						if ($ad{$_} > $1) {
							$result=0;
						}
					} elsif ($FORM{$_} =~ m/^<(.*)$/) {		# Kleiner
						if ($ad{$_} >= $1) {
							$result=0;
						}
					} elsif ($FORM{$_} =~ m/^(-?\d*?)-(-?\d*)$/) {	# Zwischen
						if (($ad{$_} < $1) or ($ad{$_} > $2)) {
							$result=0;
						}
					} else {															# Gleich
						if ($ad{$_} != $FORM{$_}) {
							$result=0;
						}
					}
				} else {																# Textfeld
					if ($ad{$_} !~ m/$FORM{$_}/i) {
						$result=0;
					}
				}
			}
		}
	} else {																			# Inserat nicht validiert
		$result=0;
	}
	return $result;
}
###########################################################################
sub compressSearch {		# Suchergebnisse verdichten
	my $keyname;
	foreach (keys(%FORM)) {
		if ($_ =~ m/srch[ft]_(.*)$/) {
			$keyname=$1;
			if (($FORM{"srchf_".$keyname} ne "") and ($FORM{"srcht_".$keyname} ne "")) {
				$FORM{$keyname}=$FORM{"srchf_".$keyname}."-".$FORM{"srcht_".$keyname};
				delete($FORM{"srchf_".$keyname});
				delete($FORM{"srcht_".$keyname});
			} elsif (($FORM{"srchf_".$keyname} ne "") and ($FORM{"srcht_".$keyname} eq "")) {
				$FORM{$keyname}=">".$FORM{"srchf_".$keyname};
				delete($FORM{"srchf_".$keyname});
				delete($FORM{"srcht_".$keyname});
			} elsif (($FORM{"srchf_".$keyname} eq "") and ($FORM{"srcht_".$keyname} ne "")) {
				$FORM{$keyname}="<".$FORM{"srcht_".$keyname};
				delete($FORM{"srchf_".$keyname});
				delete($FORM{"srcht_".$keyname});
			}
		}
	}
}
###########################################################################
sub showAd {						# Inserat anzeigen
	my $searchParams="";
	my ($ttmp, $width, $height, $twidth, $theight);
	foreach (keys(%FORM)) {
		$searchParams.="&amp;".$_."=".$FORM{$_} if (($_ ne "action") and ($_ ne "do") and ($_ ne "orderby") and ($_ ne "cat") and ($_ ne "number") and ($_ ne "to") and ($_ ne "sysMsg") and ($_ ne "prevlink") and ($_ ne "nextlink"));
	}
	&setMailTime($ad{"id"}+($ad{"valid"}*24*60*60));
	if ($ad{"valid"}) {
		$ad{"expiredate"}=$dmmmmyyyyDate2;
	} else {
		$ad{"expiredate"}="---";
	}
	$count1++;
	my (@TEMPLATE1, $line);
	@TEMPLATE1=@TEMPLATE;
	foreach $line (@TEMPLATE1) {
		$line =~ s/<!--cat-->/$cat[0]/gi;
		$line =~ s/<!--catname-->/$cat[1]/gi;
		$line =~ s/<!--field:rimage(\d*)-->/$ad{"image".$1}/gi;
		if (($line =~ m/<!--field:image(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {
			$line =~ s/<!--field:image(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$ad{"image".$1}\"$2  alt=\"$ad{"image".$1}\" \/>/gi;
		}
		if (($line =~ m/<!--field:timage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails
			$line = &thumbImageAsHTML($1, $2, $line, 0);
		}
		if (($line =~ m/<!--field:rtimage(\d*):?(.*?)-->/) and ($ad{"image".$1} ne "")) {	# Thumbnails als RAW-Code
			$line = &thumbImageAsHTML($1, $2, $line, 1);
		}
		$line =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
		$line =~ s/<!--field:([^>:]+):(\d+)-->/substr($ad{$1},0,$2)/egi;
		$line =~ s/<!--field:(.*?)-->/$ad{$1}/gi;
		$line =~ s/<!--fieldh:(.*?)-->/&newLine($ad{$1}," ")/egi;
		$line =~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%ad)/egi;
		if ($ad{"ifImage"} eq "0") {
			$line =~ s/<!--ifImage:(.*?)-->//gi;
		} else {
			$line =~ s/<!--ifImage:(.*?)-->/$1/gi;
		}
		$line =~ s/<!--detailurl-->/$COMPCGIURL?action=viewad&amp;cat=$cat[0]&amp;id=$ad{id}&amp;orderby=$FORM{"orderby"}$searchParams/gi;
		$line =~ s/<!--(start|end)List-->//g;
		if ($line =~ m/<!--After\[(.*?)\]:(.*?)-->/) {	# <!--After[2]:xyz-->: xyz nur bei jedem 2. Datensatz ausgeben
			$tmp=$2;
			if ($count1 % $1 == 0) {
				$line =~ s/<!--After\[.*?\]:.*?-->/$tmp/g;
			} else {
				$line =~ s/<!--After\[.*?\]:.*?-->//g;
			}
		}
		if ($line =~ m/<!--NotAfter\[(.*?)\]:(.*?)-->/) {    # <!--NotAfter[2]:xyz-->: xyz nur bei jedem 2. Datensatz ausgeben
			$tmp=$2;
			if ($count1 % $1 != 0) {
				$line =~ s/<!--NotAfter\[.*?\]:.*?-->/$tmp/g;
			} else {
				$line =~ s/<!--NotAfter\[.*?\]:.*?-->//g;
			}
		}
		print "$line\n";
	}
}
###########################################################################
sub errorLog {					# Eintrag ins Error-Log
	open(ERROR,">>".&secureFilename($CONFIG{"errorFile"}));
	print ERROR &mygmtime(time)."\n$_[0]\n-----------------------------\n";
	close(ERROR);
}
###########################################################################
sub lockFile {					# Datei als geöffnet für Schreibzugriff markieren
	my $lockFile=$_[0];
	if (-e $lockFile.".lock") {
		return 0;
	} else {
		open(LOCK,">".&secureFilename($lockFile).".lock");
		print LOCK "file locked; $mailDate\n";
		close(LOCK);
		if (-e $lockFile.".lock") {
			return 1;
		} else {
			return 0;
		}
	}
}
###########################################################################
sub unlockFile {				# Datei als wieder frei markieren
	my $lockFile=$_[0];
	if (-e $lockFile.".lock") {
		unlink &secureFilename($lockFile.".lock");
	}
}
###########################################################################
sub hiddenField {				# Verstecktes Feld ausgeben
	return "<input type=\"hidden\" name=\"$_[0]\" value=\"$_[1]\"/>\n";
}
###########################################################################
sub makeBoundary {			# MIME Boundary
	my ($boundary, @boundaryv, $i);
	@boundaryv = (0..9, 'A'..'F');
	for ($i = 0; $i++ < $_[0];) {
		$boundary .= $boundaryv[rand(@boundaryv)];
	}
	return $boundary;
}
###########################################################################
sub checksum {					# eindeutige Checksumme eines Strings
	my $text=$_[0];
	my $i;
	my $returnValue="";
	for ($i=0;$i<=(length($text)/8)+1;$i++) {
		$returnValue.=crypt(substr($text, $i*8, 8),"rv");
	}
	return unpack("%16C*", $returnValue);
}
###########################################################################
# Function: $result=&newLine("text","trennzeichen, def. \n");
# Ersetzt Zeilenumbrüche (\r, \n, \r\n) durch Trennzeichen resp. \n
sub newLine {
	my $text=$_[0];
	my $trenn=$_[1];
	if ($trenn eq "") {
		$trenn="\n";
	}
	if ($text =~ m/\n/) {
		$text =~ s/\r//g;
		if ($trenn ne "\n") {
			$text =~ s/\n/$trenn/g;
		}
	} else {
		$text =~ s/\r/$trenn/g;
	}
	return $text;
}
###########################################################################
# Function: $crypted=&jsCrypt($unencrypted,$key);
# Verschlüsselt einen Text mit einer Zweiwegverschlüsselung (XOR)
sub jsCrypt {
	my $tmpCrypted1="";
	my $tmpText=$_[0];														# 1. Argument: Text zum verschlüsseln
	my $tmpKey=$_[1];															# 2. Argument: Schlüssel
	my $tmpCrypted="";
	if (length($tmpText) > 0) {
		$tmpKey = $tmpKey x (length($tmpText) / length($tmpKey) + 1); # Schlüssel auf Länge des Textes bringen (hintereinanderkopieren)
	  $tmpKey = substr($tmpKey, 0, length($tmpText));	# ... und kürzen
	  $tmpCrypted=$tmpText ^ $tmpKey;						# XOR-Verknüpfung zwischen Text und Key
	  $tmpCrypted=&encodeURL($tmpCrypted);					# Verschlüsselten Text für URL codieren
	}
  return $tmpCrypted;
}
###########################################################################
# Function: $unencrypted=&jsDecrypt($crypted,$key);
# Entschlüsselt einen Text mit einer Zweiwegverschlüsselung (XOR)
sub jsDecrypt {
	my $tmpText=$_[0];														# 1. Argument: Text zum entschlüsseln
  my $tmpKey=$_[1];															# 2. Argument: Schlüssel
	my $tmpCrypted="";
	if (length($tmpText) > 0) {
		$tmpText =~ tr/+/ /;												# + durch Leerzeichen ersetzen
		$tmpText =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;  # Sonderzeichen entschlüsseln
		$tmpKey = $tmpKey x (length($tmpText) / length($tmpKey) + 1);  # Schlüssel auf Länge des Textes bringen (hintereinanderkopieren)
		$tmpKey = substr($tmpKey, 0, length($tmpText));  # ... und kürzen
		$tmpCrypted=$tmpText ^ $tmpKey;							# XOR-Verknüpfung zwischen Text und Tex
	}
	return $tmpCrypted;
}
###########################################################################
# Function: $hex=&char2hex($char);
# Wandelt ein Zeichen in einen Hexcode um
sub char2hex {
	return "%".sprintf( "%02X", ord($_[0]));
}
###########################################################################
# Function: $encodedtext=&encodeURL($text);
# Codiert einen Text URL-freundlich
sub encodeURL {
	my $result=$_[0];
	$result =~ s/ /\./gi;
	$result =~ s/([^a-z0-9\.])/&char2hex($1)/egi;
	return $result;
}
###########################################################################
sub hex2dec {
	my $value=$_[0];
	my (@returnArray, $i);
	$value =~ s/^\#//g;
	for ($i=0;$i<length($value);$i=$i+2) {
		push @returnArray, hex(substr($value,$i,2));
	}
	return @returnArray;
}
###########################################################################
sub createDrawSecCode {
	my $addFile="./subs.pl";
	if (!(-e $addFile)) {
		if ((!(-w $addFile)) and (-w "data/".$addFile)) {	# Datei kann nicht geschrieben werden, versuche Data-Verzeichnis
			$addFile="data/".$addFile;
		}
		open(OUTPUT,">".&secureFilename($addFile));
		eval {
			require GD;
		};
		if ($@) {
			print OUTPUT <<code;
sub drawSecCode {
}
sub makeThumb {
}
1;
code
		} else {
			print OUTPUT <<code;
sub drawSecCode {
	\# Diese Funktion benötigt das GD-Modul. Wenn dieses auf dem Server nicht installiert
	\# ist, müssen alle Zeilen bis # -- Ende GD-Modul -- gelöscht werden.
	use GD;
	my \$number=\$_[0];
	my \$secCodeI=\$_[1];
	my \$secCodC1=\$_[2];
	my \$secCodC2=\$_[3];
	my (\$imageWidth, \$imageHeight, \@col1, \@col2);
	my \$image = GD::Image->newFromJpeg(\$secCodeI);
	\@col1=\&hex2dec(\$secCodC1);
	\@col2=\&hex2dec(\$secCodC2);
	(\$imageWidth, \$imageHeight) = \$image->getBounds();
	my \$bgcol=\$image->colorAllocate(\$col1[0],\$col1[1],\$col1[2]);	# Hintergrundfarbe
	my \$farbe=\$image->colorAllocate(\$col2[0],\$col2[1],\$col2[2]);	# Vordergrundfarbe

	\$image->string(gdLargeFont,0,-3,sprintf("%5.5d",int(rand(100000))),\$bgcol);	# Zahlen im Hintergrund
	\$image->string(gdLargeFont,5,3,sprintf("%5.5d",int(rand(100000))),\$bgcol);
	\$image->string(gdLargeFont,30,6,sprintf("%5.5d",int(rand(100000))),\$bgcol);
	\$image->string(gdLargeFont,40,-2,sprintf("%5.5d",int(rand(100000))),\$bgcol);

	\$image->string(gdLargeFont,10,1,\$number,\$farbe);	# Zahl zeichnen
	\$image->string(gdLargeFont,9,1,\$number,\$farbe);
	\$image->rectangle(0,0,\$imageWidth-1,\$imageHeight-1,\$farbe);	# Rahmen um Grafik
	binmode(STDOUT);
	print "Content-Type: image/jpg\\n\\n";
	print \$image->jpeg(90);
	\# -- Ende GD-Modul --
}
sub makeThumb {					\# Thumbnail erstellen - &makeThumb(input,output,width,height);
	\# Diese Funktion benötigt das GD-Modul. Wenn dieses auf dem Server nicht installiert
	\# ist, müssen alle Zeilen bis \# -- Ende GD-Modul -- gelöscht werden.
	if (-e \$_[0]) {
		use GD;
		if (\$_[2] == 0) {
			\$_[2]=99999999;
		}
		if (\$_[3] == 0) {
			\$_[3]=99999999;
		}
		my (\$targetWidth,\$targetHeight);
		my \$image = newFromJpeg GD::Image(\$_[0]);
		my (\$imageWidth, \$imageHeight) = \$image->getBounds();
		if ((\$_[2]/\$_[3]) > (\$imageWidth/\$imageHeight))	{ \# Bild zu breit
			\$targetWidth=(\$_[3]/\$imageHeight)*\$imageWidth;
			\$targetHeight=\$_[3];
		} else {																		\# Bild zu hoch
			\$targetWidth=\$_[2];
			\$targetHeight=(\$_[2]/\$imageWidth)*\$imageHeight;
		}
		my \$thumb = new GD::Image(\$targetWidth, \$targetHeight, 1);
		\$thumb->copyResampled(\$image, 0, 0, 0, 0, int(\$targetWidth), int(\$targetHeight), int(\$imageWidth), int(\$imageHeight));

		my \$secureFilenameTMP=\$_[1];
		\$secureFilenameTMP =~ m/([\\w\\/\\-\\_\\.\\\\: ]+)/;
		\$secureFilenameTMP=\$1;
		open THUMB, ">\$secureFilenameTMP";
		binmode THUMB;
		print THUMB \$thumb->jpeg(50);
		close THUMB;
	}
	\# -- Ende GD-Modul --
}
1;
code
		}
		close(OUTPUT);
	}
	require $addFile;
}
###########################################################################
# Function: $parsedline=~ s/<!--if:(.*?)§(.*?)-->/&ifQuery($1,$2,\%HASH)/egi;
# Erweiterte Funktion für IF-Abfragen innerhalb von Templates
sub ifQuery {
	my $returnValue="";
	my $queryString=$_[0];
	my $queryValue=$_[1];
	my %searchHash=%{$_[2]};
	my ($sField, $sParam, $sValue);
	if ($queryString =~ m/^(.*?)([=<>!§])(.*)$/) {
		$sField=$searchHash{$1};
		$sParam=$2;
		$sValue=$3;
		if ((($sField eq $sValue) and ($sParam eq "=")) or	# Abfrage a=a
				(($sField ne $sValue) and ($sParam eq "!")) or	# Abfrage a!b
				(($sField < $sValue) and ($sParam eq "<")) or		# Abfrage 1<2
				(($sField > $sValue) and ($sParam eq ">"))) {		# Abfrage 2>1
				$returnValue=$queryValue;
		}
	}
	$returnValue=~ s/#!--(.*?)--#/<!--$1-->/g;	# verschachtelte Felder in IF-Abfrage umwandeln
	$returnValue=~ s/\\n/\n/g;	# \n durch Zeilenumbruch ersetzen
	return $returnValue;
}
###########################################################################
# Function: $text=~ s/((mailto:)?[A-Z0-9\.\-]+\@[A-Z0-9\.\-]+\.[A-Z]+)/&encodeMail($1)/egi;
# Codiert einen Text URL-freundlich
sub encodeMail {
	my $result=$_[0];
	$result =~ s/(.)/&encodeHTMLchar($1)/egi;
	return $result;
}
###########################################################################
# Function: encodeHTMLchar
# Codiert einen Text mit HTML-Dezcode
sub encodeHTMLchar {
	return "\&\#".ord($_[0]).";";
}
###########################################################################
# Function: secureFilename
# prüft einen Dateinamen, damit das Script auch im taint-Mode läuft
sub secureFilename {
	my $secureFilenameTMP=$_[0];
	$secureFilenameTMP =~ m/([\w\/\-\_\.\\: ]+)/;
	$secureFilenameTMP=$1;
	return $secureFilenameTMP;
}
###########################################################################
# Function: invalidMail("email","required 0/1");
# Gibt 1 zurück, wenn die übergebene Mailadresse ungültig ist
sub invalidMail {
	my $tmpMail=$_[0];
	if ($tmpMail ne "") {
		if ($tmpMail !~ m/^[\w\.\-\_]+\@[\w\.\-\_]+\.[a-z]+$/i) {
			return 1;
		} else {
			return 0;
		}
	} else {
		return $_[1];
	}
}
###########################################################################
sub attachment {				# sendet ein MIME-codiertes Attachment
	my $formName=$_[0];
	my $returnValue="";
	if (-e &secureFilename("tmp_".$FORM{$formName})) {
		$returnValue.="--$boundary\nContent-Type: application/octet-stream\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename=\"$FORM{$formName}\"\n\n";
		$returnValue.=&encodeBase64("tmp_".$FORM{$formName});
	}
	return $returnValue;
}
###########################################################################
sub encodeBase64 {			# &encodeBase64($file)
	open(BASE64, &secureFilename($_[0])); binmode BASE64;
	my $file = do{local$/;<BASE64>};
	close(BASE64);

	my ($res, $eol, $padding) = ("", "\n", undef);
	while (($file =~ /(.{1,45})/gs)) {
		$res .= substr(pack('u', $1), 1);
		chop $res;
	}
	$res =~ tr#` -_#AA-Za-z0-9+/#;
	$padding = (3 - length($_[0]) % 3) % 3;
	$res =~ s#.{$padding}$#'=' x $padding#e if $padding;
	$res =~ s#(.{1,76})#$1$eol#g if (length $eol);
	return $res;
}
###########################################################################
sub thumbImageAsHTML {	# $_ = &thumbImageAsHTML("number","optional arguments","line","complete=0;filenameonly=1");
	my (@subArray, $subImgNumber, $subReturnValue, $subType);
	$subImgNumber=$_[0];
	$subArray[1]=$_[1];
	$subReturnValue=$_[2];
	$subType=$_[3];
	$subArray[0]=$ad{"image".$subImgNumber};
	if ($subArray[0] =~ m/^(\d+)_(.*)$/) {
		$subArray[0]=$1."_tmb_".$2;
	}
	if (-e $CONFIG{"imgUplU"}."/".$subArray[0]) {
		if ($subType) {
			$subReturnValue =~ s/<!--field:rtimage(\d*):?(.*?)-->/$subArray[0]/gi;
		} else {
			$subReturnValue =~ s/<!--field:timage(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$subArray[0]\"$subArray[1] alt=\"$subArray[0]\" \/>/gi;
		}
	} elsif ((-e $CONFIG{"imgUplU"}."/".$ad{"image".$subImgNumber}) and ($cat[32] ne "")) {
		($subArray[201], $subArray[202])=getImageSize($CONFIG{"imgUplU"}."/".$ad{"image".$subImgNumber});
		($subArray[211], $subArray[212])=split(/x/,$cat[9]);
		if ($subArray[211] == 0) {									# 0=keine Einschränkung
			$subArray[211]=99999999;
		}
		if ($subArray[212] == 0) {
			$subArray[212]=99999999;
		}
		if (($subArray[211]/$subArray[212]) > ($subArray[201]/$subArray[202]))	{ # Bild zu breit
			$subArray[201]=int(($subArray[212]/$subArray[202])*$subArray[201]);
			$subArray[202]=$subArray[212];
		} else {																		# Bild zu hoch
			$subArray[202]=int(($subArray[211]/$subArray[201])*$subArray[202]);
			$subArray[201]=$subArray[211];
		}
	if ($subType) {
		$subReturnValue =~ s/<!--field:rtimage(\d*):?(.*?)-->/$ad{"image".$subImgNumber}/gi;
	} else {
		$subReturnValue =~ s/<!--field:timage(\d*):?(.*?)-->/<img src=\"$CONFIG{"imgUplB"}\/$ad{"image".$subImgNumber}\" width=\"$subArray[201]\" height=\"$subArray[202]\" $subArray[1] alt=\"$ad{"image".$subImgNumber}\" \/>/gi;
	}
	}
	return $subReturnValue;
}
###########################################################################
sub substrSpecial {			# Substring bis Wortende / substrSpecial("string","max","trennzeichen") / $line =~ s/<!--field:([^>:]+):(\d+):(.*?)-->/&substrSpecial($ad{$1},$2,$3)/egi;
	my $subReturnValue=$_[0];
	my $subLength=$_[1];
	my $subChar=$_[2];
	if (length($subReturnValue) > $subLength) {	# maximale Länge überschritten
		$subReturnValue=substr($subReturnValue, 0, $subLength+1);	# auf max. Länge beschränken
		$subReturnValue=~ s/^(.*)$subChar.*?$/$1/i;	# ab letztem Trennzeichen ablösen
	}
	return $subReturnValue;
}
###########################################################################
sub directLink {			# Erstellt die Direkt-Links [1] [2] etc.
	my @subParams=split(/§/, $_[0]);	# Anzahl Seiten vor und zürck § CSS-Klasse Links § Prefix § Suffix § Delemiter
	my $subReturnValue="";
	my $subNumPages=int($FORM{"number"}/$cat[13]);		# Anzahl Seiten bestimmen
	if ($FORM{"number"} % $cat[13] > 0) {					# Zahl aufrunden
		$subNumPages++;
	}
	if ($subNumPages > 1) {												# nur wenn mehr als eine Seite
		my $subThisPage=int($FORM{"from"}/$cat[13]);	# aktuelle Seite bestimmen
		if ($FORM{"from"} % $cat[13] > 0) {						# Zahl aufrunden
			$subThisPage++;
		}
		my $subLink="<a href=\"$COMPCGIURL?";					# Link für Navigation (ohne from)
		foreach (keys(%FORM)) {
			$subLink.="$_=$FORM{$_}&amp;" if (($_ ne "from") and ($_ ne "to") and ($_ ne "prevlink") and ($_ ne "nextlink") and ($_ ne "number") and ($_ ne "sysMsg") and ($FORM{$_} ne ""));
		}
		if ($subThisPage == 1) {											# aktuelle Seite ist Seite 1 --> kein Link
			$subReturnValue=$subParams[2]."1".$subParams[3];
		} else {																			# aktuelle Seite ist nicht Seite 1 --> Link
			$subReturnValue=$subLink."from=1\" class=\"".$subParams[1]."\">".$subParams[2]."1".$subParams[3]."</a>";
		}
		if ($subThisPage-$subParams[0] > 2) {
			$subReturnValue.=$subParams[4];
		}
		for ($i=$subThisPage-$subParams[0];$i<=$subThisPage+$subParams[0];$i++) {
			if ($i == $subThisPage) {										# darzustellende Seite ist aktuelle Seite --> kein Link
				$subReturnValue.=$subParams[2].$i.$subParams[3] if (($i > 1) and ($i < $subNumPages));
			} else {																		# darzustellende Seite ist andere Seite --> Link
				$subReturnValue.=$subLink."from=".((($i-1)*$cat[13])+1)."\" class=\"".$subParams[1]."\">".$subParams[2].$i.$subParams[3]."</a>" if (($i > 1) and ($i < $subNumPages));
			}
		}
		if ($subThisPage+$subParams[0] < $subNumPages-1) {
			$subReturnValue.=$subParams[4];
		}
		if ($subThisPage == $subNumPages) {						# aktuelle Seite ist letzte Seite --> kein Link
			$subReturnValue.=$subParams[2].$subNumPages.$subParams[3];
		} else {																			# aktuelle Seite ist andere Seite --> Link
			$subReturnValue.=$subLink."from=".((($subNumPages-1)*$cat[13])+1)."\" class=\"".$subParams[1]."\">".$subParams[2].$subNumPages.$subParams[3]."</a>";
		}
	}
	return $subReturnValue;
}
