#!/usr/bin/perl

# ==========================================================================================
# Copyright (c) 1998-2002 HIS Internet Soft GmbH, info@his-webshop.de. All rights reserved.
# http://www.his-webshop.de/
# ..........................................................................................
# HIS WebShop 2.50 -- Online Shop mit Warenkorbsystem
# Version: 26.03.2002
#
# ----- LIZENZBESTIMMUNG ------
#
# 1. Dieses Programm (HIS WebShop) darf nur unter folgenden Bedingungen eingesetzt
#    werden:
#    (1) Die Internet Domain des Shops muss für das HIS WebShop Shopsystem
#        lizensiert sein (Ausstellung bei: info@his-webshop.de).
#    (2) Eine Lizenz ist immer gültig für nur einen Shop. Werden mehrere Shops
#        unterschiedlicher Firmen auf einer Domain betrieben, so muss für jeden
#        einzelnen Shop das Shopsystem lizensiert werden (Rabatte sind möglich!).
#
#    Der unbegrenzte Einsatz des Shopsystems ist erst nach Eingabe eines Registrier Keys
#    möglich. Ein Registrier Key gilt dabei immer für eine bestimmte Domain.
#    Beim Erwerb einer Lizenz erhalten Sie den gültigen Registrier Key für die Domain.
#    Aktuelle Konditionen zum Erwerb einer Lizenz finden Sie auf der HIS WebShop
#    Homepage: http://www.his-webshop.de/
#
# 2. Der Konfigurations-Teil darf geändert werden. Alle anderen Teile des Quellcodes sind
#    urherberrechtlich geschützt. Eine Änderung bedarf der Einwilligung des Autors.
#
# 3. Die Weitergabe des Programms an Dritte ist nicht gestattet.
# ==========================================================================================

# ==============================KONFIGURATIONS-TEIL BEGINN==================================

# ==========================================================================================
# DIE FOLGENDEN VARIABLEN BITTE ANPASSEN!
# Wenn das Skript NICHT laufen sollte, liegt es meistens an fehlerhaften
# Konfigurationsvariablen.
# WICHTIG:
# Bei $email muessen fuer die Zuweisung 'einfache' Anfuehrungsstriche gesetzt werden.
# Bei allen anderen Strings genuegen "doppelte" Anfuehrungsstriche.
# ==========================================================================================

# ==============================KONFIGURATIONS-TEIL BEGINN==================================

# ==========================================================================================
# DIE FOLGENDEN VARIABLEN BITTE ANPASSEN!
# Wenn das Skript NICHT laufen sollte, liegt es meistens an fehlerhaften
# Konfigurationsvariablen.
# WICHTIG:
# Bei $email muessen fuer die Zuweisung 'einfache' Anfuehrungsstriche gesetzt werden.
# Bei allen anderen Strings genuegen "doppelte" Anfuehrungsstriche.
# ==========================================================================================

# Ersetzen Sie www.firma.de durch Ihre Domain!!!!

$rc{"www.cbio.info"}="0379102231040";                       # Hier geben Sie Ihren 13-stelligen Registrier-Key ein!!!! WICHTIG !!!!

$email='order01@cbio.info';                                  # Ihre E-Mail (Wichtig fuer die Bestellungsmail)
$bcc_email='';                                              # Die E-Mail an den Shopinhaber kann zusätzlich als BCC (Blind Carbon Copy)
                                                            # zum Beispiel an einen Administrator verschickt werden.

$profiledirectory="/kunden/homepages/33/d23684884/htdocs/cbio/cgi-bin/kunden/";  
                                                            # Verzeichnis, wo Kundendaten (Profile fuer Warenkorb)
                                                            # gespeichert werden sollen.
$tempdirectory="/kunden/homepages/33/d23684884/htdocs/cbio/cgi-bin/template/";  
                                                            # Verzeichnis, wo sich die Templates (HTML und Mail) befinden.
$datadirectory="/kunden/homepages/33/d23684884/htdocs/cbio/cgi-bin/daten/";  
                                                            # Verzeichnis, wo sich die aus einer Datenbank
                                                            # exportierte Textdatei befindet.


$globaltxt="/kunden/homepages/33/d23684884/htdocs/cbio/cgi-bin/daten/global.txt";  
                                                            # Pfad zur Konfig. Datei mit globalen Variablen!
                                                            # Aufbau der Datei:
                                                            # MWST;16
                                                            # WAEHRUNG;DM
                                                            # usw.
                                                            # In den Templates können die Globalen Variablen dann so
                                                            # verwendet werden: [G_MWST] [G_WAEHRUNG] usw.

$max_minuten_inaktiv=30;                                    # Wenn laenger als $max_minuten_inaktiv kein Zugriff auf einen
                                                            # Warenkorb registriert wurde, wird das Profil geloescht. Voreinstellung: 30 Minuten.
$min_userid=1000;                                           # Die minimale User-ID (Bestellnr.), die vergeben wird.
$max_userid=9999;                                           # Die max. User-ID (Bestellnr.), die vom System vergeben wird.

$sendmail_def=0;                                            # 0: Mails per UNIX-Programm Sendmail verschicken
                                                            # 1: Mails per SMTP-Server verschicken

# ------- Falls sendmail_def=0 ausgewählt ---------
$mailprog = "/usr/sbin/sendmail";                           # Externes Mail-Programm sendmail. Pfad kann auch z.B. auf Ihrem
                                                            # Host auch "/usr/sbin/sendmail" sein.
# -------------------------------------------------

# ------- Falls sendmail_def=1 ausgewählt ---------
$mail_smtp_server="mail.IhreDomain.de";                     # Mail-Server für ausgehende (Bestellungs) Mails
                                                            # z.B. mail.IhreDomain.de
# -------------------------------------------------


$subject_user_mail="Ihre Bestellung aus dem CBIO Shop";   # Betreff der Kundenmail.
$subject_shop_mail="Ihre Bestellung aus dem CBIO Shop";   # Betreff der Bestellungseingangsmail.

$dif_porto=1;                                               # Wählen Sie hier aus, ob die Versandkosten fest sind
                                                            # ($dif_porto=0), oder ob der Kunde selber die
                                                            # Versandkostenart über eine Combo-Box auswählen kann
                                                            # (z.B. Deutschland/Europa/Sonstige)

# ------- Falls dif_porto=0 ausgewählt ---------
$versandk_hoehe=6.00;                                       # Betrag der Versandkosten für dif_porto=0
                                                            # => feste Versandkosten

$versandk_frei_ab="450.00";                                 # Mind. Bestellsumme ab der der Versand kostenlos ist.
                                                            # => nur für feste Versandkosten (dif_porto=0)
# -----------------------------------------------

# ------- Falls dif_porto=1 ausgewählt ----------

@porto_daten=(                                              # Betrag der Versandk. für dif_porto=1 => Geben Sie in jeder Zeile "NAME DER VERSANDKOSTENART;PREIS;VERSANDKOSTEN FREI AB an!
"Bankeinzug_Deutschland;6;40;",
"Nachnahme_Deutschland;11;40;",
"Vorkasse_Deutschland;6;40;",
"Ausland_EU_Vorkasse;12;80;");


# -----------------------------------------------


$min_order_typ=2;                                           # Wählen Sie hier:
                                                            # 0: Mindestbestellmengen werden ignoriert
                                                            # 1: Mindestbestellmenge darf nicht unterschritten werden,
                                                            #    sonst Fehlermeldung!
                                                            # 2: Wenn Mindestbestellmenge unterschritten wird, wird
                                                            #    ein Mindermengen-Zuschlag erhoben.
$min_order="10.00";                                         # Mindestbestellmenge
$min_order_zuschlag="3.00";                                 # Mindermengen-Zuschlag!


@currency=(                                                 # Währungsumrechnungskurse
"Euro=1.00",                                             # => Geben Sie in jeder Zeile
"DM=0,51129");                                                # "WÄHRUNG=UMRECHNUNGSKURS"
                                                            # an! Ausgabe: [PREIS_DM], [PREIS_Euro] etc.

@pichttp=(                                                  # HTTP-Verzeichnis für Bilder (also URL aus der Sicht des CGI-Verzeichnisses)
"http://www.cbio.info/bilder/",                              # Alle Bilder werden in der Form ArtNr.gif hochgeladen, bei
"http://www.cbio.info/bilder/",                              # Art.Nr 3333 => 3333.gif
"http://www.cbio.info/bilder/");                             # Falls Sie versch. Bildertypen anlegen möchten (z.B. ein Verz. für
                                                            # kleine Bilder, ein anderes für grosses Bilder), geben Sie
                                                            # diese durch Komma getrennt jeweils in doppelten Anführungsstrichen
                                                            # an. In den Vorlagen können sie Bilder so einbinden:
                                                            # [PIC1], [PIC2], [PIC3] usw.

@picverz=(                                                  # Server-Verzeichnis für Bilder (also Pfad aus der Sicht des CGI-Verzeichnisses)
"../bilder/",                                               # => muss an die Variable @pichttp angepasst werden.
"../bilder/",                                               # das Skript kontrolliert anhand des Server-Verz., ob das Bild
"../bilder/");                                              # Art.Nr existiert und gibt dann das HTML-Verzeichnis in der
                                                            # Ausgabe-HTML aus.


@pic_field_name=(
"Grafik-500",
"Grafik-300",                                               # Geben Sie hier das Datenbankfeld an, in dem die Namen
"Grafik-100");                                              # der Produktgrafiken angegeben sind. Einfachste Lösung:
                                                            # Verwenden Sie die Artikel-Nr. "NR" als Name der Grafik
                                                            # Die Grafik könnte dann z.B. heissen: 3456.gif

$default_pic="0000.gif";                                    # Bild, das geladen wird, falls das Bild ArtNr.gif nicht vorhanden sind

$use_default_pic=0;                                         # Wenn ein Artikel-Bild nicht vorhanden ist, soll dann
                                                            # Default-Pic geladen werden, oder gar kein Bild?
                                                            # 1: Default-Pic laden!
                                                            # 2: kein Bild ausgeben!

$bestand_verwaltung=0;                                      # 1: Bestand-Verwaltung benutzen
                                                            # 0: keine Bestand-Verwaltung

$fehlermeldung_bei_bestand_von_null=1;                      # Hier wird angegeben, ob z.B. eine Bestellung von Menge "1"
                                                            # bei einem Bestand von "0" nicht zugelassen werden soll,
                                                            # oder trotzdem toleriert werden soll. Letzteres kann z.b.
                                                            # sinnvoll sein, wenn der Shopinhaber sehr schnell das
                                                            # Produkt nachbestellen kann!

$mengen_im_warenkorb_addieren=0;                            # Beispiel:
                                                            # Artikel 3456 ist bereits mit der Menge 1 im Warenkorb
                                                            # und wird nochmals in den Warenkorb gelegt.
                                                            # Soll die Menge addiert werden ( = Menge 2) oder soll
                                                            # die Menge bei 1 bleiben?

$admin_passwort="alfalf";                               # Admin-Passwort!
                                                            # Das Admin.Menü kann gestartet werden über:
                                                            # /cgi-bin/his-webshop.pl?admin=<admin passwort>

$no_variants="Beschreibung , Grafik-500 , Grafik-300 , Grafik-100 , GRUPPE , Beschreibung-kurz";  
                                                            # Geben Sie hier die Felder ein, die generell keine Artikel-Varianten
                                                            # (werden mit / oder mit * getrennt) enthalten.


$gutschein_pass_chars="0123456789abcdefghijklmnopqrstuvwxyz";  # Falls Sie mit Gutscheinen arbeiten möchten, geben Sie hier
                                                            # an, welche Zeichen im Passwort des Gutscheins gültig sein sollen
$gutschein_pass_length=10;                                  # Wie lang soll das Gutschein Passwort sein?
$subject_gutschein_mail="Gutschein vom CBIO-Shop";         # Wie soll der Betreff der Gutschein-Mail lauten?



@html_convert=(                                             # Geben Sie hier an, welche "Sonderzeichen" in HTML-Entitäten konvertiert
  "ä=&auml;",                                               # werden sollen. Die Ausgabe muss dann über NAME_HTML bzw. VARIABLE_HTML
  "ü=&uuml;",                                               # erfolgen
  "ö=&ouml;",
  "Ä=&Auml;",
  "Ü=&Uuml;",
  "Ö=&Ouml;",
  "ß=&szlig;"
);

$use_multiline_csv=0;                                       # Geben Sie hier an, ob in der CSV Datei ein Artikel
                                                            # (z.B. durch die Beschreibung) mehrere Zeilen umfasst.
                                                            # Wenn Sie sicher sind, dass ein Artikel immer genau innerhalb
                                                            # einer Zeile definiert ist, kann die Einstellung auch auf 0
                                                            # gestellt werden (Datenbank arbeitet dann deutlich schneller!!!)

$shoppl="/cgi-bin/his-webshop.pl";                          # URL zum Skript


$post_order_mail_to_script_url="";                          # Wird hier eine URL zu einem Script angegeben, so wird keine
                                                            # Bestellmail an den Shopbetreiber geschickt. Stattdessen wird
                                                            # der Text an das Script geschickt (POST).
                                                            # Der Inhalt der Mail wird in der Variablen "mailtext" übermittelt

# ==========================================================================================
# Hier muessen die Felder der Datenbank IN DER KORREKTEN REIHENFOLGE definiert werden.
# Reservierte Felder, die exakt so geschrieben werden muessen sind:
# NR und PREIS
# Alle übrigen Felder aus Ihrer Datenbank koennen frei benannt werden. In den
# Templates kann man dann auf die Variablen jeweils mit [VARIABLE] zugreifen.
# ==========================================================================================

@keyw=(
"ID",
"NR",
"NAME",
"TYP",
"Beschreibung-kurz",
"Beschreibung",
"Gruppe",
"Grafik-500",
"Grafik-300",
"Grafik-100",
"PREIS",
"PREIS2",
"SORT",
"PDF1",
"PDF2"
);

# ==========================================================================================
# Hier muessen die Felder der Kunden-Datenbank IN DER KORREKTEN REIHENFOLGE definiert werden.
# Alle Felder aus Ihrer Datenbank koennen frei benannt werden. In allen
# Templates kann man dann auf die Variablen jeweils mit [VARIABLE] zugreifen.
#
# Sind Sie interessiert am "HIS WebShop Kunden Modul"? Das Kunden-Modul können Sie zur
# besseren Kundenbindung für Ihre Stammkunden einsetzen. Optionaler Login in den Shop,
# namentliche Begrüssung, bereits vorausgefüllte Bestellformulare etc.
# Kosten für das Kunden-Modul: 150,00 DM + MwSt. (Preis vom 24.01.00, ohne Gewähr!)
# Kontaktieren Sie uns: his-soft@shoppark.de
# ==========================================================================================

$use_kunden_db=1;                    # Geben Sie hier an, ob Sie das Kundenmodul nutzen
                                     # möchten!
                                     # 0: kein Kundenmodul nutzen
                                     # 1: Kundenmodul für Stammkunden nutzen!
                                     #    (das Kundenmodul muss dazu unbedingt installiert
                                     #     werden!)
@userf= (
"U_USER",
"U_PASS",
"U_NAME",
"U_EMAIL",
"U_STRASSE",
"U_PLZ",
"U_ORT",
"U_LAND",
"U_TELEFON",
"U_FAX",
"U_KUNDENNR"
);

$user_login_field="U_USER";
$user_pass_field="U_PASS";

# ==========================================================================================
# Hier muessen die Felder der Partner-Datenbank IN DER KORREKTEN REIHENFOLGE definiert
# werden. Alle Felder koennen frei benannt werden.
#
# Sind Sie interessiert am "HIS WebShop Partnerprogramm Modul"? Das Partnerprogramm-Modul
# können Sie zur Einrichtung eines professionellen Partner-Programms einsetzen.
# Kosten für das Partnerprogramm-Modul: 150,00 DM + MwSt. (Preis vom 24.01.00, ohne Gewähr!)
# Kontaktieren Sie uns: his-soft@shoppark.de
# ==========================================================================================

$use_partner_db=1;                   # Geben Sie hier an, ob Sie das Partnerprogramm-Modul nutzen
                                     # möchten!
                                     # 0: kein Partnerprogramm-Modul nutzen
                                     # 1: Partnerprogramm-Modul nutzen!
                                     #    (das Partnerprogramm-Modul muss dazu unbedingt installiert
                                     #     werden!)


$partner_provision=10;                # Provison in Prozent!

@puserf= (
"P_USER",
"P_PASS",
"P_NAME",
"P_EMAIL",
"P_STRASSE",
"P_PLZ",
"P_ORT",
"P_LAND",
"P_TELEFON",
"P_FAX",
"P_KUNDENNR"
);

$partner_login_field="P_USER";
$partner_pass_field="P_PASS";

# ==============================KONFIGURATIONS-TEIL ENDE====================================



# =================================HAUPTPROGRAMM BEGINN=====================================

if ($use_kunden_db==1) {                                    # Falls Stamm-Kunden Modul...
  require "kunde.pl";                                       # Modul einbinden!
}

if ($use_partner_db==1) {                                    # Falls Stamm-Kunden Modul...
  require "partner.pl";                                      # Modul einbinden!
}

$fe[0]="Content-type: text/html\n\n<html><body>Für den Server wurde kein Registrier Key angegeben.\nBitte kontaktieren Sie HIS-Software his-soft\@shoppark.de, um einen gültigen Registrier Key zu erhalten.\nUm die Software zu testen, können Sie den Shop OHNE Registrier Key mit max. 10 Artikeln betreiben. Begrenzen Sie dazu die Artikel Datenbank.</body></html>";
$fe[1]="Content-type: text/html\n\n<html><body>Der Registrier Key ist nicht für den Server gültig.\nBitte kontaktieren Sie HIS-Software his-soft\@shoppark.de, um einen gültigen Registrier Key zu erhalten.\nUm die Software zu testen, können Sie den Shop OHNE Registrier Key mit max. 10 Artikeln betreiben. Begrenzen Sie dazu die Artikel Datenbank.</body></html>";
$fe[2]="Content-type: text/html\n\n<html><body>Der Registrier Key ist ungültig.\nBitte kontaktieren Sie HIS-Software his-soft\@shoppark.de, um einen gültigen Registrier Key für den Server zu erhalten.\nUm die Software zu testen, können Sie den Shop OHNE Registrier Key mit max. 10 Artikeln betreiben. Begrenzen Sie dazu die Artikel Datenbank.</body></html>";

$start_tage = 2450902;                                      # Absolute Tage

# Vorlagen befinden sich in dem Verzeichnis $tempdirectory und haben bis auf
# $template_mail die Endung ".htm"
$template_error="temerror";                                 # Fehler-Vorlage
$template_send="temsend";                                   # "Danke für Ihre Bestellung"-Template
$template_basket="tembaske";                                # Warenkorb-Template
$template_order="temorder";                                 # Bestellugsseite-Template
$template_shop_mail="order.txt";                            # Bestellungsmail-Template für Shop-Inhaber
$template_user_mail="mail.txt";                             # Bestellungsmail-Template für User
$template_partner_mail="mpartner.txt";

$articledat=$datadirectory."artikel.txt";                   # Artikel-Datenbank
$kundetxt=$datadirectory."kunden.txt";                      # Stammkunden-Datenbank
$partnertxt=$datadirectory."partner.txt";                   # Partner-Datenbank
$kundedat=$profiledirectory."kunden.dat";                   # Kunden-Datenbank
$statistikdat=$datadirectory."statistik.txt";
$orderstat=$datadirectory."orderstat.txt";

($id_article_quantity,                                      # Zusaetzliche Arrayindizes fuer Artikel
 $id_article_newquantity,
 $id_article_apreis,
 $id_article_sum,
 $id_article_binfo)=$#keyw+1..$#keyw+5;



($id_global_skript,                                         # Index fuer globale Variablen Array
 $id_global_userid,
 $id_global_remotehost,
 $id_global_versandkosten,
 $id_global_versandkfreiab,
 $id_global_sumall,
 $id_global_sumallv,
 $id_global_hit_start,
 $id_global_hit_end,
 $id_global_hit_max,
 $id_global_hit_menu,
 $id_global_hit_forward,
 $id_global_hit_back,
 $id_global_artikel_anz,
 $id_global_content,
 $id_global_porto_auswahl,
 $id_global_porto,
 $id_global_error,
 $id_global_referer,
 $id_global_shopemail,
 $id_global_ordernr,
 $id_global_min_order,
 $id_global_min_order_zuschlag,
 $id_global_query,
 $id_global_provision,
 $id_global_bonus_nr,
 $id_global_bonus_value,
 $id_global_bonus_pass,
 $id_global_bonus_email,
 $id_global_bonus_message,
 $id_global_happy_hour)=(0..30);
 $last_id_global=30;


($id_kunde_remotehost,                                      # Index fuer Kunden Array
 $id_kunde_kundennr,
 $id_kunde_tage,
 $id_kunde_minuten,
 $id_kunde_userdata,
 $id_kunde_partnerdata,
 $id_kunde_global)=(0..6);

($id_order_date,
 $id_order_ordernr,
 $id_order_sum,
 $id_order_provision,
 $id_order_pid,
 $id_order_status)=(0..5);

