#!/usr/bin/perl -w
#
# Programm zur Verwaltung von Hardware
#
# Naeheres siehe Webseite.
#
# Michael Schaarwaechter 
# Michael.Schaarwaechter@ub.uni-dortmund.de
#

use strict;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use CGI qw(:standard);
use DBI;
use Date::Calc qw(:all);
use Data::Dumper;   # Nur fuer Entwicklung
use File::Basename;
use Digest::MD5 qw(md5_hex);
&Language(Decode_Language("Deutsch"));

our $programinfo="Programm von ".localtime((stat($0))[9]).", Programmgr&ouml;&szlig;e ".(stat($0))[7]." Bytes";
our $version=" 1.4, 9/05";
our $author=q#<a href="mailto:Michael.Schaarwaechter@ub.uni-dortmund.de">Michael Schaarw&auml;chter</a>#;


############### Konfig ab hier ###############################

# Die Authentifizierung des Programmes gegenueber MySQL und die Angabe des MySQL-Servers:
our $dbuser = "hardware";           # User in MySQL
our $dbpassword = "daspasswort";          # zugehoeriges Passwort. 
our $dbhost = "localhost";          # MySQL-Server
our $db = "hardware";               # Name der Datenbank
our $dbport = "3306";               # MySQL-Port

our $dokupath = "/export/hardware-db";  # Pfad zu den Dokumenten
                                        # Achtung: Owner = User, unter dem der Webserver laeuft. Bei Suse wwwrun
                                        # Achtung: Nicht innerhalb von documentroot des Webservers anlegen.
our $maxfilesize = 200000000;         # Maximale Dateigroesse einer Datei im dokupath in Bytes
our $maxdoksinpulldown= 50;           # Maximale Anzahl Dokumente in Pulldownmenue (plus die, die als "zeigeimmer" gespeichert sind!)

our $loglevel=2;                    # Wieviel soll geloggt werden. 0=nix, 1=Schreibvorgaenge, 2=alles, 3=alles plus jeden Aufruf mit Parametern
                                    # Achtung: 3 bedeutet, dass Passworte im Klartext geloggt werden!!! Nie im Produktionsbetrieb anwenden.

our $cssurl="";                     # Optional: Url des CSS
our $background="";                 # Optional: Url des Hintergrundbildes

our $eigeneurl='/cgi-bin/hardware.pl';   # Eigene URL
our $eigeneurl2show='https://mein.server.tld/hw-db';   # URL, die angezeigt wird
our $logouturl=$eigeneurl;          # URL, zu der nach Logout gesprungen wird

our $pwd_minlenght=5;               # Minimale Passwortl&auml;nge
our $showloglength=300;             # Anzahl der angezeigten Logeintraege (mehr nur ausserhalb des Programmes)

our $iconpath='http://misc.ub.uni-dortmund.de/myicons';  # Pfad zu den Icons
our $ico_link=$iconpath.'/Hammer.ico';  # Link zum ICO-Icon
# Die anderen Icons sind fest verdrahtet. Sollten sie jemanden stoeren: Man kann sie
# im Quelltext alle finden, indem man nach $iconpath sucht: Steht vor jeder Stelle,
# an der ein Icon verwendet wurde.

our $sid_livetime=7200;             # Lebenszeit einer SID ohne Aktion
our $rowsperpage=70;                # Zeilen pro Seite bei Listen

# Folgend laesst sich die Statusauswahl definieren. 
# Achtung: Der Index 4 wird fuer verschrottete Datensaetze benutzt,
# Index 0 fuer Standort $netzzentrale
our @statusmenueeintraege=(
                  "Reserve",
                  "In Betrieb",
                  "Defekt",
                  "Zu prüfen",
                  "Exventarisiert",
                  "Verliehen",
                  "Reklamiert",
                  "In Reparatur"
                 ); 
# Folgend: Der String, der fuer den Lagerstandort steht.
our $netzzentrale = "Netzzentrale";
############## Konfig bis hier ###############################

our $dbh;            # Globales DB-Handle
our $g_user_id=0;    # Globale Userid der aktuellen Session
our $g_session_id=0; # Globale Sessionid der aktuellen Session
our $query=new CGI;
our $g_loggedin=0;   # Global: Ist jemand eingeloggt?
our $g_vorname="";   # Global: Vorname des Users
our $g_nachname="";  # Global: Nachname des Users
our $zurueck=qq#<table><tr><td><a href="javascript:history.back()"><img src="$iconpath/ArrowLeft2.gif"></a></td>
                           <td><a href="javascript:history.back()">Zur&uuml;ck</a></td></tr></table>#;
our $hauptmenue=qq#<table><tr><td><a href="$eigeneurl"><img src="$iconpath/ArrowRight2.gif"></a></td>
                       <td><a href="$eigeneurl">Zur&uuml;ck zum Hauptmen&uuml;</a></td></tr></table>#; # wird unten nochmal definiert wg sessionid
our $org_eigeneurl=$eigeneurl;  # Sichern, weil $eigeneurl mit Session-ID versetzt wird

# -------------------------
sub openconnection {
   $dbh = DBI->connect("DBI:mysql:database=$db;host=$dbhost;port=$dbport",$dbuser,$dbpassword)
      or die "Could not connect: $DBI::errstr\n";
}
# -------------------------
sub closeconnection {
   $dbh->disconnect;
}
# -------------------------
sub stopprog {
   &closeconnection;
   exit;
}
# -------------------------
sub datum {

   my @time;
   @time=localtime;

   my $y=$time[5]+1900;
   my $m=$time[4]+1;
   my $d=$time[3];
   my $hour=$time[2];
   my $min=$time[1];
   my $sec=$time[0];
   $sec="0".$sec if (length($sec)==1);
   $min="0".$min if (length($min)==1);
   $hour="0".$hour if (length($hour)==1);
   $d="0".$d if (length($d)==1);
   $m="0".$m if (length($m)==1);

   return $d.".".$m.".".$y." ".$hour.":".$min.":$sec";
}
# -------------------------
sub getdtfromstring {
   my ($dt) = @_;

   if (length($dt) > 14) {
      # 2003-11-05 18:07:00
      my $y = substr ($dt,0,4);
      my $m = substr ($dt,5,2);
      my $d = substr ($dt,8,2);
      my $ho = substr ($dt,11,2);
      my $mi = substr ($dt,14,2);
      my $se = substr ($dt,17,2);
      return ($y,$m,$d,$ho,$mi,$se);
   } else {
      # 20050304104136
      my $y = substr ($dt,0,4);
      my $m = substr ($dt,4,2);
      my $d = substr ($dt,6,2);
      my $ho = substr ($dt,8,2);
      my $mi = substr ($dt,10,2);
      my $se = substr ($dt,12,2);
      return ($y,$m,$d,$ho,$mi,$se);
   }
}
# -------------------------
sub log {
   # Erstellt Eintrag in Logdatei, abhaengig vom Loglevel
   my ($level,$aktion,$detail)=@_;
   $detail=($detail or "-");
   return if ($loglevel < $level);

   if ($detail eq "listofparams") {
      $detail="";
      my @names = $query->param;
      foreach my $name(@names) {
         $detail.=$name."=".$query->param($name).", ";
      }
   }
   my $sth = $dbh->prepare( q{
         insert into log (log_host,log_sessionid,log_user_id,log_aktion,log_detail) values (?,?,?,?,?)
                             } ) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute($query->remote_host(),$g_session_id,$g_user_id,$aktion,$detail) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
}
# -------------------------
sub ausgabestart {
   my $title = (shift or "Hardwaredatenbank");

   print $query->header;

   my $css="";
   $css=qq#<link rel="stylesheet" type="text/css" href="$cssurl"># if $cssurl;

   print << "EOT";
             <!DOCTYPE  HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
             <html>
             <head>
                <TITLE>$title</TITLE>
                <link rel="SHORTCUT ICON" href="$ico_link">
                <META NAME="author" CONTENT="$0, $version, Michael Schaarwaechter">
                <META NAME="copyright" CONTENT="Michael Schaarwaechter">
                <META CONTENT="text/html; charset=iso-8859-1" HTTP-EQUIV="Content-Type">
                <style type="text/css"> <!--
                   /*  spezielle CSS-Formate */
                   body {
                         font-family:Helvetica,Arial,sans-serif;
                         font-size:medium;
                         background-color:#FFFFFF;
                         background-image:url($iconpath/hardware.gif);
                         background-repeat:no-repeat; 
                         background-attachment:fixed;
                         background-position:right;
                        }
                   h1 {
                         font-size:x-large;
                        }
                   h2 {
                         font-size:large;
                        }
                   h3 {  font-size:larger;
                        }
                   th { white-space:nowrap;
                      }
                   .klein {
                         font-size:75%;
                        }
                   .frage {
                         font-size:125%;
                         color:#CC6699;
                         margin-left:5%;
                        }
                   .antwort {
                         font-size:100%;
                         margin-left:1%;
                        }
                   .nowrap {
                          white-space:nowrap;
                        }
                   img {
                         border:none;
                        }
                   .logo {
                         font-size:xx-large;
                         color:#6699CC;
                         letter-spacing:5pt;
                         border-bottom-width:3px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         margin-right:30%;
                         margin-top:0%;
                        }
                   hr {
                         color:#6699CC;
                        }
                   .rechts {
                         text-align: right;
                        }
                   .signatur {
                         text-align: right;
                         font-size:small;
                         border-top-width:3px;
                         border-top-style:solid;
                         border-top-color:#6699CC;
                         margin-left:30%;
                        }
                   .fuell10 {
                         margin-top:9em;
                         margin-bottom:0px;
                        }
                   .pgrau {
                         background:#EEEEEE;
                         margin-top:0em;
                         margin-bottom:0px;
                        }
                   .pnorm {
                         margin-top:0em;
                         margin-bottom:0px;
                        }
                   .links {
                         text-align: left;
                        }
                   .center {
                         width: 50%; 
                         margin-left: auto; 
                         margin-right: auto;
                        }
                   #rand10 {
                         margin-left:10%;
                         margin-right:10%;
                        }
                   .fixed {
                         font-family:Courier,monospace;
                        }
                   .rot {
                         color:red;
                        }
                   .gruen {
                         color:green;
                        }
                   .bggelb {
                         background: yellow;
                        }
                   .bggruen {
                         background: #B3E6C2;
                        }
                   .bgrot {
                         background: red;
                        }
                   .bghellblau {
                         background: #ECF2F9;
                        }
                   .bgorange {
                         background: #FFE600;
                        }
                   .bggrau {
                         background: #DADADA;
                        }
                   .rahmen { 
                         border-width:1px;
                         border-style:solid;
                         border-color:#6699CC;
                        }
                   .help {
                         color:#CC6676;
                        }
                   .ru {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         border-right-width:1px;
                         border-right-style:solid;
                         border-right-color:#6699CC;
                         font-size:75%;
                        }
                    .bggrau_ru {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         border-right-width:1px;
                         border-right-style:solid;
                         border-right-color:#6699CC;
                         font-size:75%;
                         background: #CC9966;
                        }
                    #formklein {font-size:75%;}
                    .u {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         font-size:75%;
                        }
                    .urechts {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         font-size:75%;
                         text-align: right;
                        }
                    .k {
                         font-size:85%;
                        }
                    .beschriftung {
                         border-bottom-width:1px;
                         border-bottom-style:solid;
                         border-bottom-color:#6699CC;
                         font-size:95%;
                         background:#66CC85;
                        }
                 --> </style>
                  $css
             </head>
             <body>