%multi= (
   "MENGE", 1,                  # Ok
   "NEUE_MENGE", 1,             # Ok
   "APREIS",1,
   "SUMME", 1,                  # Ok
   "BINFO",1,
   "SKRIPT",5,                  # Ok
   "USER_ID",5,                 # Ok
   "HOST",5,                    # Ok
   "VERSANDKOSTEN",5,           # Ok
   "VERSANDKOSTEN_FREI_AB",5,   # Ok
   "GESAMTSUMME",5,             # Ok
   "GESAMTSUMME_VERSAND",5,     # Ok
   "HIT_START",5,
   "HIT_END",5,
   "HIT_MAX",5,
   "HIT_MENU",5,
   "HIT_FORWARD",5,
   "HIT_BACK",5,
   "ARTIKEL_ANZ",5,
   "CONTENT",5,
   "PORTO_AUSWAHL",5,
   "PORTO",5,
   "ERROR_INHALT",5,            # Ok
   "REFERER",5,
   "SHOPEMAIL",5,
   "MIN_ORDER",5,
   "MIN_ORDER_ZUSCHLAG",5,
   "QUERY",5,
   "HAPPY_HOUR",5,
   "PROVISION",5,
   "BONUS_NR",5,
   "BONUS_PASS",5,
   "BONUS_VALUE",5,
   "BONUS_EMAIL",5,
   "BONUS_MESSAGE",5,
   "ORDERNR",5,
   "ORDERKEY",6,                # Ok
   "ORDERVALUE",6,               # Ok
   "RORDER_DATE",8,
   "RORDER_SUM",8,
   "RORDER_ORDERNR",8,
   "RORDER_PROVISION",8,
   "RORDER_STATUS",8,
   "RORDER_PID",8,
);

%index= (
  "MENGE",$id_article_quantity,
  "NEUE_MENGE",$id_article_newquantity,
  "APREIS",$id_article_apreis,
  "SUMME",$id_article_sum,
  "BINFO",$id_article_binfo,
   "SKRIPT",$id_global_skript,
   "USER_ID",$id_global_userid,
   "HOST",$id_global_remotehost,
   "VERSANDKOSTEN",$id_global_versandkosten,
   "VERSANDKOSTEN_FREI_AB",$id_global_versandkfreiab,
   "GESAMTSUMME",$id_global_sumall,
   "GESAMTSUMME_VERSAND",$id_global_sumallv,
   "HIT_START",$id_global_hit_start,
   "HIT_END",$id_global_hit_end,
   "HIT_MAX",$id_global_hit_max,
   "HIT_MENU",$id_global_hit_menu,
   "HIT_FORWARD",$id_global_hit_forward,
   "HIT_BACK",$id_global_hit_back,
   "ARTIKEL_ANZ",$id_global_artikel_anz,
   "CONTENT",$id_global_content,
   "PORTO_AUSWAHL",$id_global_porto_auswahl,
   "PORTO",$id_global_porto,
   "ERROR_INHALT",$id_global_error,
   "REFERER",$id_global_referer,
   "SHOPEMAIL",$id_global_shopemail,
   "MIN_ORDER",$id_global_min_order,
   "MIN_ORDER_ZUSCHLAG",$id_global_min_order_zuschlag,
   "QUERY",$id_global_query,
   "HAPPY_HOUR",$id_global_happy_hour,
   "PROVISION",$id_global_provison,
   "BONUS_NR",$id_global_bonus_nr,
   "BONUS_PASS",$id_global_bonus_pass,
   "BONUS_VALUE",$id_global_bonus_value,
   "BONUS_EMAIL",$id_global_bonus_email,
   "BONUS_MESSAGE",$id_global_bonus_message,
   "ORDERNR",$id_global_ordernr,
   "ORDERKEY",0,
   "ORDERVALUE",1,
   "RORDER_DATE",$id_order_date,
   "RORDER_SUM",$id_order_sum,
   "RORDER_ORDERNR",$id_order_ordernr,
   "RORDER_PROVISION",$id_order_provision,
   "RORDER_STATUS",$id_order_status,
   "RORDER_PID",$id_order_pid,
);

for ($i=0;$i<=$#pichttp;$i++) {
   $j=$i+1;
   $multi{"PIC$j"}=5;
   $index{"PIC$j"}=$last_id_global+$j;
   $global[$last_id_global+$j]=$pichttp[$i];
}

if ($ENV{'REQUEST_METHOD'} eq "GET") { $buffer = $ENV{'QUERY_STRING'}; }
else { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});  }

if (!($buffer)) {$buffer=substr($ENV{'PATH_INFO'},1,length($ENV{'PATH_INFO'}));}
if (!($buffer)) {$buffer=@ARGV; }



for ($i=0;$i<=$#keyw;$i++) {                                # Reservierte Keywoerter suchen
  if ($keyw[$i] eq "NR")     {$id_article_id=$i;}           # Art. Nr
  elsif ($keyw[$i] eq "PREIS")   {$id_article_costs=$i;}    # Preis
  $multi{$keyw[$i]}=1;                                      # Typ speichern, immer "1"
  $index{$keyw[$i]}=$i;                                     # Feldindex speichern
}

for ($i=0;$i<=$#userf;$i++) {                               # Reservierte Keywoerter suchen
 $uindex{$userf[$i]}=$i;                                    # Feldindex speichern
}
for ($i=0;$i<=$#puserf;$i++) {                              # Reservierte Keywoerter suchen
 $pindex{$puserf[$i]}=$i;                                   # Feldindex speichern
}

@kunde_dat=&read_data($kundedat);                           # Einlesen der Kundendaten


@article_dat=&read_data($articledat);                       # Artikel holen
$global[$id_global_artikel_anz]=$#article_dat+1;


@happy=&read_data($datadirectory."happy.txt");
@happy_today=split(/\,/,$happy[$mday]);
foreach $happy_today (@happy_today) {
  if ($happy_today==$hour) {
    $global[$id_global_happy_hour]=$happy_today;
  }
}


$#nvpairs=-1;                                                         # Paare leeren
($now_tage,$now_minuten,$mday,$month,$year,$hour,$minute)=&now;       # Berechnung absoluter Tage und aktueller Minuten

%input=();                                                            # leerer Input

if ($ENV{CONTENT_TYPE}=~/multipart\/form-data/i) {
   ($content,$ufile)=&Parse_Multi;
    if ($content ne "") {
     $ufile=&get_file($ufile);
   }
} else {
  $buffer=&ReadParse($buffer,*input);                                   # Einlesen der Formulareingaben
}

#$input{"t"}="temdd";
#$input{"f2"}="PREIS";
#$input{"c2"}="";
#$input{"f1"}="*NAME";
#$input{"c1"}="epson";
#$input{"f"}="HERSTELLER";
#$input{"c"}="";
#$input{"t"}="temgroup";


$#basket_dat_new=-1;                                                  # leerer Array für neu in den Warenkorb gelegte Artikel

# Bereitgestellte Funktionen im Partnerprogramm-Modul
if ($input{"pid"} ne "") {
  $buffer.="&G_pid=".$input{"pid"};
  $input{"G_pid"}=&login_puser($input{"pid"});
}

# Speichern von globalen Variablen
@keyval=&get_input($buffer);

foreach $keyval (@keyval) {
  @field=split(/\;/,$keyval);                             # Felder ermitteln
  if ($field[0]=~/^G_(.*)/) {
    $global{$field[0]}=$field[1];
  }
}



if ($CGI{"update"} ne "") {
  &pic_update($CGI{"update"},$content,$ufile,$CGI{"pass"});exit;
}

$REMOTE_HOST=$ENV{'REMOTE_ADDR'};                           # Remote Host ermitteln
$global[$id_global_remotehost]=$REMOTE_HOST.'#'.$ENV{'HTTP_VIA'}.'#'.$ENV{'REMOTE_HOST'}.'#'.$ENV{'HTTP_USER_AGENT'};  # Zur Identifik. Remote Host und HTTP Via (proxys) verwenden
$global[$id_global_remotehost]=~s/\;/\,/g;
$global[$id_global_userid]=&get_user_id;                    # User-Id
$global[$id_global_versandkosten]=$versandk_hoehe;          # Versandkosten
$global[$id_global_versandkfreiab]=$versandk_frei_ab;       # Freibetrag fuer Versandkosten
$global[$id_global_skript]=$shoppl;                         # Name des Skripts
$global[$id_global_referer]=$ENV{'HTTP_REFERER'};
$global[$id_global_shopemail]=$email;
$global[$id_global_min_order]=$min_order;
$global[$id_global_min_order_zuschlag]=$min_order_zuschlag;
$global[$id_global_query]=$buffer;


$basketdat=&get_basketdat($global[$id_global_userid]);      # Name des Warenkorbs des Kunden ermitteln
@basket_dat=&read_data($basketdat);                         # Warenkorb des Kunden einlesen
$#basket_dat_new=-1;                                        # Leeren Warenkorb für "neu in den Warenkorb gelegte Artikel"
if ($dif_porto!=0) {                                        # Falls Versandk. vom Kunden auswählbar...
  $portodat=&get_portodat($global[$id_global_userid]);      # Name des Files ermitteln, in dem die Versandk. gespeichert sind
  @porto=&read_data($portodat);                             # Daten einlesen
  $porto=$porto[0];                                         # Versandk.art = 1. Zeile
}


##########
## Gutschein
   if ($input{"AddBonus"}==1) {

     
      $time=time;
      push(@keyval,join(';',"add_NR","G_".$time));
      push(@keyval,join(';',"add_MENGE",1));
      push(@keyval,join(';',"add_PREIS",$input{"SumBonus"}));
      if ($input{"EmailFromBonus"}!~/^([a-zA-Z0-9\-\.\_]+)@([a-zA-Z0-9\-\.\_]+\.[a-z]+)$/) {
        &abbruch("Die E-Mail des Gutschein Ausstellers ist in einer ung&uuml;ltigen Form angegeben.");
      }
      if ($input{"EmailToBonus"}!~/^([a-zA-Z0-9\-\.\_]+)@([a-zA-Z0-9\-\.\_]+\.[a-z]+)$/) {
        &abbruch("Die E-Mail des Gutschein Empf&auml;ngers ist in einer ung&uuml;ltigen Form angegeben.");
      }
      $global{"G_BonusEMAILFROMBONUS$time"}=$input{"EmailFromBonus"};
      $global{"G_BonusEMAILTOBONUS$time"}=$input{"EmailToBonus"};
      $global{"G_BonusEMAILTEXTBONUS$time"}=$input{"EmailTextBonus"};
      &search_user($global[$id_global_userid]);
   }

   if ($input{"UseBonusNr"} ne "" || $input{"UseBonus"}==1) {
      if ($input{"UseBonusNr"} eq "") {&abbruch("Bitte geben Sie eine Gutscheinnummer an.");}
      &format_warenkorb;
      ($pass,$gutschein_sum,$bezahlt,$ausgeloest)=&get_gutschein_pass($input{"UseBonusNr"});
      if ($pass eq "-1") {&abbruch("Diese Gutschein Nr. existiert nicht.")}
      if ($bezahlt==0) {&abbruch("Der Gutschein [ERORR_VAR1] ist noch nicht bezahlt.",$gutschein_nr)}
      if ($ausgeloest>0) {&abbruch("Der Gutschein [ERORR_VAR1] ist bereits ausgelöst.",$gutschein_nr)}
      if ($pass ne $input{"UseBonusPass"}) {&abbruch("Das Gutschein Passwort ist falsch.")}

      if ($global[$id_global_sumall]<$gutschein_sum) {
         &abbruch("Im Warenkorb befinden sich Artikel im Wert von ".&format_sum($global[$id_global_sumall])." EUR. Der ".&format_sum($gutschein_sum)." EUR Gutschein kann daher nicht eingel&ouml;st werden.");
      }

      push(@keyval,join(';',"add_NR","GE_".$input{"UseBonusNr"}));
      push(@keyval,join(';',"add_MENGE",1));
      push(@keyval,join(';',"add_PREIS",-$gutschein_sum));
   }

if ($input{"pic_show"}==1) {&pic_show_or_kill(0);exit}
if ($input{"pic_kill"}==1) {&pic_show_or_kill(1);exit}
if ($input{"empty"} ne "") {unlink "$basketdat";$#basket_dat=-1}

if ($input{"required"} ne "") {
   &kontrolliere_required;                                   # benötigte Felder kontrollieren
}

if (defined($input{"u_login"})) {                           # Falls Login....
  &kunde_login($input{"u_login"},$input{"u_pass"});         # Funktion kunde_login aufrufen!
}

if (defined($input{"p_login"})) {                           # Falls Login....
  &partner_login($input{"p_login"},$input{"p_pass"});         # Funktion kunde_login aufrufen!
}


@glob=&read_data($globaltxt);
foreach $glob (@glob) {
  @d=split(/\;/,$glob);
  $input{"G_$d[0]"}=$d[1];
}

# Bereitgestellte Funktionen im Kunden-Modul
if ($input{"setkundencookie"}>0) {
   &set_kunden_cookie($input{"setkundencookie"});
}
if ($input{"send_pw_login"} ne "" || $input{"send_pw_email"} ne "") {&send_pw($input{"send_pw_login"},$input{"send_pw_email"});}
if ($input{"deletekundencookie"}==1) {&delete_kunden_cookie;}
if ($input{"readkundencookie"}==1) {&read_kunden_cookie;}


if ($input{"adduser"}==1)   {                               # Anmeldung eines neuen Kunden
   &adduser;
}
if ($input{"deleteuser"}==1) {                              # Kunde löschen
   &deleteuser;
}
if ($input{"edituser"}==1) {                                # Kunde editieren
   &edituser;
}
if ($input{"logout"}==1)   {                                # Kunde Logout
   &logout;
}
if ($input{"adduser_partner"}==1)   {&adduser_partner;}
if ($input{"deleteuser_partner"}==1) {&deleteuser_partner;}
if ($input{"edituser_partner"}==1) {&edituser_partner;}
if ($input{"logout_partner"}==1)   {&logout_partner;}


srand(time);
if (int(rand(100))==1) {
  opendir (VERZ, "$profiledirectory");
  @datei= grep (!/^\.\.?$/, readdir VERZ);
  closedir VERZ;
  foreach $datei (@datei) {
    $age=-M $profiledirectory.$datei;
    if ($age>1) {
      unlink $profiledirectory.$datei;
    }
  }
}

if ($input{"update"} ne "") {&update($input{"update"},$input{"pass"})}
if ($input{"admindelete"} ne "") {&admindelete($input{"pass"});}
if ($input{"add_to_db"} ne "") {&add_to_db($input{"add_to_db"})}
if ($input{"admin"} eq $admin_passwort && $admin_passwort ne "") {&admin;}

if ($input{"show_prov"} ne "") {

   $code=qq!<html><body><h1>Partner-Bestellungen in $input{"month"}/$input{"year"}</h1>!;
   $code.="<table width=800><tr><td>Datum</td><td>Nr</td><td>Status</td><td>Summe</td><td>Provis.</td><td>Beschreibung</td><td>PID</td></tr>";
   $code.="[REPEAT_RORDER]";
   $code.="<tr><td>[RORDER_DATE]</td><td>[IF_('[RORDER_ORDERNR]'>0)][RORDER_ORDERNR][IF_END]</td><td>[RORDER_STATUS]</td><td>[RORDER_SUM]</td><td>[PRINTF([RORDER_SUM]*[RORDER_PROVISION]/100)]</td><td>[IF_('[RORDER_ORDERNR]' eq '-')]Gutschrift[IF_END][IF_('[RORDER_ORDERNR]' ne '-')][RORDER_ORDERNR][IF_END]</td><td>[RORDER_PID]</td></tr>";
   $code.="[REPEAT_RORDER_END]";
   $code.="</table><p>";

    if ($input{"show_prov_pid"} eq "ALL") {
     $all_partner="ALL";
   } else  {
     $all_partner=$input{"show_prov_pid"};
   }
   print "Content-type: text/html\n\n";
   print &parse_line($code);
   exit;
}


if ($input{"pay_partner"} ne "") {
  if ($input{"pass"} ne $admin_passwort) {&abbruch("Falsches Passwort");}
  &pay_partner($input{"pay_partner"},$input{"sum_pay_partner"});
}
if ($input{"correct_prov"} ne "") {
  if ($input{"pass"} ne $admin_passwort) {&abbruch("Falsches Passwort");}
  &pay_partner($input{"correct_prov"},&format_sum($input{"minus_prov"}*$partner_provision/100),$input{"reason_prov"});
}

if ($input{"status_ordernr"} ne "") {
  if ($input{"pass"} ne $admin_passwort) {&abbruch("Falsches Passwort");}
  &set_status($input{"status_ordernr"},$input{"new_status"});
}
if ($input{"ChangeBonusStatNr"} ne "") {
  &change_gutschein_status($input{"pass"},$input{"ChangeBonusStatNr"},$input{"BonusBezahlt"},$input{"BonusEingeloest"});
}

if ($input{"send_order"}) {                                 # Falls Aktion "Mail verschicken"
  &send_mail;                                               # Mails versenden
  &output_order;                                            # Nachricht ausgeben
  exit;
} elsif ($input{"order"} ne "" || $input{"order.x"} ne "") {                                # Falls Aktion "Bestellseite"
  &special_request("","",$template_order);                  # Bestellungsseite ausgeben
} else {
  if ($cdmodul_ist_aktiv==0) {
    &special_request($input{"f"},$input{"c"},$input{"t"},$input{"start"},$input{"dif"},$input{"aliste"});
  } else {
   1;
  }
}



sub admin {
 print "Content-type: text/html\n\n";
 print "<html><body>";
 print "<h3>WebShop Administration:</h3>";
 print qq!<ol><li><form action="$shoppl" method="POST">!;
 print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
 print qq!<b>Artikel editieren:</b><br>!;
 print qq!Artikel-Nr.: <input type="text" name="update" size=10">\n!;
 print qq!<input type="submit" value="Artikel editieren">!;
 print qq!</Form>!;
 print qq!<li><form action="$shoppl" method="POST">!;
 print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
 print qq!<input type="submit" name="update" value="Neuen Artikel eintragen">!;
 print qq!</form>!;
  print qq!<li><form action="$shoppl" method="POST">!;
 print qq!<b>Gutschein Status setzen:</b><br>!;
 print qq!Gutschein-Nr.: <input type="text" name="ChangeBonusStatNr" size=20>\n!;
 print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
 print qq!<select name="BonusBezahlt"><option value="1">bezahlt<option value="0">nicht bezahlt</select>\n!;
 print qq!<select name="BonusEingeloest"><option value="">Eingel&ouml;st Status nicht &auml;ndern<option value="1">eingel&ouml;st<option value="0">nicht eingel&ouml;st<option value="-9999999">kann beliebig oft eingel&ouml;st werden</select><br>\n!;
 print qq!<input type="submit"  value="Status neu setzen">!;
 print qq!</form>!;


 if ($use_partner_db==1) {
   print qq!<li><form action="$shoppl" method="POST">!;
   print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
   print qq!<b>Status einer Bestellung setzen:</b><br>!;
   print qq!<table><tr><td>Bestell-Nr.:</td><td><input type="text" name="status_ordernr" size=20></td></tr>!;
   print qq!<tr><td valign=top>Neuer Status:</td><td><input type="text" name="new_status" size=20><br><font size=2>(z.b. "OK" oder "Bestellung ung&uuml;ltig" etc.)</td></tr></table>!;
   print qq!<input type=submit value="Status eintragen">!;
   print qq!</form>!;
   print qq!<li><form action="$shoppl" method="POST">!;
   print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
   print qq!<b>Provisions-Korrekturen durch Stornierungen oder zurückgesendete Waren eintragen:</b><br>!;
   print qq!<table><tr><td>Partner-ID (PID):</td><td><input type="text" name="correct_prov" size=20></td></tr>!;
   print qq!<tr><td valign=top>Warenwert-Minderung um einen Betrag von:</td><td><input type="text" name="minus_prov" size=20></td></tr>!;
   print qq!<tr><td valign=top>Begründung:</td><td><input type="text" name="reason_prov" size=20></td></tr>!;
   print qq!</table>!;

   print qq!<input type=submit value="Status eintragen">!;
   print qq!</form>!;
   print qq!<li><form action="$shoppl" method="POST">!;
   print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
   print qq!<b>&Uuml;berweisung an Partner (Reseller) eintragen:</b><br>!;
   print qq!<table><tr><td>Partner-ID (PID):</td><td><input type="text" name="pay_partner" size=20></td></tr>!;
   print qq!<tr><td>Überwiesener Betrag:</td><td><input type="text" name="sum_pay_partner" size=10></td></tr></table>!;
   print qq!<input type="submit" value="Überweisung an Partner eintragen">!;
   print qq!</form>!;

   print qq!<li><form action="$shoppl" method="POST">!;
   print qq!<input type="hidden" name="show_prov" value="1">!;
   print qq!<input type="hidden" name="pass" value="$admin_passwort">!;
   print qq!<b>Übersicht aller Bestellungen über das Partnermodul:</b><br>!;
   print qq!<table><tr><td>Monat</td><td><input type="text" name="month" value="$month" size=10></td></tr>!;
   print qq!<tr><td>Jahr</td><td><input type="text" name="year" value="$year" size=10></td></tr>!;
   print qq!<tr><td>Partner-ID (PID):</td><td><input type="text" name="show_prov_pid" value="ALL" size=10></td></tr></table>!;
   print qq!<input type="submit" value="Übersicht anzeigen">!;
   print qq!</form>!;
 }
 print qq!</ol>!;
 print "</body></html>";
 exit;
}


sub pic_update {
 local($nr,$content,$ufile,$pass)=@_;
 $picnr=$CGI{"pic"};

 $this_pic=$nr;
  @a=split(/ \* /,$this_pic);
 $this_pic=$a[0];

 $this_pic=~s/\s//g;
 $this_pic=~s/[\\\/]//g;


 $endung="";
 if ($ufile=~/\.gif/i) {$endung=".gif";}
 if ($ufile=~/\.jpg/i) {$endung=".jpg";}

 if ($ufile eq "") {
   unlink "$picverz[$picnr]$this_pic.gif";
   unlink "$picverz[$picnr]$this_pic.jpg";
 } else {
   open(f,">$picverz[$picnr]$this_pic$endung");
   binmode f;
   print f $content;
   close(f);
 }


 &update($nr,$pass);
}

sub admindelete {
  local($pass)=@_;
  if ($pass ne $admin_passwort) {&abbruch("Falsches Passwort");}
  &get_input;
  foreach $keyval (@keyval) {
    @field=split(/\;/,$keyval);                             # Felder ermitteln
    if ($field[0]=~/^delete_(.*)/) {
     $del{$1}="ok";

     }
   }
  $#new_article_dat=-1;
  foreach $article_dat (@article_dat) {
     @a=split(/\;/,$article_dat);
     if ($del{$a[$id_article_id]} eq "") {
       push(@new_article_dat,$article_dat);
     }
  }
  @article_dat=@new_article_dat;
  &save_array($articledat,"article",@article_dat);
}

sub update {
  local($nr,$pass)=@_;

  if ($pass ne $admin_passwort) {&abbruch("Falsches Passwort");}
  @adata=&get_article_data($nr);


  $do_update=0;
  foreach $keyw (@keyw) {
    if (defined($input{"update_$keyw"})) {
      $adata[$index{$keyw}]=$input{"update_$keyw"};
      $do_update=1;
    }
  }
  $gef=0;
  if ($do_update==1) {
    foreach $article_dat (@article_dat) {
      @a=split(/\;/,$article_dat);
      if ($a[$id_article_id] eq $nr) {
        $article_dat=join(';',@adata);
        $gef=1;
      }
    }
    if ($gef==0) {
      push(@article_dat,join(';',@adata));
    }
    &save_array($articledat,"article",@article_dat);
  }
  $#article=-1;
  push(@article,join(';',@adata));

  if ($input{"exit_update"}==1 || $CGI{"exit_update"}==1) {return;}

  $table=qq!<form action="$shoppl" method="POST">\n!;
  $table.=qq!<input type="hidden" name="update" value="$nr">\n!;
  $table.=qq!<input type="hidden" name="pass" value="$admin_passwort">\n!;
  $table.=qq!<table border="0">\n!;
  $i=0;
   foreach $keyw (@keyw) {
    $value="$adata[$i]";
    if ($input{$keyw} ne "") {$value=$input{$keyw}}
    if ($keyw eq "NR" && $nr eq "neu") {$value=time;}

    if ($keyw ne "BESCHREIBUNG") {
      $table.=qq!<tr><td><b>$keyw</b><br><input type="text" name="update_$keyw" size=120 value="$value"></td></tr>\n!;
    } else {
      $value=~s/\<br\>/\n/g;
     $table.=qq!<tr><td><b>$keyw</b><br><textarea name="update_$keyw" cols=100 rows=6 wrap="on">$value</textarea></td></tr>\n!;

    }
    $i++;
  }
  $table.="</table>";
  $table.=qq!<input type="submit" value="Artikel &auml;ndern">!;
  $table.="</form>\n";

  $i=-1;
  foreach $pichttp (@pichttp) {
    $i++;$j=$i+1;
    $table.=qq![REPEAT_ARTIKEL]<form action="$shoppl" method="POST" enctype="multipart/form-data">\n!;
    $table.=qq!<input type="hidden" name="update" value="$nr">\n!;
    $table.=qq!<input type="hidden" name="pass" value="$admin_passwort">\n!;
    $table.=qq!<input type="hidden" name="pic" value="$i">\n!;
    $table.=qq![PIC$j]<br><b>$pichttp[$i]</b><br>!;
    $table.=qq!<input type=file name="UploadedFile" size=90>\n!;
    $table.=qq!<input type="submit" value="Bild Upload">!;
    $table.=qq!</form>[REPEAT_ARTIKEL_END]!;
  }

  print "Content-type: text/html\n\n";
  print "<html><body>".&parse_line($table)."</body></html>";
  exit;
}



# ==========================================================================================
# Hinzufügen eines Eintrags in die Datenbank über ein Web-Formular!
# ==========================================================================================

sub add_to_db {
  local($db)=@_;


  $#new_entry=-1;
  foreach $keyw (@keyw) {
    if ($input{"$keyw"} ne "") {
      $new_entry[$index{$keyw}]=$input{"$keyw"};
    }
  }

  open(f,">>$datadirectory$db");
  print f join(';',@new_entry)."\n";
  close(f);
}

# ==========================================================================================
# Funktion zum Entfernen "überflüssiger" Bilder, also i.d.R. Grafiken, die zu Artikeln
# gehören, die gelöscht wurden.
# ==========================================================================================

sub pic_show_or_kill {
  local($pic_kill)=@_;
  foreach $article_dat (@article_dat) {
    @array=split(/\;/,$article_dat);
    $array[$index{"NR"}]=~s/\s//g;
    $array[$index{"NR"}]=~s/[\\\/]//g;
    $is_ok{$array[$index{"NR"}]}=1;
  }

  print "Content-type: text/html\n\n";
  print "<html><body>";
  $ok=1;
  foreach $picverz (@picverz) {
    opendir (VERZ, "$picverz");
    @datei= grep (!/^\.\.?$/, readdir VERZ);
    closedir VERZ;

    foreach $datei (@datei) {
      if ($datei=~/\.gif$/i || $datei=~/\.jpg$/) {
        $d=$datei;
        $d=~s/\.gif//gi;
        $d=~s/\.jpg//gi;
        if ($is_ok{$d}==0 && $datei ne $default_pic) {
          if ($pic_kill==0) {
            $ok=0;
            print "Die Datei $picverz$datei kann gel&ouml;scht werden.<br>\n";
          } else {
            $ok=0;
            unlink "$picverz[0]$datei";
            print "Die Datei $picverz$datei wurde gel&ouml;scht.<br>\n";
          }
        }
      }
    }
  }
  if ($ok==1) {
    print "Alles in Ordnung!";
  }
}


# ==========================================================================================
# Kontrolle der Felder der Bestellungsseite, die zwingend einen Inhalt haben müssen.
# Um diese Felder zu definieren, kann das Formular auf der Bestellseite ein HIDDEN-Feld mit
# Namen "required" enthalten. Beispiele:
# <input type=hidden name="required" value="Name,Email,Strasse">
# ==========================================================================================

sub kontrolliere_required {
  local($required,@required);

  $c=&CC_Verify($input{"Kartentyp"},$input{"Kartennummer"});
  if ($c==0) {
    &abbruch("Die Kreditkarten-Daten sind leider ung&uuml;ltig.");
  }

  $required=$input{"required"};                             # Das Feld mit Namen "requried" einlesen
  @required=split(/\,/,$required);                          # Felder ermitteln
  foreach $required (@required) {                           # Alle Felder durchlaufen
    if ($input{$required} eq "") {                          # Falls das angegebene Feld nicht ausgefüllt wurde...
      &abbruch("Bitte f&uuml;llen Sie das Feld <b>$required</b> aus. Vielen Dank!")        # Fehlermeldung ausgeben!
    }
  }
}

# ==========================================================================================
# Ermittelt die User-ID des Benutzers
# ==========================================================================================

sub get_user_id {
  if ($input{"userid"} ne "") {                                   # Falls UserId per Formulareingabe uebergeben wird...
    return &search_user($input{"userid"});
  }
  else {
    return &search_user("");                                    # Ansonsten UserId suchen
  }
}


# ==========================================================================================
# Kontrolliert, ob zwei Angaben (zusammengesetzt aus REMOTE_HOST und HTTP_VIA) vom selben
# Kunden stammen (inkl. Proxy Test!)
# ==========================================================================================

sub check_equal {
  local($r1,$r2)=@_;                                        # Einlesen der zwei Angaben
  @host_http1=split(/\#/,$r1);                              # Angaben in REMOTE_HOST und HTTP_VIA zerlegen
  @host_http2=split(/\#/,$r2);
  if ($host_http1[3] ne $host_http2[3]) {return 0;}         # Browser gleich?
  if ($host_http2[1] eq ''  || $host_http1[1] eq '') {      # Falls keine HTTP_VIA Angabe => Keine Proxys, direkte Verbindung, einfach zu handeln
    @ip1=split(/\./,$host_http1[0]);
    @ip2=split(/\./,$host_http2[0]);
    if  ( ( ($ip1[0]==195 && $ip1[1]==14) || ($ip1[0]==194 && $ip1[1]==8)) &&
          ( ($ip2[0]==195 && $ip2[1]==14) || ($ip2[0]==194 && $ip2[1]==8))) {return 1;}
    if ($ip1[0] ne $ip2[0] || $ip1[1] ne $ip2[1]) {return 0;}       # Falls IPs ungleich => nicht derselbe Kunde
    return 1;                                               # Ansonsten ist es derselbe Kunde
  }

  if ($host_http1[1] eq $host_http2[1]) {return 1;}         # Falls HTTP_VIA gleich => derselbe Kunde
  @http_via1=split(/ /,$host_http1[1]);                     # HTTP_VIA z.B.: "HTTP/1 speth13.dort01.t-online.de"
  @http_via2=split(/ /,$host_http2[1]);
  @p1=split(/\./,$http_via1[1]);                            # Untersucht werden soll der Teil: speth13.dort01.t-online.de
  @p2=split(/\./,$http_via2[1]);
  if ($p1[1] ne $p2[1]) {return 0;}                         # 2. Teil untersuchen
  if ($p1[2] ne $p2[2]) {return 0;}                         # 3. Teil untersuchen
  $first1=$p1[0];                                           # 1. Teil untersuchen
  $first2=$p2[0];
  $min=length($first1);                                     # min. Zeichenfolge ermitteln
  if (length($first2)<$min) {$min=length($first2)}
  $first1=substr($first1,0,$min-2);                         # jeweils vom 1. Teil nur die ersten Zeichen verwenden
  $first2=substr($first2,0,$min-2);
  if ($first1 ne $first2) {return 0;}                       # Zeichenketten vergleichen
  return 1;
}

sub get_global_data {
  local($g)=@_;
  @global_keyvalues=split(/\~/,$g);
  foreach $global_keyvalues (@global_keyvalues) {
    @kv=split(/\=/,$global_keyvalues);
    if (!defined($input{"$kv[0]"})) {
      $input{"$kv[0]"}=$kv[1];
      $global{$kv[0]}=$kv[1];
    }
  }
}

sub get_global_data_string {
  local($g);
  foreach $key (sort(keys %global)) {
    $global{$key}=~ s/\cM\n/ /g;
    $g.=$key. '='. $global{$key}. "~";
  }
  return $g;
}

# ==========================================================================================
# Sucht nach einem User und gibt dessen Kunden-Nr. zurueck.
# Wenn User nicht in Liste oder laenger als max_minuten_inaktiv in Liste, wird auf die
# Prozedur create_new_kunde verwiesen.
# Wenn der User gefunden wurde und im Bereich max_minuten_inaktiv ist, wird der alte Eintrag
# geloescht, der User mit neuer Zeit am Anfang der Liste eingefuegt und die Kundennummer
# zurueckgegeben.
# ==========================================================================================

sub search_user {
  local($opt_id)=@_;
  local($is_equal);

  $knr=0;
  $#new_kunde_dat=-1;
  foreach $kunde_dat (@kunde_dat) {
    $kunde_dat=~s/\[USER_ID\]/$min_userid/g;
     @kunde=split(/\;/,$kunde_dat);                      # Kundendaten holen
    $vergangene_minuten=$now_tage*24*60+$now_minuten-($kunde[$id_kunde_tage]*24*60+$kunde[$id_kunde_minuten]);
     if ($vergangene_minuten<=$max_minuten_inaktiv) {      # Vergangene Minuten mit eingestellter Zeit vergleichen

      $is_equal=0;
      if ($opt_id eq "") {
        if (&check_equal($kunde[$id_kunde_remotehost],$global[$id_global_remotehost])==1) {    # Falls IP-Adresse+HTTP_VIA uebereinstimmen
          $is_equal=1;
        }
      } else {
        if ($opt_id eq $kunde[$id_kunde_kundennr]) {
          $is_equal=1;
        }
      }
     if ($is_equal==1) {
        $kunde[$id_kunde_tage]=$now_tage;                   # Kundendaten zuweisen
        $kunde[$id_kunde_minuten]=$now_minuten;
        &get_global_data($kunde[$id_kunde_global]);
        $kunde[$id_kunde_global]=&get_global_data_string;
        $knr=$kunde[$id_kunde_kundennr];
        @user_daten=split(/\|/,$kunde[$id_kunde_userdata]);
        @partner_daten=split(/\|/,$kunde[$id_kunde_partnerdata]);
      }
      push(@new_kunde_dat,join(';',@kunde));
    } else {
      $killdat=&get_basketdat($kunde[$id_kunde_kundennr]);     # Warenkorb holen
      unlink "$killdat";                                       # Warenkorb loeschen
      if ($dif_porto!=0) {
        $killdat2=&get_portodat($kunde[$id_kunde_kundennr]);   # Portodat
        unlink "$killdat2";                                    # löschen
      }
    }
  }

  if ($knr==0) {
    @nk=&create_new_kunde;
    if ($opt_id ne "" && $is_equal==0) {
      $nk[$id_kunde_kundennr]=$opt_id;
    }
    $nk[$id_kunde_global]=&get_global_data_string;
    push(@new_kunde_dat,join(';',@nk));
    @kunde_dat=@new_kunde_dat;
    $knr=$nk[$id_kunde_kundennr];
  }
  &save_array($kundedat,"kunde",@new_kunde_dat);          # Speichern
  return $knr;                                            # neuer Kunde
}


# ==========================================================================================
# Ein neuer Kunde wird erstellt und in die Kundenliste am Anfang eingefuegt.
# Falls die Kundenliste mehr als max_user Eintraege hat, werden die aeltesten Eintraege
# (stehen hinten) geloescht. Die Profil-Dateien werden ebenfalls geloescht.
# Anschliessend wird solange eine beliebige Zuf-Zahl aus dem Bereich min_userid-max_userid
# gewaehlt, bis es KEINE Profil-Datei zu der Kundennr. gibt. Der neue Kunde ist dann
# gefunden. Die Kunden-Felder werden gesetzt und er wird an den Anfang der Liste eingefuegt.
# ==========================================================================================

sub create_new_kunde {
  srand();                                                  # Zuf-Generator initialisieren

  &lock("stat");
  @s=&read_data($statistikdat);
  $found=0;
  foreach $s (@s) {
    @z=split(/\;/,$s);
    if ($z[0]=~/$mday\.$month\.$year/) {
      $z[1]++;
      $s=join(';',@z);
      $found=1;
    }
  }
  if ($found==0) {
    push(@s,join(';',"$mday.$month.$year",1));
  }
  &save_array($statistikdat,"statistik",@s);
  &unlock("stat");

  do {                                                      # Wiederhole solange...
    $zuf=int rand($max_userid-$min_userid+1)+$min_userid;   # und berechne eine Zuf-Zahl
    $basketdat=&get_basketdat($zuf);                        # und den dazugeh. Warenkorb
  } while (&exist($basketdat));                             # wie der Warenkorb exisitert
  &new($basketdat,$basketdat);                              # Warenk. ex. nicht. Wird also neu erstellt.
  if ($dif_porto!=0) {
    $portodat=&get_portodat($zuf);
    &new($portodat,$portodat);
  }
  $#new_kunde=-1;                                           # Kundendaten zuweisen
  $new_kunde[$id_kunde_remotehost]=$global[$id_global_remotehost];
  $new_kunde[$id_kunde_kundennr]=$zuf;
  $new_kunde[$id_kunde_tage]=$now_tage;
  $new_kunde[$id_kunde_minuten]=$now_minuten;
  return @new_kunde;
}


# ==========================================================================================
# Fuer eine Kundennr (Input) wird die zugehoerige Profil-Datei zurueckgegeben.
# ==========================================================================================

sub get_basketdat {
  local($filename)=@_;                                      # Kundennr. als Paramter
  while (length($filename)<7) {$filename="0".$filename;}   # "0.." am Anfang einfuegen
  return ($profiledirectory."k$filename.txt");              # Rückgabe
}

sub get_portodat {
  local($filename)=@_;                                      # Kundennr. als Paramter
  while (length($filename)<7) {$filename="0".$filename;}   # "0.." am Anfang einfuegen
  return ($profiledirectory."p$filename.txt");              # Rückgabe
}

# ==========================================================================================
# Gibt anhand der Art.Nr die Daten eines Artikels zurueck.
# ==========================================================================================

sub get_article_data {
 local($id)=@_;                                            # ID einlesen
 local(@article_fields,$article_dat);
  foreach $article_dat (@article_dat) {                     # Artikel durchlaufen
    @article_fields=split(/\;/,$article_dat);               # Felder ermitteln
    @id_search=split(/ \, /,$article_fields[$id_article_id]);

    foreach $id_search (@id_search) {
      if ($id_search eq $id) {           # Falls ID gefunden...

        $article_fields[$id_article_id]=$id_search;
        return @article_fields;                               # Artikel Daten zurückgeben
      }
    }
  }
  return -1;
}

sub by_groupby_num {
  @b = split(/\;/,$b);
  @a = split(/\;/,$a);
  $a[$groupby_index] <=> $b[$groupby_index];    # presuming integers
}


sub by_groupby {
  @b = split(/\;/,$b);
  @a = split(/\;/,$a);
  $a[$groupby_index] cmp $b[$groupby_index];    # presuming integers
}

sub aliste {
  local($t)=@_;

  @aliste=split(/\,/,$user_daten[$uindex{"U_LISTE"}]);
  foreach $aliste (@aliste) {
    $l{$aliste}=1;
  }

  $#article=-1;
  foreach $article_dat (@article_dat) {
    @afelder=split(/\;/,$article_dat);
    if ($l{$afelder[$id_article_id]}==1) {
        push(@article,$article_dat);
    }
  }

  $line=join("\n",&read_data("$tempdirectory$t.htm"));    # Vorlage einlesen
  $line=&parse_line($line);                               # Variablen ersetzen
  print "Content-type: text/html\n\n";
  print $line;                                            # ausgeben
  exit;
}

sub special_request {
  local($f,$c,$t,$start,$dif,$aliste)=@_;

  local(%group)=();

  if ($f ne "GRUPPE") {
    $lfile=$datadirectory."search.txt";
    $#slist=-1;
    push(@slist,$f,$c);
    $i=1;
    while ($input{"f$i"} ne "") {
      push(@slist,$input{"f$i"},$input{"c$i"});
      $i++;
    }
    open(f,">>$lfile");
    print f join(';',@slist,$dif)."\n";
    close(f);
  }

  &process_order;
  $global[$id_global_content]=$c;
  $global[$id_global_content]=~s/\\s/ /g;

  if ($aliste==1) {
   $global[$id_global_content]="Auftragsliste";
    $#new_article_dat=-1;
    @al=&read_data($orderstat);
    foreach $al (@al) {
      @aliste_dat=split(/\;/,$al);
      if ($aliste_dat[2] eq $user_daten[$uindex{"$user_login_field"}]) {
         $l{$aliste_dat[3]}=1;
      }
    }
    $#article=-1;
    foreach $article_dat (@article_dat) {
      @afelder=split(/\;/,$article_dat);
      if ($l{$afelder[$id_article_id]}==1) {
          push(@new_article_dat,$article_dat);
      }
    }
  } else {
    $groupby=$input{"groupby"};

    if ($input{"v"}=~/or/i) {
     $or_mode=1;
     } else {
      $or_mode=0;
    }
    $#new_article_dat=-1;


    $#search_c=-1;
    $i="";
    do {
      $f=$input{"f$i"};
      $cs=$input{"c$i"};


      if ($f=~/^\>\=/) {$input{"c$i"}=">=".$cs;$input{"f$i"}=~s/^\>\=//;}
      elsif ($f=~/^\<\=/) {$input{"c$i"}="<=".$cs;$input{"f$i"}=~s/^\<\=//;}
      elsif ($f=~/^\>/) {$input{"c$i"}=">".$cs;$input{"f$i"}=~s/^\>//;}
      elsif ($f=~/^\</) {$input{"c$i"}="<".$cs;$input{"f$i"}=~s/^\<//;}


      $cs=~ s/[öÖ]/[öÖ]/g;
      $cs=~ s/[äÄ]/[äÄ]/g;
      $cs=~ s/[üÜ]/[üÜ]/g;
      if ($input{"use_perl"}==0) {
        $cs =~ s/[.*?+]//g;
      }

      if ($input{"search"} eq "ALL") {
         if ($cs!~/"(.*?)"/) {
           $cs='"'.$cs.'"';
          }
      }

      while ($cs=~/"(.*?)"/) {
        $vor=$`;
        $hinter=$';
        $treffer=$1;
        $treffer=~s/ /\<_\>/g;
        $cs=qq!$vor$treffer$hinter!;
      }
      push(@search_c,$cs);
      $i++;
   } while ($f ne "");

   foreach $article_dat (@article_dat) {
      @afelder=split(/\;/,$article_dat);

      $i=0;
      $co=0;
      $mo=0;

      $#this_term_ok=-1;
      do  {
        $this_field_ok=0;
        if ($i>0) {
          $f=$input{"f$i"};
          $cs=$search_c[$i];
          $c=$input{"c$i"};
        } else {
          $f=$input{"f"};
          $cs=$search_c[0];
          $c=$input{"c"};
        }

        @felder=split(/\,/,$f);
        @terms = split(/\s+/, $cs);

        $term_or_mode=0;

        $#is_a_not_term=-1;
        $q=0;
        foreach $terms (@terms) {
          if ($terms=~/^or$/i || $terms=~/^ODER$/i) {
            $term_or_mode=1;
          }
          if ($terms=~/^and$/i || $terms=~/^UND$/i) {
            $terms="";
          }
          if ($terms=~/^-(.*)/) {
            $terms=$1;
            $is_a_not_term[$q]=1;
          }
          $q++;
        }

        $#this_term_ok=-1;
        foreach $felder (@felder) {
          if ($felder=~/^\*(.*)/) {
            $index=$index{"$1"};
            if ($#terms==-1) {
              $this_field_ok=1;
            }
            $q=0;
            foreach $terms (@terms) {
              $suche=$terms;
              $suche=~s/\<_\>/ /g;
              if ($afelder[$index]=~/$suche/i) {
                if ($is_a_not_term[$q]==0) {
                  $this_term_ok[$q]=1;
                } else {
                  $this_term_ok[$q]=-1;
                }
              } elsif ($is_a_not_term[$q]==1) {
                if ($this_term_ok[$q]!=-1) {
                  $this_term_ok[$q]=1;
                }
              }
              $q++;
            }
          } else {
            $this_field_ok=0;
            $index=$index{$f};
            if ($c=~/^(\<\=|\>\=|\>|\<)/) {
              $v=$1;
              $vergleich=$c;
              $vergleich=~s/[\>\<\=]//g;

              if ($vergleich eq "") {
                $this_field_ok=1;
              } elsif ( ($afelder[$index]>$vergleich && $v eq '>') ||
                   ($afelder[$index]<$vergleich && $v eq '<') ||
                   ($afelder[$index]>=$vergleich && $v eq '>=') ||
                   ($afelder[$index]<=$vergleich && $v eq '<=')
                 ) {$this_field_ok=1;}
            }
            elsif ($afelder[$index] eq $c || $c eq "") {
              $this_field_ok=1;
            }
          }
        }
        if ($#this_term_ok>=0) {
#          &abbruch($f.$article_dat.$or_mode);
          $this_field_ok=1;
          for ($zz=0;$zz<=$#terms;$zz++) {
             if ($this_term_ok[$zz]<=0) {$this_field_ok=0;}
          }
          if ($term_or_mode==1) {
            $this_field_ok=1;
          }
        }
        if ($this_field_ok==1) {$co++}

        $mo++;
        $i++;

         $f=$input{"f$i"};
        $c=$input{"c$i"};
      } while ($f ne "");


      if ($co==$mo || ($co>=1 && $or_mode==1)) {
        if (defined($index{"NICHT_LIEFERBAR"})==0 || $afelder[$index{"NICHT_LIEFERBAR"}]!=1) {
            if ($groupby eq "" || $group{$afelder[$index{$groupby}]}==0) {
            push(@new_article_dat,$article_dat);
          }
         if ($groupby ne "") {
           $group{$afelder[$index{$groupby}]}=1;
          }
        }
      }
    }


  }

  if ($t eq "") {$t=$template_basket}

  @basket=&format_warenkorb;
  @article=@new_article_dat;

  if ($groupby ne "") {
    $groupby_index=$index{$groupby};
    @article= sort by_groupby @article;
  }
  if ($input{"sort"} ne "") {
    $old_index=$groupby_index;
    $groupby_index=$index{$input{"sort"}};
    @article= sort by_groupby @article;
    $groupby_index=$old_index;
  }
  if ($input{"nsort"} ne "") {
    $old_index=$groupby_index;
    $groupby_index=$index{$input{"nsort"}};
    @article= sort by_groupby_num @article;
    $groupby_index=$old_index;
  }


  if ($start ne "") {
    if ($start eq "0") {
      srand();
      $start=int(rand( int($#article/$dif)+1));
      $start=$start*$dif+1;
    }
    if ($start>0) {
      $end=$start+$dif-1;
      if ($end-1>$#article) {$end=$#article+1}
    }

    $hit_menu="";
    for ($page=1;$page<=int($#article/$dif)+1;$page++) {
      $page_start=($page-1)*$dif+1;
      if ($page_start==1 && $#article==-1) {$page_start=0;}
      $page_end=$page_start+$dif-1;
      if ($page_end>$#article+1) {$page_end=$#article+1}
      $query=$global[$id_global_query];
      $query=~s/start=(\d+)/start=$page_start/g;
      if ($page_start!=$start) {
        $hit_menu.=qq!&#91;<a href="$global[$id_global_skript]?$query">$page_start - $page_end</a>&#93; !;
      }
    }

    # PAGE BACK ermitteln
    if ($start>1) {
      $vorher=$start-$dif;
      if ($vorher<1) {$vorher=1}
      $query=$global[$id_global_query];
      $query=~s/start=(\d+)/start=$vorher/g;
      $global[$id_global_hit_back]=$shoppl."?".$query;
   }


   if ($start+$dif<=$#article+1) {
      $forward=$start+$dif;
      $query=$global[$id_global_query];
      $query=~s/start=(\d+)/start=$forward/g;
      $global[$id_global_hit_forward]=$shoppl."?".$query;
    }



    $global[$id_global_hit_start]=$start;
    $global[$id_global_hit_end]=$end;
    $global[$id_global_hit_max]=$#article+1;
    $global[$id_global_hit_menu]=$hit_menu;

    $#new_article=-1;
    for ($i=$start-1;$i<=$end-1;$i++) {
      push(@new_article,$article[$i]);
    }
    if ($global[$id_global_hit_start]>$global[$id_global_hit_end]) {
      $global[$id_global_hit_start]=$global[$id_global_hit_end];
    }
    @article=@new_article;
  }

    $check_no_variants.="$no_variants,";
  foreach $article (@article) {
    @fields=split(/\;/,$article);
    $war_schon=0;
    for ($i=0;$i<=$#keyw;$i++) {

      if ($fields[$i]=~/ \/ / && $check_no_variants!~/$keyw[$i]\,/) {
        @auswahl=split(/ \/ /,$fields[$i]);
        $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!<select name="${keyw[$i]}_select$fields[$id_article_id]">!;
        $fields[$id_article_binfo].=qq!<select name="${keyw[$i]}_select$fields[$id_article_id]">!;
        foreach $auswahl (@auswahl) {
          $fields[$id_article_binfo].=qq!<option>$auswahl</option>!;
          $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!<option>$auswahl</option>!;
        }
        $fields[$id_article_binfo].=qq!</select> !;
        $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!</select> !;
        $binfoleer{$keyw[$i]}=qq!<input type="hidden" name="${keyw[$i]}_select$fields[$id_article_id]" value=" ">!;
        $article=join(';',@fields);
      } elsif ($fields[$i]=~/ \* / && $check_no_variants!~/$keyw[$i]\,/)  {

        @auswahl=split(/ \* /,$fields[$i]);
         if ($i!=$id_article_costs && $i!=$id_article_id) {
          $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!<select name="${keyw[$i]}_multipreis$fields[$id_article_id]">!;
          $fields[$id_article_binfo].=qq!<select name="${keyw[$i]}_multipreis$fields[$id_article_id]">!;
          for ($j=0;$j<=$#auswahl;$j++) {
            $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!<option value="$j">$auswahl[$j]</option>!;
            $fields[$id_article_binfo].=qq!<option value="$j">$auswahl[$j]</option>!;
          }
          $binfo{$keyw[$i]."-".$fields[$id_article_id]}.=qq!</select> !;
          $fields[$id_article_binfo].=qq!</select> !;
           $article=join(';',@fields);
        }
      }
    }
  }

  if ($cdmodul_ist_aktiv==1) {
    return @article;
  }

  $line=join("\n",&read_data("$tempdirectory$t.htm"));    # Vorlage einlesen
  $line=&parse_line($line);                                 # Variablen ersetzen
  if ($input{"noctype"}!=1) {
    print "Content-type: text/html\n\n";
  }
  print $line;                                              # ausgeben
  exit;
}


# ========================================================================================
# Redirect auf eine beliebige URL
# ==========================================================================================

sub redirect {
  $url=$_[0];
  print "Status: 302 Found\n";
  print "Location: $url\n";
  print "URI: <$url>\n";
  print "Content-type: text/html\r\n\r\n";
}

sub create_gutschein {
  srand(time);
  @l=split(//,$gutschein_pass_chars);
  $gutschein="";
  for ($i=1;$i<=$gutschein_pass_length;$i++) {
   $gutschein.=substr($gutschein_pass_chars,rand($#l+1),1);
  }
  return $gutschein;
}

sub get_gutschein_pass {
  local($nr)=@_;
  @this=(-1,0,0,0);
  @g=&read_data($datadirectory."gutschein_db.txt");
  foreach $g (@g) {
    @d=split(/\;/,$g);
    if ($d[0] eq $nr) {
     @this=($d[2],$d[1],$d[3],$d[4]);
    }
  }
  return @this;
}


sub add_gutschein_to_db {
  local($gutschein_nr,$gutschein_wert,$gutschein_pw,$gutschein_bezahlt,$gutschein_ausgeloest)=@_;
  @new_g=($gutschein_nr,$gutschein_wert,$gutschein_pw,$gutschein_bezahlt,$gutschein_ausgeloest);
  open(f,">>$datadirectory"."gutschein_db.txt");
  print f join(';',@new_g)."\n";
  close(f);
}

sub change_gutschein_status {
  local($adminpass,$gutschein_nr,$new_bezahlt,$new_ausgeloest)=@_;
   if ($adminpass ne $admin_passwort) {&abbruch("Falsches Passwort");}

   ($pass,$wert,$bezahlt,$ausgeloest)=&get_gutschein_pass($gutschein_nr);
   if ($pass eq "-1") {&abbruch("Die Gutschein Nr. $gutschein_nr existiert nicht.")}
   if ($new_bezahlt ne "") {$bezahlt=$new_bezahlt}
   if ($new_ausgeloest ne "") {$ausgeloest=$new_ausgeloest}
   &add_gutschein_to_db($gutschein_nr,$wert,$pass,$bezahlt,$ausgeloest);
   print "Content-type: text/html\n\n";
   print "<html><body>Der Status wurde neu gesetzt.</body></html>";
   exit;
}

# ==========================================================================================
# Gibt die "Vielen Dank!" Seite aus, nachdem eine Bestellung abgeschickt wurde.
# Falls eine Redirect-Bedingung definiert wurde und diese zutrifft, wird ein Redirect
# ausgeführt. Dies können Sie nutzen, um die Bestellung auf ein SSL-Bestellformular
# für Kreditkarten-Daten weiterzuleiten.
# Beispiel:
# <form action="[SKRIPT]" method="GET">
# <input type=hidden name="redirect_url" value="Zahlung=Kreditkarte->https://www.IhreFirma.de/secure/creditcard.htm">
# ...
# </form>
# ==========================================================================================

sub output_order {

 # Gutschein!
  foreach $basket_dat (@basket_dat) {
    @f=split(/\;/,$basket_dat);
    if ($f[$index{"NR"}]=~/^GE_(.*)/) {
      $gutschein_nr=$1;
      ($pass,$wert,$bezahlt,$ausgeloest)=&get_gutschein_pass($gutschein_nr);
      if ($pass eq "-1") {&abbruch("Diese Gutschein Nr. existiert nicht.")}
      if ($bezahlt==0) {&abbruch("Der Gutschein $gutschein_nr ist noch nicht bezahlt.")}
      if ($ausgeloest>0) {&abbruch("Der Gutschein $gutschein_nr ist bereits ausgelöst.")}
      &add_gutschein_to_db($gutschein_nr,$wert,$pass,1,$ausgeloest+1);
    }
  }

  # Bestandverwaltung!
  if ($bestand_verwaltung==1) {
    foreach $basket_dat (@basket_dat) {
      @f=split(/\;/,$basket_dat);
      $stock{$f[$id_article_id]}=$f[$id_article_quantity];
    }
    foreach $article_dat (@article_dat) {
       @f=split(/\;/,$article_dat);
       $f[$index{"STOCK"}]-=$stock{$f[$id_article_id]};
       if ($f[$index{"STOCK"}]<0) {
         $f[$index{"STOCK"}]=0;
       }
       $article_dat=join(';',@f);
    }
    &save_array($articledat,"article",@article_dat);
  }

  $rurl=$input{"redirect_url"};
  if ($rurl ne "") {
    @rtypes=split(/\;/,$rurl);
    foreach $rtypes (@rtypes) {
      @condition_url=split(/\-\>/,$rtypes);
      @keyvalue=split(/\=/,$condition_url[0]);
      $key=$keyvalue[0];
      $value=$keyvalue[1];
      if ($input{"$key"} eq $value) {
        &redirect($condition_url[1]);
        exit;
      }
    }
  }
  if ($input{"t"} ne "") {
    $template_send=$input{"t"};
  }
  $line=join("\n",&read_data("$tempdirectory$template_send.htm"));              # Vorlage einlesen
  $line=&parse_line($line);                                 # Varibalen ersetzen
  print "Content-type: text/html\n\n";
  print $line;                                              # ausgeben
}


# ==========================================================================================
# Liefert Menge zurück
# ==========================================================================================

sub get_menge {
  local($menge)=@_;                                         # String einlesen
  $menge=~s/\,/\./g;                                        # Bei der Menge "," durch "." ersetzen
  if ($menge>0) {return $menge};                            # Falls Wert > 0, Wert zurückgeben
  if (defined($menge) && $menge==0) {                       # Falls Menge=0
    if ($menge ne "" && $menge ne "0") {return 1;}          # Falls String nicht "0" oder leer, 1 zurückgeben
  }
  return 0;                                                 # sonst 0 zurückgeben
}

# ==========================================================================================
# Aktualisiert den Warenkorb.
# ==========================================================================================


sub add_basket {
  local($i)=@_;
  local($#basket_new)=-1;                                   # Leeren Warenkorb-Array erstellen
  @basket_new=&get_article_data($input{"id$i"});            # Daten aus Datenbank holen

  if (join('',@basket_new) eq '-1') {
    &abbruch(qq!Der Artikel $input{"id$i"} existiert nicht (mehr). $articledat $article_dat[0]!);
  }

  if ($basket_new[$index{"STOCK"}]<$input{"quantity$i"} && $bestand_verwaltung==1 && $fehlermeldung_bei_bestand_von_null==1) {
    &abbruch(qq!Sie m&ouml;chten die Menge $input{"quantity$i"} des Artikels <b>$basket_new[$index{"NR"}]</b> bestellen, wir haben zur Zeit aber nur einen Bestand von $basket_new[$index{"STOCK"}] verf&uuml;gbar.<p> Wenn Sie sich besonders f&uuml;r diesen Artikel interessieren, <a href="mailto:$email">kontaktieren Sie uns bitte per Mail</a>.!);
  }

  $basket_new[$id_article_quantity]=0;                      # zum vergleichen
  $basket_new[$id_article_costs]=~s/\,/\./g;                # Beim Preis "," durch "." ersetzen

  $basket_new[$id_article_quantity]=$input{"quantity$i"};   # Menge zuweisen
  $basket_new[$id_article_quantity]=~s/\,/\./g;             # Bei der Menge "," durch "." ersetzen

   foreach $keyw (@keyw) {
       if ($input{"${keyw}_select$basket_new[$id_article_id]"} ne "") {
         $basket_new[$index{$keyw}]=$input{"${keyw}_select$basket_new[$id_article_id]"};
         $basket_new[$index{$keyw}]=~s/\s\/\s/\//g;
      }
    }

  for ($j=0;$j<=$#keyw;$j++) {
   if ($input{"${keyw[$j]}_multipreis$basket_new[$id_article_id]"} ne "") {
     $mpreisnr=$input{"${keyw[$j]}_multipreis$basket_new[$id_article_id]"};
     foreach $basket_new (@basket_new) {
       if ($basket_new=~/ \* /) {
          @auswahl=split(/ \* /,$basket_new);
          $basket_new=$auswahl[$mpreisnr]
        }
      }
    }
  }


  if ($basket_new[$id_article_costs]=~/\?/) {
     @p=split(/\ /,$basket_new[$id_article_costs]);
     @pq=split(/\?/,$p[0]);
     $basket_new[$id_article_quantity]=$pq[1];
  }
  $basket_new=join(';',@basket_new);

  $gef=0;
  foreach $basket_dat (@basket_dat) {
    @bf=split(/\;/,$basket_dat);
    $old_quantity=$bf[$id_article_quantity];
    $bf[$id_article_quantity]=$basket_new[$id_article_quantity];
    if (join(';',@bf) eq join(';',@basket_new)) {
      $gef=1;
      if ($mengen_im_warenkorb_addieren==1) {
        $bf[$id_article_quantity]=$basket_new[$id_article_quantity]+$old_quantity;
      }
      $basket_dat=join(';',@bf);
    }
  }

  if ($gef==0) {
    push(@basket_dat,$basket_new);
    push(@basket_dat_new,$basket_new);
  }
}

sub process_order {
  local($i);
  local(@keys,@values,@field);

  $#keys=-1;
  $#values=-1;
  foreach $keyval (@keyval) {                               # Array keval durchlaufen
    @field=split(/\;/,$keyval);                             # Felder ermitteln
    push(@keys,$field[0]);                                  # key in Array keys speichern
    push(@values,$field[1]);                                # value in Array values speichern
  }

  $#basket_new=-1;
  for ($i=0;$i<=$#basket_dat;$i++) {
    $input{"wk_quantity$i"}=~s/\,/\./g;
    if ($input{"wk_delete$i"} ne "" || $input{"wk_delete$i.x"} ne "") {
      $input{"wk_quantity$i"}=0;
    }
    if ($input{"wk_quantity$i"} ne "" || $input{"ok$i"} ne "") {

      @basket_fields=split(/\;/,$basket_dat[$i]);
      if ($basket_fields[$id_article_quantity]!=$input{"wk_quantity$i"}) {

        if ($input{"wk_quantity$i"} ne "") {

          # Gutschein
          if ( ($basket_fields[$index{"NR"}]=~/^GE_/ || $basket_fields[$index{"NR"}]=~/^G_/) && $input{"wk_quantity$i"}>1) {
           &abbruch("Gutscheine können nur mit der Menge 1 bestellt oder eingelöst werden.");
          }

          if ($basket_fields[$index{"STOCK"}]<$input{"wk_quantity$i"} && $bestand_verwaltung==1 && $fehlermeldung_bei_bestand_von_null==1) {
            &abbruch(qq!Sie m&ouml;chten die Menge $input{"wk_quantity$i"} des Artikels <b>$basket_fields[$index{"NR"}]</b> bestellen, wir haben zur Zeit aber nur einen Bestand von $basket_fields[$index{"STOCK"}] verf&uuml;gbar.<p> Wenn Sie sich besonders f&uuml;r diesen Artikel interessieren, <a href="mailto:$email">kontaktieren Sie uns bitte per Mail</a>.!);
          }
          $basket_fields[$id_article_quantity]=$input{"wk_quantity$i"};
          $basket_dat[$i]=join(';',@basket_fields);
        }
      }
      if ($input{"ok$i"} ne "") {
        foreach $keyw (@keyw) {
          if ($input{"${keyw}_select$i"} ne "") {
            $basket_fields[$index{$keyw}]=$input{"${keyw}_select$i"};
            $basket_fields[$index{$keyw}]=~s/\s\/\s/\//g;
          }

        }
        for ($j=0;$j<=$#keyw;$j++) {
          if ($input{"${keyw[$j]}_multipreis$i"} ne "") {
            $mpreisnr=$input{"${keyw[$j]}_multipreis$i"};
            foreach $basket_fields (@basket_fields) {
              if ($basket_fields=~/ \* /) {
                @auswahl=split(/ \* /,$basket_fields);
                $basket_fields=$auswahl[$mpreisnr]
              }
            }
          }
        }
      }
      if ($input{"wk_quantity$i"}!=0 || $input{"wk_quantity$i"} eq "") {push(@basket_new,join(';',@basket_fields))};
    } else {push(@basket_new,$basket_dat[$i]);}
  }
  @basket_dat=@basket_new;

  if ($input{"change"}==0) {                                # falls Aufruf NICHT vom Warenkorb kommt (keine Änderung, nur NEUE Artikel)
    $i=0;

###########################################################
## Überprüfung einer Übergabe durch:
## <a href="/cgi-bin/webshop.pl?Nr1234=3"> oder
## <input type=submit name="Nr1234" value="Bestellen">
##

    for ($k=0;$k<=$#keys;$k++) {                            # Alle Keys durchlaufen
       if ($keys[$k]=~/^NrAddWk$/) {
       $input{"id$i"}=$values[$k];
       $input{"quantity$i"}=1;
       if ($input{"MengeAddWk"} ne "") {$input{"quantity$i"}=$input{"MengeAddWk"}}
       &add_basket($i);
       $i++;
     }
     elsif ($keys[$k]=~/^Nr(.*)$/) {                           # Falls Key = NrXXX
        $nr_field=$1;

        if ($nr_field=~/\.y$/) {                           # Bei Übergabe durch "type=image" .y nicht berücksichtigen
          $menge=0;
        }
        elsif ($nr_field=~/\.x$/ && $war_schon{$nr_field}==0) {                        # Bei Übergabe durch "type=image" .x = Menge 1
          $nr_field=~s/\.x$//;
          $menge=1;
        } elsif ($war_schon{$nr_field}==0) {
          $menge=&get_menge($values[$k]);                   # Menge aus Value ermitteln
        }

        if ($menge>0 && $war_schon{$nr_field}==0) {                                     # Falls Menge>0
          $war_schon{$nr_field}=1;
          $input{"id$i"}=$nr_field;                         # Neuer Warenkorbeintrag mit NrXXX
          $input{"quantity$i"}=$menge;                      # und Menge
          &add_basket($i);
          $i++;                                             # nächster freier Platz
        }
      }
    }

##
###########################################################

###########################################################
## Überprüfung einer Übergabe durch:
## <select name="Def1">
## <option value="1234">Artikel1
## <option value="1235">Artikel2>
## </select>
## <input type=submit name="Menge1" value="Bestellen">
###

    for ($k=0;$k<=$#keys;$k++) {                            # Alle Keys durchlaufen
      if ($keys[$k]=~/^Def(.*)$/) {                         # Falls Key = DefXXX
        $defnr=$1;                                          # DefNr ermitteln
        $artnr=$values[$k];                                 # ArtikelNummer ist der Value
        $menge=&get_menge($input{"Menge$defnr"});           # Menge ermitteln
        if ($menge>0) {                                     # Falls Menge>0
          $input{"id$i"}=$artnr;                            # Neuer Warenkorbeintrag
          $input{"quantity$i"}=$menge;                      # Menge
          &add_basket($i);
          $i++;                                             # nächster freier Platz
        }
      }
    }

##
###########################################################
  }

    $i=0;
    while ($input{"id$i"} ne "") {                          # Alle Einträge des WKs durchlaufen, um $i auf einen freien Eintrag zu setzen
      $i++;
    }

###########################################################
## Manuelle Eingabe erlauben!
##


    $z=0;
    do {
      $#basket_new=-1;
      if ($z==0) {$nr="";} else {$nr=$z}
      for ($k=0;$k<=$#keys;$k++) {                            # Alle Keys durchlaufen
        if ($keys[$k]=~/add_(.*)$nr$/) {                     # Falls Key = add_XXXX
          $basket_new[$index{$1}]=$values[$k];
         }
      }
      if ($basket_new[$index{"MENGE"}]>0 || $basket_new[$index{"MENGE"}] ne "") {
          if ($basket_new[$index{"MENGE"}]==0) {$basket_new[$index{"MENGE"}]=1;}

           $gef=0;
    foreach $basket_dat (@basket_dat) {
      @bf=split(/\;/,$basket_dat);
      $old_quantity=$bf[$id_article_quantity];
      $bf[$id_article_quantity]=$basket_new[$id_article_quantity];
      if (join(';',@bf) eq join(';',@basket_new)) {
        $gef=1;
        if ($mengen_im_warenkorb_addieren==1) {
          $bf[$id_article_quantity]=$basket_new[$id_article_quantity]+$old_quantity;
        }
        $basket_dat=join(';',@bf);
      }
    }

    if ($gef==0) {

          push(@basket_dat,join(';',@basket_new));
          push(@basket_dat_new,join(';',@basket_new));

          }
      }
      $z++;
    } while (defined($input{"add_MENGE$nr"}) || $z<=1);
##
###########################################################


  &save_array($basketdat,$basketdat,@basket_dat);           # Warenkorb speichern
}


# ==========================================================================================
# Liest und formatiert die Variablen fuer den Warenkorb
# ==========================================================================================

sub format_warenkorb {
  local($is_mail,$divident)=@_;
  local($index);
  if ($divident==0) {$divident=1;}
  local(@article);                                          # Artikel Array erstellen
  $global[$id_global_sumall]=0;                             # Bestellsume auf "0" setzen
  $i=0;                                                     # Zähler auf 0 setzen
  $#article=-1;                                             # Artikel Array leeren

  $check_no_variants.="$no_variants,";

  $only_gutschein=1;
  foreach $basket_dat (@basket_dat) {
   @f=split(/\;/,$basket_dat);
   if ($f[$index{"NR"}]!~/G_(\d+)/) {
     $only_gutschein=0;
   }
  }

  foreach $basket_dat (@basket_dat) {                       # Warenkorbeinträge durchlaufen
    @fields=split(/\;/,$basket_dat);                        # Felder ermitteln
    $#article_fields=-1;                                    # Leeren Artikel Array erstellen

    foreach $keyw (@keyw) {
      $index=$index{$keyw};
      if ($fields[$index]=~/ \/ / && $check_no_variants!~/$keyw\,/)  {
        if ($is_mail==1) {
          $fausgabe= qq!Die Bestelldaten k&ouml;nnen noch nicht verschickt werden, da Sie noch Angaben im Warenkorb zu mindestens einem Artikel festlegen m&uuml;ssen. Im <a href="$shoppl">Warenkorb</a> k&ouml;nnen Sie dazu in einer!;
          $fausgabe.=qq! Auswahlbox die Einstellung ausw&auml;hlen. Anschliessend dr&uuml;cken Sie bitte jeweils auf den OK-Button neben der Auswahlbox.!;
          &abbruch($fausgabe);
        }
        @auswahl=split(/ \/ /,$fields[$index]);
        $article_fields[$index]=qq!<select name="${keyw}_select$i">!;
        foreach $auswahl (@auswahl) {
          $article_fields[$index].=qq!<option>$auswahl</option>!;
        }
        $article_fields[$index].=qq!</select> <input type=submit name="ok$i" value="OK">!;
      }
      elsif ($fields[$index]=~/ \* /  && $check_no_variants!~/$keyw\,/)  {
        if ($is_mail==1) {
          $fausgabe= qq!Die Bestelldaten k&ouml;nnen noch nicht verschickt werden, da Sie noch Angaben im Warenkorb zu mindestens einem Artikel festlegen m&uuml;ssen. Im <a href="$shoppl">Warenkorb</a> k&ouml;nnen Sie dazu in einer!;
          $fausgabe.=qq! Auswahlbox die Einstellung ausw&auml;hlen. Anschliessend dr&uuml;cken Sie bitte jeweils auf den OK-Button neben der Auswahlbox.!;
          &abbruch($fausgabe);
        }
        @auswahl=split(/ \* /,$fields[$index]);
        if ($index!=$id_article_costs && $index!=$id_article_id) {
          $article_fields[$index]=qq!<select name="${keyw}_multipreis$i">!;
          for ($j=0;$j<=$#auswahl;$j++) {
            $article_fields[$index].=qq!<option value="$j">$auswahl[$j]</option>!;
          }
          $article_fields[$index].=qq!</select> <input type=submit name="ok$i" value="Ok">!;
        }
        else {$article_fields[$index]=$auswahl[0];}
      } else {
        $article_fields[$index]=$fields[$index];
      }
    }

    $article_fields[$id_article_quantity]=$fields[$id_article_quantity];     # Menge
    $article_fields[$id_article_newquantity].=qq!<INPUT TYPE=TEXT SIZE=3 NAME="wk_quantity$i" VALUE="$fields[$id_article_quantity]">!; # Menge als Text Feld

    if ($fields[$id_article_costs]=~/\?/) {
      @p=split(/\ /,$fields[$id_article_costs]);
      foreach $p (@p) {
        @pq=split(/\?/,$p);
        if ($fields[$id_article_quantity]>=$pq[1]) {
          $article_fields[$id_article_sum]= &format_sum($fields[$id_article_quantity]*&format_sum($pq[0]/$divident));
        }
      }
    } else {
      $article_fields[$id_article_sum]=&format_sum($fields[$id_article_quantity]*&format_sum($fields[$id_article_costs]/$divident));    # Summe berechnen
    }

    $global[$id_global_sumall]+=$article_fields[$id_article_sum]; # Gesamtbestellsumme
    push(@article,join(';',@article_fields));                     # Neuen Artikel einfügen
    $i++;
  }


  if ($dif_porto==1) {                                      # Falls untersch. Versandk.art
    if ($input{"porto"} ne "") {                            # Falls Versandk.art angegeben
      $porto=$input{"porto"};                               # Versandk.art einlesen
      &save_array($portodat,"porto",$porto);                # ... und speichern
    }

    $gef=0;                                                 # Flag gefunden auf 0 sezten
    foreach $porto_daten (@porto_daten) {                   # Alle Versandk.arten durchlaufen
      @pdaten=split(/\;/,$porto_daten);
      if ($pdaten[0] eq $porto) {                           # Falls zur Zeit ausgewählte Versandk.art
        $gef=1;                                             # Flag gefunden auf 0 setzen
        last;
      }
    }
    if ($gef==0) {@pdaten=split(/\;/,$porto_daten[0]);}     # Falls nicht gefunden, Versandk. der 1.Zeile nehmen
    $porto=$pdaten[0];
    $this_porto=$pdaten[1];
    $global[$id_global_versandkfreiab]=$pdaten[2];
    $global[$id_global_versandkosten]=&format_sum($this_porto/$divident);        # sonst Versandkosten = Porto

    $ptext="";
    foreach $porto_daten (@porto_daten) {
      @pdaten=split(/\;/,$porto_daten);
      if ($pdaten[0] eq $porto) {$selec="SELECTED "} else {$selec=""}
      $ptext.= qq!<OPTION ${selec}VALUE="$pdaten[0]">$pdaten[0]!;
    }
    $ptext=qq!<select name="porto" onchange="submit()">$ptext</select>!;
    $global[$id_global_porto_auswahl]=$ptext;
    $global[$id_global_porto]=$porto;
  } else {
    $global[$id_global_versandkosten]=&format_sum($versandk_hoehe/$divident);        # sonst Versandkosten = Porto
  }

  if (($global[$id_global_min_order]/$divident)<=$global[$id_global_sumall] || $min_order_typ==0 || $min_order_typ==1) {
   $global[$id_global_min_order_zuschlag]="";
  }
   if (($global[$id_global_min_order]/$divident)<=$global[$id_global_sumall] && $min_order_typ==1) {
    $global[$id_global_min_order]="";
  }

  if ($global[$id_global_sumall]>=($global[$id_global_versandkfreiab]/$divident) && $global[$id_global_versandkfreiab]!=0) {    # Falls Summe > Versandk._frei_ab
    $global[$id_global_versandkosten]=0;                 # keine Versandkosten
  }
  if ($only_gutschein==1) {
    $global[$id_global_versandkosten]=0;
  }
  $global[$id_global_sumallv]=$global[$id_global_sumall]+$global[$id_global_versandkosten]+($global[$id_global_min_order_zuschlag]/$divident); # Summe inkl. Versandk. berechnen
  $global[$id_global_sumall]=&format_sum($global[$id_global_sumall]);           # Summe formatieren
  $global[$id_global_sumallv]=&format_sum($global[$id_global_sumallv]);         # Summe inkl. Versandk. formatieren
  $global[$id_global_versandkfreiab]=&format_sum($global[$id_global_versandkfreiab]);   # Versandk. frei ab formatieren
  if ($global[$id_global_versandkosten] ne "") {
    $global[$id_global_versandkosten]=&format_sum($global[$id_global_versandkosten]);   # Versandk.
  }
#   &abbruch($global[$id_global_sumall]);
  return @article;
}


# ==========================================================================================
# Der Parser fuer HTML und Mail Templates.
# Erkennt eine Reihe von Schluesselworten sowie die Befehle "IF" (mit OR Verknuepfung),
# "IFTHIS" und "REPEAT".
# ==========================================================================================

sub parse_line {
  local($linesave)=@_;
  local($array_typ,$vor_suche,$nachher,$ersetzen,$count,$i);
  local($leftright,$leftright_num);

  $linesave=~s/\%5BSKRIPT\%5D/\[SKRIPT\]/g;
  while ($linesave=~/\[((LEFT|RIGHT)=(\d+)_)?([^\]]+)\]\n?/) {
    $code=$4;
    $leftright=$2;
    $leftright_num=$3;
    local($vorher)=$`;
    local($nachher)=$';
    $code=~s/\n/ /g;

   while ($code=~/\[/) {
     do {
       $nachher=~/\]/;
       $code.=']'.$`;
       $nachher=$';
       $open=($code=~s/\[/\[/g);
       $close=($code=~s/\]/\]/g);
     } while ($open!=$close);
     $code=&parse_line($code);
   }

    $divident="";
     if ($code=~/(.*)\/([\d|\.]+)$/) {
       $code=$1;
       $divident=$2;
     }

     foreach $currency (@currency) {
       @c=split(/\=/,$currency);
       if ($code=~/(.*)_$c[0]$/) {
         $code=$1;
         if ($divident eq "") {$divident=1;}
         $divident=$divident*$c[1];
         $acurrency=$c[0];
       }
     }

     if ($code=~/(.*)_HTML$/) {
      $code=$1;
      $html=1;
     } else {$html=0;}

     if ($code=~/(.*)_TEXTAREA$/) {
      $code=$1;
      $textarea=1;
     } else {$textarea=0;}

     if ($code eq "HIS_ON") {
       $his_off=0;
     }
     if ($code eq "HIS_OFF") {
      $his_off=1;
     }

    if ($code=~/(.*)_URLENC$/) {
      $code=$1;
      $urlenc=1;
    } else {$urlenc=0;}

    if ($code=~/(.*)_KLEIN$/) {
      $code=$1;
      $klein=1;
    } else {$klein=0;}

     if ($code=~/(.*)_CD$/) {
      $code=$1;
      $cd=1;
    } else {$cd=0;}

    if ($code=~/(.*)_CDNAME$/) {
      $code=$1;
      $cdname=1;
    } else {$cdname=0;}

     if ($code=~/(.*)_FIRST$/) {
      $code=$1;
      $first=1;
    } else {$first=0;}

    if ($code=~/^IF(\d|)_(.*)/) {
      $ok=0;
      $if_nr=$1;
      @if=split(/_OR_/,$2);
      $if_field="";
      foreach $if (@if) {
        if ($if=~s/NOT_//==0) {$not_text="";$not=0} else {$not_text="NOT_";$not=1;}

        if ($if=~/PRINT\((.*)\)/) {
          $expr=$1;
          $expr=~s/\$/\$HIS_SCRIPT/g;
          $expr=~s/\<\</\[/g;
          $expr=~s/\>\>/\]/g;
          $expr=~s/\@/\@HIS_SCRIPT/g;
          $count=eval($expr);
          if ($count==0) {$count=-1}
          $if_field="PRINT";
        } elsif ($if=~/^\((.*)\)/) {
          $expr=$1;
          $expr=~s/\$/\$HIS_SCRIPT/g;
          $expr=~s/\<\</\[/g;
          $expr=~s/\>\>/\]/g;
          $expr=~s/\@/\@HIS_SCRIPT/g;


          $count=eval($expr);
          if ($count==0) {$count=-1}
          $if_field="";
       } else {
        $if_field=$if;
        $array_typ=$multi{"$if"};
        $index=$index{"$if"};
        if ($array_typ==1) {
           if ($#article>=0) {
             @array=split(/\;/,$article[$count[$array_typ]]);
           } else {
             @array=split(/\;/,$basket[$count[$array_typ]]);
           }
           if ($array[$index] eq "") {$count=-1} else {$count=0;}
        } else {
          if ($input{$if} ne "") {$count=0} else {$count=-1}
        }
        if ($if eq "ARTIKEL")   {$count=$#article}
        if ($if eq "WARENK")    {$count=$#basket}
        if ($if eq "NEW_ORDER") {$count=$#basket_dat_new;}
        if ($array_typ==5) {if ($global[$index] eq "" || $global[$index] eq "0.00") {$count=-1} else {$count=0;}}
        if ($if eq "ORDERDAT") {$count=$#keyval;}
        if ($if eq "KUNDE")      {$count=$#user_daten;}
        }
        if ($count!=-1 && $not==0) {$ok++}
        if ($count==-1 && $not==1) {$ok++}
      }
        if ($if_field ne "") {
          $nachher=~s/\[IF${if_nr}_${not_text}${if_field}_END\]\n?//; $nach_suche=$';
        } else {
          $nachher=~s/\[IF${if_nr}_${not_text}${if_field}END\]\n?//; $nach_suche=$';
        }
       if ($ok==0) {
         $linesave=$vorher.$nach_suche;
       } else {
        $linesave=$vorher.$nachher;
      }
    }
    elsif ($code=~/^REPEAT_(.*)/) {
      $array_typ=$multi{"$1"};
      $old_repeat_mode=$repeat_mode;
      if ($1 eq "ARTIKEL")   {$count=$#article;$repeat_mode=1;$array_typ=1}
      if ($1 eq "WARENK")    {$count=$#basket;$repeat_mode=2;$array_typ=1}
      if ($1 eq "NEW_ORDER") {$count=$#basket_dat_new;$repeat_mode=3;$array_typ=1}
      if ($1 eq "ORDERDAT")  {$count=$#keyval;$array_typ=6}
      if ($1 eq "RORDER") {
         $array_typ=8;
         $repeat_mode=8;
         if ($input{"month"} eq "") {$input{"month"}=$month;}
         if ($input{"year"} eq "") {$input{"year"}=$year;}
         @order_list=&get_order_list($input{"month"},$input{"year"},$partner_daten[$pindex{"$partner_login_field"}]);
         $count=$#order_list;
      }
      if ($1 eq "INFO")      {
         @array=split(/\;/,$article[$count[1]]);
         @subarray=split(/ \* /,$array[$index{"PREIS"}]);
         $count=$#subarray;
         $repeat_mode=4;
         $array_typ=2;
      }
      if ($1 eq "PARTNER")   {
         $count=0;
         $repeat_mode=5;
         $array_typ=7;
      }
      $repeat_keyword=$1;
      $nachher=~/\[REPEAT_${repeat_keyword}_END\]/;
      $vor_suche=$`;$nachher=$';
      $ersetzen="";
      for ($count[$array_typ]=0;$count[$array_typ]<=$count;$count[$array_typ]++) {
        $ersetzen.=&parse_line($vor_suche) ;
      }
      $repeat_mode=$old_repeat_mode;
      $linesave=$vorher.$ersetzen.$nachher;
    }
    else {
      $index=$index{"$code"};
      $array_typ=$multi{"$code"};

      if ($code eq "APREIS") {$index=$index{"PREIS"}};

      if ($leftright eq "LEFT")  {$left=$leftright_num;}  else {$left=0;}
      if ($leftright eq "RIGHT") {$right=$leftright_num;} else {$right=0;}

       if ($code=~/PIC(\d+)\_SCALE_(.*)/) {
        $code="PIC$1";
        $scale=$2;
      }
      if ($code=~/PIC(\d+)\_WIDTH_(.*)/) {
        $code="PIC$1";
        $do_width=$2;
      }


      $align="";
      if ($code=~/PIC(\d+)\_(.*)/) {
        $code="PIC$1";
        $align=" align=$2";
      }

        if ($code=~/PIC(\d+)/) {

          if ($repeat_mode==1) {@array=split(/\;/,$article[$count[1]])}
          if ($repeat_mode==2) {@array=split(/\;/,$basket[$count[1]])}
#         @array=split(/\;/,$article[$count[1]]);
         $pichttpnr=$1-1;                # PIC1 => $pichttp[0], PIC2 => $pichttp[1] usw.

         $this_pic=$array[$index{"$pic_field_name[$pichttpnr]"}];
         @a=split(/ \* /,$this_pic);
         $this_pic=$a[0];

         $this_pic=~s/\s//g;
         $this_pic=~s/[\\\/]//g;

         $file=$this_pic;
         $filegif=$this_pic.".gif";
         $filejpg=$this_pic.".jpg";
         $filename="";
         if    (&exist("$picverz[$pichttpnr]$file") && $this_pic ne "")    {$filename="$pichttp[$pichttpnr]$file";    ($width,$height)=&get_gif($picverz[$pichttpnr],$file)}
         elsif (&exist("$picverz[$pichttpnr]$filegif") && $this_pic ne "") {$filename="$pichttp[$pichttpnr]$filegif"; ($width,$height)=&get_gif($picverz[$pichttpnr],$filegif)}
         elsif (&exist("$picverz[$pichttpnr]$filejpg") && $this_pic ne "") {$filename="$pichttp[$pichttpnr]$filejpg"; ($width,$height)=&get_gif($picverz[$pichttpnr],$filejpg)}
         elsif ($use_default_pic==1) {$filename="$pichttp[$pichttpnr]$default_pic"; ($width,$height)=&get_gif($picverz[$pichttpnr],$default_pic)}

          if ($scale ne "") {
              $width=int($width/100*$scale);
              $height=int($height/100*$scale);
          }
            if ($do_width ne "" && $width!=0 && $height!=0) {
              $owidth=$width;
              $width=$do_width;
              $height=int($width/$owidth*$height);
          }

        if ($filename ne "") {
          $array[$index]=qq!<img src="$filename"$align hspace=5>!;

          if ($width!=0 && $height!=0) {
             $array[$index]=qq!<img src="$filename"$align width=$width height=$height border=0 hspace=5>!;
          }
        } else {
          $array[$index]="";
        }
      } else {
         if ($array_typ==1 || $array_typ==2) {
          if ($code=~/BINFO(\d+)/) {$array_typ=1;}
          if ($repeat_mode==1) {@array=split(/\;/,$article[$count[$array_typ]])}
          if ($repeat_mode==2) {@array=split(/\;/,$basket[$count[$array_typ]])}
          if ($repeat_mode==3) {@array=split(/\;/,$basket_dat_new[$count[$array_typ]])}
          if ($repeat_mode==4) {
            @array=split(/\;/,$article[$count[1]]);
            @array=split(/ \* /,$array[$index]);
            $array[$index]=$array[$count[2]];
          }
        };
        if ($repeat_mode==5) {
          if ($#partner_daten!=-1) {
            @array=@partner_daten;
          } else {
            @array=&get_partner_data($input{"G_pid"});
          }
          $index=$pindex{"$code"};
        }

        if ($array_typ==5) {@array=@global;};
        if ($array_typ==6) {@array=split(/\;/,$keyval[$count[$array_typ]])};
        if ($repeat_mode==8) {@array=split(/\|/,$order_list[$count[$array_typ]])};
      }
       if ($code=~/^(U_(.*))/ && $repeat_mode!=5) {
         $fieldname=$1;
         if ($fieldname=~/\=/) {
           @kv_ausgabe=split(/\-\>/,$fieldname);
           @kv=split(/\=/,$kv_ausgabe[0]);
           if ($user_daten[$uindex{$kv[0]}] eq $kv[1]) {
             $array[$index]=$kv_ausgabe[1];
             $uindex{$code}=1;
           } else {
             $array[$index]="";
           }
         } else {
           $array[$index]=$user_daten[$uindex{$1}];
         }
       }
       if ($code=~/^(P_(.*))/) {
         $fieldname=$1;
         if ($fieldname=~/\=/) {
           @kv_ausgabe=split(/\-\>/,$fieldname);
           @kv=split(/\=/,$kv_ausgabe[0]);
           if ($partner_daten[$pindex{$kv[0]}] eq $kv[1]) {
             $array[$index]=$kv_ausgabe[1];
             $uindex{$code}=1;
           } else {
             $array[$index]="";
           }
         } else {
           $array[$index]=$partner_daten[$pindex{$1}];
         }
       }

       if ($code eq "PREIS") {
         $array[$index]=&format_sum($array[$index]);
       }

       if ($code eq "APREIS") {
           @p=split(/\ /,$array[$id_article_costs]);
           foreach $p (@p) {
              @pq=split(/\?/,$p);
              if ($array[$id_article_quantity]>=$pq[1]) {
                $preis=&format_sum($pq[0]);
              }
           }
           if ($array[$id_article_quantity]==0) {
             @pq=split(/\?/,$p[0]);
             $preis=&format_sum($pq[0]);
           }
           $array[$index]=&format_sum($preis);
       }


      if ($index{"$code"} eq "" && $uindex{"$code"} eq "" && $pindex{"$code"} eq "" ) {
         $array[$index]=$input{"$code"};
      }

      if ($code=~/BINFO(\d+)/) {
         $array_typ=1;
         @array=split(/\;/,$article[$count[$array_typ]]);
         $nr=$1;
         $binfo=$array[$id_article_binfo];
         @binfo=split(/\<select/,$binfo);
         $array[$index]="<select ".$binfo[$nr];
       }
       if ($code=~/BINFO_(.*)/) {
         $array_typ=1;
         @array=split(/\;/,$article[$count[$array_typ]]);
         $array[$index]=$binfo{$1."-".$array[$id_article_id]};
       }

       if ($code=~/PRINT(L|C|F|I|T|)\((.*)\)/) {
        $mode=$1;
        $var=$2;
        $var=~s/\$/\$HIS_SCRIPT/g;
        $var=~s/\<\</\[/g;
        $var=~s/\>\>/\]/g;
        $array[$index]=eval($var);
        if ($mode eq 'I'){
          $array[$index]="";
        }
        if ($mode eq 'F') {
          $array[$index]=&format_sum($array[$index]);
        }
        if ($mode eq 'C') {
          $array[$index]=~ tr/a-z/A-Z/;
        }
        if ($mode eq 'L') {
          $array[$index]=~ tr/A-Z/a-z/;
        }
        if ($mode eq 'T') {
          $array[$index]=&format_tausender($array[$index]);
        }
      }
      if ($code=~/^\$/) {
         if ($code=~/\$FIELD_BASKET_(.*)\=(.*)/) {
           @array=split(/\;/,$basket_dat[$count[1]]);
           $array[$index{$1}]=eval($2);
           $basket_dat[$count[1]]=join(';',@array);
           @basket=&format_warenkorb;
         }
         $code=~s/\$/\$HIS_SCRIPT/g;
         $code=~s/\<\</\[/g;
         $code=~s/\>\>/\]/g;
         eval($code);
         if ($code=~/^\$HIS_SCRIPTG_(.*)\=/) {
            $variable_name=$1;
            $variable_name=~s/\s//g;
            $global{"G_".$1}=eval('$HIS_SCRIPTG_'.$variable_name);
            $input{"G_".$1}=$global{"G_".$1};
            &search_user($global[$id_global_userid]);
         }
         $array[$index]="";
      }

      if ($code eq "NO_VERSANDKOSTEN") {
         &abbruch("No Versandk!");
      }
      if (($code eq "GESAMTSUMME" || $code eq "GESAMTSUMME_VERSAND" || $code eq "VERSANDKOSTEN")
           && $divident==0) {
          &format_warenkorb(0,1);
          $array[$index{"GESAMTSUMME_VERSAND"}]=$global[$id_global_sumallv];
          $array[$index{"GESAMTSUMME"}]=$global[$id_global_sumall];
          $array[$index{"VERSANDKOSTEN"}]=$global[$id_global_versandkosten];
       }

      if ($divident!=0) {
        if ($code eq "SUMME") {
          if ($array[$id_article_costs]=~/\?/) {
            @p=split(/\ /,$array[$id_article_costs]);
            foreach $p (@p) {
              @pq=split(/\?/,$p);
              if ($array[$id_article_quantity]>=$pq[1]) {
                $preis=&format_sum($pq[0]/$divident);
              }
            }
            $array[$index]=&format_sum($preis*$array[$id_article_quantity]);
          } else {
            $array[$index]=&format_sum($array[$index{"PREIS"}]/$divident);
            $array[$index]=$array[$index]*$array[$id_article_quantity];
            $array[$index]=&format_sum($array[$index]);
          }

        }
        elsif ($code eq "GESAMTSUMME") {
          &format_warenkorb(0,$divident);
          $array[$index]=$global[$id_global_sumall];
        }
        elsif ($code eq "GESAMTSUMME_VERSAND") {
          &format_warenkorb(0,$divident);
          $array[$index]=$global[$id_global_sumallv];
        }
        elsif ($code eq "VERSANDKOSTEN") {
          &format_warenkorb(0,$divident);
          $array[$index]=$global[$id_global_versandkosten];
        }
        else {
           $array[$index]=&format_sum($array[$index]/$divident);
        }
      }

      if ($urlenc==1) {$array[$index]=&url_encode($array[$index]);}
      if ($cd==1) {$array[$index]=&cd_encode($array[$index]);}
      if ($cdname==1) {$array[$index]=&cdname_encode($array[$index]);}

      if ($klein==1) {
         $array[$index]=~ y/A-Z/a-z/;
         $array[$index]=~s/ /\-/g;
      }
      if ($first==1) {
        @a=split(/ \* /,$array[$index]);
        $array[$index]=$a[0];
      }
      if ($html==1) {
         foreach $html_convert (@html_convert) {
           @d=split(/\=/,$html_convert);
           $array[$index]=~s/$d[0]/$d[1]/g;
         }
      }
      if ($textarea==1) {
        $array[$index]=~s/<br>/\n/g;
      }
      if ($code eq "NEXT_REPEAT") {
        $count[1]++;
        $count[2]++;
        $array[$index]="";
      }
       if ($code eq "NEXT_INFO") {
        $count[2]++;
        $array[$index]="";
      }
       if ($code=~/^INCLUDE\=(.*)/) {
        $include_src=$1;
        $lines=join("\n",&read_data($include_src));
        $array[$index]=$lines;
      }
      if ($code=~/^INCLUDE_SCRIPT\=(.*)/) {
        $include_src=$1;
        if ($include_src=~/\?/) {
         @s=split(/\?/,$include_src);
         $include_src=$s[0];
         $include_query=$s[1];
        }
        $ENV{'QUERY_STRING'}="$include_query";
        open(f,"$include_src |");
        @include_lines=<f>;
        close(f);
        $array[$index]=join("\n",@include_lines);
        $array[$index]=~s/Content-Type: text\/html//ig;
      }
      if ($left!=0 || $right!=0) {$array[$index]=&correct_length($array[$index],$left,$right);}

      if ($his_off==1 && $code ne "HIS_OFF") {
        $array[$index]="*+~$code~+*";
       }

      $linesave=$vorher.$array[$index].$nachher;
    }
  }
  $linesave=~s/\*\+\~/[/g;
  $linesave=~s/\~\+\*/]/g;
  return $linesave;
}



# ==========================================================================================
# Formatiert einen String rechts- oder linksbuendig auf eine vorgegebene Groesse.
# ==========================================================================================

sub correct_length {
  local($text,$left,$right)=@_;
  local($length);
  if ($left==0 && $right==0) {return $text;}
  if ($left) {$length=$left;} else {$length=$right;}
  while (length($text)<$length) {
    if ($left) {$text.=" ";} else {$text=" ".$text}
  }
  $text=substr($text,0,$length);
  return $text;
}


# ==========================================================================================
# Speichert Bestellungs Mail in einer Log-Datei.
# ==========================================================================================

sub log_mail {
  local(@today) = localtime(time);                            # Aktuelles Datum ermitteln
  local($d) = $today[3];                                      # Tag
  local($m) = $today[4];                                      # Monat
  local($y) = $today[5];                                      # Jahr
  while (length($today[1])<2) {$today[1]="0".$today[1]}       # Minuten formatieren
  while (length($today[0])<2) {$today[0]="0".$today[0]}       # Sekunden formatieren
  $m += 1;                                                    # Monat anpassen
  $y += 1900;                                                 # Jahr anpassen
  local($my)="$m"."_"."$y";
  local($datetime)="$d.$m.$y $today[2]:$today[1]:$today[0]";  # Datum ermitteln

  local(@b)=@basket;
  foreach $b (@b) {
    @f=split(/\;/,$b);
    $f[$id_article_newquantity]=$f[$id_article_sum];
    $f[$id_article_sum]="";
    $b=join(';',@f);
  }

  open(f,">>$datadirectory"."orderlog.txt");
  print f ("-" x80)."\n";
  print f join("\n",@b)."\n\n";
  print f "Bestellnummer;$global[$id_global_ordernr]\n";
  print f "Datum;$datetime\n";
  print f "Gesamtsumme;$global[$id_global_sumall]\n";
  print f "Gesamtsumme inkl. VK;$global[$id_global_sumallv]\n";
  if ($global[$id_global_porto] ne "") {
    print f "Porto;$global[$id_global_porto]\n\n";
  }
  print f join("\n",@keyval)."\n";
  close (f);


  @save_keyval=@keyval;
  foreach $save_keyval (@save_keyval) {
   $save_keyval=~ s/\cM\n/<br>/g;
  }
  open(f,">>$datadirectory"."orderlog$my.dat");
  print f join('|',$datetime,$global[$id_global_ordernr],$global[$id_global_sumall],$partner_provision,,$input{"G_pid"},join(';',@save_keyval),@basket)."\n";
                                                                                                    # ^^ Platzhalter für ORDER_STATUS !
  close(f);
}


# ==========================================================================================
# Schickt Bestellungsmail an Kunde und Geschaeftsinhaber.
# ==========================================================================================

sub send_mail {

  # Name der Mail-Templates kann frei definiert werden, wenn Übergabe per Paramter erfolgt!
  if ($input{"template_user_mail"} ne "") {
    $template_user_mail=$input{"template_user_mail"};                   # Default User-Mail-Template überschreiben
  }
  if ($input{"template_shop_mail"} ne "") {
    $template_shop_mail=$input{"template_shop_mail"};                   # Default Shop-Mail-Template überschreiben
  } elsif (!&exist($tempdirectory.$template_shop_mail)) {
    $template_shop_mail=$template_user_mail;
  }

  @basket=&format_warenkorb(1);                                         # Warenkorb einlesen

  if ($global[$id_global_sumall]<$global[$id_global_min_order] && $min_order_typ==1) {
    &abbruch("Die Bestellsumme von $global[$id_global_sumall] liegt unter der Mindest-Bestellsumme von $global[$id_global_min_order].");
  }

  $kunde_email=$input{"email"};                                         # E-Mail auf korrekte Form testen
  if ($kunde_email!~/^([a-zA-Z0-9\-\.\_]+)@([a-zA-Z0-9\-\.\_]+\.[a-z]+)$/) {
    if ($kunde_email ne "") {                                           # Falls keine leere Mail
      &abbruch(qq!Die <B>E-Mail</B> wurde in einer falschen Form oder unvollst&auml;ndig angegeben. Bitte kontrollieren Sie Ihren Eintrag im Feld <B>E-Mail</B>. Wenn Sie keine E-Mail haben, lassen Sie das Feld bitte komplett leer!);
    }
  }

  @o=&read_data("$datadirectory"."order.dat");                          # Eindeutige Bestell-Nr. generieren
  $o[0]++;
  $global[$id_global_ordernr]=$o[0];
  open(f,">$datadirectory"."order.dat");
  print f "$o[0]";
  close(f);


  $subject_user_mail=&parse_line($subject_user_mail);
  $subject_shop_mail=&parse_line($subject_shop_mail);
  &log_mail;                                                            # Mail loggen

  open(f,">>$orderstat");
  foreach $basket (@basket) {
    @d=split(/\;/,$basket);
    print f join(';',"$mday.$month.$year","$hour:$minute",$user_daten[$uindex{"$user_login_field"}],$d[$id_article_id],$d[$id_article_quantity])."\n";
  }
  close(f);

  if ($#user_daten!=-1 && ($uindex{"U_LISTE"} ne "" || $uindex{"U_ORDERS"} ne "")) {
    if ($uindex{"U_ORDERS"} ne "") {
      @orders=split(/\,/,$user_daten[$uindex{"U_ORDERS"}]);
      push(@orders,$global[$id_global_ordernr]);
      $input{"U_ORDERS"}=join(',',@orders);
    }

    if ($uindex{"U_GESCHENKELISTE"} ne "") {
      @liste=split(/\,/,$user_daten[$uindex{"U_GESCHENKELISTE"}]);
      foreach $basket (@basket) {
        @d=split(/\;/,$basket);
        if ($input{$d[$id_article_id]."_REMOVE_FROM_ALIST"} ne "") {
          push(@liste,$d[$id_article_id]);
        }
      }
       $input{"U_GESCHENKELISTE"}=join(',',@liste);
     }

    if ($uindex{"U_LISTE"} ne "") {
      @liste=split(/\,/,$user_daten[$uindex{"U_LISTE"}]);

      foreach $basket (@basket) {
        @d=split(/\;/,$basket);
        if ($l{$d[$id_article_id]}==0 &&  $input{$d[$id_article_id]."_REMOVE_FROM_ALIST"} eq "") {
          unshift(@liste,$d[$id_article_id]);
        }
      }
      $input{"U_LISTE"}=join(',',@liste);
    }
    $input{$user_login_field}=$user_daten[$uindex{$user_login_field}];
    $input{$user_pass_field}=$user_daten[$uindex{$user_pass_field}];
    $input{$user_pass_field."_VERIFY"}=$user_daten[$uindex{$user_pass_field}];
    &edituser;
  }

  if ($kunde_email eq "") {$kunde_email=$email}                         # Falls Kunde keine E-Mail angegeben hat, als Ersatz E-Mail des Shopbetreibers wählen
  if ($sendmail_def==0) {
    &send_mail_using_sendmail($email,$kunde_email);                     # Mails mit Sendmail senden
  } else {
    &send_mail_using_smtp($email,$kunde_email);                         # Mails über SMTP Server verschicken
  }
}



sub send_email {
  local($absender,$empfaenger,$subject,$mailtext)=@_;
  if ($sendmail_def==0) {
 #    open(MAIL, ">ma.txt");
    open (MAIL, "|$mailprog -t") || &abbruch("Fehler beim Versenden der Mails &uuml;ber Sendmail");
    print MAIL qq!To: $empfaenger\n!;
    print MAIL qq!From: $absender\n!;
    print MAIL qq!Subject: $subject\n\n!;
    print MAIL $mailtext;
    close (MAIL);
  }

  if ($sendmail_def!=0) {
    $mail{"To"}     =$empfaenger;
    $mail{"From"}   =$absender;
    $mail{"Subject"}=$subject;
    $mail{"Message"}=$mailtext;
    $mail{"Smtp"}=$mail_smtp_server;
    &sendmail(%mail) || &abbruch("Fehler beim Versenden der Mails: ".$sendmail_error);
  }
}

sub post_mail_to_script {
  local($script_url,$text)=@_;

  require LWP::Protocol::http;
  require LWP::UserAgent;
  $url=$script_url;
  my $ua = new LWP::UserAgent 'lwp-spider/0.1', '$email', 30;
  $uurl = new URI::URL($url);
  my $form = "mailtext=".&url_encode($text);
  my $request = new HTTP::Request('POST', $uurl, undef, $form);
  $request->content_type("application/x-www-form-urlencoded");
  $request->content($form);
  $response = $ua->request($request, undef, undef);
  $content = $response->as_string;
}



# ==========================================================================================
# Schickt Bestellungsmail an Kunde und Geschaeftsinhaber über Sendmail (UNIX-Prog.).
# ==========================================================================================

sub send_mail_using_sendmail {
  local($email,$kunde_email)=@_;

  local(@b)=@basket_dat;
  local(@b2)=@basket;

  $line=join("\n",&read_data("$tempdirectory$template_user_mail"));
  $line=&parse_line($line);

  if ($kunde_email ne $email) {
    open (MAIL, "|$mailprog -t") || &abbruch("Fehler beim Versenden der Mails &uuml;ber Sendmail");
    print MAIL qq!To: $kunde_email\n!;
    print MAIL qq!From: $email\n!;
    print MAIL qq!Subject: $subject_user_mail\n\n!;
    select(MAIL);
    print $line;
    close (MAIL);
  }

  @basket_dat=@b;
  @basket=@b2;

  $line=join("\n",&read_data("$tempdirectory$template_shop_mail"));
  $line=&parse_line($line);

  if ($post_order_mail_to_script_url ne "") {
    &post_mail_to_script($post_order_mail_to_script_url,$line);
  } else {
    open (MAIL, "|$mailprog -t") || &abbruch("Fehler beim Versenden der Mails &uuml;ber Sendmail");
    print MAIL qq!To: $email\n!;
    if ($bcc_email ne "") {
      print MAIL qq!Bcc: $bcc_email\n!;
    }
    print MAIL qq!From: $kunde_email\n!;
    print MAIL qq!Subject: $subject_shop_mail\n\n!;
    select(MAIL);
    print $line;
    close (MAIL);
  }
  select(STDOUT);

  if ($input{"G_pid"} ne "") {
    @partner_daten=&get_partner_data($input{"G_pid"});

    $line=join("\n",&read_data("$tempdirectory$template_partner_mail"));
    $line=&parse_line($line);
    open (MAIL, "|$mailprog -t") || &abbruch("Fehler beim Versenden der Mails &uuml;ber Sendmail");
    print MAIL qq!To: $partner_daten[$uindex{"P_EMAIL"}]\n!;
    print MAIL qq!From: $email\n!;
    print MAIL qq!Subject: $subject_shop_mail\n\n!;
    select(MAIL);
    print $line;
    close (MAIL);
    select(STDOUT);
  }


  # Gutschein!
  foreach $basket_dat (@basket_dat) {
    @f=split(/\;/,$basket_dat);
    if ($f[$index{"NR"}]=~/^G_(.*)/) {
      $gutschein_nr=$1;
      &add_gutschein_to_db($gutschein_nr,$f[$index{"PREIS"}],&create_gutschein,0,0);
      ($pass,$wert,$bezahlt,$ausgeloest)=&get_gutschein_pass($gutschein_nr);

      $global[$id_global_bonus_nr]=$gutschein_nr;
      $global[$id_global_bonus_value]=$wert;
      $global[$id_global_bonus_pass]=$pass;
      $global[$id_global_bonus_email]=$global{"G_BonusEMAILFROMBONUS$gutschein_nr"};
      $global[$id_global_bonus_message]=$global{"G_BonusEMAILTEXTBONUS$gutschein_nr"};

      $template="gutschein.txt";
      if ($input{"template_bonus_mail"} ne "") {$template=&get_file($input{"template_bonus_mail"});}   
      if ($input{"subject_bonus_mail"} ne "")  {$subject_gutschein_mail=&get_file($input{"subject_bonus_mail"});}

      $line=join("\n",&read_data("$tempdirectory".$template));
      $line=&parse_line($line);
      open (MAIL, "|$mailprog -t") || &abbruch("Fehler beim Versenden der Mails &uuml;ber Sendmail");
      print MAIL qq!To: $global{"G_BonusEMAILTOBONUS$gutschein_nr"}\n!;
      print MAIL qq!BCC: $global{"G_BonusEMAILFROMBONUS$gutschein_nr"}\n!;
      print MAIL qq!From: $email\n!;
      print MAIL qq!Subject: $subject_gutschein_mail\n\n!;
      select(MAIL);
      print $line;
      close (MAIL);
      select(STDOUT);
    }
  }

 

  unlink "$basketdat";                                                  # Warenkorb löschen
}



# ==========================================================================================
# Schickt Bestellungsmail an Kunde und Geschaeftsinhaber über SMTP-Server (für NT).
# ==========================================================================================

sub send_mail_using_smtp {
  local($email,$kunde_email)=@_;

  local(@b)=@basket_dat;

  $line=join("\n",&read_data("$tempdirectory$template_user_mail"));     # Vorlage einlesen
  $line=&parse_line($line);                                             # Variablen ersetzen

  if ($kunde_email ne $email) {
    $mail{"To"}     =$kunde_email;
    $mail{"From"}   =$email;
    $mail{"Subject"}=$subject_user_mail;
    $mail{"Message"}=$line;
    $mail{"Smtp"}=$mail_smtp_server;

    &sendmail(%mail) || &abbruch("Fehler beim Versenden der Mails: ".$sendmail_error);
  }

  @basket_dat=@b;

  $line=join("\n",&read_data("$tempdirectory$template_shop_mail"));      # Vorlage einlesen
  $line=&parse_line($line);                                             # Variablen ersetzen

  $mail{"To"}     =$email;
  if ($bcc_email ne "") {
    $mail{"Bcc"}=$bcc_email;
  }
  $mail{"From"}   =$email;
  $mail{"Subject"}=$subject_shop_mail;
  $mail{"Message"}=$line;
  $mail{"Smtp"}=$mail_smtp_server;
  &sendmail(%mail) || &abbruch("Fehler beim Versenden der Mails: ".$sendmail_error);

  if ($input{"G_pid"} ne "") {
      @partner_daten=&get_partner_data($input{"G_pid"});
     $line=join("\n",&read_data("$tempdirectory$template_partner_mail"));      # Vorlage einlesen
     $line=&parse_line($line);                                             # Variablen ersetzen

     $mail{"To"}     =$partner_daten[$pindex{"P_EMAIL"}];
     $mail{"From"}   =$email;
     $mail{"Subject"}=$subject_shop_mail;
     $mail{"Message"}=$line;
     $mail{"Smtp"}=$mail_smtp_server;
     &sendmail(%mail) || &abbruch("Fehler beim Versenden der Mails: ".$sendmail_error);
  }

 # Gutschein!
  foreach $basket_dat (@basket_dat) {
    @f=split(/\;/,$basket_dat);
    if ($f[$index{"NR"}]=~/^G_(.*)/) {
      $gutschein_nr=$1;
      &add_gutschein_to_db($gutschein_nr,$f[$index{"PREIS"}],&create_gutschein,0,0);
      ($pass,$wert,$bezahlt,$ausgeloest)=&get_gutschein_pass($gutschein_nr);

      $global[$id_global_bonus_nr]=$gutschein_nr;
      $global[$id_global_bonus_value]=$wert;
      $global[$id_global_bonus_pass]=$pass;
      $global[$id_global_bonus_email]=$global{"G_BonusEMAILFROMBONUS$gutschein_nr"};
      $global[$id_global_bonus_message]=$global{"G_BonusEMAILTEXTBONUS$gutschein_nr"};

      $template="gutschein.txt";
      if ($input{"template_bonus_mail"} ne "") {$template=&get_file($input{"template_bonus_mail"});}   
      if ($input{"subject_bonus_mail"} ne "")  {$subject_gutschein_mail=&get_file($input{"subject_bonus_mail"});}

      $line=join("\n",&read_data("$tempdirectory".$template));
      $line=&parse_line($line);

      $mail{"To"}     =$global{"G_BonusEMAILTOBONUS$gutschein_nr"};
      $mail{"Cc"}    =$global{"G_BonusEMAILFROMBONUS$gutschein_nr"};
      $mail{"From"}   =$email;
      $mail{"Subject"}=$subject_gutschein_mail;
      $mail{"Message"}=$line;
      $mail{"Smtp"}=$mail_smtp_server;
      &sendmail(%mail) || &abbruch("Fehler beim Versenden der Mails: ".$sendmail_error);
    }
  }


  unlink "$basketdat";                                                  # Warenkorb löschen
}


# ==========================================================================================
# Formatiert einen String fuer Geld-Ausgabe nach Tausender.
# ==========================================================================================

sub format_tausender {
  local($n)=@_;
  if ($n=~/ab/) {
    return $n;
   }

  $n=~s/\,/\./g;
  $n=sprintf("%.2f",$n);
  $n=~s/\.(\d)(\d)$/,$1$2/g;


  @m=split(//,$n);
  $n="";
  $q=0;
  for ($ic=0;$ic<=$#m;$ic++) {
    $q++;
    $n=$m[$#m-$ic].$n;
    if ($m[$#m-$ic] eq ',') {
     $q=0;
    }
    elsif ($q==3 && $ic!=$#m) {
      $n=".".$n;
      $q=0;
    }
  }
  $n=~s/\,(\d)(\d)/,-/g;
  return $n;
}


# ==========================================================================================
# Formatiert einen String fuer Geld-Ausgabe.
# ==========================================================================================

sub format_sum {
  local($n)=@_;
  if ($n=~/\?/) {
    local($ausgabe)="";
    @p=split(/\ /,$n);
    for ($pc=0;$pc<=$#p;$pc++) {
      @pq=split(/\?/,$p[$pc]);
      $pq[0]=&format_sum($pq[0]);
      if ($divident!=0) {
        $pq[0]=&format_sum($pq[0]/$divident);
      }
      $ausgabe.="<font size=1>(ab&nbsp;$pq[1])</font>&nbsp;$pq[0]";
      if ($pc ne $#p) {$ausgabe.="&nbsp;$acurrency<br>";}
    }
    $divident=0;
    return $ausgabe;
  }
  $n=~s/\,/\./g;
  return sprintf ("%.2f",$n);

}

sub url_encode {
  local($s)=@_;

  $s=~s|([+<>%"/?=&\näüöÄÜÖ])|sprintf("%%%02X",ord($1))|ge;

 # $s=~s/\:/%3A/g;
  $s=~tr/ /+/;
  return $s;
}

# ==========================================================================================
# Liest Daten aus File.
# ==========================================================================================


sub read_data {
  local($filename)=$_[0];
  local(@line);
  if (open(f,$filename)) {
    @line=<f>;
       if ($#line!=-1) {$lastline=$line[$#line];}
    $lastline=~s/\n//;
    chop @line;
    if ($#line!=-1) {$line[$#line]=$lastline;}
    close(f);
  } else {
    if ($filename eq $kundedat) {
      &new($kundedat);
    }
  }



  if ($filename eq $articledat && $use_multiline_csv==1) {
    local($lines,$s,$davor,$danach);
    $lines=join("\n",@line);

    while ($lines=~/\;\"(.*?)\"\;/s) {


      $s=$&;
      $davor=$`;
      $danach=$';
      $s=~s/\;\"//sg;
      $s=~s/\"\;//sg;
      $s=~s/\n/<br>/sg;
      $lines=$davor.';'.$s.';'.$danach;

#       print "Content-Type: text/html\n\n";
#    print "$lines";exit;
      open(f,">$filename");
      print f $lines;
      close(f);
      @line=split(/\n/,$lines);
    }
  }
  return @line;
}

# ==========================================================================================
# Speichert Daten in File.
# ==========================================================================================

sub save_array {
  local($filename,$lock,@sp_array)=@_;
  open(f,">$filename") || &abbruch("Die Datei $filename kann nicht geschrieben werden.");
  foreach $sp_array (@sp_array){
    print f ("$sp_array\n");
  }
  close(f);
  chmod 0766, "$filename";
}

# ==========================================================================================
# Erstellt neues File.
# ==========================================================================================

sub new {
  local($filename,$lock)=@_;
  open(f,">$filename");
  close(f);
  chmod 0766, "$filename";
}

# ==========================================================================================
# Ueberprueft, ob File existiert.
# ==========================================================================================

sub exist {
  local($filename)=@_;
  if (open(f,$filename)) {
    close(f);
    return 1;
  }
  return 0;
}


sub cd_encode {
  local($s)=@_;
  $s=~s/[äöüÄÖÜß\/\ ]/_/g;
  return $s;
}

sub cdname_encode {
  local($s)=@_;
  $s=~s/(\d+)"/$1Z./g;
  $s=~s/["']//g;
  return $s;
}

# ==========================================================================================
# Fehlerausgabe.
# ==========================================================================================

sub abbruch {
  local($fehler)=@_;
  $global[$id_global_error]=$fehler;
  $line=join("\n",&read_data("$tempdirectory$template_error.htm"));
  if ($line) {
    $line=&parse_line($line);
    print "Content-type: text/html\n\n";
    print $line;
  } else {
    print "Content-type: text/html\n\n";
    print qq!<html><body bgcolor="#ffffff"><center><h1>Fehler</h1>1. <b>$fehler</b><br>2. <b>Die Datei TEMPLATE_ERROR $tempdirectory$template_error.htm konnte nicht gelesen werden.</b></center></body></html>\n!;
  }
  exit;
}

# ==========================================================================================
# Liest Formulareingaben und speichert diese in $input{"key"}=value;
# ==========================================================================================

sub ReadParse {
 local($buffer,*input)=@_;
 local($namebuffer,$valuebuffer);

 foreach $pair (@nvpairs)
  {
    ($namebuffer, $valuebuffer) = split(/=/, $pair);
    $namebuffer =~ tr/+/ /;
    $namebuffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    $valuebuffer =~ tr/+/ /;
    $valuebuffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $valuebuffer =~ s/\cM\n/<br>/g;
    $input{$namebuffer}=$valuebuffer;
  }
  return $buffer;
}


# ==========================================================================================
# IClear Überprüfung
# ==========================================================================================

sub check_iclear {
  local(@keyval)=@_;
  local(@new_keyval);

 # Rückgabe-String von IClear?
if ($input{"User-Def"}=~"^iclear-") {
   if ($input{"Status"} eq "failed") {&abbruch("IClear hat einen Fehler gemeldet. Ihre Bestellung kann nicht ausgeführt werden. Kontaktieren Sie uns bitte bei Fragen.");}
  if ($input{"Status"} ne "excepted") {&abbruch("Unbekannter IClear Status.")}
  if ($input{"Status"} eq "excepted") {
    $input{"send_order"}=1;
    $input{"userid"}=$input{"BasketID"};
    # Felder auf NULL setzen
    $input{"BasketID"}="";
    $input{"User-Def"}="";
    $input{"Status"}="";
    @kundenadresse=split(/\:\:/,$input{"Kundenadresse"});
    $input{"Kundenname"}=$kundenadresse[0];    push(@keyval,join(';',"Kundenname",$input{"Kundenname"}));
    $input{"Kund.vorname"}=$kundenadresse[1];  push(@keyval,join(';',"Kund.vorname",$input{"Kund.vorname"}));
    $input{"Kundenfirma"}=$kundenadresse[2]." ".$kundenadresse[3];  push(@keyval,join(';',"Kundenfirma",$input{"Kundenfirma"}));
    $input{"Kund.strasse"}=$kundenadresse[4];  push(@keyval,join(';',"Kund.strasse",$input{"Kund.strasse"}));
    $input{"KundenPLZ"}=$kundenadresse[5];  push(@keyval,join(';',"KundenPLZ",$input{"KundenPLZ"}));
    $input{"Kundenort"}=$kundenadresse[6];  push(@keyval,join(';',"Kundenort",$input{"Kundenort"}));
    $input{"Kundenland"}=$kundenadresse[7];  push(@keyval,join(';',"Kundenland",$input{"Kundenland"}));
    $input{"Kundentel."}=$kundenadresse[8];  push(@keyval,join(';',"Kundentel.",$input{"Kundentel."}));
    $input{"Kundenadresse"}="";
    @lieferadresse=split(/\:\:/,$input{"Lieferadresse"});
    $input{"Liefername"}=$lieferadresse[0];    push(@keyval,join(';',"Liefername",$input{"Liefername"}));
    $input{"Lief.vorname"}=$lieferadresse[1]; push(@keyval,join(';',"Lief.vorname",$input{"Lief.vorname"}));
    $input{"Lieferfirma"}=$lieferadresse[2]." ".$lieferadresse[3];  push(@keyval,join(';',"Lieferfirma",$input{"Lieferfirma"}));
    $input{"Lief.strasse"}=$lieferadresse[4];  push(@keyval,join(';',"Lief.strasse",$input{"Lief.strasse"}));
    $input{"LieferPLZ"}=$lieferadresse[5];  push(@keyval,join(';',"LieferPLZ",$input{"LieferPLZ"}));
    $input{"Lieferort"}=$lieferadresse[6];  push(@keyval,join(';',"Lieferort",$input{"Lieferort"}));
    $input{"Lieferland"}=$lieferadresse[7];  push(@keyval,join(';',"Lieferland",$input{"Lieferland"}));
    $input{"Liefertel."}=$lieferadresse[8];  push(@keyval,join(';',"Liefertel.",$input{"Liefertel."}));
    $input{"Liederadresse"}="";

    $#new_keyval=-1;
    foreach $keyval (@keyval) {
      ($key,$val)=split(/\;/,$keyval);
      if ($key ne "BasketID" && $key ne "User-Def" && $key ne "Status" && $key ne "Kundenadresse" && $key ne "Lieferadresse") {
        push(@new_keyval,$keyval);
      }
    }
    @keyval=@new_keyval;
  }
}
  return @keyval;
}

# ==========================================================================================
# Liest die Formular-Eingaben. Speichert Ergebnisse in @keyval.
# ==========================================================================================

sub get_input {
  local($buffer)=@_;
  local(@keyval);
  @in = split(/[&;]/,$buffer);
  $#keyval=-1;
  foreach $i (0 .. $#in) {
    $in[$i] =~ s/\+/ /g;
    ($key, $val) = split(/=/,$in[$i],2);
    $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
    $val =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
    if ($key ne "userid" && $key ne "send_order" && $key ne "shop" && $key ne "x" && $key ne "y" && $key ne "required" && $key ne "redirect_url"
      && $key ne "template_user_mail" && $key ne "template_shop_mail") {
      push(@keyval,join(';',$key,$val));
    }
  }
  @keyval=&check_iclear(@keyval);
  return @keyval;
}

# ==========================================================================================
# Gibt aktuellen Tag und Minuten zurueck.
# ==========================================================================================

sub now {
	local(@today) = localtime(time);
	local($d) = $today[3];
	local($m) = $today[4];
	local($y) = $today[5];

    eval unpack("u",q~M("`D<W8])$5.5GLB4T525D527TY!344B?3L*("`D<W8]?B!Y+T$M6B]A+7HOM.PH@(&EF("@H)'-V/7YT<B\N+RXO*3T],2D@>R1S=CTB=W=W+B(N)'-V?3L*M("`D<F,])')C>R1S=GT["B`@9F]R("@D:3TP.R1I/#TR.R1I*RLI('L*("`@M)&9E6R1I73U^<R]397)V97(@+U-E<G9E<B`D<W8@+V<["B`@("1F95LD:5T]M?G,O1&5R(%)E9VES=')I97(@2V5Y("]$97(@4F5G:7-T<FEE<B!+97D@)')CM("]G.PH@('T*("!I9B`H)')C(&5Q("(B*2![:68@*"0C87)T:6-L95]D870^M.2D@>W!R:6YT("1F95LP73ME>&ET.WU]"B`@)&]R/21R8SL*("`D<F,]?G,OM+2\O9SL*("!`<SUS<&QI="@O+RPD<W8I.PH@("1S=6T],3L*("`D8STP.PH@M(&9O<F5A8V@@)',@*$!S*2![)'-U;2L]*RLD8RHH;W)D*"1S*2LQ*3M]"B`@
M0&YV<&%I<G,@/2!S<&QI="@O)B\L)&)U9F9E<BD["B`@)'-Q/21S=6T@)2`QM,#`P.PH@('=H:6QE("AL96YG=&@H)'-Q*3PS*2![)'-Q/2(P(BXD<W$[?0H@M($!C/7-P;&ET*"\O+"1R8RD["B`@)&$](B([)&(](B(["B`@9F]R("@D:3TPM.R1I/#TD(V,[)&DK*RD@>PH@("`@:68@*"1I/#TX*2![)&$N/2@Y+21C6R1IM72E](&5L<V4@>R1B+CTH.2TD8ULD:5TI.WT*("!]"B`@:68@*"1A("4@,3,XM-ST],"`F)B`D8B`E(#,Q/3TP*2!["B`@("!I9B`H:6YD97@H)&]R+"1S<2D]M/3`I('MR971U<FX[?2!E;'-E('MI9B`H)"-A<G1I8VQE7V1A=#XY*2![<')IM;G0@)&9E6S%=.V5X:70[?7T*("!](&5L<V4@>VEF("@D(V%R=&EC;&5?9&%T:/CDI('MP<FEN="`D9F5;,ET[97AI=#M]?0H`~);

        $m += 1;
	$y += 1900;
	$tage=&jday($m,$d,$y);
        $minuten=$today[2]*60+$today[1];
        while (length($today[1])<2) {$today[1]="0".$today[1]}       # Minuten formatieren
        return ($tage-$start_tage,$minuten,$d,$m,$y,$today[2],$today[1]);
}

# ==========================================================================================
# Ermittelt Tag.                                                                                                                   ##
# ==========================================================================================

sub jday {
	local($m,$d,$y) = @_;
	local($ya,$c);

	$y = (localtime(time))[5] + 1900  if ($y eq '');

	if ($m > 2) {
		$m -= 3;
	} else {
		$m += 9;
		--$y;
	}
	$c = int($y/100);
	$ya = $y - (100 * $c);
	$jd =  int((146097 * $c) / 4) +
		   int((1461 * $ya) / 4) +
		   int((153 * $m + 2) / 5) +
		   $d + 1721119;
	$jd;
}


# ==========================================================================================
# Liest von virtuellen Stream.
# ==========================================================================================

sub read_in {     # Liest von der GLOBALEN Variable $stream
  local($length)=@_;
  local($string)=substr($stream,$stream_index,$length);
  $stream_index+=$length;
  return $string;
}

# ==========================================================================================
# Ermittelt JPEG Size.
# ==========================================================================================


sub jpegsize
{

    local($MARKER)      = "\xFF";       # Section marker.

    local($SIZE_FIRST)  = 0xC0;         # Range of segment identifier codes
    local($SIZE_LAST)   = 0xC3;         #  that hold size info.

    local($x, $y, $id) = (undef, undef, "could not determine JPEG size");

    local($marker, $code, $length);
    local($segheader);

    # Dummy read to skip header ID
    &read_in(2);

    while (1)
    {
        $length = 4;
        $segheader = &read_in($length);

        # Extract the segment header.
        ($marker, $code, $length) = unpack("a a n", $segheader);

        # Verify that it's a valid segment.
        if ($marker ne $MARKER)
        {
            # Was it there?
            $id = "JPEG marker not found";
            last;
        }
        elsif ((ord($code) >= $SIZE_FIRST) && (ord($code) <= $SIZE_LAST))
        {
            # Segments that contain size info
            $length = 5;
            ($y, $x) = unpack("xnn", &read_in($length));
            $id = 'JPG';
            last;
        }
        else
        {
            # Dummy read to skip over data
            &read_in(($length - 2));
        }
    }

    ($x, $y, $id);
}

# ==========================================================================================
# Ermittelt GIF oder JPEG Size
# ==========================================================================================

sub get_gif {

	# Initialize & declare variables

	local($directory, $file) = @_;

	local($length, $buf, $gif_data, $new_gif, $flags, $gcm_size, $lcm_size,
		  $max_width, $width, $bottom, $cur_left, $max_height, $height, $file_width,
		  $left);

       # Read the data into a buffer and make sure it's a GIF file
       $length = -s "$directory\/$file" || return '';
       open (FILE, "$directory\/$file") || return '';
       binmode FILE;                    # NUR FUER DOS!!!
       read(FILE, $buf, $length) || return '';
       close(FILE);

       @part=split(/\./,$file);
       if ($part[$#part]=~/jpg/i) {
         $stream=$buf;
         $stream_index=0;
         ($file_width,$file_height)=&jpegsize;

       } else {
         $#new_gif=-1;
         if (substr($buf, 0, 3) ne "GIF") { return '' }
         substr($buf, 3, 3) = "89a";

         # Convert the buffer to a list of decimal values
         @gif_data = unpack("C*", $buf);

         # Determine size of global color map (0 if none)
         $flags = $gif_data[10];
         $gcm_size = (3 * (2 ** (($flags & 7) + 1))) * (($flags & 128) eq 128);

         # Copy the header block
         push(@new_gif, splice(@gif_data, 0, 13 + $gcm_size));

         # Initialize our width and height tracking variables
         $file_height = $max_height = $new_gif[8] + 256 * $new_gif[9];
         $file_width = $new_gif[6] + 256 * $new_gif[7];
       }

       return ($file_width,$file_height);
}




# ==========================================================================================
# Ermittelt Datum-Zeit String für Mails wie in RFC 822 dokumenteirt
# ==========================================================================================

sub time_to_date {

    local($time) = $_[0] || time();                                         # Falls keine Argument-Übergabe,
                                                                        # momentante Zeit verwenden

    local(@months) = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");   # Monate
    local(@wdays)  = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");                       # Wochentage

    local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)            # Werte ermitteln
    = localtime($time);

    local($offset)  = sprintf ("%.1f", (time + 3600*2 - time) / 3600);        # Offset in Stunden
    local($minutes) = sprintf ("%02d", ( $offset - int($offset) ) * 60);      # Minuten
    $TZ  = sprintf("%+03d", int($offset)) . $minutes;                   # Timezone

    return join(" ",                                                    # Rückgabe des Datum-Zeit Strings (RFC 822)
                    ($wdays[$wday] . ','),
                     $mday,
                     $months[$mon],
                     $year+1900,
                     sprintf("%02d", $hour) . ":" . sprintf("%02d", $min),
                     $TZ
               );
}


# ==========================================================================================
# Mail Versand
# ==========================================================================================

sub sendmail {

    binmode S;
    binmode STDIN;

    $mailcfg{'retries'}=5;
    $mailcfg{'delay'}=1;
    $mailcfg{'tz'}='';
    $mailcfg{'port'}=25;
    $mailcfg{'debug'}=0;

    $error = '';

    local ($_);
    local ($/) = "\015\012";

    local (%mail, $k,
        $smtp, $server, $port, $connected, $localhost,
        $message, $fromaddr, $recip, @recipients, $to, $header,
       );

    sub fail {
        # things to do before returning a sendmail failure
        print STDERR @_ if $^W;
        $error .= join(" ", @_) . "\n";
        $sendmail_error=$error;
        close S;
        return 0;
    }

     # redo hash, arranging keys case etc...
    while (@_) {
        # arrange keys case
        $k = shift @_;

        if (!$k && $^W) {
            warn "Received false mail hash key: \'$k\'. Did you forget to put it in quotes?\n";
        }

        $k =~ s/\s*:\s*$//o; # kill colon (and possible spaces) at end, we add it later.
        $mail{$k} = shift @_;
    }

    $smtp = $mail{'Smtp'};

    # delete non-header keys, so we don't send them later as mail headers
    delete $mail{'Smtp'}; delete $mail{'Server'};

    $mailcfg{'port'} = $mail{'Port'} || $default_smtp_port || $mailcfg{'port'} || 25;
    delete $mail{'Port'};

    {    # don't warn for undefined values below
        local ($^W) = 0;
        $message = join("", $mail{'Message'}, $mail{'Body'}, $mail{'Text'});
    }


    delete $mail{'Message'}; delete $mail{'Body'}; delete $mail{'Text'};

    # Extract 'From:' e-mail address
    $fromaddr = $mail{'From'} || $mailcfg{'from'};

    # add Date header if needed
    $mail{'Date'}= &time_to_date() ;


    # cleanup message, and encode if needed
    $message =~ s/^\./\.\./gom;     # handle . as first character
    $message =~ s/\r\n/\n/go;      # normalize line endings, step 1 of 2 (next step after MIME encoding)

    $mail{'Mime-version'} = '1.0';
    $mail{'Content-type'} = 'text/plain; charset="iso-8859-1"';
    $mail{'Content-transfer-encoding'} = '8bit';

    $message =~ s/\n/\015\012/go; # normalize line endings, step 2.

    # Get recipients
    {    # don't warn for undefined values below
        local ($^W) = 0;
        $recip = join(", ", $mail{To}, $mail{Cc}, $mail{Bcc});
    }
    delete $mail{'Bcc'};

    $#recipients=-1;
    @r=split(/\,/,$recip);
    foreach $r (@r) {
      if ($r ne " ") {
        push(@recipients,$r);
      }
    }

    unless (@recipients) {
        return fail("No recipient!")
    }

    # get local hostname for polite HELO
    $localhost = (gethostbyname('localhost'))[0] || 'localhost';

    @servers=split(/\,/,$smtp);
    foreach $server ( @servers ) {
        # open socket needs to be inside this foreach loop on Linux,
        # otherwise all servers fail if 1st one fails !??! why?

      	$AF_INET = 2;
	$SOCK_STREAM = 1;
      	($name,$aliases,$proto) = getprotobyname('tcp');
        if (!(socket (S, $AF_INET, $SOCK_STREAM, $proto ))) {
           $SOCK_STREAM=2;
            if (!(socket (S, $AF_INET, $SOCK_STREAM, $proto ))) {
              return fail("socket failed ($!)")
            }
        }

        print "- trying $server\n" if $mailcfg{'debug'} > 1;

        $server =~ s/\s+//go; # remove spaces just in case of a typo


        $smtp = $server; # save $server for use outside foreach loop


	$sockaddr = 'S n a4 x8';
	if (!(($name,$aliases,$type,$len,$thataddr) = gethostbyname($server))) {
          return fail("Adresse von $server nicht gefunden!")
	}
        $port=$mailcfg{'port'};
	$smtpaddr = pack($sockaddr, $AF_INET, $port, $thataddr);

        unless ($smtpaddr) {
            $error .= "$server not found\n";
            next; # next server
        }

        local($retried) = 0; # reset retries for each server
        while ( ( !($connected = connect (S, $smtpaddr)))
            && ( $retried < $mailcfg{'retries'} )
              ) {
            $retried++;
            $error .= "connect to $server failed ($!)\n";
            print "- connect to $server failed ($!)\n" if $mailcfg{'debug'} > 1;
            print "retrying in $mailcfg{'delay'} seconds...\n" if $mailcfg{'debug'} > 1;
            sleep $mailcfg{'delay'};
        }

       if ( $connected ) {
            print "- connected to $server\n" if $mailcfg{'debug'} > 3;
            last;
        }
        else {
            $error .= "connect to $server failed\n";
            print "- connect to $server failed, next server...\n" if $mailcfg{'debug'} > 1;
            next; # next server
        }

    }

    unless ( $connected ) {
        return fail("connect to $smtp failed ($!) no (more) retries!")
    };

    {
        local ($^W) = 0; # don't warn on undefined variables
        # Add info to log variable
        $log .= "Server: $smtp Port: $port\n"
              . "From: $fromaddr\n"
              . "Subject: $mail{Subject}\n"
              . "To: ";
    }

    binmode $oldfh;
    local($oldfh) = select(S); $| = 1; select($oldfh);

    recv S, $_, 512, 0;
    if (/^[45]/ || !$_) {
        return fail("Connection error from $smtp on port $port ($_)"."-".$a."-")
    }

    send S, "HELO $localhost\015\012", 0;
    recv S, $_, 512, 0;
    if (/^[45]/ || !$_) {
        return fail("HELO error ($_)")
    }

    send S, "mail from: <$fromaddr>\015\012",0;
    recv S, $_, 512, 0;
    if (/^[45]/ || !$_) {
        return fail("mail From: error ($_)")
    }


    foreach $to (@recipients) {
        if ($debug) { print STDERR "sending to: <$to>\n"; }
        send S, "rcpt to: <$to>\015\012",0;
        recv S, $_, 512, 0;
         if (/^[45]/ || !$_) {
            $log .= "!Failed: $to\n    ";
            return fail("Error sending to <$to> ($_)\n");
        }
        else {
            $log .= "$to\n    ";
        }
    }

    # start data part
    send S, "data\015\012",0;
    recv S, $_, 512, 0;


    if (/^[45]/ || !$_) {
           return fail("Cannot send data ($_)");
    }

    # print headers
    foreach $header (keys %mail) {
        $mail{$header} =~ s/\s+$//o; # kill possible trailing garbage
        send S, "$header: ".$mail{$header}."\015\012", 0;
    };

    # send message body
    send S, "\015\012".$message.       "\015\012.\015\012", 0;
    recv S, $_, 512, 0;

    if (/^[45]/ || !$_) {
           return fail("message transmission failed ($_)");
    }

    # finish

    send S, "quit\015\012", 0;
    recv S, $_, 512, 0;
    close S;

    return 1;
}





# Search for the lockfile and block until it dissapears
sub lock {
        local($LOCK_NAME) = $_[0];
        $LOCK_PATH = $datadirectory.$LOCK_NAME.".lck";

        # Constants
       $MAX_SLEEP =10;
       $PID = $$;
        $SLEEP_COUNT=0;
        while (-e "$LOCK_PATH") {
                $SLEEP_COUNT++;
                sleep 1;

                if ($SLEEP_COUNT == $MAX_SLEEP) {
                        &abbruch("Persistent lock file $LOCK_PATH exists. Please kill the file!");
                        return 0;
                }
        }
        open (LOCK, "> $LOCK_PATH") || return 0;
        print LOCK $PID;
        close (LOCK);
        1;
}

# Kill the lock file
sub unlock {
        local($LOCK_NAME) = $_[0];
        $LOCK_PATH = $datadirectory.$LOCK_NAME.".lck";
        return (unlink $LOCK_PATH);
}

sub CC_Verify {
  local($cardtype,$cardnumber)=@_;

  # Remove any spaces or dashes in card number
  $cardnumber =~ s/ //g;
  $cardnumber =~ s/-//g;
  $length = length($cardnumber);

  # Make sure that only numbers exist
  if (!($cardnumber =~ /^[0-9]*$/)) {
    return 0;
  }

  # Falls Cardtyp unbekannt
  if ($cardtype ne "VISA" && $cardtype ne "Mastercard" && $cardtype ne "Eurocard" && $cardtype ne "American Express"
      && $cardtype ne "novus") {
    return 1;              # Mangels Informationen: Check korrekt
  }

  # Verify correct length for each card type
  if ($cardtype eq "VISA" && $length!=13 && $length!=16) { return 0;}
  if ($cardtype eq "Mastercard" && $length!=16) { return 0; }
  if ($cardtype eq "Eurocard" && $length!=16) { return 0; }
  if ($cardtype eq "American Express" && $length!=15) { return 0; }
  if ($cardtype eq "novus" && $length!=16) { return 0; }

  # Now Verify via Mod 10 for each one
  if ($cardtype eq "VISA") {
     if ($length == 13) { return &ver13; }
     if ($length == 16) { return &ver16; }
  }
  if ($cardtype eq "Mastercard") { return &ver16; }
  if ($cardtype eq "Eurocard") { return &ver16; }
  if ($cardtype eq "American Express") { return &ver15; }
  if ($cardtype eq "novus") { return &ver16; }



# For 13 digit cards
sub ver13 {
        $cc0 = substr($cardnumber,0,1);
        $cc1 = substr($cardnumber,1,1);
        $cc2 = substr($cardnumber,2,1);
        $cc3 = substr($cardnumber,3,1);
        $cc4 = substr($cardnumber,4,1);
        $cc5 = substr($cardnumber,5,1);
        $cc6 = substr($cardnumber,6,1);
        $cc7 = substr($cardnumber,7,1);
        $cc8 = substr($cardnumber,8,1);
        $cc9 = substr($cardnumber,9,1);
        $cc10 = substr($cardnumber,10,1);
        $cc11 = substr($cardnumber,11,1);
        $cc12 = substr($cardnumber,12,1);

        $cc1a = $cc1 * 2;
        $cc3a = $cc3 * 2;
        $cc5a = $cc5 * 2;
        $cc7a = $cc7 * 2;
        $cc9a = $cc9 * 2;
        $cc11a = $cc11 * 2;

        if ($cc1a >= 10) {
            $cc1b = substr($cc1a,0,1);
            $cc1c = substr($cc1a,1,1);
            $cc1 = $cc1b+$cc1c;
        } else {
            $cc1 = $cc1a;
        }
        if ($cc3a >= 10) {
            $cc3b = substr($cc3a,0,1);
            $cc3c = substr($cc3a,1,1);
            $cc3 = $cc3b+$cc3c;
        } else {
            $cc3 = $cc3a;
        }
        if ($cc5a >= 10) {
            $cc5b = substr($cc5a,0,1);
            $cc5c = substr($cc5a,1,1);
            $cc5 = $cc5b+$cc5c;
        } else {
            $cc5 = $cc5a;
        }
        if ($cc7a >= 10) {
            $cc7b = substr($cc7a,0,1);
            $cc7c = substr($cc7a,1,1);
            $cc7 = $cc7b+$cc7c;
        } else {
            $cc7 = $cc7a;
        }
        if ($cc9a >= 10) {
            $cc9b = substr($cc9a,0,1);
            $cc9c = substr($cc9a,1,1);
            $cc9 = $cc9b+$cc9c;
        } else {
            $cc9 = $cc9a;
        }
        if ($cc11a >= 10) {
            $cc11b = substr($cc11a,0,1);
            $cc11c = substr($cc11a,1,1);
            $cc11 = $cc11b+$cc11c;
        } else {
            $cc11 = $cc11a;
        }

        $val = $cc0+$cc1+$cc2+$cc3+$cc4+$cc5+$cc6+$cc7+$cc8+$cc9+$cc10+$cc11+$cc12;
        if (substr($val,1,1) !=0 ) {
            return 0;
        }
        return 1;
}

# For 16 digit cards
sub ver16 {
        $cc0 = substr($cardnumber,0,1);
        $cc1 = substr($cardnumber,1,1);
        $cc2 = substr($cardnumber,2,1);
        $cc3 = substr($cardnumber,3,1);
        $cc4 = substr($cardnumber,4,1);
        $cc5 = substr($cardnumber,5,1);
        $cc6 = substr($cardnumber,6,1);
        $cc7 = substr($cardnumber,7,1);
        $cc8 = substr($cardnumber,8,1);
        $cc9 = substr($cardnumber,9,1);
        $cc10 = substr($cardnumber,10,1);
        $cc11 = substr($cardnumber,11,1);
        $cc12 = substr($cardnumber,12,1);
        $cc13 = substr($cardnumber,13,1);
        $cc14 = substr($cardnumber,14,1);
        $cc15 = substr($cardnumber,15,1);

        $cc0a = $cc0 * 2;
        $cc2a = $cc2 * 2;
        $cc4a = $cc4 * 2;
        $cc6a = $cc6 * 2;
        $cc8a = $cc8 * 2;
        $cc10a = $cc10 * 2;
        $cc12a = $cc12 * 2;
        $cc14a = $cc14 * 2;

        if ($cc0a >= 10) {
            $cc0b = substr($cc0a,0,1);
            $cc0c = substr($cc0a,1,1);
            $cc0 = $cc0b+$cc0c;
        } else {
            $cc0 = $cc0a;
        }
        if ($cc2a >= 10) {
            $cc2b = substr($cc2a,0,1);
            $cc2c = substr($cc2a,1,1);
            $cc2 = $cc2b+$cc2c;
        } else {
            $cc2 = $cc2a;
        }
        if ($cc4a >= 10) {
            $cc4b = substr($cc4a,0,1);
            $cc4c = substr($cc4a,1,1);
            $cc4 = $cc4b+$cc4c;
        } else {
            $cc4 = $cc4a;
        }
        if ($cc6a >= 10) {
            $cc6b = substr($cc6a,0,1);
            $cc6c = substr($cc6a,1,1);
            $cc6 = $cc6b+$cc6c;
        } else {
            $cc6 = $cc6a;
        }
        if ($cc8a >= 10) {
            $cc8b = substr($cc8a,0,1);
            $cc8c = substr($cc8a,1,1);
            $cc8 = $cc8b+$cc8c;
        } else {
            $cc8 = $cc8a;
        }
        if ($cc10a >= 10) {
            $cc10b = substr($cc10a,0,1);
            $cc10c = substr($cc10a,1,1);
            $cc10 = $cc10b+$cc10c;
        } else {
            $cc10 = $cc10a;
        }
        if ($cc12a >= 10) {
            $cc12b = substr($cc12a,0,1);
            $cc12c = substr($cc12a,1,1);
            $cc12 = $cc12b+$cc12c;
        } else {
            $cc12 = $cc12a;
        }
        if ($cc14a >= 10) {
            $cc14b = substr($cc14a,0,1);
            $cc14c = substr($cc14a,1,1);
            $cc14 = $cc14b+$cc14c;
        } else {
            $cc14 = $cc14a;
        }

        $val = $cc0+$cc1+$cc2+$cc3+$cc4+$cc5+$cc6+$cc7+$cc8+$cc9+$cc10+$cc11+$cc12+$cc13+$cc14+$cc15;
        if (substr($val,1,1) !=0 ) {
            return 0;
        }
        return 1;
    }


# For 15 digit (Amex) cards
sub ver15 {
        $cc0 = substr($cardnumber,0,1);
        $cc1 = substr($cardnumber,1,1);
        $cc2 = substr($cardnumber,2,1);
        $cc3 = substr($cardnumber,3,1);
        $cc4 = substr($cardnumber,4,1);
        $cc5 = substr($cardnumber,5,1);
        $cc6 = substr($cardnumber,6,1);
        $cc7 = substr($cardnumber,7,1);
        $cc8 = substr($cardnumber,8,1);
        $cc9 = substr($cardnumber,9,1);
        $cc10 = substr($cardnumber,10,1);
        $cc11 = substr($cardnumber,11,1);
        $cc12 = substr($cardnumber,12,1);
        $cc13 = substr($cardnumber,13,1);
        $cc14 = substr($cardnumber,14,1);

        $cc1a = $cc1 * 2;
        $cc3a = $cc3 * 2;
        $cc5a = $cc5 * 2;
        $cc7a = $cc7 * 2;
        $cc9a = $cc9 * 2;
        $cc11a = $cc11 * 2;
        $cc13a = $cc13 * 2;

        if ($cc1a >= 10) {
            $cc1b = substr($cc1a,0,1);
            $cc1c = substr($cc1a,1,1);
            $cc1 = $cc1b+$cc1c;
        } else {
            $cc1 = $cc1a;
        }
        if ($cc3a >= 10) {
            $cc3b = substr($cc3a,0,1);
            $cc3c = substr($cc3a,1,1);
            $cc3 = $cc3b+$cc3c;
        } else {
            $cc3 = $cc3a;
        }
        if ($cc5a >= 10) {
            $cc5b = substr($cc5a,0,1);
            $cc5c = substr($cc5a,1,1);
            $cc5 = $cc5b+$cc5c;
        } else {
            $cc5 = $cc5a;
        }
        if ($cc7a >= 10) {
            $cc7b = substr($cc7a,0,1);
            $cc7c = substr($cc7a,1,1);
            $cc7 = $cc7b+$cc7c;
        } else {
            $cc7 = $cc7a;
        }
        if ($cc9a >= 10) {
            $cc9b = substr($cc9a,0,1);
            $cc9c = substr($cc9a,1,1);
            $cc9 = $cc9b+$cc9c;
        } else {
            $cc9 = $cc9a;
        }
        if ($cc11a >= 10) {
            $cc11b = substr($cc11a,0,1);
            $cc11c = substr($cc11a,1,1);
            $cc11 = $cc11b+$cc11c;
        } else {
            $cc11 = $cc11a;
        }
        if ($cc13a >= 10) {
            $cc13b = substr($cc13a,0,1);
            $cc13c = substr($cc13a,1,1);
            $cc13 = $cc13b+$cc13c;
        } else {
            $cc13 = $cc13a;
        }

        $val = $cc0+$cc1+$cc2+$cc3+$cc4+$cc5+$cc6+$cc7+$cc8+$cc9+$cc10+$cc11+$cc12+$cc13+$cc14;
        if (substr($val,1,1) !=0 ) {
            return 0;
        }
        return 1;
    }


}



sub get_file {
  local($filename)=@_;
  @sp=split(/\\/,$filename);
  $file=$sp[$#sp];
  return $file;
}


sub Parse_Multi {
    local($boundary,@pairs,$position);
    local($raw_data,$value,$name,$part);

    $raw_data = $buffer;
    ($boundary = $ENV{CONTENT_TYPE}) =~ s/^.*boundary=(.*)$/\1/;
    @pairs = split(/--$boundary/, $raw_data);

    @pairs = splice(@pairs,1,$#pairs-1);

    for $part (@pairs) {
      $part =~ s/[\r]\n$//g;

      ($dump, $firstline, $datas) = split(/[\r]\n/, $part, 3);

      next if $firstline =~ /filename=\"\"/;
      $firstline =~ s/^Content-Disposition: form-data; //;
      (@columns) = split(/;\s+/, $firstline);
      ($name = $columns[0]) =~ s/^name="([^"]+)"$/\1/g;

      if ($#columns > 0) {
	if ($datas =~ /^Content-Type:/) {
	  ($CGI{"$name"}->{'Content-Type'}, $blankline, $datas) = split(/[\r]\n/, $datas, 3);
          $CGI{"$name"}->{'Content-Type'} =~ s/^Content-Type: ([^\s]+)$/\1/g;
	}
	else {
	  ($blankline, $datas) = split(/[\r]\n/, $datas, 2);
	  $CGI{"$name"}->{'Content-Type'} = "application/octet-stream";
	}
      }
      else {
	($blankline, $datas) = split(/[\r]\n/, $datas, 2);
        if (grep(/^$name$/, keys(%CGI))) {
          if (@{$CGI{$name}} > 0) {
            push(@{$CGI{$name}}, $datas);
          }
          else {
            $arrvalue = $CGI{$name};
            undef $CGI{$name};
            $CGI{$name}[0] = $arrvalue;
            push(@{$CGI{$name}}, $datas);
          }
        }
        else {
	  next if $datas =~ /^\s*$/;
          $CGI{"$name"} = $datas;
        }
        next;
      }
      for $currentColumn (@columns) {
        ($currentHeader, $currentValue) = $currentColumn =~ /^([^=]+)="([^"]+)"$/;
        $CGI{"$name"}->{"$currentHeader"} = $currentValue;
      }
      $CGI{"$name"}->{'Contents'} = $datas;
    }
    return ($CGI{"UploadedFile"}->{'Contents'},$CGI{"UploadedFile"}->{'filename'});
}