EOT
}
# -------------------------
sub ausgabeende {

   my $prog=basename($0);
   print qq#<p class="signatur">Erzeugt von $prog, Version $version ($author) am #.&datum.qq#<br>$programinfo</p># ;
   print $query->end_html;
}
# -------------------------
sub fehler {
   my $fehler=shift;

   &ausgabestart;

   print qq#
            <p class="logo">Hardware-DB - <span class="rot">Fehler</span></p>
            <div id="rand10">
            <p class="fuell10"><span class="rot">$fehler</span></p>
            </div>
            <p class="fuell10">&nbsp;</p> 
   #;
   &ausgabeende;
   &stopprog;
}
# -------------------------
sub datefromtimestamp {
   my $t=shift;
   return substr($t,6,2) . "." .
          substr($t,4,2) . "." .
          substr($t,0,4) . ", " . 
          substr($t,8,2) . ":" .
          substr($t,10,2) . ":" .
          substr($t,12,2);
}
# -------------------------
sub newsessionid {

   my $remotehost=$query->remote_host();
   my ($y,$m,$d,$ho,$mi,$se) = Date::Calc::Today_and_Now;

   my $sth = $dbh->prepare( q{
      insert into sessions (s_sessionid,s_user_id,s_lastseen,s_remotehost) values (?,?,?,?)
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $g_session_id=int(rand(99999999)).$y.$m.$d.$ho.$mi.$se;
   $sth->execute($g_session_id,$g_user_id,($y."-".$m."-".$d." ".$ho.":".$mi.":".$se),$remotehost)
         or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   $eigeneurl=$eigeneurl."?sid=$g_session_id";
   &log(2,"Neue Session-ID $g_session_id vergeben");
}
# -------------------------
sub validatesid {

   my $sid=$query->param("sid");
   my ($lastseen,$user_id,$remotehost);
   # $g_user_id ist global!

   # Holen des Eintrages zur Sessionid aus der Tabelle
   my $sth = $dbh->prepare( q{
      select s_lastseen,s_user_id,s_remotehost from sessions where s_sessionid=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($sid) or die "Can't execute statement: $DBI::errstr";
   ($lastseen,$user_id,$remotehost) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   &log(1,"Sid $sid nicht in der Datenbank, Zugriff verweigert.") if ($rc == 0);
   return 0 if ($rc == 0);  # Keine sid da

   # Pruefen, ob Lebenszeit der sid erloschen ist oder anderer host mit selber sid

   my ($y,$m,$d,$ho,$mi,$se) = Date::Calc::Today_and_Now;
   my ($sy,$sm,$sd,$sho,$smi,$sse) = &getdtfromstring($lastseen);

   my ($dy,$dm,$dd,$dho,$dmi,$dse) = Date::Calc::Delta_YMDHMS($y,$m,$d,$ho,$mi,$se,$sy,$sm,$sd,$sho,$smi,$sse);
   if (
         (Date::Calc::Date_to_Time($sy,$sm,$sd,$sho,$smi,$sse)
                + $sid_livetime <
                Date::Calc::Date_to_Time($y,$m,$d,$ho,$mi,$se))
         or
         ($remotehost ne $query->remote_host())
      ) {  # sid ist da aber expired oder anderer host als in sid gespeichert
      my $sth = $dbh->prepare( q{
         delete from sessions where s_sessionid=?
                             } )
         or die "Can't prepare statement: $DBI::errstr";
      $sth->execute($sid) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      &log(1,"Sid $sid geloescht, weil unter anderem Hostnamen $remotehost gespeichert");
      return 0;
   }

   if ($user_id) {
      $g_loggedin=1;
      $g_user_id=$user_id;
      $sth = $dbh->prepare( q{
      select user_vorname,user_nachname,user_isblocked from user where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
      my $rc = $sth->execute($g_user_id) or die "Can't execute statement: $DBI::errstr";
      my $user_isblocked=0;
      ($g_vorname,$g_nachname,$user_isblocked) = $sth->fetchrow_array if ($rc != 0);
      $sth->finish;   
      if ($user_isblocked) {    # User ist nach dem Einloggen geblockt worden
	 &log("Blockierter Benutzer $g_user_id ausgeloggt");
	 &logout;
	 &fehler("Ihr Account wurde geblockt, Sie wurden ausgeloggt.");
	 &stopprog;
      }
   }

   # Alles i.O.: lastseen der sid updaten
   $sth = $dbh->prepare( q{
      update sessions set s_lastseen=? where s_sessionid=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($y."-".$m."-".$d." ".$ho.":".$mi.":".$se,$sid) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;

   $eigeneurl.="?sid=".$sid;
   $g_session_id=$sid;
   return 1;
}
# -------------------------
sub cleansids {

   my $ausgabe=shift;     # Textausgabe ueber geloeschte SIDs oder nicht
   my @todelete;
   my $count=0;
   my ($sid,$lastseen,$userid,$remotehost);

   # Holen alles sids aus der Tabelle
   my $sth = $dbh->prepare( q{
      select s_sessionid,s_lastseen,s_user_id,s_remotehost from sessions
                          } )
   or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute or die "Can't execute statement: $DBI::errstr";
   my ($y,$m,$d,$ho,$mi,$se) = Date::Calc::Today_and_Now;
   my ($sy,$sm,$sd,$sho,$smi,$sse);
   while (($sid,$lastseen,$userid,$remotehost) = $sth->fetchrow_array) {
       ($sy,$sm,$sd,$sho,$smi,$sse) = &getdtfromstring($lastseen);
       if ( Date::Calc::Date_to_Time($sy,$sm,$sd,$sho,$smi,$sse)
            + $sid_livetime <
            Date::Calc::Date_to_Time($y,$m,$d,$ho,$mi,$se)) {
          push @todelete,$sid;
          &log(2,"Sid $sid von Userid $userid, $remotehost ist zu alt (Lastseen=$lastseen): geloescht.");
       }

   }
   $sth->finish;
   $sth =  $dbh->prepare( q{
      delete from sessions where s_sessionid=?
                          } )
   or die "Can't prepare statement: $DBI::errstr";

   foreach $sid(@todelete) {
      $rc = $sth->execute($sid);
      $count++ if $rc;
   }
   $sth->finish;
   &log(2,"$count alte Session-IDs geloescht") if ($count);
   print "<h2>$count alte Session-IDs gel&ouml;scht.</h2>\n" if ($ausgabe);
}
# -------------------------
sub loginmaske {
   my $text=shift || "";
   
   &ausgabestart("Hardware-DB - Bitte einloggen");
   print qq#<p class="logo">Hardware-DB - Login</p>
            <div id="rand10">
            <p class="fuell10"><span class="rot">$text&nbsp;</span></p>
            <p><span class="bggelb">Bitte einloggen</span></p>
            <form action="$eigeneurl" method="post">
            <input type="hidden" name="sid" value="$g_session_id">
            <input type="hidden" name="login" value="1">
            <table class="rahmen">
               <tr>
                  <td class="rechts">Benutzername</td><td><input type="text" size="20" name="account"></td>
               </tr>
               <tr>
                  <td class="rechts">Passwort</td><td><input type="password" size="20" name="passwort"></td>
               </tr>
               <tr><td>&nbsp;</td><td><input type="submit" value="Abschicken"></td>
            </table>
            <p>Wenn Sie auf diese Seite eine Bookmark/ein Lesezeichen<br>setzen m&ouml;chten, verwenden Sie bitte
            die reine URL ohne die Session-ID:<br> $eigeneurl2show</p>
            </div>
            </form>
            <p class="fuell10">&nbsp;</p>
           #;
   &ausgabeende;
}
# -------------------------
sub getuserflag {
   # Holt Status des uebergebenen Flags zu aktuellem User
   my $flag=shift;
   my $return=0;

   my $sth = $dbh->prepare( qq{
      select $flag from user where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($g_user_id) or die "Can't execute statement: $DBI::errstr";
   ($return) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   return $return;
}
# -------------------------
sub getuseraccount {
   my $id=shift;
   my $return=0;

   my $sth = $dbh->prepare( qq{
      select user_account from user where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
   ($return) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   return $return;
}
# -------------------------
sub zeigelogdaten {

   my ($log_zeitstempel,$log_host,$log_user_id,$log_aktion);
   &log(2,"Logdatenansicht");
   &ausgabestart;
   print qq#<p class="logo">Hardware-DB - Logdaten</p>
            <p>$zurueck</p>
            <table class="rahmen">
            <tr>
               <th class="rahmen">Zeit</th>
               <th class="rahmen">User</th>
               <th class="rahmen">Host</th>
               <th class="rahmen">Aktion</th>
            </tr>
           #;
   my $sth = $dbh->prepare( qq{
      select 
             log_zeitstempel,
             log_host,
             log_user_id,
             log_aktion
         from log order by log_zeitstempel DESC limit $showloglength
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute or die "Can't execute statement: $DBI::errstr";
   my $color="";
   while ( ($log_zeitstempel,$log_host,$log_user_id,$log_aktion)=$sth->fetchrow_array) {
      $log_zeitstempel=&datefromtimestamp($log_zeitstempel);
      $log_user_id=&getuseraccount($log_user_id) if ($log_user_id);
      $color="";
      $color="gruen" if ($log_aktion=~/^Login/);
      $color="rot" if ($log_aktion=~/^Logout/);
      print qq#
              <tr>
                 <td class="ru">$log_zeitstempel</td>
                 <td class="ru">$log_user_id</td>
                 <td class="ru">$log_host</td>
                 <td class="ru"><span class="$color">$log_aktion</span></td>
              </tr>
              #;
   }
   print qq#<tr>
            <td colspan="4"><span class="rot">
                   Es werden nur die letzten $showloglength Eintr&auml;ge gelistet. Weitere nur per Direktzugriff auf die DB.
            </span></td>
            </tr>
            </table>
           #;
   $sth->finish;
   &ausgabeende;
}
# -------------------------
sub loggedin {
   # Gibt Sessionid zurueck, wenn uebergebene Userid eingeloggt ist. Sonst 0.
   my $userid=shift;

   my $return=0;

   my $sth = $dbh->prepare( qq{
      select s_id from sessions where s_user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($userid) or die "Can't execute statement: $DBI::errstr";
   ($return) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   return $return;
}
# -------------------------
sub authentificate {
# Authentifiziert User aus Loginmaske. Setzt, wenn ok, globale g_loggedin und g_user_id

   return "Leeres Passwort nicht erlaubt." if (not $query->param("passwort"));
   return "Bitte Benutzernamen angeben." if (not $query->param("account"));
   my $passwort=md5_hex($query->param("passwort"));
   my $account=$query->param("account");
   my $sth = $dbh->prepare( q{
      select user_id,user_vorname,user_nachname,user_passwort,user_isblocked from user where user_account=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($account) or die "Can't execute statement: $DBI::errstr";
   my ($user_id,$user_vorname,$user_nachname,$user_passwort,$user_isblocked) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   return "Passwort falsch oder Account existiert nicht." if (not ($passwort eq $user_passwort));
   return "Account ist blockiert." if ($user_isblocked);
   $g_user_id=$user_id;
   $g_loggedin=1;
   $g_vorname=$user_vorname;
   $g_nachname=$user_nachname;
   $sth = $dbh->prepare( q{
      update sessions set s_user_id=? where s_sessionid=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($g_user_id,$g_session_id) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   $sth = $dbh->prepare( q{
      update user set user_logincount=user_logincount+1, user_lastlogin=? where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my ($y,$m,$d,$ho,$mi,$se) = Date::Calc::Today_and_Now;
   $rc = $sth->execute($y."-".$m."-".$d." ".$ho.":".$mi.":".$se,$g_user_id) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   &log(1,"Login User_id $g_user_id");
   return "OK";
}
# -------------------------
sub logout {
   my $sth = $dbh->prepare( q{
      delete from sessions where s_sessionid=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute($g_session_id) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   &log(1,"Logout User_id $g_user_id, Session-ID $g_session_id");
}
# -------------------------
sub userliste {
   &ausgabestart;
   print qq{<p class="logo">Hardware-DB - Userliste</p>
            <p>$zurueck</p>
            <table class="rahmen">
            <tr>
               <th class="rahmen">ID</th>
               <th class="rahmen">Account</th>
               <th class="rahmen">Name</th>
               <th class="rahmen">Bemerkung</th>
               <th class="rahmen">User darf ...</th>
               <th class="rahmen">Logins</th>
               <th class="rahmen">Letztes Login</th>
               <th class="rahmen">Eingeloggt?</th>
            </tr>
           };

   my (      $user_id,
             $user_account,
             $user_vorname,
             $user_nachname,
             $user_bem,
             $user_logincount,
             $user_lastlogin,
             $user_isadmin,
             $user_readonly,
             $user_canviewhw,
             $user_canviewuser,
             $user_canchangehispwd,
             $user_canchangeuser,
             $user_canchangehw,
             $user_canaddhw,
             $user_canviewlog);

   my $sth = $dbh->prepare( q{
      select 
             user_id,
             user_account,
             user_vorname,
             user_nachname,
             user_bem,
             user_logincount,
             user_lastlogin,
             user_isadmin,
             user_readonly,
             user_canviewhw,
             user_canviewuser,
             user_canchangehispwd,
             user_canchangeuser,
             user_canchangehw,
             user_canaddhw,
             user_canviewlog
                              from user where user_isblocked=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute("0") or die "Can't execute statement: $DBI::errstr";
  
   my $loggedinhtml="";
   while (  ($user_id,
             $user_account,
             $user_vorname,
             $user_nachname,
             $user_bem,
             $user_logincount,
             $user_lastlogin,
             $user_isadmin,
             $user_readonly,
             $user_canviewhw,
             $user_canviewuser,
             $user_canchangehispwd,
             $user_canchangeuser,
             $user_canchangehw,
             $user_canaddhw,
             $user_canviewlog) = $sth->fetchrow_array) {
      print qq#
             <tr>
                <td class="ru">$user_id</td>
                <td class="ru">$user_account</td>
                <td class="ru">$user_vorname $user_nachname</td>
                <td class="ru">$user_bem</td>
                <td class="ru">#;
      print qq#<span class="gruen"><b>Alles=Admin</b></span><br># if ($user_isadmin);
      if (not $user_isadmin) {
         print qq#<span class="rot">Read only</span><br># if ($user_readonly);
         if (not $user_readonly) {
            print qq#<span class="gruen">User &auml;ndern</span><br># if ($user_canchangeuser);
            print qq#<span class="rot">  User nicht &auml;ndern</span><br># if (not $user_canchangeuser);
            print qq#<span class="gruen">HW &auml;ndern</span><br># if ($user_canchangehw);
            print qq#<span class="rot">  HW nicht &auml;ndern</span><br># if (not $user_canchangehw);
            print qq#<span class="gruen">HW zuf&uuml;gen</span><br># if ($user_canaddhw);
            print qq#<span class="rot">  HW nicht zuf&uuml;gen</span><br># if (not $user_canaddhw);
         }
         print qq#<span class="gruen">User ansehen</span><br># if ($user_canviewuser);
         print qq#<span class="rot">  User nicht ansehen</span><br># if (not $user_canviewuser);
         print qq#<span class="rot">  HW nicht ansehen</span><br># if (not $user_canviewhw);
         print qq#<span class="gruen">HW ansehen</span><br># if ($user_canviewhw);
         print qq#<span class="gruen">Passwort &auml;ndern</span><br># if ($user_canchangehispwd);
         print qq#<span class="rot">Passwort nicht &auml;ndern</span><br># if (not $user_canchangehispwd);
         print qq#<span class="gruen">Log ansehen</span><br># if ($user_canviewlog);
         print qq#<span class="rot">  Log nicht ansehen</span><br># if (not $user_canviewlog);
      }
      $loggedinhtml=qq#<td class="ru"><img src="$iconpath/Sleeping.gif"></td>#;
      $loggedinhtml=qq#<td class="ru"><img src="$iconpath/Working.gif"></td># if &loggedin($user_id);

      print qq#</td>
               <td class="ru">$user_logincount</td>
               <td class="ru">$user_lastlogin</td>
               $loggedinhtml
             </tr>
              #;
   }
   $sth->finish;

   print qq{</table></div>
           };
   &ausgabeende;
   &log(2,"Userliste");
}
# -------------------------
sub getoptionlines {
   # Gibt Optinenzeilen mit entsprechendem selected zurueck, nur fuer sub userverwaltung
   my ($texta,$textb,$val)=@_;
   my ($sela,$selb)=("","");
   $sela="selected" if ($val);
   $selb="selected" if (not $val);
   return qq#
               <option $sela value="1">$texta</option>
               <option $selb value="0">$textb</option>
            #;
}
# -------------------------
sub userverwaltung {
   my $text=shift || "";

   $text=qq#<table class="rahmen"><tr>
                <td><a href="$eigeneurl"><img src="$iconpath/Note.gif"></a></td><td><a href="$eigeneurl"><span class="bggruen">$text</span></a></td>
            </tr></table>
           # if $text;


   my (   $user_id, 
          $user_account, 
          $user_vorname, 
          $user_nachname, 
          $user_passwort, 
          $user_bem, 
          $user_logincount, 
          $user_lastlogin, 
          $user_isadmin, 
          $user_readonly, 
          $user_isblocked, 
          $user_canviewhw, 
          $user_canviewuser, 
          $user_canchangehispwd, 
          $user_canchangeuser, 
          $user_canchangehw, 
          $user_canaddhw, 
          $user_canviewlog );

   my $sth = $dbh->prepare( q{
      select
             user_id,
             user_account,
             user_vorname,
             user_nachname,
             user_passwort, 
             user_bem,
             user_logincount,
             user_lastlogin,
             user_isadmin,
             user_readonly,
             user_isblocked,
             user_canviewhw,
             user_canviewuser,
             user_canchangehispwd,
             user_canchangeuser,
             user_canchangehw,
             user_canaddhw,
             user_canviewlog
                              from user 
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   &ausgabestart;
   print qq{<p class="logo">Hardware-DB - Userverwaltung</p>
            <p>
            $text
            $hauptmenue;
            Berechtigungen:
            <ul>
            <li>Wenn ein User Admin ist, sind alle anderen Berechtigungen irrelevant</li>
            <li>Ansonsten gilt:<br>
            <ul>
            <li>Wenn ein User blockiert ist, taucht er nur auf dieser Seite auf und darf sich nicht einloggen.</li>
            <li>Wenn ein User Readonly ist, gelten alle anderen "darf schreiben" nicht.</li>
            <li>Wenn ein User Schreibrecht auf Hardware oder Usertabelle hat, darf er automatisch auch Entsprechendes lesen.</li>
            </ul></li>
            </ul>
            User werden nicht gel&ouml;scht sondern lediglich blockiert. Das L&ouml;schen ist nur auf Datenbankebene m&ouml;glich.<br>
            <span class="bggelb">User hinzuf&uuml;gen am Ende der Tabelle.</span>
            </p>
            <table class="rahmen"
            <tr>
            <th class="rahmen">ID</td>
            <th class="rahmen">Account</td>
            <th class="rahmen">Vor- und Nachname</th>
            <th class="rahmen">Bemerkung</th>
            <th class="rahmen">Berechtigungen</th>
            <th class="rahmen">Aktionen</th>
            </tr>
           };
  

   while (  ($user_id,
             $user_account,
             $user_vorname,
             $user_nachname,
             $user_passwort, 
             $user_bem,
             $user_logincount,
             $user_lastlogin,
             $user_isadmin,
             $user_readonly,
             $user_isblocked,
             $user_canviewhw,
             $user_canviewuser,
             $user_canchangehispwd,
             $user_canchangeuser,
             $user_canchangehw,
             $user_canaddhw,
             $user_canviewlog) = $sth->fetchrow_array) {

   
      print qq# <form action="$eigeneurl" method="post">
		<input type="hidden" name="sid" value="$g_session_id">
		<input type="hidden" name="userdatensatz" value="$user_id">
                <input type="hidden" name="olduser_passwort" value="$user_passwort">
		   <tr>
		      <td class="u">$user_id</td>
		      <td class="u">
			 <input class="k" type="text" name="user_account" value="$user_account" size="10">
		      </td>
		      <td class="u">
			 <input class="k" type="text" name="user_vorname"  value="$user_vorname"  size="10">
			 <input class="k" type="text" name="user_nachname" value="$user_nachname" size="15">
		      </td>
		      <td class="u">
			 <textarea cols="20" rows="15" name="user_bem">$user_bem</textarea>
		      </td>
		      <td class="u">
	      #;
      print qq#<select class="k" size="1" name="user_isadmin">#;
      print &getoptionlines("Ist Admin","Kein Admin",$user_isadmin);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_isblocked">#;
      print &getoptionlines("Blockiert","Darf sich einloggen",$user_isblocked);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_readonly">#;
      print &getoptionlines("Readonly","Nicht readonly",$user_readonly);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_canchangehispwd">#;
      print &getoptionlines("Darf sein PWD &auml;ndern","Darf sein PWD nicht &auml;ndern",$user_canchangehispwd);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_canviewhw">#;
      print &getoptionlines("Darf HW ansehen","Darf HW nicht ansehen",$user_canviewhw);
      print qq#</select><br>#;
      print qq#<select class="k" size="1" name="user_canchangehw">#;
      print &getoptionlines("Darf HW &auml;ndern","Darf HW nicht &auml;ndern",$user_canchangehw);
      print qq#</select><br>#;
      print qq#<select class="k" size="1" name="user_canaddhw">#;
      print &getoptionlines("Darf HW zuf&uuml;gen","Darf HW nicht zuf&uuml;gen",$user_canaddhw);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_canviewuser">#;
      print &getoptionlines("Darf Userliste ansehen","Darf Userliste nicht ansehen",$user_canviewuser);
      print qq#</select><br>#;
      print qq#<select class="k" size="1" name="user_canchangeuser">#;
      print &getoptionlines("Darf User &auml;ndern","Darf User nicht &auml;ndern",$user_canchangeuser);
      print qq#</select><br><hr>#;
      print qq#<select class="k" size="1" name="user_canviewlog">#;
      print &getoptionlines("Darf Logdaten ansehen","Darf Logdaten nicht ansehen",$user_canviewlog);
      print qq#</select><br>#;
      print qq#       </td>
		      <td class="u"> 
                         Neues Passwort vergeben:<br>
                         <input class="k" type="password" name="user_passwort" size="10">
                         <hr>
			 Diese Zeile:<br>
			 <input class="k" type="submit" name="aendern" value="&Auml;nderungen speichern"><br><br>
		      </td>
		   </tr>
		</form>
	      #;
   } # ende while daten aus der sql-abfrage

   print qq{</table>
            <p>Neuer Datensatz:</p>
            <div id="formklein">
            <table class="rahmen">
            <tr>
            <th class="rahmen">ID</td>
            <th class="rahmen">Account</td>
            <th class="rahmen">Passwort</td>
            <th class="rahmen">Vor- und Nachname</th>
            <th class="rahmen">Bemerkung</th>
            <th class="rahmen">Berechtigungen</th>
            <th class="rahmen">Aktionen</th>
            </tr>
           };

   print qq# <form action="$eigeneurl" method="post">
             <input type="hidden" name="sid" value="$g_session_id">
             <input type="hidden" name="userdatensatz" value="neu">
                <tr>
                   <td class="bghellblau">Neu</td>
                   <td class="bghellblau">
                      <input class="k" type="text" name="user_account" value="" size="10">
                   </td>
                   <td class="bghellblau">
                      <input class="k" type="password" name="user_passwort" size="10">
                   </td>
                   <td class="bghellblau">
                      <input class="k" type="text" name="user_vorname"  value=""  size="10">
                      <input class="k" type="text" name="user_nachname" value="" size="15">
                   </td>
                   <td class="bghellblau">
                      <textarea cols="20" rows="15" name="user_bem"></textarea>
                   </td>
                   <td class="bghellblau">
           #;
   print qq#<select class="k" size="1" name="user_isadmin">#;
   print &getoptionlines("Ist Admin","Kein Admin",0);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_isblocked">#;
   print &getoptionlines("Blockiert","Darf sich einloggen",0);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_readonly">#;
   print &getoptionlines("Readonly","Nicht readonly",0);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_canchangehispwd">#;
   print &getoptionlines("Darf sein PWD &auml;ndern","Darf sein PWD nicht &auml;ndern",1);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_canviewhw">#;
   print &getoptionlines("Darf HW ansehen","Darf HW nicht ansehen",1);
   print qq#</select><br>#;
   print qq#<select class="k" size="1" name="user_canchangehw">#;
   print &getoptionlines("Darf HW &auml;ndern","Darf HW nicht &auml;ndern",1);
   print qq#</select><br>#;
   print qq#<select class="k" size="1" name="user_canaddhw">#;
   print &getoptionlines("Darf HW zuf&uuml;gen","Darf HW nicht zuf&uuml;gen",1);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_canviewuser">#;
   print &getoptionlines("Darf Userliste ansehen","Darf Userliste nicht ansehen",1);
   print qq#</select><br>#;
   print qq#<select class="k" size="1" name="user_canchangeuser">#;
   print &getoptionlines("Darf User &auml;ndern","Darf User nicht &auml;ndern",0);
   print qq#</select><br><hr>#;
   print qq#<select class="k" size="1" name="user_canviewlog">#;
   print &getoptionlines("Darf Logdaten ansehen","Darf Logdaten nicht ansehen",0);
   print qq#</select><br>#;
   print qq#       </td>
                   <td class="bghellblau">
                      Diese Zeile:<br>
                      <input class="k" type="submit" name="aendern" value="Neuen Eintrag speichern"><br><br>
                   </td>
                </tr>
             </form>
           #;
   print qq{</table></div>
           };
   &ausgabeende;
   &log(2,"Useraenderungsmaske");
}
# -------------------------
sub useraendern {

   my $message="";
   my $datensatz=$query->param("userdatensatz");
   my $sth;
   my $rc;
   my $got_one=0;
   my ($user_passwort,$user_canviewhw,$user_canchangehw,$user_canviewuser)=(0,0,0,0);
  
   &fehler("Useraccount darf nicht leer sein! $zurueck") if (not defined $query->param("user_account") or (not $query->param("user_account")));

   if ($datensatz eq "neu") {
      $sth = $dbh->prepare( q{
         select user_id from user where user_account=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("user_account")) or die "Can't execute statement: $DBI::errstr";
      ($got_one) = $sth->fetchrow_array if ($rc);
   } else {
      $sth = $dbh->prepare( q{
         select user_id from user where user_account=? and user_id<>?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("user_account"),$datensatz) or die "Can't execute statement: $DBI::errstr";
      ($got_one) = $sth->fetchrow_array if ($rc);
   }
   &fehler("Useraccount schon vorhanden. Bitte w&auml;hlen Sie einen anderen. $zurueck") if ($got_one);
   $sth->finish;

   $user_canviewhw=$query->param("user_canviewhw") || 0;
   $user_canchangehw=$query->param("user_canchangehw") || 0;
   $user_canviewuser=$query->param("user_canviewuser") || 0;

   $user_canviewhw=1 if ($query->param("user_canchangehw"));
   $user_canviewhw=1 if ($query->param("user_canaddhw"));
   $user_canchangehw=1 if ($query->param("user_canaddhw"));
   $user_canviewuser=1 if ($query->param("user_canchangeuser"));

   if ($datensatz eq "neu") {
      if (not defined $query->param("user_passwort")) {
         &fehler("Leeres Passwort nicht erlaubt! $zurueck");
      }
      $user_passwort=md5_hex($query->param("user_passwort"));
      $sth = $dbh->prepare( q{
         insert into user (
                      user_account,
                      user_passwort,
                      user_vorname,
                      user_nachname,
                      user_bem,
                      user_isadmin,
                      user_readonly,
                      user_isblocked,
                      user_canviewhw,
                      user_canviewuser,
                      user_canchangehispwd,
                      user_canchangeuser,
                      user_canchangehw,
                      user_canaddhw,
                      user_canviewlog)
                     values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
                         } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(
                      $query->param("user_account"),
                      $user_passwort,
                      $query->param("user_vorname"),
                      $query->param("user_nachname"),
                      $query->param("user_bem"),
                      $query->param("user_isadmin"),
                      $query->param("user_readonly"),
                      $query->param("user_isblocked"),
                      $user_canviewhw,
                      $user_canviewuser,
                      $query->param("user_canchangehispwd"),
                      $query->param("user_canchangeuser"),
                      $user_canchangehw,
                      $query->param("user_canaddhw"),
                      $query->param("user_canviewlog")
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      &log(2,"User ".$query->param("user_account")." mit der ID ".$query->param("userdatensatz")." zugefuegt.","listofparams");

   } else {
      $user_passwort=$query->param("olduser_passwort");
      $user_passwort=md5_hex($query->param("user_passwort")) if (defined($query->param("user_passwort")));
      $sth = $dbh->prepare( qq{
         update user set
                      user_account=?,
                      user_passwort=?,
                      user_vorname=?,
                      user_nachname=?,
                      user_bem=?,
                      user_isadmin=?,
                      user_readonly=?,
                      user_isblocked=?,
                      user_canviewhw=?,
                      user_canviewuser=?,
                      user_canchangehispwd=?,
                      user_canchangeuser=?,
                      user_canchangehw=?,
                      user_canaddhw=?,
                      user_canviewlog=?
             where user_id=?               } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(
                      $query->param("user_account"),
                      $user_passwort,
                      $query->param("user_vorname"),
                      $query->param("user_nachname"),
                      $query->param("user_bem"),
                      $query->param("user_isadmin"),
                      $query->param("user_readonly"),
                      $query->param("user_isblocked"),
                      $user_canviewhw,
                      $user_canviewuser,
                      $query->param("user_canchangehispwd"),
                      $query->param("user_canchangeuser"),
                      $user_canchangehw,
                      $query->param("user_canaddhw"),
                      $query->param("user_canviewlog"),
                      $datensatz
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      &log(2,"User ".$query->param("user_account")." mit der ID ".$query->param("userdatensatz")." geaendert.","listofparams");
   }

   return $message;
}
# -------------------------
sub passwortaenderungmaske {
   &ausgabestart;
   print qq#<p class="logo">Hardware-DB - Passwort&auml;nderung</p>
            <div id="rand10">
            <p class="fuell10">$zurueck<br>Passwort&auml;nderung f&uuml;r Benutzer <span class="rot">$g_vorname $g_nachname</span></p>
            <p><span class="bggelb">Bitte einmal das alte Passwort und zweimal das neue (mind $pwd_minlenght Zeichen) eingeben</span></p>
            <form action="$eigeneurl" method="post">
            <input type="hidden" name="sid" value="$g_session_id">
            <input type="hidden" name="neuespasswort" value="1">
            <table class="rahmen">
               <tr><td class="rechts">altes Passwort</td><td><input type="password" size="20" name="passwortalt"></td></tr>
               <tr><td class="rechts">neues Passwort</td><td><input type="password" size="20" name="passwortneu1"></td></tr>
               <tr><td class="rechts">neues Passwort</td><td><input type="password" size="20" name="passwortneu2"></td></tr>
               <tr><td>&nbsp;</td><td><input type="submit" value="Abschicken"></td></tr>
            </table>
            </div>
            </form>
            <p class="fuell10">&nbsp;</p>
           #;
   &ausgabeende;
   &log(2,"Passwortaenderungsmaske");
}
# -------------------------
sub passwortaenderung {
   return "Altes Passwort nicht angegeben! " if (not defined $query->param("passwortalt"));
   return "Neues Passwort darf nicht leer sein! " if (not defined $query->param("passwortneu1") and not defined $query->param("passwortneu2"));
   return "Eingaben f&uuml;r neues Passwort  unterschiedlich!" if ($query->param("passwortneu1") ne $query->param("passwortneu2"));
   return "Neues Passwort zu kurz (Mind. $pwd_minlenght Zeichen!)" if ( length($query->param("passwortneu1")) < $pwd_minlenght);

   my $sth = $dbh->prepare( q{
      select user_passwort from user where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   my $rc = $sth->execute($g_user_id) or die "Can't execute statement: $DBI::errstr";
   my ($user_passwort) = $sth->fetchrow_array if ($rc != 0);
   $sth->finish;
   return "Altes Passwort falsch! $zurueck" if ($user_passwort ne md5_hex($query->param("passwortalt")));

   $sth = $dbh->prepare( q{
      update user set user_passwort=? where user_id=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute(md5_hex($query->param("passwortneu1")),$g_user_id) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   &log(1,"Passwortaenderung User $g_user_id");
   return "OK";
}
# -------------------------
sub getoptions {
   # Erstellt Optionenliste fuer Auswahlmenue
   # 1. Parameter: Tabellenname
   # 2. Parameter: Feldname
   # 3. Parameter: ID-Feldname der Tabelle
   # 4. Parameter: Datensatz-ID, aus der der Defaultwert kommt. Oder 0.
   # 5. Parameter: Jointabelle, aus der der Text kommt, sonst leer
   # 6. Parameter: Jointabellenfeld mit ID, welche zu 2.P korrespondiert
   # 7. Parameter: Jointabellenfeld mit Text, der anzuzeigen ist
   # 8.-9. Parameter: Weitere Jointabellenfelder mit Text, optional

   my ($tabelle, $feld, $idfeldname, $id, $jointabelle, $jointabelle_idfeld, $jointabelle_textfeld, $jointabelle_textfeld2, $jointabelle_textfeld3) = @_;
   if (defined $jointabelle) {
      if (defined $jointabelle_textfeld2) {
         $jointabelle_textfeld2=",$jointabelle_textfeld2"
      } else {
         $jointabelle_textfeld2=" ";
      }
      if (defined $jointabelle_textfeld3) {
         $jointabelle_textfeld3=",$jointabelle_textfeld3"
      } else {
         $jointabelle_textfeld3=" ";
      }
   }
   my ($sth,$sth2,$rc,$rc2,$selected,$toshow,$value,$feldinhalt2,$feldinhalt3);
   my $return="";
   
   my $toselect="";
   if ($id) {    # Defaultwert holen
      $sth = $dbh->prepare( qq{
         select $feld from $tabelle where $idfeldname=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
      ($toselect)=$sth->fetchrow_array;
      $sth->finish;
   } else {
      $toselect=$query->param($feld) || "";    # Wenn Default aus vorheriger Eingabe stammen soll
   }

   # Jetzt alle verschiedenen Werte des Feldes holen
   if (defined $jointabelle) {
      $sth = $dbh->prepare( qq{
         select distinct $jointabelle_idfeld from $jointabelle order by $jointabelle_textfeld $jointabelle_textfeld2 $jointabelle_textfeld3
                             } ) or die "Can't prepare statement: $DBI::errstr";      
   } else {
      $sth = $dbh->prepare( qq{
         select distinct $feld from $tabelle order by $feld
                             } ) or die "Can't prepare statement: $DBI::errstr";
   }
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   # Ueber alle diese Werte die Optionen bilden
   while (my ($feldinhalt)=$sth->fetchrow_array) {
      $selected="";
      $selected="selected" if ($feldinhalt eq $toselect);
      $value=$feldinhalt;
      if (defined $jointabelle) {
         $sth2 = $dbh->prepare( qq{
            select $jointabelle_textfeld $jointabelle_textfeld2 $jointabelle_textfeld3 from $jointabelle where $jointabelle_idfeld=?
                                } ) or die "Can't prepare statement: $DBI::errstr";
         $rc2 = $sth2->execute($feldinhalt) or die "Can't execute statement: $DBI::errstr";
         ($feldinhalt, $feldinhalt2, $feldinhalt3)=$sth2->fetchrow_array;
         $feldinhalt="$feldinhalt, $feldinhalt2" if (defined $feldinhalt2);
         $feldinhalt="$feldinhalt, $feldinhalt3" if (defined $feldinhalt3);
         $sth2->finish;
      }
      $return.=qq#<option value="$value" $selected>$feldinhalt</option>\n# if ($feldinhalt);
   }
   $sth->finish;
   return $return;
}
# -------------------------
sub hardwareneu {

   my $id2change=shift || 0;       

   my ($sth,$rc,$hs_id,$lief_id,$fp_id,$so_id);

   # Erstmal die ganzen Tests auf doppelte Daten:
   if ($query->param("g_hs_name_neu")) {
      $sth = $dbh->prepare( qq{
         select hs_id from hersteller where hs_name=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_hs_name_neu")) or die "Can't execute statement: $DBI::errstr";
      my ($hs_temp)=$sth->fetchrow_array;
      $sth->finish;
      &fehler("Hersteller bereits vorhanden, bitte aus Men&uuml; ausw&auml;hlen! $zurueck") if ($hs_temp);
   }
   if ($query->param("g_lief_name_neu")) {
      $sth = $dbh->prepare( qq{
         select lief_id from lieferant where lief_name=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_lief_name_neu")) or die "Can't execute statement: $DBI::errstr";
      my ($lief_temp)=$sth->fetchrow_array;
      $sth->finish;
      &fehler("Lieferant bereits vorhanden, bitte aus Men&uuml; ausw&auml;hlen! $zurueck") if ($lief_temp);
   }
   if ($query->param("g_fp_name_neu") or $query->param("g_fp_hersteller_neu")) {
      &fehler("Bei einem neuen Festplattentyp m&uuml;ssen mind. Hersteller und Typbez. ausgef&uuml;llt sein!")
               if (not ($query->param("g_fp_hersteller_neu").$query->param("gs_fp_name_neu")));
      $sth = $dbh->prepare( qq{
         select fp_id from festplatte where fp_name=? and fp_hersteller=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_fp_name_neu"),$query->param("g_fp_hersteller_neu")) or die "Can't execute statement: $DBI::errstr";
      my ($fp_temp)=$sth->fetchrow_array;
      $sth->finish;
      &fehler("Festplatte (Hersteller + Typ) bereits vorhanden, bitte aus Men&uuml; ausw&auml;hlen! $zurueck") if ($fp_temp);
   }
   if ($query->param("g_so_gebaeude_neu")) {
      &fehler("Bei einem neuen Standort m&uuml;ssen Geb&auml;ude, Raum und User ausgef&uuml;llt sein!")
               if (not ($query->param("g_so_raum_neu").$query->param("g_so_user_neu")));
      $sth = $dbh->prepare( qq{
         select so_id from standort where so_gebaeude=? and so_raum=? and so_user=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_so_gebaeude_neu"),$query->param("g_so_raum_neu"),$query->param("g_so_user_neu"))
                           or die "Can't execute statement: $DBI::errstr";
      my ($so_temp)=$sth->fetchrow_array;
      $sth->finish;
      &fehler("Standort (Geb&auml;ude + Raum + Benutzer) bereits vorhanden, bitte aus Men&uuml; ausw&auml;hlen! $zurueck") if ($so_temp);
   }

   &fehler("Der Typ des Ger&auml;tes mu&szlig; angegeben werden!")
               if (not ($query->param("g_typ_neu").$query->param("g_typ")));

   # SN schon da?
   $sth = $dbh->prepare( qq{
      select g_id from geraet where g_sn=?
                          } ) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($query->param("g_sn")) or die "Can't execute statement: $DBI::errstr";
   my ($temp)=$sth->fetchrow_array;
   $sth->finish;
   if (not $id2change) {
      &fehler("Seriennummer leer oder bereits vorhanden! Satz nicht eingef&uuml;gt. $zurueck") if ($temp);
   } else {
      &fehler("Seriennummer bereits in anderem Datensatz vorhanden! Satz nicht ge&auml;ndert. $zurueck") 
         if ($temp and (not $temp==$id2change));
   }

   # INVNR schon da? (Leer ist erlaubt)
   if ($query->param("g_invnr")) {
      $sth = $dbh->prepare( qq{
         select g_id from geraet where g_invnr=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_invnr")) or die "Can't execute statement: $DBI::errstr";
      my ($temp)=$sth->fetchrow_array;
      $sth->finish;
      if (not $id2change) {
         &fehler("Inventarnummer bereits vorhanden! Satz nicht eingef&uuml;gt. $zurueck") if ($temp);
      } else {
         &fehler("Inventarnummer bereits in anderem Datensatz vorhanden! Satz nicht ge&auml;ndert. $zurueck") 
            if ($temp and (not $temp==$id2change));
      }
   }

   # MAC schon da? (Leer ist erlaubt)
   our $mac=$query->param("g_mac")||"";
   if ($mac) {
      $mac=uc($mac);            # GROSS
      $mac=~s/[^A-F0-9]//g;   # Alles ausser a-f und 0-9 raus
      while ($mac=~m/[A-F0-9]{3}/) {   # Alle zwei Stellen ein : rein
         $mac=~s/([A-F0-9][A-F0-9])([A-F0-9])/$1:$2/;
      }
      $sth = $dbh->prepare( qq{
         select g_id from geraet where g_mac=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($mac) or die "Can't execute statement: $DBI::errstr";
      my ($temp)=$sth->fetchrow_array;
      $sth->finish;
      if (not $id2change) {
         &fehler("MAC-Adresse bereits vorhanden! Satz nicht eingef&uuml;gt. $zurueck") if ($temp);
      } else {
         &fehler("MAC-Adresse bereits in anderem Datensatz ($temp) vorhanden! Satz ($id2change) nicht ge&auml;ndert. $zurueck") 
            if ($temp and (not $temp==$id2change));
      }
   }

   my $g_lieferdatum="";
   if ($query->param("g_lieferdatum")) {
      my ($j,$m,$t) = &Decode_Date_EU($query->param("g_lieferdatum"));
      &fehler("Lieferdatum im falschen Format!") if (not $t or not $m or not $j);
      $g_lieferdatum="$j-$m-$t";
   }

   # Keine doppelten Daten, jetzt
   # testen, ob neue Sub-Tabellensaetze dabei sind und ggf eintragen

   if ($query->param("g_hs_name_neu")) {
      $sth = $dbh->prepare( q{
         insert into hersteller (
                      hs_name,
                      hs_web,
                      hs_bem
                      ) values (?,?,?) } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(  $query->param("g_hs_name_neu"),
                      ($query->param("g_hs_web_neu") || ""),
                      ($query->param("g_hs_bem_neu") || "")
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      # und wie ist die ID des neuen Satzes?
      $sth = $dbh->prepare( qq{
         select hs_id from hersteller where hs_name=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_hs_name_neu")) or die "Can't execute statement: $DBI::errstr";
      ($hs_id)=$sth->fetchrow_array;
      $sth->finish;
      &log(2,"Neuer Herstellerdatensatz $hs_id zugefuegt.");
   } else {
      $hs_id=$query->param("g_hs_id");
   } 
   if ($query->param("g_lief_name_neu")) {
      $sth = $dbh->prepare( q{
         insert into lieferant (
                      lief_name,
                      lief_web,
                      lief_tel,
                      lief_kdnr,
                      lief_bem
                      ) values (?,?,?,?,?) } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(  $query->param("g_lief_name_neu"),
                      ($query->param("g_lief_web_neu") || ""),
                      ($query->param("g_lief_tel_neu") || ""),
                      ($query->param("g_lief_kdnr_neu") || ""),
                      ($query->param("g_lief_bem_neu") || "")
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      # und wie ist die ID des neuen Satzes?
      $sth = $dbh->prepare( qq{
         select lief_id from lieferant where lief_name=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_lief_name_neu")) or die "Can't execute statement: $DBI::errstr";
      ($lief_id)=$sth->fetchrow_array;
      $sth->finish;
      &log(2,"Neuer Lieferantendatensatz $lief_id zugefuegt.");
   } else {
      $lief_id=$query->param("g_lief_id");
   }
   if ($query->param("g_fp_name_neu") or $query->param("g_fp_hersteller_neu")) {
      $sth = $dbh->prepare( q{
         insert into festplatte (
                      fp_name,
                      fp_hersteller,
                      fp_groesse,
                      fp_anschluss,
                      fp_bem
                      ) values (?,?,?,?,?) } ) or die "Can't prepare statement: $DBI::errstr";
      my $temp=$query->param("g_fp_hersteller_neu");
      $temp =~ s/^ +//; # Fuehrende Leerzeichen weg, sonst klappt die Sortierung beim Auswahlmenue nicht
      $sth->execute(  $query->param("g_fp_name_neu"),
                      ($temp),
                      ($query->param("g_fp_groesse_neu") || ""),
                      ($query->param("g_fp_anschluss_neu") || ""),
                      ($query->param("g_fp_bem_neu") || "")
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      # und wie ist die ID des neuen Satzes?
      $sth = $dbh->prepare( qq{
         select fp_id from festplatte where fp_name=? and fp_hersteller=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_fp_name_neu"),$query->param("g_fp_hersteller_neu")) or die "Can't execute statement: $DBI::errstr";
      ($fp_id)=$sth->fetchrow_array;
      $sth->finish;
      &log(2,"Neuer Festplattendatensatz $fp_id zugefuegt.");
   } else {
      $fp_id=$query->param("g_fp_id");
   } 
   if ($query->param("g_so_gebaeude_neu")) {
      $sth = $dbh->prepare( q{
         insert into standort (
                      so_gebaeude,
                      so_raum,
                      so_user,
                      so_bem
                      ) values (?,?,?,?) } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(  $query->param("g_so_gebaeude_neu"),
                      ($query->param("g_so_raum_neu")),
                      ($query->param("g_so_user_neu")),
                      ($query->param("g_so_bem_neu") || "")
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      # und wie ist die ID des neuen Satzes?
      $sth = $dbh->prepare( qq{
         select so_id from standort where so_gebaeude=? and so_raum=? and so_user=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_so_gebaeude_neu"),
                          $query->param("g_so_raum_neu"),
                          $query->param("g_so_user_neu")) or die "Can't execute statement: $DBI::errstr";
      ($so_id)=$sth->fetchrow_array;
      $sth->finish;
      &log(2,"Neuer Standortdatensatz $so_id zugefuegt.");
   } else {
      $so_id=$query->param("g_so_id");
   }

   my ($insert,$update)=("","");
   my ($old_so_gebaeude,$old_so_raum,$old_so_user,$old_g_status)=("","","","");
   my ($new_so_gebaeude,$new_so_raum,$new_so_user,$new_g_status)=("","","","");
   $sth = $dbh->prepare( q{
           select so_gebaeude,so_raum,so_user from standort where so_id=?
                      } ) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($so_id) or die "Can't execute statement: $DBI::errstr";
   ($new_so_gebaeude,$new_so_raum,$new_so_user)=$sth->fetchrow_array;
   $sth->finish;

   $new_g_status= $query->param("g_status_neu") || $query->param("g_status");

   if ($id2change) {
      $sth = $dbh->prepare( q{
           select s.so_gebaeude,s.so_raum,s.so_user,g.g_status from geraet as g, standort as s where g.g_id=? and g.g_so_id=s.so_id
                         } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($id2change) or die "Can't execute statement: $DBI::errstr";
      ($old_so_gebaeude,$old_so_raum,$old_so_user,$old_g_status)=$sth->fetchrow_array;
      $sth->finish;

      $update= qq{ update geraet set
                                                 g_bearbeiter=?,
                                                 g_lieferdatum=?,
                                                 g_typ=?,
                                                 g_status=?,
                                                 g_hs_id=?,
                                                 g_lief_id=?,
                                                 g_fp_id=?,
                                                 g_so_id=?,
                                                 g_sn=?,
                                                 g_invnr=?,
                                                 g_mac=?,
                                                 g_garantie=?,
                                                 g_extras=?,
                                                 g_bem=?,
                                                 g_takt=?,
                                                 g_cpu=?,
                                                 g_mem=?,
                                                 g_modell=?,
                                                 g_board=?,
                                                 g_grafik=?,
                                                 g_netzkarte=?,
                                                 g_monitortyp=?,
                                                 g_monitordiag=?,
                                                 g_druckertyp=?,
                                                 g_druckerdpi=?,
                                                 g_historie=?
                            where g_id=? limit 1 }; 
   } else {
      $insert= qq{ insert into geraet (          g_deleted,
                                                 g_bearbeiter,
                                                 g_lieferdatum,
                                                 g_typ,
                                                 g_status,
                                                 g_hs_id,
                                                 g_lief_id,
                                                 g_fp_id,
                                                 g_so_id,
                                                 g_sn,
                                                 g_invnr,
                                                 g_mac,
                                                 g_garantie,
                                                 g_extras,
                                                 g_bem,
                                                 g_takt,
                                                 g_cpu,
                                                 g_mem,
                                                 g_modell,
                                                 g_board,
                                                 g_grafik,
                                                 g_netzkarte,
                                                 g_monitortyp,
                                                 g_monitordiag,
                                                 g_druckertyp,
                                                 g_druckerdpi,
                                                 g_historie
                                                ) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) };
   }
   my @values=(0) if (not $id2change);
   push @values, (
                       &getuseraccount($g_user_id),
                       $g_lieferdatum,
                       $query->param("g_typ_neu") || $query->param("g_typ"),
                       $new_g_status,
                       $hs_id,
                       $lief_id,
                       $fp_id,
                       $so_id,
                       $query->param("g_sn"),
                       $query->param("g_invnr") || "",
                       $mac,
                       $query->param("g_garantie_neu") || $query->param("g_garantie"),
                       $query->param("g_extras") || "",
                       $query->param("g_bem") || "",
                       $query->param("g_takt_neu") || $query->param("g_takt"),
                       $query->param("g_cpu_neu")  || $query->param("g_cpu"),
                       $query->param("g_mem_neu")  || $query->param("g_mem"),
                       $query->param("g_modell_neu") || $query->param("g_modell"),
                       $query->param("g_board_neu") || $query->param("g_board"),
                       $query->param("g_grafik_neu") || $query->param("g_grafik"),
                       $query->param("g_netzkarte_neu") || $query->param("g_netzkarte"),
                       $query->param("g_monitortyp_neu") || $query->param("g_monitortyp"),
                       $query->param("g_monitordiag_neu") || $query->param("g_monitordiag"),
                       $query->param("g_druckertyp_neu") || $query->param("g_druckertyp"),
                       $query->param("g_druckerdpi_neu") || $query->param("g_druckerdpi")
               );

   my $g_id=$id2change || "";

   my $histtemp=&datum;
   $histtemp.= " Datensatz zugefuegt von ".&getuseraccount($g_user_id)."." if (not $id2change);
   $histtemp.= " Datensatz $g_id geaendert von ".&getuseraccount($g_user_id)."." if ($id2change);
   if ($old_g_status ne $new_g_status) {
      $histtemp.=" Statusänderung von $old_g_status nach $new_g_status.";
   }
   if (($new_so_gebaeude ne $old_so_gebaeude) or
       ($new_so_raum ne $old_so_raum) or
       ($new_so_user ne $old_so_user)) {
      $histtemp.=" Neuer Standort: $new_so_gebaeude, $new_so_raum, $new_so_user.";
   }
   if ($id2change) {
      push @values,($query->param("g_historie").$histtemp."\n",$id2change);
   } else {
      push @values,($query->param("g_historie").$histtemp."\n");
   }
   $sth = $dbh->prepare($insert.$update) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute(@values) or die "Can't execute statement: $DBI::errstr";

   if (not $id2change) {
      # Wie lautet die Nummer des neuen Satzes?
      $sth = $dbh->prepare( qq{
          select g_id from geraet where g_sn=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param("g_sn")) or die "Can't execute statement: $DBI::errstr";
      ($g_id)=$sth->fetchrow_array;
      $sth->finish;
   }


   # GD-Tabelle anpassen -> Verknuepfungen zwischen Geraeten und Dokumenten
   my @doks=();
   @doks=$query->param("dokumente");  
   $sth = $dbh->prepare( q{
        delete from gd where gd_g_id=?
                   } ) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($g_id) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
   $year+=1900;
   $mon+=1;
   my $sqldat = ("$year.$mon.$mday");
   if (not $query->param("keinedoks")) {
      foreach my $dok(@doks) {
         $sth = $dbh->prepare( q{
              insert into gd (gd_g_id,gd_d_id,gd_user_id,gd_datum) values (?,?,?,?)
                         } ) or die "Can't prepare statement: $DBI::errstr";
         $rc = $sth->execute($g_id,$dok,$g_user_id,$sqldat) or die "Can't execute statement: $DBI::errstr";
         $sth->finish;
      }
   }


   if (not $id2change) {
      &log(1,$histtemp);
      return ($histtemp,$g_id);
   } else {
      &log(1,$histtemp);
      return ($histtemp,$g_id);
   }

}
# -------------------------
sub hardwareliste {
   my ($offset,$rowcount,$sort,$ascdesc,$text,$l_showdeleted,$l_showrun,$l_showproof,$l_moreinfo,$l_suche) = @_;
   my ($sth,$rc,$sthgd,$sthd);
   my $tempstring;
   my $limit="";
   my $order="";
   my $ordertext="Sortiert nach ";

   # Defaults aus DB holen
   $sth = $dbh->prepare( qq{
      select user_list_sort,
             user_list_ascdesc,
             user_list_offset,
             user_list_showdeleted,
             user_list_showrun,
             user_list_showproof,
             user_list_moreinfo,
             user_list_suche,
             user_list_zusuchen from user 
             where user_id=?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($g_user_id) or die "Can't execute statement: $DBI::errstr";
   my ( $user_list_sort,
        $user_list_ascdesc,
        $user_list_offset,
        $user_list_showdeleted,
        $user_list_showrun,
        $user_list_showproof,
        $user_list_moreinfo,
        $user_list_suche,
        $user_list_zusuchen)=$sth->fetchrow_array;
   $sth->finish;
   $user_list_zusuchen=~s/\%//g;

   # Checken: Gilt der Default aus der DB oder hat User was anderes ausgewaehlt?
   if (not defined $query->param("hardwareliste")) {
      $offset=$user_list_offset || 0;
   }
   $rowcount=$rowcount || $rowsperpage;
   $sort=$sort || $user_list_sort || "g.g_status" ;
   $ascdesc=$ascdesc || $user_list_ascdesc;
   if (defined $query->param("filterbutton")) {   # Hier wurde was veraendert und die Liste neu angefordert
      $l_showdeleted=0; $l_showdeleted=1 if (defined $query->param("showdeleted"));
      $l_showrun=0; $l_showrun=1 if (defined $query->param("showrun"));
      $l_showproof=0; $l_showproof=1 if (defined $query->param("showproof"));
      $l_moreinfo=0; $l_moreinfo=1 if (defined $query->param("moreinfo"));
   } else {   # sonst: erst schauen, ob Parameter mitgekommen, sonst die Defaults nehmen
      $l_showdeleted=$query->param("showdeleted") || $user_list_showdeleted;
      $l_showrun=$query->param("showrun") || $user_list_showrun;
      $l_showproof=$query->param("showproof") || $user_list_showproof;
      $l_moreinfo=$query->param("moreinfo") || $user_list_moreinfo;
   }
   
   $sort="date_add( g_lieferdatum, INTERVAL g_garantie MONTH )" if ($sort eq "g.g_garantieende");
   $text=qq#<table class="rahmen"><tr>
                <td><img src="$iconpath/Note.gif"></td><td><span class="bggruen">$text</span></td>
            </tr></table>
           # if $text;
   
   $limit="limit $offset,$rowcount";
   $ordertext.="letzter &Auml;nderung, " if ($sort eq "g.g_zeitstempel");
   $ordertext.="Ger&auml;tetyp, " if ($sort eq "g.g_typ");
   $ordertext.="Status, " if ($sort eq "g.g_status");
   $ordertext.="Standort, " if ($sort eq "standort");
   $ordertext.="Hauptspeicher, " if ($sort eq "g.g_mem");
   $ordertext.="Modell, " if ($sort eq "g.g_modell");
   $ordertext.="Hersteller, " if ($sort eq "h.hs_name");
   $ordertext.="Lieferdatum, " if ($sort eq "g.g_lieferdatum");
   $ordertext.="Inventarnummer, " if ($sort eq "g.g_invnr");
   $ordertext.="MAC-Adresse, " if ($sort eq "g.g_mac");
   $ordertext.="Garantieende, " if ($sort =~ /INTERVAL g_garantie/);
   $ordertext.="aufsteigend" if ($ascdesc eq "ASC");
   $ordertext.="absteigend" if ($ascdesc eq "DESC");
   $order="order by $sort $ascdesc";
   $order="order by s.so_gebaeude $ascdesc, s.so_raum $ascdesc, s.so_user $ascdesc" if ($sort eq "standort");

   my $filtersql="";
   $filtersql.=qq# and g.g_deleted<>"1" # if ($l_showdeleted);
   $filtersql.=qq# and g.g_status="$statusmenueeintraege[1]" # if ($l_showrun);;
   $filtersql.=qq# and g.g_status="$statusmenueeintraege[3]" # if ($l_showproof);;

   my $temp="";
   my $otheroptions="";
   my $filterstext="";
   $temp=""; $temp=qq#"checked="checked"# if ($l_moreinfo);
   $filterstext.=qq#<input type="checkbox" name="moreinfo" value="1" $temp> Erweiterte Infos<br>#;
   $otheroptions.="&moreinfo=1" if ($l_moreinfo);
   my $showdeletedtext="";
   $temp=""; $temp=qq#"checked="checked"# if ($l_showdeleted);
   $showdeletedtext.=qq#<input type="checkbox" name="showdeleted" value="1" $temp> Gel&ouml;scht-markierte ausblenden<br>#;
   $otheroptions.="&showdeleted=1" if ($l_showdeleted);
   my $showruntext="";
   $temp=""; $temp=qq#"checked="checked"# if ($l_showrun);
   $showruntext.=qq#<input type="checkbox" name="showrun" value="1" $temp> Nur laufende Ger&auml;te<br>#;
   $otheroptions.="&showrun=1" if ($l_showrun);
   my $showprooftext="";
   $temp=""; $temp=qq#"checked="checked"# if ($l_showproof);
   $showprooftext.=qq#<input type="checkbox" name="showproof" value="1" $temp> Nur zu pr&uuml;fende Ger&auml;te<br>#;
   $otheroptions.="&showproof=1" if ($l_showproof);

   # Suchstrings: Eingaben gehen ueber gespeicherte Defaults
   $l_suche=$query->param("suche") || $user_list_suche;
   my $zusuchen;

   if ($l_suche and not defined $query->param("delsuch")) {
      my $suchen=$l_suche;
      $filterstext.=qq#<input type="hidden" name="suche" value="$suchen">#;
      $suchen=substr($l_suche,0,1).".".$l_suche;
      $otheroptions.="&suche=".$l_suche;
      if (defined $query->param($suchen) or $user_list_zusuchen) {
         $zusuchen=$query->param($suchen) || $user_list_zusuchen;
         if ($suchen eq "g.g_mac") {
            $zusuchen=uc($zusuchen);            # GROSS
            $zusuchen=~s/[^A-F0-9]//g;   # Alles ausser a-f und 0-9 raus
            while ($zusuchen=~m/[A-F0-9]{3}/) {   # Alle zwei Stellen ein : rein
               $zusuchen=~s/([A-F0-9][A-F0-9])([A-F0-9])/$1:$2/;
            }
         }
         $filterstext.=qq#<input type="hidden" name="$suchen" value="$zusuchen">#;
         $otheroptions.="&$suchen=$zusuchen";
         my $suchfeld="";

         $suchfeld="Ger&auml;te-ID=" if ($suchen eq "g.g_id");
         $suchfeld="Seriennummer=" if ($suchen eq "g.g_sn");
         $suchfeld="Inventarnummer=" if ($suchen eq "g.g_invnr");
         $suchfeld="MAC-Adresse=" if ($suchen eq "g.g_mac");
         $suchfeld="Geb&auml;ude=" if ($suchen eq "s.so_gebaeude");
         $suchfeld="Raum=" if ($suchen eq "s.so_raum");
         $suchfeld="Benutzername=" if ($suchen eq "s.so_user");
         $suchfeld="Standort-ID=" if ($suchen eq "g.g_so_id");
         $suchfeld="Ger&auml;tetyp=" if ($suchen eq "g.g_typ");
         $suchfeld="Status=" if ($suchen eq "g.g_status");
         $suchfeld="Hersteller-ID=" if ($suchen eq "g.g_hs_id");
         $suchfeld="Lieferant-ID=" if ($suchen eq "g.g_lief_id");
         $suchfeld="Festplatte-ID=" if ($suchen eq "g.g_fp_id");

         my $delsort=qq#<br><a href="$eigeneurl&hardwareliste=$offset&sort=h.hs_name$otheroptions&ascdesc=ASC&delsuch=1">Suche beenden, alle anzeigen</a>#;
         $ordertext=qq#Suchergebnis nach $suchfeld *$zusuchen*.$delsort<br>$ordertext# if (not $suchen=~m/_id|typ/);
         $ordertext=qq#Suchergebnis nach $suchfeld $zusuchen.$delsort<br>$ordertext# if ($suchen=~m/_id|typ/);
         $zusuchen='%'.$zusuchen.'%' if (not $suchen=~m/_id/ and not $zusuchen=~m/\%/);
         $filtersql.=qq# and $suchen like "$zusuchen" #;
      }
   }

   # Defaults fuer Anzeige pro User in DB schreiben
   $sth = $dbh->prepare( qq{
      update user set user_list_sort=?,
                      user_list_ascdesc=?,
                      user_list_offset=?,
                      user_list_showdeleted=?,
                      user_list_showrun=?,
                      user_list_showproof=?,
                      user_list_moreinfo=?,
                      user_list_suche=?,
                      user_list_zusuchen=? where user_id=? limit 1
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute(
                       $sort,
		       $ascdesc,
		       $offset,
		       $l_showdeleted,
		       $l_showrun,
		       $l_showproof,
		       $l_moreinfo,
		       $l_suche,
		       $zusuchen,
                       $g_user_id
                       ) or die "Can't execute statement: $DBI::errstr";
   $sth->finish;

   $sth = $dbh->prepare( qq{
      select count(g.g_id) from geraet as g , hersteller as h, lieferant as l, festplatte as f, standort as s
             where g.g_hs_id=h.hs_id and
                   g.g_lief_id=l.lief_id and
                   g.g_fp_id=f.fp_id and
                   g.g_so_id=s.so_id  $filtersql
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";
   my ($anzahlsaetze)=$sth->fetchrow_array;

   my $selectstatement= qq{
      select h.hs_name,
             h.hs_web,
             h.hs_bem,
	     l.lief_name,
	     l.lief_web,
	     l.lief_tel,
	     l.lief_kdnr,
	     l.lief_bem,
	     f.fp_hersteller,
	     f.fp_name,
	     f.fp_groesse,
	     f.fp_anschluss,
	     f.fp_bem,
	     s.so_gebaeude,
	     s.so_raum,
	     s.so_user,
             g.g_id,
             g.g_deleted,
             g.g_zeitstempel,
             g.g_bearbeiter,
             g.g_lieferdatum,
             g.g_typ,
             g.g_status,
             g.g_hs_id,
             g.g_lief_id,
             g.g_fp_id,
             g.g_so_id,
             g.g_sn,
             g.g_invnr,
             g.g_mac,
             g.g_garantie,
             g.g_extras,
             g.g_bem,
             g.g_takt,
             g.g_cpu,
             g.g_mem,
             g.g_modell,
             g.g_board,
             g.g_grafik,
             g.g_netzkarte,
             g.g_monitortyp,
             g.g_monitordiag,
             g.g_druckertyp,
             g.g_druckerdpi,
             g.g_historie
	     from geraet as g, hersteller as h, lieferant as l, festplatte as f, standort as s
             where g.g_hs_id=h.hs_id and
                   g.g_lief_id=l.lief_id and
                   g.g_fp_id=f.fp_id and
                   g.g_so_id=s.so_id
                   $filtersql
             $order
             $limit 
                           };
   $sth = $dbh->prepare($selectstatement) or die "Can't prepare statement: $DBI::errstr";
#   $rc = $sth->execute($query->param("g_sn")) or die "Can't execute statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   my $lastofpage=$anzahlsaetze;
   $lastofpage=$offset+$rowsperpage if ($lastofpage > ($rowsperpage-$offset));
   my $firstofpage=$offset + 1;
   $firstofpage=0 if (not $lastofpage);
   my $morepages="";
   $temp=1;
   while ($temp <= $anzahlsaetze) {
      my $tempmax=$temp+$rowsperpage-1;
      $tempmax=$anzahlsaetze if ($tempmax > $anzahlsaetze);
      my $tempoffset=$temp-1;
      $morepages.=qq#<a href="$eigeneurl&hardwareliste=$tempoffset$otheroptions&sort=$sort&ascdesc=$ascdesc">$temp-$tempmax</a>&nbsp;#;
      $temp+=$rowsperpage;
   }
   $morepages="Zeige S&auml;tze ".$morepages if ($morepages);

   &ausgabestart("HW-Liste $firstofpage bis $lastofpage");
   my $selectinfo="";
   $selectinfo=qq#
                <p class="rahmen"><span class="bggelb">(Loglevel 3!) Debuginfo, nur f&uuml;r Entwicklung: Verwendetes SELECT</span><br> $selectstatement</p>
                 # if ($loglevel==3);
   print qq#<p class="logo">Hardware-DB - Hardwareliste</p>
            $text
            <p>$hauptmenue<br>$zurueck</p>
            $selectinfo
            <table>
            <tr><td class="rahmen">
               <span class="klein">
               $anzahlsaetze Datens&auml;tze in der Datenbank.<br>
               $morepages<br>
               $ordertext, Datensatz $firstofpage bis $lastofpage.
               </span>
            </td>
            <td class="rahmen">
               <span class="klein">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="sort" value="$sort">
               <input type="hidden" name="ascdesc" value="$ascdesc">
               <input type="hidden" name="hardwareliste" value="$offset">
               $filterstext
               $showdeletedtext
               $showruntext
               $showprooftext
               <input type="submit" name="filterbutton" value="Liste so anzeigen">
               </form>
               </span>
            </td>
            <td class="rahmen">
               <span class="klein">
               <img src="$iconpath/Sheep.gif" alt="Clone"> = Clonen <br>
               <img src="$iconpath/Write.gif" alt="Edit"> = Editieren<br> 
               <img src="$iconpath/trash.gif" alt="Delete"> = Weiss: L&ouml;schmarkierung setzen, Braun: L&ouml;schen<br> 
               <img src="$iconpath/Recycle.gif" alt="Entloeschen"> = L&ouml;schmarkierung entfernen<br> 
               <img src="$iconpath/FedExTruck.gif" alt="zur&uuml;ck zur NZ"> = Zur&uuml;ck zur $netzzentrale (setzt Status=Reserve und,
                          wenn ein Standort mit der Bemerkung="$netzzentrale" existiert, diesen Standort)<br>
               <img src="$iconpath/Garbage.gif" alt="Verschrotten"> = Datensatz als Status=verschrottet markieren<br>
               <img src="$iconpath/up.gif"> = Sortieren nach diesem Wert, aufw&auml;rts<br> 
               <img src="$iconpath/down.gif"> = Sortieren nach diesem Wert, abw&auml;rts
               </span>
            </td>
            </tr>
            </table>
            <table class="rahmen">
            <tr>
               <th class="rahmen">Aktion</th>
          #;   
   print qq#   <th class="rahmen">ID<br>Bearbeiter<br>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_zeitstempel$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_zeitstempel$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                               Stand</th>
           # if ($l_moreinfo);
   print qq#   <th class="rahmen">
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_typ$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_typ$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a> 
                           Ger&auml;tetyp</th>
	       <th class="rahmen">
                           <a href="$eigeneurl&hardwareliste=$offset&sort=h.hs_name$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=h.hs_name$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Hersteller</th>
	       <th class="rahmen">
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_modell$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_modell$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Modell</th>
	       <th class="rahmen">
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_status$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_status$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Status<br>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=standort$otheroptions&ascdesc=ASC">
                               <img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=standort$otheroptions&ascdesc=DESC">
                               <img src="$iconpath/down.gif"></a>
                           Standort</th>
	       <th class="rahmen">SN<br>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_invnr$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_invnr$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Inv.Nr.</th>
             #;
    print qq#
	       <th class="rahmen">Lieferant</th>
	       <th class="rahmen">
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_lieferdatum$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_lieferdatum$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Lieferdatum
                           <br>Garantie<br>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_garantieende$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_garantieende$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Garantieende</th>
            # if ($l_moreinfo);
   print qq#
	       <th class="rahmen">CPU<br>Takt<br>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_mem$otheroptions&ascdesc=ASC"><img src="$iconpath/up.gif"></a>
                           <a href="$eigeneurl&hardwareliste=$offset&sort=g.g_mem$otheroptions&ascdesc=DESC"><img src="$iconpath/down.gif"></a>
                           Hauptspeicher</th>
	       <th class="rahmen"><p class="pnorm">Board</p>
                                  <p class="pgrau">Grafik</p>
                                  <p class="pnorm">Netzkarte</p>
                                  <p class="pgrau"><span class="fixed">MAC</span></p></th>
	       <th class="rahmen">Festplatte</th>
	       <th class="rahmen"><span class="klein">Falls Monitor:</span>Typ/Diagonale<hr>
	                          <span class="klein">Falls Drucker:</span>Typ/Aufl&ouml;sung</th>
           #;
   print qq# <th class="rahmen">Extras</th>
             <th class="rahmen">Bemerkungen</th>
             <th class="rahmen">Dokumente</th>
             <th class="rahmen">Historie</th># if ($l_moreinfo);
   print qq#</tr>#;
   while (my ($hs_name,
             $hs_web,
             $hs_bem,
             $lief_name,
             $lief_web,
             $lief_tel,
             $lief_kdnr,
             $lief_bem,
             $fp_hersteller,
             $fp_name,
             $fp_groesse,
             $fp_anschluss,
             $fp_bem,
             $so_gebaeude,
             $so_raum,
             $so_user,
             $g_id,
             $g_deleted,
             $g_zeitstempel,
             $g_bearbeiter,
             $g_lieferdatum,
             $g_typ,
             $g_status,
             $g_hs_id,
             $g_lief_id,
             $g_fp_id,
             $g_so_id,
             $g_sn,
             $g_invnr,
             $g_mac,
             $g_garantie,
             $g_extras,
             $g_bem,
             $g_takt,
             $g_cpu,
             $g_mem,
             $g_modell,
             $g_board,
             $g_grafik,
             $g_netzkarte,
             $g_monitortyp,
             $g_monitordiag,
             $g_druckertyp,
             $g_druckerdpi,
             $g_historie
         ) =$sth->fetchrow_array) {
      $g_zeitstempel=&datefromtimestamp($g_zeitstempel);
      my $garantieende="";
      if ($g_garantie and ($g_garantie=~/^\d+$/) and (not $g_lieferdatum=~m/0000/)) {
         my @temp=&Add_Delta_YMDHMS(
                                    substr($g_lieferdatum,0,4),
                                    substr($g_lieferdatum,5,2),
                                    substr($g_lieferdatum,8,2),0,0,0,
                                    , 0,$g_garantie,0,0,0,0);
         $garantieende = $temp[2].".".$temp[1].".".$temp[0];
         $g_lieferdatum = (0+substr($g_lieferdatum,8,2)).".".(0+substr($g_lieferdatum,5,2)).".".substr($g_lieferdatum,0,4); # Das "0+" entfernt fuehr. 0
      }
      $g_lieferdatum=" " if ($g_lieferdatum=~m/0000/);
      my $klasse=qq#class="ru"#;
      $klasse=qq#class="bggrau_ru"# if $g_deleted;
      my $recyclelink="";
      $recyclelink=qq#
                       <a href="$eigeneurl&hardwareliste=$offset&sort=$sort$otheroptions&ascdesc=$ascdesc&recycle=$g_id">
                       <img src="$iconpath/Recycle_s.gif" alt="Entloeschen" title="Entl&ouml;schen"></a>
                     # if $g_deleted;
 
      $g_status=~s/$statusmenueeintraege[0]/<span class="bggrau">$statusmenueeintraege[0]<\/span>/;   # "Reserve"
      $g_status=~s/$statusmenueeintraege[1]/<span class="bggruen">$statusmenueeintraege[1]<\/span>/;  # "Betrieb"
      $g_status=~s/$statusmenueeintraege[2]/<span class="bgrot">$statusmenueeintraege[2]<\/span>/;   # "Defekt"
      $g_status=~s/$statusmenueeintraege[3]/<span class="bggelb">$statusmenueeintraege[3]<\/span>/;   # "Zu prüfen"
      $g_status=~s/$statusmenueeintraege[4]/<span class="bgrot">$statusmenueeintraege[4]<\/span>/;   # "Exventarisiert"
      $g_status=~s/$statusmenueeintraege[5]/<span class="bghellblau">$statusmenueeintraege[5]<\/span>/;   # "Verliehen"
      $g_status=~s/$statusmenueeintraege[6]/<span class="bgorange">$statusmenueeintraege[6]<\/span>/;   # "Reklamiert"
      $g_status=~s/$statusmenueeintraege[7]/<span class="bgorange">$statusmenueeintraege[7]<\/span>/;   # "Reparatur"

      my $dokumente="";
      $sthgd = $dbh->prepare( q{
           select gd_d_id from gd where gd_g_id=?
                      } ) or die "Can't prepare statement: $DBI::errstr";
      $sthgd->execute($g_id) or die "Can't execute statement: $DBI::errstr";
      while (my ($d_id)=$sthgd->fetchrow_array) {
         $sthd = $dbh->prepare( q{
           select d_bem,d_groesse from dokumente where d_id=?
                      } ) or die "Can't prepare statement: $DBI::errstr";
         $sthd->execute($d_id) or die "Can't execute statement: $DBI::errstr";
         my ($dokname,$dokgroesse)=$sthd->fetchrow_array;
         $dokumente.=qq#
                       <a href="$eigeneurl&download=$d_id">$dokname</a>($dokgroesse Bytes)<br>
                       #;
         $sthd->finish;
      }
      $sthgd->finish;

      print qq#<tr>
               <td class="rahmen"><a href="$eigeneurl&clone=$g_id"><img src="$iconpath/Sheep_s.gif" alt="Clone" title="Clonen"></a>
                                  <a href="$eigeneurl&edit=$g_id"><img src="$iconpath/Write_s.gif" alt="Edit" title="&Auml;ndern"></a>
                                  <a href="$eigeneurl&hardwareliste=$offset&sort=$sort$otheroptions&ascdesc=$ascdesc&delete=$g_id">
                                        <img src="$iconpath/trash_s.gif" alt="Delete" title="L&ouml;schen"></a>
                                  <a href="$eigeneurl&hardwareliste=$offset&sort=$sort$otheroptions&ascdesc=$ascdesc&schrott=$g_id">
                                        <img src="$iconpath/Garbage_s.gif" alt="Verschrotten" title="Verschrotten"></a>
                                  <a href="$eigeneurl&hardwareliste=$offset&sort=$sort$otheroptions&ascdesc=$ascdesc&netzzentrale=$g_id">
                                        <img src="$iconpath/FedExTruck_s.gif" alt="zur NZ" title="Zur&uuml;ck zur $netzzentrale"></a>
                                  $recyclelink
               </td>#;
      print qq#
               <td $klasse>$g_id<br>$g_bearbeiter<br>$g_zeitstempel</td>
              # if ($l_moreinfo);
      print qq#<td $klasse>$g_typ</td>
               <td $klasse>$hs_name
              #;
      $tempstring="";
      $tempstring=$hs_web if ($hs_web);
      $tempstring=qq#<a href="$hs_web">$hs_web</a># if ($hs_web and $hs_web=~m#tp://#i);
      print qq#<br>$tempstring<br>$hs_bem</td># if ($l_moreinfo);
      print qq#
               <td $klasse>$g_modell</td>
               <td $klasse>$g_status<br>$so_gebaeude, $so_raum, $so_user</td>
               <td $klasse>$g_sn<br>$g_invnr</td>
              #;
      $tempstring="";
      $tempstring=$lief_web if ($lief_web);
      $tempstring=qq#<a href="$lief_web">$lief_web</a># if ($lief_web and $lief_web=~m#tp://#i);
      print qq#
               <td $klasse>$lief_name<br>$lief_kdnr<br>$tempstring<br>$lief_bem</td>
               <td $klasse>$g_lieferdatum<br>$g_garantie Monate<br>$garantieende</td>
              # if ($l_moreinfo);
      $tempstring="";
      $tempstring.="$g_monitortyp" if ($g_monitortyp);
      $tempstring.=", $g_monitordiag Zoll" if ($g_monitordiag);
      $tempstring.="<br>";
      $tempstring.="$g_druckertyp" if ($g_druckertyp);
      $tempstring.=", $g_druckerdpi dpi" if ($g_druckerdpi);
      print qq#
               <td $klasse>$g_cpu<br>$g_takt MHz<br>$g_mem MB</td>
               <td $klasse>
                           <p class="pnorm">$g_board</p>
                           <p class="pgrau">$g_grafik</p>
                           <p class="pnorm">$g_netzkarte</p>
                           <p class="pgrau"><span class="fixed">$g_mac</span></p></th>
               <td $klasse>$fp_hersteller $fp_name, $fp_groesse GB, $fp_anschluss<br>$fp_bem</td>
               <td $klasse>$tempstring</td>
               #;
      $g_historie=~s/\n/<br>/isg;
      $g_bem=~s/\n/<br>/isg;
      $g_extras=~s/\n/<br>/isg;
      print qq#
               <td $klasse><span class="nowrap">$g_extras</span></td>
               <td $klasse><span class="nowrap">$g_bem</span></td>
               <td $klasse><span class="nowrap">$dokumente</span></td>
               <td $klasse><span class="nowrap">$g_historie</span></td>
               </tr>
               # if ($l_moreinfo); 
   }
   $sth->finish;
   print qq#</table>
            <table>
            <tr><td class="rahmen">
               <span class="klein">
               $anzahlsaetze Datens&auml;tze in der Datenbank.<br>
               $morepages<br>
               $ordertext, Datensatz $firstofpage bis $lastofpage.
               </span>
            </td>
            <td class="rahmen">
               <span class="klein">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="sort" value="$sort">
               <input type="hidden" name="ascdesc" value="$ascdesc">
               <input type="hidden" name="hardwareliste" value="$offset">
               $filterstext
               $showdeletedtext
               $showruntext
               $showprooftext
               <input type="submit" name="filterbutton" value="Liste so anzeigen">
               </form>
               </span>
            </td>
            <td class="rahmen">
               <span class="klein">
               <img src="$iconpath/Write.gif" alt="Edit"> = Editieren<br>
               <img src="$iconpath/trash.gif" alt="Delete"> = Weiss: L&ouml;schmarkierung setzen, Braun: L&ouml;schen<br>
               <img src="$iconpath/Recycle.gif" alt="Entloeschen"> = L&ouml;schmarkierung entfernen,<br>
               <img src="$iconpath/up.gif"> = Sortieren nach diesem Wert, aufw&auml;rts<br>
               <img src="$iconpath/down.gif"> = Sortieren nach diesem Wert, abw&auml;rts
               </span>
            </td>
            </tr>
            </table>
           #;
   &ausgabeende;
   
   &log(2,"Hardwareliste Offset $offset, Rows $rowcount.");
}
# -------------------------
sub getdokumenue {
   my ($id)=@_;
   my ($menue,$sth,$sth2,$menuecounter);
   my %items;
  
   $menue=qq#<select name="dokumente" size="5" multiple class="k">#;

   $sth = $dbh->prepare( qq{
            select d_id,d_bem,d_zeigeimmer from dokumente order by d_eingangsdatum
                              }) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute() or die "Can't execute statement: $DBI::errstr";

   $menuecounter=0;
   while (my ($dokid,$dokbem,$dokzeigeimmer) = $sth->fetchrow_array) {
      $sth2 = $dbh->prepare( qq{
            select gd_id from gd where gd_d_id=? and gd_g_id=?
                              }) or die "Can't prepare statement: $DBI::errstr";
      $sth2->execute($dokid,$id) or die "Can't execute statement: $DBI::errstr";
      my ($gdid)=$sth2->fetchrow_array;
      $sth2->finish;
      if ($gdid) {
         $items{$dokbem}="s$dokid";
      } else {
         if ($dokzeigeimmer) {
            $items{$dokbem}=$dokid;
         } else {
            if ($menuecounter < $maxdoksinpulldown) {
               $items{$dokbem}=$dokid;
               $menuecounter++;
            }
         }
      }
   }
   $sth->finish;
   foreach my $k(reverse sort keys %items) {
      if ($items{$k}=~s/s//) {
         $menue.=qq#<option value="$items{$k}" selected>$k</option>#;
      } else {
         $menue.=qq#<option value="$items{$k}">$k</option>#;
      }
   }
   $menue.=qq#</select>#;
   return $menue;
}
# -------------------------
sub hardwaremaske {

   my $text=shift || "";
   my $editid=0;
   $editid=$query->param("edit") if (defined $query->param("edit"));
   my $vorlageid=shift || $editid;
   my $showid=$editid || "Neu";
   my ($sth,$rc);

   $text=qq#<table class="rahmen"><tr>
                <td><a href="$eigeneurl"><img src="$iconpath/Note.gif"></a></td><td><a href="$eigeneurl"><span class="bggruen">$text</span></a></td>
            </tr></table>
           # if $text;

   my $dokumenue=&getdokumenue($vorlageid);

   my $typmenue=qq#<select class="k" size="1" name="g_typ">#;
   $typmenue.=&getoptions("geraet","g_typ","g_id",$vorlageid);
   $typmenue.=qq#</select>#;
   my $statusmenue=qq#<select class="k" size="1" name="g_status">#;
   $statusmenue.=&getoptions("geraet","g_status","g_id",$vorlageid);
   foreach my $i(@statusmenueeintraege) {
      $statusmenue.="<option>$i</option>" if (not $statusmenue=~m/$i/s)
   }
   $statusmenue.=qq#</select>#;
   my $hsmenue=qq#<select class="k" size="1" name="g_hs_id">#;
   $hsmenue.=&getoptions("geraet","g_hs_id","g_id",$vorlageid,"hersteller","hs_id","hs_name");
   $hsmenue.=qq#</select>#;
   my $liefmenue=qq#<select class="k" size="1" name="g_lief_id">#;
   $liefmenue.=&getoptions("geraet","g_lief_id","g_id",$vorlageid,"lieferant","lief_id","lief_name");
   $liefmenue.=qq#</select>#;
   my $fpmenue=qq#<select class="k" size="1" name="g_fp_id">#;
   $fpmenue.=&getoptions("geraet","g_fp_id","g_id",$vorlageid,"festplatte","fp_id","fp_hersteller","fp_name","fp_groesse");
   $fpmenue.=qq#</select>#;
   my $somenue=qq#<select class="k" size="1" name="g_so_id">#;
   $somenue.=&getoptions("geraet","g_so_id","g_id",$vorlageid,"standort","so_id","so_gebaeude","so_raum","so_user");
   $somenue.=qq#</select>#;
   my $garantiemenue=qq#<select class="k" size="1" name="g_garantie">#;
   $garantiemenue.=&getoptions("geraet","g_garantie","g_id",$vorlageid);
   $garantiemenue.=qq#</select>#;
   my $taktmenue=qq#<select class="k" size="1" name="g_takt">#;
   $taktmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $taktmenue.=&getoptions("geraet","g_takt","g_id",$vorlageid);
   $taktmenue.=qq#</select>#;
   my $cpumenue=qq#<select class="k" size="1" name="g_cpu">#;
   $cpumenue.=qq#<option value="0">nicht vorhanden</option>#;
   $cpumenue.=&getoptions("geraet","g_cpu","g_id",$vorlageid);
   $cpumenue.=qq#</select>#;
   my $memmenue=qq#<select class="k" size="1" name="g_mem">#;
   $memmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $memmenue.=&getoptions("geraet","g_mem","g_id",$vorlageid);
   $memmenue.=qq#</select>#;
   my $modellmenue=qq#<select class="k" size="1" name="g_modell">#;
   $modellmenue.=&getoptions("geraet","g_modell","g_id",$vorlageid);
   $modellmenue.=qq#</select>#;
   my $boardmenue=qq#<select class="k" size="1" name="g_board">#;
   $boardmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $boardmenue.=&getoptions("geraet","g_board","g_id",$vorlageid);
   $boardmenue.=qq#</select>#;
   my $grafikmenue=qq#<select class="k" size="1" name="g_grafik">#;
   $grafikmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $grafikmenue.=&getoptions("geraet","g_grafik","g_id",$vorlageid);
   $grafikmenue.=qq#</select>#;
   my $netzkartemenue=qq#<select class="k" size="1" name="g_netzkarte">#;
   $netzkartemenue.=qq#<option value="0">nicht vorhanden</option>#;
   $netzkartemenue.=&getoptions("geraet","g_netzkarte","g_id",$vorlageid);
   $netzkartemenue.=qq#</select>#;
   my $monitortypmenue=qq#<select class="k" size="1" name="g_monitortyp">#;
   $monitortypmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $monitortypmenue.=&getoptions("geraet","g_monitortyp","g_id",$vorlageid);
   $monitortypmenue.=qq#</select>#;
   my $monitordiagmenue=qq#<select class="k" size="1" name="g_monitordiag">#;
   $monitordiagmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $monitordiagmenue.=&getoptions("geraet","g_monitordiag","g_id",$vorlageid);
   $monitordiagmenue.=qq#</select>#;
   my $druckertypmenue=qq#<select class="k" size="1" name="g_druckertyp">#;
   $druckertypmenue.=qq#<option value="0">nicht vorhanden</option>#;
   $druckertypmenue.=&getoptions("geraet","g_druckertyp","g_id",$vorlageid);
   $druckertypmenue.=qq#</select>#;
   my $druckerdpimenue=qq#<select class="k" size="1" name="g_druckerdpi">#;
   $druckerdpimenue.=qq#<option value="0">nicht vorhanden</option>#;
   $druckerdpimenue.=&getoptions("geraet","g_druckerdpi","g_id",$vorlageid);
   $druckerdpimenue.=qq#</select>#;
   my $useraccount=&getuseraccount($g_user_id);
   my $datum=substr(&datum,0,10);
   my $g_lieferdatum=$query->param("g_lieferdatum") || $datum;
   my $g_bem=$query->param("g_bem") || "";
   my $g_historie="";
   my $g_sn=$query->param("g_sn") || "";
   my $g_invnr=$query->param("g_invnr") || "";
   my $g_extras=$query->param("g_extras") || "";
   my $g_mac=$query->param("g_mac") || "";
   my $change_new_text=qq#<input type="hidden" name="neuehardware" value="1">#;
   my $returnbutton=qq#<input type="submit" name="neuehardware_hardwaremaske" value="Eintragen und Maske wieder anzeigen">#;
   if ($vorlageid) {
      $sth = $dbh->prepare( qq{
         select g_lieferdatum,g_sn,g_invnr,g_mac,g_extras,g_bem,g_historie from geraet where g_id=?
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($vorlageid) or die "Can't execute statement: $DBI::errstr";
      ($g_lieferdatum,$g_sn,$g_invnr,$g_mac,$g_extras,$g_bem,$g_historie)=$sth->fetchrow_array;
      $sth->finish;
      $g_lieferdatum = substr($g_lieferdatum,8,2).".".substr($g_lieferdatum,5,2).".".substr($g_lieferdatum,0,4) if (not $g_lieferdatum=~m/0000/);
      $g_lieferdatum="" if ($g_lieferdatum=~m/0000/);
      $change_new_text=qq#<input type="hidden" name="changehardware" value="$editid"># if ($editid);
      $returnbutton="" if ($editid);
      $g_historie="" if (not $editid);
   } 
   &ausgabestart;
   print qq#<p class="logo">Hardware-DB - Hardware &auml;ndern/zuf&uuml;gen</p>
            $text
            <p>$hauptmenue<br>$zurueck</p>
            <form action="$eigeneurl" method="post">
            <input type="hidden" name="sid" value="$g_session_id">
            $change_new_text 
            <input type="hidden" name="useraccount" value="$useraccount">
            <table class="rahmen">
            <tr>
               <th class="rahmen"><span class="bggelb">ID=$showid</span></td>
               <th class="rahmen"><span class="bggelb">Hier m&ouml;glichst ausw&auml;hlen/&auml;ndern/eintragen</span></td>
               <th class="rahmen"><span class="bggelb">Nur wenn links nicht vorhanden, hier neu eintragen.</span></td>
            </tr>
            <tr>
               <td class="beschriftung">Bearbeiter<br>Angelegt</td>
               <td class="beschriftung">$useraccount<br>$datum</td>
               <td class="beschriftung">&nbsp;</td>
            </tr>
            <tr>
               <td class="beschriftung">Typ des Ger&auml;tes</td>
               <td class="urechts">Auswahl: $typmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_typ_neu" size="20"></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Hersteller</td>
               <td class="urechts">Auswahl: $hsmenue</td>
               <td class="u">oder neu: <table><tr>
                                       <td>Herstellername</td><td><input class="k" type="text" name="g_hs_name_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Webadresse</td><td><input class="k" type="text" name="g_hs_web_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Bemerkungen</td><td><textarea cols="30" rows="2" name="g_hs_bem_neu"></textarea></td>
                                       </tr></table>
               </td>
            </tr>
            <tr>
               <td class="beschriftung">Modell/Typbezeichnung</td>
               <td class="urechts">Auswahl: $modellmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_modell_neu" size="20"></td>
            </tr> 
            <tr class="bggrau">
               <td class="beschriftung"><br>Status<br><br></td>
               <td class="urechts">Auswahl: $statusmenue</td>
               <td>&nbsp;</td>
            </tr>
            <tr>
               <td class="beschriftung">Standort</td>
               <td class="urechts">Auswahl: $somenue</td>
               <td class="u">oder neu: <table><tr>
                                       <td>Geb&auml;ude</td><td><input class="k" type="text" name="g_so_gebaeude_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Raum</td><td><input class="k" type="text" name="g_so_raum_neu" size="20">
                                          <span class="help">Raumnummer</span></td>
                                       </tr><tr>
                                       <td>Benutzer</td><td><input class="k" type="text" name="g_so_user_neu" size="20">
                                          <span class="help">Logink&uuml;rzel, leer oder "öff."</span></td>
                                       </tr><tr>
                                       <td>Bemerkungen</td><td><textarea cols="30" rows="2" name="g_so_bem_neu"></textarea></td>
                                       </tr></table>
              </td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Lieferant</td>
               <td class="urechts">Auswahl: $liefmenue</td>
               <td class="u">oder neu: <table><tr>
                                       <td>Lieferantenname</td><td><input class="k" type="text" name="g_lief_name_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Webadresse</td><td><input class="k" type="text" name="g_lief_web_neu" size="20">
                                          <span class="help">Komplett, also mit http://</span></td>
                                       </tr><tr>
                                       <td>Telefon</td><td><input class="k" type="text" name="g_lief_tel_neu" size="20">
                                          <span class="help">+land vorwahl_ohne_0 nummer</span></td>
                                       </tr><tr>
                                       <td>Kundennummer</td><td><input class="k" type="text" name="g_lief_kdnr_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Bemerkungen</td><td><textarea cols="30" rows="2" name="g_lief_bem_neu"></textarea></td>
                                       </tr></table>
               </td>
            </tr>
            <tr>
               <td class="beschriftung">Lieferdatum</td>
               <td class="urechts"> 
                      <input class="k" type="text" name="g_lieferdatum" size="20" value="$g_lieferdatum"></td>
               <td class="u"><span class="help">Bitte im Format tt.mm.jjjj oder leer </span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Garantie</td>
               <td class="urechts">Auswahl: $garantiemenue Monate</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_garantie_neu" size="20"> Monate</td>
            </tr>
            <tr>
               <td class="beschriftung">Seriennummer</td>
               <td class="urechts"><input class="k" type="text" name="g_sn" size="20" value="$g_sn"></td>
               <td class="u"><span class="help">Muss eindeutig sein, d.h. nur einmal in Datenbank vorkommen.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Inventarnummer</td>
               <td class="urechts"><input class="k" type="text" name="g_invnr" size="20" value="$g_invnr"></td>
               <td class="u"><span class="help">Kann leer bleiben.</span></td>
            </tr>
            <tr>
               <td class="beschriftung">Dokumente</td>
               <td class="urechts"><input type="checkbox" name="keinedoks" value="ja">Zuordnungen l&ouml;schen<br>
                                   $dokumenue</td>
               <td class="u"><span class="help">Hier Mehrfachauswahl m&ouml;glich (mit STRG selektieren).<br>Neue Dokumente 
                             werden &uuml;ber das separate Dokument-Men&uuml; hochgeladen.<br>
                             Wenn "Zuordnungen l&ouml;schen" angeklickt ist, wird eine evtl. Mehrfachauswahl nicht beachtet.</span>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Festplatte</td>
               <td class="urechts">Auswahl: $fpmenue</td>
               <td class="u">oder neu: <table><tr>
                                       <td>Hersteller</td><td><input class="k" type="text" name="g_fp_hersteller_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Typbezeichnung</td><td><input class="k" type="text" name="g_fp_name_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Kapazit&auml;t</td><td><input class="k" type="text" name="g_fp_groesse_neu" size="20">
                                         <span class="help">Angabe in GB, nur die Zahl eingeben.</span></td>
                                       </tr><tr>
                                       <td>Anschlu&szlig;art</td><td><input class="k" type="text" name="g_fp_anschluss_neu" size="20"></td>
                                       </tr><tr>
                                       <td>Bemerkungen</td><td><textarea cols="30" rows="2" name="g_fp_bem_neu"></textarea></td>
                                       </tr></table>
               </td>
            </tr>
            <tr>
               <td class="beschriftung">MAC-Adresse</td>
               <td class="urechts"><input class="k" type="text" name="g_mac" size="20" value="$g_mac">
                </td>
               <td class="u"><span class="help">Format egal, Macadresse wird in jedem Fall zu XX:XX:etc. normiert.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Extras</td>
               <td class="urechts"><textarea cols="40" rows="4" name="g_extras">$g_extras</textarea></td>
               <td class="u"><span class="help">Freitext: Besonderheiten des Ger&auml;tes, z.B. ein DVD-Brenner.</span></td>
            </tr>
            <tr>
               <td class="beschriftung">Bemerkung</td>
               <td class="urechts"><textarea cols="40" rows="4" name="g_bem">$g_bem</textarea></td>
               <td class="u"><span class="help">Freitext: Sonstige Bemerkungen, die in kein anderes Feld passen.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Board</td>
               <td class="urechts">Auswahl: $boardmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_board_neu" size="20">
                <span class="help">Typbezeichnung des eingebauten Boardes.</span></td>
            </tr>
            <tr>
               <td class="beschriftung">CPU</td>
               <td class="urechts">Auswahl: $cpumenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_cpu_neu" size="20"></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Takt</td>
               <td class="urechts">Auswahl: $taktmenue MHz</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_takt_neu" size="20">
                <span class="help">Angabe in MHz, nur die Zahl eingeben.</span></td>
            </tr>
            <tr>
               <td class="beschriftung">Hauptspeicher</td>
               <td class="urechts">Auswahl: $memmenue MB</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_mem_neu" size="20">
                <span class="help">Angabe in MB, nur die Zahl eingeben.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Grafik</td>
               <td class="urechts">Auswahl: $grafikmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_grafik_neu" size="20"></td>
            </tr>
            <tr>
               <td class="beschriftung">Netzwerkkarte</td>
               <td class="urechts">Auswahl: $netzkartemenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_netzkarte_neu" size="20"></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Monitortyp</td>
               <td class="urechts">Wenn Monitor, Auswahl: $monitortypmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_monitortyp_neu" size="20"></td>
            </tr>
            <tr>
               <td class="beschriftung">Monitor-Diagonale</td>
               <td class="urechts">Wenn Monitor, Auswahl: $monitordiagmenue Zoll</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_monitordiag_neu" size="20">
                <span class="help">Angabe in Zoll, nur die Zahl eingeben.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Druckertyp</td>
               <td class="urechts">Wenn Drucker, Auswahl: $druckertypmenue</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_druckertyp_neu" size="20"></td>
            </tr>
            <tr>
               <td class="beschriftung">Drucker-Aufl&ouml;sung</td>
               <td class="urechts">Wenn Drucker, Auswahl: $druckerdpimenue dpi</td>
               <td class="u">oder neu: <input class="k" type="text" name="g_druckerdpi_neu" size="20">
                <span class="help">Angabe in dpi, nur die Zahl eingeben.</span></td>
            </tr>
            <tr class="bggrau">
               <td class="beschriftung">Historie</td>
               <td class="urechts"><textarea cols="60" rows="10" name="g_historie">$g_historie</textarea></td>
               <td class="u">Dieses Feld m&ouml;glichst nicht bearbeiten, es wird automatisch gef&uuml;llt.</td>
            </tr>

            <tr><td colspan=3>
                           $returnbutton
                           <input type="submit" name="neuehardware_hauptmenue" value="Eintragen und zur&uuml;ck">
                          </td></tr>
            </table>
            </form>
           #; 
   &ausgabeende;

   &log(2,"Hardwaremaske Geraete-ID $editid aendern") if ($editid);
   &log(2,"Hardwaremaske neues Geraet") if (not $editid);
}
# -------------------------
sub work2do {
   &ausgabestart("Hardware-DB - Baustelle");
   print qq{<p class="logo">Hardware-DB - Hauptmen&uuml;</p>
            <div id="rand10">
            <p class="fuell10"></p>
            <p><img src="$iconpath/const.gif">Hier gibts noch Arbeit ... $zurueck</p>
            <p class="fuell10"></p>
            </div>
           };
   &ausgabeende;
}
# -------------------------
sub hardwaresuchen {

   my $somenue=qq#<select class="k" size="1" name="g.g_so_id">#;
   $somenue.=&getoptions("geraet","g_so_id","g_id",0,"standort","so_id","so_gebaeude","so_raum","so_user");
   $somenue.=qq#</select>#;
   my $typmenue=qq#<select class="k" size="1" name="g.g_typ">#;
   $typmenue.=&getoptions("geraet","g_typ","g_id",0);
   $typmenue.=qq#</select>#;
   my $statusmenue=qq#<select class="k" size="1" name="g.g_status">#;
   $statusmenue.=&getoptions("geraet","g_status","g_id",0);
   foreach my $i(@statusmenueeintraege) {
      $statusmenue.="<option>$i</option>" if (not $statusmenue=~m/$i/s)
   }
   $statusmenue.=qq#</select>#;
   my $hsmenue=qq#<select class="k" size="1" name="g.g_hs_id">#;
   $hsmenue.=&getoptions("geraet","g_hs_id","g_id",0,"hersteller","hs_id","hs_name");
   $hsmenue.=qq#</select>#;
   my $liefmenue=qq#<select class="k" size="1" name="g.g_lief_id">#;
   $liefmenue.=&getoptions("geraet","g_lief_id","g_id",0,"lieferant","lief_id","lief_name");
   $liefmenue.=qq#</select>#;
   my $fpmenue=qq#<select class="k" size="1" name="g.g_fp_id">#;
   $fpmenue.=&getoptions("geraet","g_fp_id","g_id",0,"festplatte","fp_id","fp_hersteller","fp_name");
   $fpmenue.=qq#</select>#;

   &ausgabestart;
   print qq#<p class="logo">Hardware-DB - Suchen</p>
            <p>$hauptmenue</p>  
            <p>Es sind nur alphanumerische Eingaben erlaubt, alle anderen Zeichen werden entfernt. 
               Es werden alle Datens&auml;tze gelistet, die die eingegebenen Zeichen im jeweiligen Feld enthalten.
            </p>
            <table>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_id">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Ger&auml;te-ID:
               </td><td>
                  <input type="text" name="g.g_id" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_sn">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Seriennummer:
               </td><td>
                  <input type="text" name="g.g_sn" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_mac">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach MAC-Adresse:
               </td><td>
                  <input type="text" name="g.g_mac" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_invnr">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Inventarnummer:
               </td><td>
                  <input type="text" name="g.g_invnr" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="so_gebaeude">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Geb&auml;ude:
               </td><td>
                  <input type="text" name="s.so_gebaeude" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="so_raum">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Raum:
               </td><td>
                  <input type="text" name="s.so_raum" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="so_user">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Benutzername:
               </td><td>
                  <input type="text" name="s.so_user" value="" length="20">
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_so_id">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Geb&auml;ude, Raum, Benutzer:
               </td><td>
                  $somenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_typ">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Ger&auml;tetyp:
               </td><td>
                  $typmenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_status">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Status:
               </td><td>
                  $statusmenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_hs_id">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Hersteller:
               </td><td>
                  $hsmenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_lief_id">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Lieferant:
               </td><td>
                  $liefmenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>
            <tr class="rahmen">
               <form action="$eigeneurl" method="post">
               <input type="hidden" name="sid" value="$g_session_id">
               <input type="hidden" name="suche" value="g_fp_id">
               <input type="hidden" name="hardwareliste" value="0">
               <td>
                  Suche nach Festplatte:
               </td><td>
                  $fpmenue
               </td><td>
                  <input type="submit" name="suchbutton" value="Suchen">
               </td>
               </form>
            </tr>

            </table>
           #;
   &ausgabeende;
}
# -------------------------
sub hardwarezaehlen {
   my ($sth,$rc,$linkstring);

   &ausgabestart;
   print qq#<p class="logo">Hardware-DB - Statistik</p>
            <p>$hauptmenue</p>
            <p>
            Verlinkungen f&uuml;hren direkt zur Anzeige der entsprechenden Datens&auml;tze.<br>
            Im Betrieb werden sich weitere Bed&uuml;rfnisse f&uuml;r diese Seite ergeben - 
            wer Ideen hat, welche Statistiken man hier noch anzeigen kann: Mail an 
            <a href="mailto:Michael.Schaarwaechter\@ub.uni-dortmund.de">mich</a>.
            </p>
           #;

   print qq#<table class="rahmen">
            <tr> 
               <th class="rahmen">Datens&auml;tze pro</th>
               <th class="rahmen">Status</th>
            </tr>
           #;
   $sth = $dbh->prepare( qq{
      SELECT g_status,count(g_status) FROM geraet group by g_status
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   while (my ($status,$count)=$sth->fetchrow_array) {
      $linkstring=qq#$eigeneurl&suche=g_status&hardwareliste=0&g.g_status=$status#;
      print qq#
               <tr>
                  <td class="ru"><a href="$linkstring">$count</a></td>
                  <td class="ru"><a href="$linkstring">$status</a></td>
               <tr>
              #;
   }
   print qq#</table>#;

   print qq#<table class="rahmen">
            <tr>
               <th class="rahmen">Datens&auml;tze pro</th>
               <th class="rahmen">Ger&auml;tetyp</th>
            </tr>
           #;
   $sth = $dbh->prepare( qq{
      SELECT g_typ,count(g_typ) FROM geraet group by g_typ
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   while (my ($typ,$count)=$sth->fetchrow_array) {
      $linkstring=qq#$eigeneurl&suche=g_typ&hardwareliste=0&g.g_typ=$typ#;
      print qq#
               <tr>
                  <td class="ru"><a href="$linkstring">$count</a></td>
                  <td class="ru"><a href="$linkstring">$typ</a></td>
               <tr>
              #;
   }
   print qq#</table>#;


   &ausgabeende;
   &log(2,"Statistik");
}
# -------------------------
sub subtabellenliste {
   my $tabelle = $_[0];
   my $text = $_[1] || ""; 
   my ($sth,$rc,$sth2,$rc2,$hs_id,$hs_name,$hs_web,$hs_bem);

   my $tbl2show="";
   $tbl2show="Herstellerliste" if ($tabelle eq "hersteller");
   $tbl2show="Lieferantenliste" if ($tabelle eq "lieferant");
   $tbl2show="Standortliste" if ($tabelle eq "standort");
   $tbl2show="Festplattenliste" if ($tabelle eq "festplatte");
   $tbl2show="Dokumentenliste" if ($tabelle eq "dokumente");
   my $geraeteid="";
   $geraeteid="g_hs_id" if ($tabelle eq "hersteller");
   $geraeteid="g_lief_id" if ($tabelle eq "lieferant");
   $geraeteid="g_so_id" if ($tabelle eq "standort");
   $geraeteid="g_fp_id" if ($tabelle eq "festplatte");
   my $querytag=$tabelle."aenderung";

   $text=qq#<table class="rahmen"><tr>
                <td><img src="$iconpath/Note.gif"></td><td><span class="bggruen">$text</span></td>
            </tr></table>
           # if $text;

   $sth = $dbh->prepare( qq{
      select count(*) from $tabelle
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";
   my ($anzahlsaetze)=$sth->fetchrow_array;
   &fehler("Keine Daten vorhanden. Neue Daten bitte mit neuer Hardware zuf&uuml;gen. $zurueck") if ($anzahlsaetze==0 and $tabelle ne "dokumente");
  
   my $neudokument="";
   if ($tabelle eq "dokumente") {
      $neudokument= qq#
                        <form action="$eigeneurl" method="post" enctype="multipart/form-data">
                        <input type="hidden" name="sid" value="$g_session_id">
                        <input type="hidden" name="upload" value="1">
			<table class="rahmen">
			  <tr>
			     <td class="ru">
                             Neues Dokument hochladen:<br>
			     <input type="file" name="putfile" accept="text/*" maxlength="$maxfilesize" size="80" class="klein">
			     </td><td class="klein">
			     Hier die Datei ausw&auml;hlen
			     </td>
			  </tr>
                          <tr>
                             <td class="ru">
                             <input type="text" length="80" size="80" name="d_bem" class="klein">
                             </td><td class="klein">
                             Inhaltliche Beschreibung. Bitte kurz halten,<br>wird in Pulldownmenue verwendet.<br>
                             Vorschlag: <i>jjmmtt-rechnung-lieferant-warenbezeichnung</i>
                             </td>
                          </tr>
			  <tr><td>&nbsp;</td><td class="klein">
			     und <input type="submit" value="Abschicken" class="klein">
			     </td>
			  </tr>
			</table>
			</form>
                      #;
   }

   &ausgabestart("Hardwaredatenbank - Subtabelle $tabelle");
   my $dokuerklaerung="";
   $dokuerklaerung=qq#<br>Es werden bei der Hardwaremaske nur die 
                         neuesten Dokumente angezeigt, damit das
                         Auswahlmen&uuml; nicht zu lang wird.
                         "Immer zeigen" bewirkt, da&szlig; diese Dokumente immer zus&auml;tzlich zur Auswahl angeboten werden.<br>
                         Zu jedem verwendeten Dokument werden hier die Ger&auml;te-IDs angezeigt. Diese sind verlinkt und erm&ouml;glichen einen
                         direkten Sprung zu dem jeweiligen Ger&auml;tesatz.<br><br>
                        # if ($tabelle eq "dokumente");
   print qq#<p class="logo">Hardware-DB - $tbl2show</p>
            $text
            <p>$hauptmenue</p>
            <p>
            &Auml;nderungen bitte zeilenweise vornehmen und danach jeweils den zugeh&ouml;rigen Button am Ende der Zeile klicken.<br>
            Es k&ouml;nnen nur Datens&auml;tze gel&ouml;scht werden, die nicht in der Ger&auml;tedatenbank verwendet werden.<br>
            $dokuerklaerung
            $anzahlsaetze Datens&auml;tze in der $tbl2show.
            $neudokument
            </p>
            <table class="rahmen">
            <tr>
               <th class="rahmen">Verwendet</th>
               <th class="rahmen">ID</th>
           #;
   print qq#   <th class="rahmen">Name</th>
               <th class="rahmen">Web</th>
               <th class="rahmen">Bemerkung</th> # if ($tabelle eq "hersteller");
   print qq#   <th class="rahmen">Name</th>
               <th class="rahmen">Web</th>
               <th class="rahmen">Telefon</th>
               <th class="rahmen">KundenNr</th>
               <th class="rahmen">Bemerkung</th> # if ($tabelle eq "lieferant");
   print qq#   <th class="rahmen">Geb&auml;ude</th>
               <th class="rahmen">Raum</th>
               <th class="rahmen">Benutzer</th>
               <th class="rahmen">Bemerkung</th> # if ($tabelle eq "standort");
   print qq#   <th class="rahmen">Hersteller</th>
               <th class="rahmen">Bezeichnung</th>
               <th class="rahmen">Gr&ouml;&szlig;e (GB)</th>
               <th class="rahmen">Anschlu&szlig;</th>
               <th class="rahmen">Bemerkung</th> # if ($tabelle eq "festplatte");
   print qq#   <th class="rahmen">Eingang<br>Bearbeiter</th>
               <th class="rahmen">Dateiname orig.</th>
               <th class="rahmen">Mimetyp</th>
               <th class="rahmen">Gr&ouml;&szlig;e</th>
               <th class="rahmen">Immer anzeigen</th> 
               <th class="rahmen">Inhaltliche Beschreibung</th># if ($tabelle eq "dokumente");
   print qq#
               <th class="rahmen">Aktion</th>
            </tr>
           #;

   my $sqlstatement="";
   $sqlstatement= qq{select hs_id,hs_name,hs_web,hs_bem from hersteller order by hs_name} if ($tabelle eq "hersteller");
   $sqlstatement= qq{select lief_id,lief_name,lief_web,lief_tel,lief_kdnr,lief_bem from lieferant order by lief_name} if ($tabelle eq "lieferant");
   $sqlstatement= qq{select so_id,so_gebaeude,so_raum,so_user,so_bem from standort order by so_gebaeude,so_raum,so_user} if ($tabelle eq "standort");
   $sqlstatement= qq{select fp_id,fp_hersteller,fp_name,fp_groesse,fp_anschluss,fp_bem from festplatte order by fp_hersteller,fp_name} 
          if ($tabelle eq "festplatte");
   $sqlstatement= qq{select d_id,d_stand,d_eingangsdatum,d_user_id,d_datei,d_mime,d_groesse,d_zeigeimmer,d_bem,d_orgname from dokumente order by d_stand}
          if ($tabelle eq "dokumente");
   $sth = $dbh->prepare($sqlstatement) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";

   while (my ($x1,$x2,$x3,$x4,$x5,$x6,$x7,$x8,$x9,$x10) = $sth->fetchrow_array) {
      my $loeschen="";
      if ($tabelle ne "dokumente") {
         $sth2 = $dbh->prepare( qq{
            select count(*) from geraet where $geraeteid=?
                                 }) or die "Can't prepare statement: $DBI::errstr";
      } else {
         $sth2 = $dbh->prepare( qq{
            select count(*) from gd where gd_d_id=?
                                 }) or die "Can't prepare statement: $DBI::errstr";
      }
      $rc2 = $sth2->execute($x1) or die "Can't execute statement: $DBI::errstr";
      my ($verwendet)=$sth2->fetchrow_array;
      if (not $verwendet) {
         $loeschen=qq#<input type="submit" name="loeschen" value="L&ouml;schen">#;
         $verwendet=qq#<span class="bggelb">$verwendet</span>#;
      } else {
         $verwendet.=" mal";
         $verwendet=qq#<a href="$eigeneurl&suche=g_hs_id&hardwareliste=0&g.g_hs_id=$x1">#.$verwendet.qq#</a># if ($tabelle eq "hersteller");
         $verwendet=qq#<a href="$eigeneurl&suche=g_lief_id&hardwareliste=0&g.g_lief_id=$x1">#.$verwendet.qq#</a># if ($tabelle eq "lieferant");
         $verwendet=qq#<a href="$eigeneurl&suche=g_so_id&hardwareliste=0&g.g_so_id=$x1">#.$verwendet.qq#</a># if ($tabelle eq "standort");
         $verwendet=qq#<a href="$eigeneurl&suche=g_fp_id&hardwareliste=0&g.g_fp_id=$x1">#.$verwendet.qq#</a># if ($tabelle eq "festplatte");
         if ($tabelle eq "dokumente") { # Die Geraete-IDs zursammensuchen und als Link anzeigen
            $verwendet.="<br>";
            $sth2 = $dbh->prepare( qq{
               select gd_g_id from gd where gd_d_id=?
                                     }) or die "Can't prepare statement: $DBI::errstr";
            $sth2->execute($x1) or die "Can't execute statement: $DBI::errstr";
            while (my $g_id= $sth2->fetchrow_array) {
               $verwendet.=qq#<a href="$eigeneurl&suche=g_id&hardwareliste=0&g.g_id=$g_id">#.$g_id.qq#</a> #
            }
            $sth2->finish;
         }
      }

      print qq#
              <tr>
                 <form action="$eigeneurl" method="post">
                 <input type="hidden" name="sid" value="$g_session_id">
                 <input type="hidden" name="$querytag" value="$x1">
                 <td class="ru">$verwendet</td>
                 <td class="ru">$x1</td>
              #;
      print qq#
                 <td class="ru"><input class="k" type="text" name="hs_name" value="$x2" length="20"></td>
                 <td class="ru"><input class="k" type="text" name="hs_web" value="$x3" length="20"</td>
                 <td class="ru"><textarea cols="20" rows="1" name="hs_bem">$x4</textarea>
              # if ($tabelle eq "hersteller");
      print qq#
                 <td class="ru"><input class="k" type="text" name="lief_name" value="$x2" length="20"></td>
                 <td class="ru"><input class="k" type="text" name="lief_web" value="$x3" length="20"</td>
                 <td class="ru"><input class="k" type="text" name="lief_tel" value="$x4" length="20"</td>
                 <td class="ru"><input class="k" type="text" name="lief_kdnr" value="$x5" length="20"</td>
                 <td class="ru"><textarea cols="20" rows="1" name="lief_bem">$x6</textarea>
              # if ($tabelle eq "lieferant");
      print qq#
                 <td class="ru"><input class="k" type="text" name="so_gebaeude" value="$x2" length="20"></td>
                 <td class="ru"><input class="k" type="text" name="so_raum" value="$x3" length="20"</td>
                 <td class="ru"><input class="k" type="text" name="so_user" value="$x4" length="20"</td>
                 <td class="ru"><textarea cols="20" rows="1" name="so_bem">$x5</textarea>
              # if ($tabelle eq "standort");
      print qq#
                 <td class="ru"><input class="k" type="text" name="fp_hersteller" value="$x2" length="20"></td>
                 <td class="ru"><input class="k" type="text" name="fp_name" value="$x3" length="20"</td>
                 <td class="ru"><textarea cols="20" rows="1" name="fp_groesse">$x4</textarea>
                 <td class="ru"><textarea cols="20" rows="1" name="fp_anschluss">$x5</textarea>
                 <td class="ru"><textarea cols="20" rows="1" name="fp_bem">$x6</textarea>
              # if ($tabelle eq "festplatte");
      if ($tabelle eq "dokumente") {
         my $selzi0="";
         my $selzi1="";
         $selzi0="selected" if (not $x8);
         $selzi1="selected" if ($x8);
         my $spanclass="";
         $spanclass="bggruen" if ($x8);
         $spanclass="bgrot" if (not $x8);
         $x4=&getuseraccount($x4);
         $x7=int($x7 / 1024) . " kB";
         $x3=(0+substr($x3,8,2)).".".(0+substr($x3,5,2)).".".substr($x3,0,4);
         print qq#
                    <td class="ru">$x3<br>$x4</td>
                    <td class="ru"><a href="$eigeneurl&download=$x1">$x10</a></td>
                    <td class="ru">$x6</td>
                    <td class="ru">$x7</td>
                    <td class="ru"><span class="$spanclass">&nbsp; 
                       <select class="k" size="1" name="d_zeigeimmer">
                       <option $selzi0 value="0">nein</option>
                       <option $selzi1 value="1">ja</option>
                       </select>&nbsp;
                       </span>
                    </td>
                    <td class="ru"><input class="k" type="text" name="d_bem" value="$x9" length="20"></td>
                 #;
      }
      print qq#
                 <td class="ru"><input type="submit" name="aendern" value="&Auml;ndern">$loeschen</td>
                 </form>
              </tr>
              #;
   }

   print qq#
            </table>
           #;
   &ausgabeende;
   &log(2,"Liste der Tabelle $tabelle");
}
# -------------------------
sub subtabellenaenderung {
   my ($tabelle)=@_;
   my ($message,$sth,$rc);
   my $querytag=$tabelle."aenderung";
   my $id;
   $id="hs_id" if ($tabelle eq "hersteller");
   $id="lief_id" if ($tabelle eq "lieferant");
   $id="so_id" if ($tabelle eq "standort");
   $id="fp_id" if ($tabelle eq "festplatte");
   $id="d_id" if ($tabelle eq "dokumente");

   if (defined $query->param("loeschen")) {
      if ($tabelle eq "dokumente") {   # Datei loeschen
         $sth = $dbh->prepare( qq{
            select d_datei from dokumente where d_id=?
                              }) or die "Can't prepare statement: $DBI::errstr";
         $rc = $sth->execute($query->param($tabelle."aenderung")) or die "Can't execute statement: $DBI::errstr";
         my ($dateiname)=$sth->fetchrow_array;
         $sth->finish;
         unlink("$dokupath/$dateiname") if ($dateiname);
         &log(1,"$dokupath/$dateiname geloescht");
      }
      $sth = $dbh->prepare( qq{
         delete from $tabelle where $id=? limit 1 
                              }) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($query->param($tabelle."aenderung")) or die "Can't execute statement: $DBI::errstr";
      &log(1,"Datensatz ".$query->param($tabelle."aenderung")." aus $tabelle geloescht.");
      return ("Datensatz ".$query->param($tabelle."aenderung")." aus $tabelle gel&ouml;scht.");
   }
   if (defined $query->param("aendern")) {
      &fehler("Inhaltliche Beschreibung muss angegeben werden! $zurueck") if ($tabelle eq "dokumente" and not $query->param("d_bem"));
      if ($tabelle eq "dokumente") {
         $sth = $dbh->prepare( qq{
               select d_id from dokumente where d_bem=? and d_id<>?
                                 }) or die "Can't prepare statement: $DBI::errstr";
         $sth->execute($query->param("d_bem"),$query->param($tabelle."aenderung")) or die "Can't execute statement: $DBI::errstr";
         my ($id_temp)=$sth->fetchrow_array;
         $sth->finish;
         &fehler("Diese inhaltliche Beschreibung ist bereits vorhanden! $zurueck") if ($id_temp);
      }
      my $sqlstatement="";
      $sqlstatement=qq{update hersteller set hs_name=?, hs_web=?, hs_bem=? where hs_id=? limit 1} if ($tabelle eq "hersteller");
      $sqlstatement=qq{update lieferant set lief_name=?, lief_web=?, lief_tel=?, lief_kdnr=?, lief_bem=? where lief_id=? limit 1} 
            if ($tabelle eq "lieferant");
      $sqlstatement=qq{update standort set so_gebaeude=?, so_raum=?, so_user=?, so_bem=? where so_id=? limit 1} if ($tabelle eq "standort");
      $sqlstatement=qq{update festplatte set fp_hersteller=?, fp_name=?, fp_groesse=?, fp_anschluss=?, fp_bem=? where fp_id=? limit 1} 
            if ($tabelle eq "festplatte");
      $sqlstatement=qq{update dokumente set d_zeigeimmer=?, d_bem=? where d_id=? limit 1} if ($tabelle eq "dokumente");

      $sth = $dbh->prepare($sqlstatement) or die "Can't prepare statement: $DBI::errstr";

      my @values;
      @values=($query->param("hs_name"),
               $query->param("hs_web"),
               $query->param("hs_bem"),
               $query->param("herstelleraenderung")) if ($tabelle eq "hersteller");
      @values=($query->param("lief_name"),
               $query->param("lief_web"),
               $query->param("lief_tel"),
               $query->param("lief_kdnr"),
               $query->param("lief_bem"),
               $query->param("lieferantaenderung")) if ($tabelle eq "lieferant");
      @values=($query->param("so_gebaeude"),
               $query->param("so_raum"),
               $query->param("so_user"),
               $query->param("so_bem"),
               $query->param("standortaenderung")) if ($tabelle eq "standort");
      @values=($query->param("fp_hersteller"),
               $query->param("fp_name"),
               $query->param("fp_groesse"),
               $query->param("fp_anschluss"),
               $query->param("fp_bem"),
               $query->param("festplatteaenderung")) if ($tabelle eq "festplatte");
      @values=($query->param("d_zeigeimmer"),
               $query->param("d_bem"),
               $query->param("dokumenteaenderung")) if ($tabelle eq "dokumente");

      $rc = $sth->execute(@values) or die "Can't execute statement: $DBI::errstr";
      &log(1,"Satz ".$query->param($tabelle."aenderung")." in $tabelle geaendert.");
      return ("Satz ".$query->param($tabelle."aenderung")." in $tabelle ge&auml;ndert.");
   }
}
# -------------------------
sub filedownload {
   my ($sth,$data);

   $sth = $dbh->prepare( q{
           select d_datei,d_orgname,d_mime,d_groesse,d_bem from dokumente where d_id=?
                      } ) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute($query->param("download")) or die "Can't execute statement: $DBI::errstr";
   my ($datei,$orgname,$mime,$groesse,$bem)=$sth->fetchrow_array;
   $sth->finish;

   &fehler("Dokument ist nicht (mehr?) vorhanden.$zurueck") if (not $datei);                    # Nix in der DB gefunden?
   &fehler("Dokument ist nicht (mehr?) vorhanden.$zurueck") if (not -e $dokupath."/".$datei);   # Datei nicht da?

   print $query->header(-type=>$mime,
                        -attachment=>$orgname,
                        -"Content-length"=>$groesse
                       );

   open (my $fh,$dokupath."/".$datei)
          or die "Fehler beim oeffnen von ".$dokupath."/".$datei.": $!";     # Sicher, weil dieser Name im Hash sein muss. Ansonsten wäre ../ usw möglich.
   while(my $b=read($fh,$data,1024)) {
     print $data;
   }
   close $fh;
   &log(2,$dokupath."/".$datei." downloaded von ".$query->remote_host());
}
# -------------------------
sub fileupload {

   my $message="";
   my $sth;
  
   # FIXME: Pruefen, ob Platte voll. Dann Fehlermeldung

   my $d_bem=$query->param("d_bem");
   if (not $d_bem) {
      &fehler("Bitte geben Sie eine inhaltliche Beschreibung f&uuml;r die Datei an! $zurueck");
   } else {
      $sth = $dbh->prepare( qq{
            select d_bem from dokumente where d_bem=?
                              }) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute($d_bem) or die "Can't execute statement: $DBI::errstr";
      my ($d_bem_neu)=$sth->fetchrow_array;
      $sth->finish;
      &fehler("Diese inhaltliche Beschreibung ist bereits vorhanden! $zurueck") if ($d_bem_neu);
   }

   my $file = $query->param("putfile");
   my $fh=$file;

   my $filename = $query->uploadInfo($file)->{'Content-Disposition'};
   $filename =~ s/^.*?filename="(.*?)"/$1/;

   $filename=&basename($filename);    # Zur Sicherheit, falls ein Browser einen Pfad mitliefert
   &fileparse_set_fstype("MSWin32");
   $filename=&basename($filename);    # und nochmal fuer Windozeclients

   my $filetype = $query->uploadInfo($file)->{'Content-Type'};
   my $datum=&datum;
   my $md5=&md5_hex($filename.$datum); 

   my $fname = $dokupath."/".$md5;
   open DAT,'>'.$fname or die 'Error processing file: ',$!;

   binmode $fh;
   binmode DAT;

   my $data;
   my $bytesread;

   while(my $b=read($fh,$data,1024)) {
     $bytesread+=$b;
     print DAT $data;
     last if ($bytesread > $maxfilesize);
   }
   close DAT;

   if ($bytesread > $maxfilesize) {
      unlink $dokupath."/".$md5 if ($bytesread > $maxfilesize);
      &fehler("Die Dateigr&ouml;&szlig;e &uuml;bersteigt die zul&auml;ssigen $maxfilesize Bytes! Hochladen nicht erfolgt.");
      &log(2,"Hochladen fehlgeschlagen, Datei zu gross.");
   } else {
      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
      $year+=1900;
      $mon+=1;
      my $sqldat = ("$year.$mon.$mday");
      my $sqlstatement= q{
            INSERT INTO `dokumente` ( d_eingangsdatum, d_user_id, d_datei, d_orgname, d_mime, d_groesse, d_zeigeimmer, d_bem ) VALUES ( ?,?,?,?,?,?,?,? )
                             };
      $sth = $dbh->prepare($sqlstatement) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute($sqldat,
                    $g_user_id,
                    $md5,
                    $filename,
                    $filetype,
                    $bytesread,
                    "0",
                    $query->param("d_bem") || "" 
                    ) or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      $message="Hochladen von $filename ($bytesread Bytes) erfolgreich.";
      &log(1,"Hochladen von $filename = $fname erfolgreich.");
   }
   return $message;
}
# -------------------------
sub recycle {
   # Entfernt die Loeschmarkierung von einem Satz, wenn gesetzt.
   my $id=shift or return "Programmfehler: Recycle ohne ID";
   my ($sth,$rc);

   $sth = $dbh->prepare( qq{
      select g_deleted from geraet where g_id=?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
   my ($deleted)=$sth->fetchrow_array;
   $sth->finish;

   return "Satz ist bereits entl&ouml;scht!" if (not $deleted);

   $sth = $dbh->prepare( qq{
      update geraet set g_deleted=0 where g_id=? limit 1
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
   &log(1,"Satz $id reaktiviert");
   return "Satz mit der ID $id reaktiviert!";
}
# -------------------------
sub delete {
   # Setzt die Loeschmarkierung von einem Satz, wenn noch nicht gesetzt.
   # Entfernt Satz, wenn Loeschmarkierung schon gesetzt.
   my $id=shift or return "Programmfehler: Recycle ohne ID";
   my ($sth,$rc);

   $sth = $dbh->prepare( qq{
      select g_deleted from geraet where g_id=?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
   my ($deleted)=$sth->fetchrow_array;
   $sth->finish;

   if ($deleted) {
      $sth = $dbh->prepare( qq{
         delete from geraet where g_id=? limit 1
                              }) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
      $sth = $dbh->prepare( q{
           delete from gd where gd_g_id=?
                      } ) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
      &log(1,"Satz $id geloescht");
      return "Satz mit der ID $id geloescht!";
   } else {
      $sth = $dbh->prepare( qq{
         UPDATE `geraet` SET `g_deleted` = '1' WHERE `g_id` = ? LIMIT 1
                              }) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
      &log(1,"Satz $id zum Loeschen markiert");
      return "Satz mit der ID $id zum Loeschen markiert.";
   }
}
# -------------------------
sub quickchange {
   # Aendert Status, Standort und Historie eines Satzes zu verschrottet oder $netzzentrale
   # $statusmenueeintraege[0] = "Reserve"
   # $statusmenueeintraege[4] = "Exventarisiert"
   my $id=shift or return "Programmfehler: quickchange ohne ID";
   my $statusname=shift or return "Programmfehler: quickchange ohne ID";
   my ($sth,$rc, $neustandort, $statustext,$new_so_gebaeude, $new_so_raum, $new_so_user);
   $statustext = $statusmenueeintraege[0] if ($statusname eq $netzzentrale); 
   $statustext = $statusmenueeintraege[4] if ($statusname eq "Schrott");

   $sth = $dbh->prepare( qq{
      select so_id,so_gebaeude,so_raum,so_user from standort where so_bem like ?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute('%'.$statusname.'%') or die "Can't execute statement: $DBI::errstr";
   ($neustandort,$new_so_gebaeude, $new_so_raum, $new_so_user)=$sth->fetchrow_array; 
   $sth->finish;

   if (not $neustandort) {
      $sth = $dbh->prepare( q{
         insert into standort (
                      so_gebaeude,
                      so_raum,
                      so_user,
                      so_bem
                      ) values (?,?,?,?) } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute(  $statusname,
                      $statusname,
                      $statusname,
                      $statusname
                       ) or die "Can't execute statement: $DBI::errstr";
      $sth = $dbh->prepare( qq{
         select so_id,so_gebaeude,so_raum,so_user from standort where so_bem like ?
                              }) or die "Can't prepare statement: $DBI::errstr";
      $rc = $sth->execute('%'.$statusname.'%') or die "Can't execute statement: $DBI::errstr";
      ($neustandort,$new_so_gebaeude, $new_so_raum, $new_so_user)=$sth->fetchrow_array;
      $sth->finish;
   }
   
   $sth = $dbh->prepare( qq{
      select g_historie from geraet where g_id like ?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute($id) or die "Can't execute statement: $DBI::errstr";
   my ($histold)=$sth->fetchrow_array;
   $sth->finish;

   my $update= qq{ update geraet set
                          g_bearbeiter=?,
                          g_status=?,
                          g_so_id=?,
                          g_historie=?
                            where g_id=? limit 1 };
   my $histtemp= " Datensatz $id geaendert von ".&getuseraccount($g_user_id).".";
   $histtemp.=" Statusänderung nach $statustext.";
   $histtemp.=" Neuer Standort: $new_so_gebaeude, $new_so_raum, $new_so_user.";
   $sth = $dbh->prepare($update) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute( &getuseraccount($g_user_id),
                  $statustext,
                  $neustandort,
                  $histold."\n".$histtemp,
                  $id ) or die "Can't execute statement: $DBI::errstr";
   &log(1,$histtemp); 
   return $histtemp;
}
# -------------------------
sub hauptmenu {

   my $text=shift || "";

   $text=qq#<table class="rahmen"><tr>
                <td><a href="$eigeneurl"><img src="$iconpath/Note.gif"></a></td><td><a href="$eigeneurl"><span class="bggruen">$text</span></a></td>
            </tr></table>
           # if $text;

   &ausgabestart("Hardware-DB - Hauptmenue");
   print qq{<p class="logo">Hardware-DB - Hauptmen&uuml;</p>
            <div id="rand10">
            <table><tr>
            <td>Eingeloggt als $g_vorname $g_nachname.</td>
            <td><a href="$eigeneurl&logout=1"><img border="none" src="$iconpath/ArrowRight.gif"></a></td>
            <td><a href="$eigeneurl&logout=1">Ausloggen!</a></td>
            </tr></table>

            $text
            
            <p><span class="bggelb">Bitte Men&uuml;punkt ausw&auml;hlen</span></p>
            <table>
            <tr><td>
            <table class="rahmen">
            <tr>
               <td><a href="$eigeneurl&hardwaremaske=1"><img src="$iconpath/Monitor.gif"></a></td>
               <td><a href="$eigeneurl&hardwaremaske=1">Hardware zuf&uuml;gen</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&hardwareliste=0"><img src="$iconpath/Clipboard.gif"></a></td>
               <td><a href="$eigeneurl&hardwareliste=0">Hardware auflisten</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&hardwaresuchen=1"><img src="$iconpath/Search.gif"></a></td>
               <td><a href="$eigeneurl&hardwaresuchen=1">Hardware suchen</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&hardwarezaehlen=1"><img src="$iconpath/48applic.gif"></a></td>
               <td><a href="$eigeneurl&hardwarezaehlen=1">Hardwarezahlen/Statistik</a></td>
            </tr>
            </table>
            </td><td>
            <table class="rahmen">
            <tr>
               <td><a href="$eigeneurl&herstellerliste=1"><img src="$iconpath/build.gif"></a></td>
               <td><a href="$eigeneurl&herstellerliste=1">Herstellerliste</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&lieferantenliste=1"><img src="$iconpath/Van.gif"></a></td>
               <td><a href="$eigeneurl&lieferantenliste=1">Lieferantenliste</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&standortliste=1"><img src="$iconpath/Desk2.gif"></a></td>
               <td><a href="$eigeneurl&standortliste=1">Standortliste</a></td>
            </tr>
            <tr>
               <td><a href="$eigeneurl&festplattenliste=1"><img src="$iconpath/festplatte.gif"></a></td>
               <td><a href="$eigeneurl&festplattenliste=1">Festplattenliste</a></td>
            </tr> 
            <tr>
               <td><a href="$eigeneurl&dokumentenliste=1"><img src="$iconpath/DrawerFull.gif"></a></td>
               <td><a href="$eigeneurl&dokumentenliste=1">Dokumentenliste</a></td>
            </tr>
            </table>
            </td><td>
            <table class="rahmen">
            <tr>
               <td><a href="$eigeneurl&pwdchange=1"><img src="$iconpath/Oldkey.gif"></a></td>
               <td><a href="$eigeneurl&pwdchange=1">Passwort &auml;ndern</a></td>
            </tr></tr>
               <td><a href="$eigeneurl&userliste=1"><img src="$iconpath/CharlieBrown.gif"></a></td>
               <td><a href="$eigeneurl&userliste=1">Userliste</a></td>
            </tr><tr>
               <td><a href="$eigeneurl&userverwaltung=1"><img src="$iconpath/Lucy.gif"></a></td>
               <td><a href="$eigeneurl&userverwaltung=1">Userverwaltung</a></td>
            </tr><tr>
               <td><a href="$eigeneurl&viewlog=1"><img src="$iconpath/Filestext.gif"></a></td>
               <td><a href="$eigeneurl&viewlog=1">Letzte Logeintr&auml;ge ansehen</a></td>
            </tr>
            </table>
            </td><td>
            <table class="rahmen">
            <tr>
               <td><a href="$eigeneurl&faq=1"><img src="$iconpath/CookieMonster2.gif"></a></td>
               <td><a href="$eigeneurl&faq=1">FAQ</a></td>
            </tr>
            </table>
            </td></tr>
            </table>

            </div>
            <p class="fuell10">&nbsp;</p>
           };
   &ausgabeende;
   &log(2,"Hauptmenue");
}
# -------------------------
sub faq {
   &ausgabestart("Hardware-DB - FAQ");
   print qq{<p class="logo">Hardware-DB - FAQ</p>
            <p>$hauptmenue</p>
            <p class="rahmen">
            <span class="frage">Dokumente an Ger&auml;tes&auml;tze h&auml;ngen</span>
            <br>
            <img src="$iconpath/CookieMonster2.gif">
            <span class="antwort">
            Ein Dokument wird &uuml;ber das Men&uuml; Dokumentenverwaltung hochgeladen. Anschlie&szlig;end
            kann man den Datensatz eines Ger&auml;tes aufrufen, editieren und dort aus den verf&uuml;gbaren
            angezeigten Dokumenten ein oder mehrere ausw&auml;hlen.
            </span>
            </p>

            <p class="rahmen">
            <span class="frage">Auswahl oder Neueintrag beim Hardwarezuf&uuml;gen?</span>
            <br>
            <img src="$iconpath/CookieMonster2.gif">
            <span class="antwort">
            Sofern die Daten in der Datenbank bereits vorhanden sind, muss die Auswahlm&ouml;glichkeit
            auf der linken Seite des Hardware-zuf&uuml;gen/&auml;ndern-Men&uuml;s genutzt werden. Nur,
            wenn die Daten noch nicht in den Auswahlmen&uuml;s auftauchen, m&uuml;ssen sie manuell auf
            der rechten Seite eingetragen werden.
            </span>
            </p>

            <p class="rahmen">
            <span class="frage">Es fehlen Datens&auml;tze?</span>
            <br>
            <img src="$iconpath/CookieMonster2.gif">
            <span class="antwort">
            Nein, nicht unbedingt. Die Sortierung und ein evt. Filter werden pro Benutzer gespeichert. Und zwar
            Session-&uuml;bergreifend. Wenn Sie sich also die Hardwareliste gefiltert nach z.B. Monitoren angesehen haben,
            dann ausgeloggt und irgendwann wieder eingeloggt haben und die Hardwareliste ansehen, wird sie immer noch
            den Filter nach Monitoren gesetzt haben. Man kann Sortierungen mit den roten Pfeilen in der Tabellen&uuml;berschrift
            einstellen und Filter mit Klick auf den Link "Suche beenden, alle anzeigen" entfernen.
            </span>
            </p>

            <p class="rahmen">
            <span class="frage">Mehr?</span>
            <br>
            <img src="$iconpath/CookieMonster2.gif">
            <span class="antwort">
            Weitere Unklarheiten bitte mailen, sie werden dann hier beantwortet.
            </span>
            </p>
           };
   &ausgabeende;
  
}
# -------------------------
sub parametersortieren {
   my $done=0;
   my $message="";
   my $g_id=0;

   $hauptmenue=qq#<table><tr><td><a href="$eigeneurl"><img src="$iconpath/ArrowRight2.gif"></a></td>
                       <td><a href="$eigeneurl">Zur&uuml;ck zum Hauptmen&uuml;</a></td></tr></table>#;


   if (defined $query->param("faq")) {
      &faq;
      $done=1;
   }
   if (defined $query->param("userverwaltung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#) 
          if ( (not &getuserflag("user_canchangeuser")) and
               (not &getuserflag("user_isadmin"))
             );
      &userverwaltung;
      $done=1;
   }
   if (defined $query->param("userdatensatz")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangeuser")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&useraendern;
      &userverwaltung($message);
      $done=1;
   }
   if (defined $query->param("userliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewuser")) and
               (not &getuserflag("user_isadmin"))
             );
      &userliste;
      $done=1;
   }
   if (defined $query->param("herstellerliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &subtabellenliste("hersteller");
      $done=1;
   }
   if (defined $query->param("herstelleraenderung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&subtabellenaenderung("hersteller");
      &subtabellenliste("hersteller",$message);
      $done=1;
   }
   if (defined $query->param("lieferantenliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &subtabellenliste("lieferant");
      $done=1;
   }
   if (defined $query->param("lieferantaenderung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&subtabellenaenderung("lieferant");
      &subtabellenliste("lieferant",$message);
      $done=1;
   }
   if (defined $query->param("standortliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &subtabellenliste("standort");
      $done=1;
   }
   if (defined $query->param("standortaenderung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&subtabellenaenderung("standort");
      &subtabellenliste("standort",$message);
      $done=1;
   }
   if (defined $query->param("festplattenliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &subtabellenliste("festplatte");
      $done=1;
   }
   if (defined $query->param("festplatteaenderung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&subtabellenaenderung("festplatte");
      &subtabellenliste("festplatte",$message);
      $done=1;
   }
   if (defined $query->param("dokumentenliste")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &subtabellenliste("dokumente");
      $done=1;
   }
   if (defined $query->param("dokumenteaenderung")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&subtabellenaenderung("dokumente");
      &subtabellenliste("dokumente",$message);
      $done=1;
   }
   if (defined $query->param("upload")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&fileupload;
      &subtabellenliste("dokumente",$message);
      $done=1;
   }
   if (defined $query->param("download")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck</a>#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &filedownload;
      $done=1;
   }
   if (defined $query->param("pwdchange")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehispwd")) and
               (not &getuserflag("user_isadmin"))
             );
      &passwortaenderungmaske;
      $done=1;
   }
   if (defined $query->param("neuespasswort")) {
      my $return=&passwortaenderung;
      if ($return eq "OK") {
         $message="Passwort ge&auml;ndert";
      } else {
         &log(2,"Fehler bei Passwortaenderung: $return");
         &fehler($return." ".$zurueck);
      }
   }
   if (defined $query->param("viewlog")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canviewlog")) and
               (not &getuserflag("user_isadmin"))
             );
      &zeigelogdaten;
      $done=1;
   }
   if (defined $query->param("hardwaremaske") or defined $query->param("edit")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      &hardwaremaske;
      $done=1;
   }
   if (defined $query->param("neuehardware")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canaddhw")) and
               (not &getuserflag("user_isadmin"))
             );
      ($message,$g_id)=&hardwareneu;
      if (defined $query->param("neuehardware_hardwaremaske")) {
         &hardwaremaske($message,$g_id); 
         $done=1;
      }
   }
   if (defined $query->param("clone")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canaddhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &hardwaremaske("Neuer Satz, Maske mit Daten des alten gef&uuml;llt",$query->param("clone"));
      $done=1;
   }
   if (defined $query->param("changehardware")) {     # Muss vor hardwareliste stehen, da das danach aufgerufen wird
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );    
      ($message,$g_id)=&hardwareneu($query->param("changehardware"));
   }
   if (defined $query->param("recycle")) {   # Muss vor hardwareliste stehen, da das danach aufgerufen wird
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );     
      $message=&recycle($query->param("recycle"));
   }
   if (defined $query->param("delete")) {   # Muss vor hardwareliste stehen, da das danach aufgerufen wird
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&delete($query->param("delete"));
   }
   if (defined $query->param("schrott")) {   # Muss vor hardwareliste stehen, da das danach aufgerufen wird
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&quickchange($query->param("schrott"),"Schrott");
   }
   if (defined $query->param("netzzentrale")) {   # Muss vor hardwareliste stehen, da das danach aufgerufen wird
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canchangehw")) and
               (not &getuserflag("user_isadmin"))
             );
      $message=&quickchange($query->param("netzzentrale"),$netzzentrale);
   }
   if (defined $query->param("hardwareliste") or defined $query->param("changehardware")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      my $ascdesc=$query->param("ascdesc") || "0";
      my $sort=$query->param("sort") || "0";
      my $startwith=$query->param("hardwareliste") || 0;
      &hardwareliste($startwith,$rowsperpage,$sort,$ascdesc,$message);
      $done=1;
   }
   if (defined $query->param("hardwaresuchen")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &hardwaresuchen;
      $done=1;
   }
   if (defined $query->param("hardwarezaehlen")) {
      &fehler(qq#Sie haben das Nutzungsrecht f&uuml;r diese Funktion nicht! $zurueck#)
          if ( (not &getuserflag("user_canviewhw")) and
               (not &getuserflag("user_isadmin"))
             );
      &hardwarezaehlen;
      $done=1;
   }
   &hauptmenu($message) if (not $done); 
}
# -------------------------
sub checkfordefaultdata {
   # Checkt DB nach Datensaetzen mit Defaultwerten und legt an, wenn nicht vorhanden
   my ($sth,$rc);
   my $temp=0;
   
   $sth = $dbh->prepare( qq{
      select fp_id from festplatte where fp_id=?
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute(1) or die "Can't execute statement: $DBI::errstr";
   ($temp)=$sth->fetchrow_array;
   $sth->finish;
   if (not $temp) {
      $sth = $dbh->prepare( q{
            INSERT INTO `festplatte` ( fp_id , fp_hersteller , fp_name ) VALUES ( ?,?,? )
                             } ) or die "Can't prepare statement: $DBI::errstr";
      $sth->execute('1',  ' Nicht vorhanden' , 'leer') or die "Can't execute statement: $DBI::errstr";
      $sth->finish;
      &log(1,"Erster Eintrag (n.v.) in Festplattentabelle automatisch erstellt");
   }

   # Defaultuser als Admin anlegen, wenn noch kein admin da. Default-Pwd ist schaarwaechter
   $sth = $dbh->prepare( qq{
      select count(*) from user 
                           }) or die "Can't prepare statement: $DBI::errstr";
   $rc = $sth->execute() or die "Can't execute statement: $DBI::errstr";
   ($temp)=$sth->fetchrow_array;
   $sth->finish;
   if (not $temp) {
      $sth = $dbh->prepare( q{
            INSERT INTO user ( user_account, user_vorname, user_nachname, user_passwort, user_bem, user_isadmin ) VALUES ( ?,?,?,?,?,? )
                             } ) or die "Can't prepare statement: $DBI::errstr";
   $sth->execute('admin', 'Default', 'Admin', '050408f9c12da793472ac955953df414', 'User/Passwort als Default angelegt, bitte sofort aendern!!!','1' ) 
      or die "Can't execute statement: $DBI::errstr";
   $sth->finish;
   &log(1,"Erster Eintrag (admin) in Usertabelle automatisch erstellt. Passwort siehe Dokumentation.");
   }
}
# -------------------------

# --------------------- Hauptprogramm -----------------------

&openconnection;
&log(3,"Programmaufruf","listofparams");
&cleansids;
&checkfordefaultdata;

if (defined $query->param("sid")) {
   if (&validatesid) {
      if ($query->param("login")) {  # Loginversuch
         my $return=&authentificate;
         if (not ($return eq "OK")) {
             &log(2,$return);
             &loginmaske($return);
             &stopprog;
         } 
      }
      if ($query->param("logout")) { # Logout
         &logout; 
         print $query->redirect($logouturl);
         &stopprog;
      }
      if (not $g_loggedin) {   # noch nicht eingeloggt
         &loginmaske; 
         &stopprog;
      } else {                 # Validiert, eingeloggt
         &parametersortieren;  
         &stopprog;
      }
   } else {
      &fehler(qq#Die Session ist leider abgelaufen, bitte <a href="$eigeneurl">neu starten</a>!#);
   }
} else {   # Keine Sid: Eine erzeugen
   &newsessionid;
   print $query->redirect($eigeneurl);
}

&closeconnection;
