Benutzer:Kirmse/fip03
Zur Navigation springen
Zur Suche springen
Quelltext
einfach mit der Maus runterkratzen :)
- #!/usr/bin/perl -w
- use strict; # Variablen -> deklariert sein
- use Getopt::Long; # fuer Kommandozeilenparameter
- # ------------------- Konfigurationsbereich ---------------------
- # hier wird der Pfad zur Datei "dhcpd.leases" eingetragen. Diese
- # Voreinstellung gilt für Arktur 4, wird aber ueber schrieben,
- # wenn man mit Kommandozeilenparameter -f eine Datei uebergibt
- my $leasedatei = "dhcpd.leases";
- # hier die Bildungsvorschrift fuer den Namen als Regex uebergeben
- # diese Voreinstellung bedeutet, dass am Ende die Rechnernummer
- # erwartet wird und davor der Raumname. Hinweis: die erste Klammer
- # muss der Raumname sein
- my $regex = '(.*\D)\d+';
- # hier wird die Standardbezeichnung für die Gruppierung festgelegt
- # dabei werden die Gruppierungen hochgezaehlt und an diesen Namen
- # die Nummer standardmaessig als zweistellige Zahl angehangen.
- # die Stelligkeit muss durch eine nachgestellte Zahl hinter dem
- # Doppelpunkt angegeben werden z.B. Raum:3 bedeutet Raum007
- # diese Standardbezeichnung kann durch eine Liste hinter dem
- # Parameter -n oder -name ueberschrieben werden.
- my $name = 'Raum:2';
- # ------------------- Initialisierungsbereich -------------------
- # Deklaration der globalen Variablen
- my @daten = (); # Element = Zeile von 'computer'
- my @temp1 = (); # Daten vom 1. File
- my @temp2 = (); # Daten vom 2. File
- my $liste = ""; # String mit temp.Gruppennamen
- my $liste2 = ""; # String mit gener. Gruppennamen
- my %gruppen = (); # Gruppenname => \@Gruppe
- my $datei = "computer"; # Daten nicht ok, dann .= '.not_okay'
- my $startwerte = 20; # Initialisierung fuer IP
- # Deklaration Variablen für Parameter, wenn kein Schalter: undef
- my $namen; # Namensliste als String (Komma)
- my $reg; # Regex fuer Bildungsvorschrift
- # =================== Hauptprogramm =============================
- # ------- 1. Schritt: Kommandozeilenparameter uebernehmen -------
- # hier werden die Zuordnungen fuer die Parameter erstellt
- # Bsp.: 'conf' bedeutet Aufruf mit "-c dhcpd_alt.conf"
- GetOptions ( # Parameter fuer:
- 'namen=s' => \$namen, # Namensliste
- 'regex=s' => \$reg); # Regex
- # wenn Regex uebergeben, dann wird Voreinstellung ueberschrieben
- if (defined($reg)) { $regex = $reg }
- # ------- 2. Schritt: Einlesen der Daten ------------------------
- # wir lesen die leases-Datei ein und geben die Daten zurueck
- @daten = &einlesen_leases($leasedatei);
- # ------- 3. Schritt: Vernichten von Doubletten -----------------
- # bei der dhcpd.leases ist es bei kurzer LEASE-Time normal,
- # dass fuer einen Rechner mehrere Eintraege (Doubletten) stehen
- # sicherheitshalber vernichten wir in Bezug auf die MAC und Namen
- @daten = &vernichte_Doubletten(@daten);
- # ------- 4. Schritt: Bestimmen der Gruppen ---------------------
- # mit Hilfe der Regex versuchen wir die Gruppen zu bestimmen
- # mit diesen (temporaeren) Namen ueberschreiben wir das 4. Feld
- @daten = &bestimme_Gruppen($regex,@daten);
- $liste = &bestimme_Gruppenliste(@daten);
- # ------- 5. Schritt: Reihenfolge bestimmen ---------------------
- # die Daten werden jetzt folgendermassen sortiert: die Gruppen
- # werden entsprechend der Anzahl der PCs sortiert und innerhalb
- # der Gruppe alphabetisch nach dem Rechnernamen
- ($liste,@daten) = &sortieren($liste,@daten);
- # ------- 6. Schritt: Gruppennamem vergeben -------------------
- # es wird in gleicher Reihenfolge der temp. Namen ein Name generiert
- $liste2 = &generiere_Gruppennamen($name,$liste);
- # es wird das 4. Feld von @daten ueberschrieben
- @daten = &setze_Gruppenname($liste,$liste2,$namen,@daten);
- # ------- 7. Schritt: IP vergeben -------------------------------
- # es wird das 1. Feld @daten ueberschrieben
- @daten = &setze_ip(@daten);
- # ------- 8. Schritt: Schreiben der Datei 'computer' ------------
- &schreibe_datei($datei,@daten);
- print "\n";
- unless (defined($namen)) {
- print 'Es wurden die Namen Raum01, Raum02, ... vergeben'."\n";
- print 'Als temporaere Namen wurden in dieser Reihenfolge ermittelt:'."\n\n";
- print $liste."\n"
- } else {
- print "bin fertig! \n"
- }
- # =================== Funktionen ================================
- #--------------------------------------------------------------------
- # Funktion: Liest die dhcpd.leases ein und erstellt eine Datenliste
- # Aufruf: @daten = &einlesen_leases($pfad);
- # Input: Pfad zur Datei dhcpd.leases
- # Output: Liste von Strings: IP, Rechnername, MAC, Gruppe
- # Bemerk.: Es wird dieses File (siehe bei Input) eingelesen
- # Bemerk.: die Gruppe ist einfach der String 'Raum'
- # Update: 24.10.2005
- #--------------------------------------------------------------------
- sub einlesen_leases {
- my $datei = shift; # Pfad zur lease-Datei
- my ($hostname, $mac, $ip, @daten, @temp);
- # die Datei einlesen
- open (DATEI,'<'.$datei) or die "die Datei wurde nicht gefunden";
- @daten = <DATEI>;
- close DATEI;
- foreach my $zeile (@daten) {
- if ($zeile =~ /lease\s+(\d+\.\d+\.\d+\.\d+)/i) { $ip = $1 }
- if ($zeile =~ /client-hostname\s*"?(\S*)";?/i) { $hostname = $1 }
- if ($zeile =~ /ethernet\s+(\w+:\w+:\w+:\w+:\w+:\w+)/) { $mac = $1 }
- if ($zeile =~ /}/ and defined($ip)) {
- # sichern die Werte in die Liste @pcs
- push @temp, $ip.','.$hostname.','.$mac.',Raum';
- # wir initialisieren die Variablen neu
- $hostname = $mac = $ip = "";
- }
- }
- return @temp;
- }
- #--------------------------------------------------------------------
- # Funktion: vernichtet die Doubletten bzgl. MAC und Name
- # Aufruf: @daten = &vernichte_Doubletten(@daten);
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Update: 24.10.2005
- #--------------------------------------------------------------------
- sub vernichte_Doubletten {
- my @daten = @_;
- my @temp = ();
- my %h = ();
- my ($pc,$ip,$mac,$gruppe);
- # jeder Datensatz kommt in den Hash %h: $h{$mac} -> Datensatz
- foreach my $datensatz (@daten) {
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- $h{$mac} = $datensatz;
- }
- # und dann wird daraus wieder eine Liste erstellt
- foreach my $ds (keys %h) {
- push @temp, $h{$ds}
- }
- # jeder Datensatz kommt in den Hash %h: $h{$pc} -> Datensatz
- %h = ();
- foreach my $datensatz (@temp) {
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- $h{$pc} = $datensatz;
- }
- # und dann wird daraus wieder eine Liste erstellt
- @daten = ();
- foreach my $rechner (keys %h) {
- push @daten, $h{$rechner}
- }
- return @daten
- }
- #--------------------------------------------------------------------
- # Funktion: Ermittelt temporaeren Gruppennamen, schreibt ins 4. Feld
- # Aufruf: @daten = &bestimme_Gruppen($regex,@daten);
- # Input: Regex als Bildungsvorschrift fuer den Rechnernamen
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Update: 24.10.2005
- #--------------------------------------------------------------------
- sub bestimme_Gruppen
- {
- my $regex = shift; # die Regex uebergeben
- my @liste = @_; # es wird @daten uebergeben
- my ($pc,$ip,$mac,$gruppe,@temp);
- foreach my $datensatz (@liste) {
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- if ($pc =~ /$regex/i) { # wir suchen den Gruppenname
- $gruppe = $1
- } else {
- $gruppe = $pc # sonst den ganzen Rechnername
- }
- push @temp, $ip.','.$pc.','.$mac.','.$gruppe
- }
- return @temp
- }
- #--------------------------------------------------------------------
- # Funktion: Ermittelt eine doublettenfreie Liste der Gruppennamen
- # Aufruf: @liste = &bestimme_Gruppenliste(@daten);
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: der String Gruppe1,Gruppe2,Gruppe3,Gruppe4,...
- # Update: 24.10.2005
- #--------------------------------------------------------------------
- sub bestimme_Gruppenliste {
- my @daten = @_;
- my $liste = "";
- my ($pc,$ip,$mac,$gruppe,%h);
- foreach my $datensatz (@daten) {
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- $h{$gruppe} = 1; # Gruppenname in den Hash
- }
- foreach my $x (keys %h) {
- $liste .= $x.',' ;
- }
- chop($liste); # das letzte Komma weg
- return $liste
- }
- #--------------------------------------------------------------------
- # Funktion: sortiert $liste und @daten (nach Anzahl der PCs)
- # Aufruf: ($liste,@daten) = &sortieren($liste,@daten);
- # Input: der String Gruppe1,Gruppe2,Gruppe3,Gruppe4,...
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: der sortierte String Gruppe1,Gruppe2,Gruppe3,...
- # Output: die sortierte Liste @daten "IP,Rechnername,MAC,Gruppe"
- # Update: 24.10.2005
- #--------------------------------------------------------------------
- sub sortieren {
- my $liste = shift;
- my @daten = @_;
- my ($pc,$ip,$mac,$gruppe); # zum Zerlegen des Datensatzes
- my (@gruppen,%h,%anz); # Gruppen, Hash auf DS und Anzahl
- my (@tmp,@tmp2,@tmp3,%namen);
- # den String zerlegen, damit wir auf jede Gruppe zugreifen koennen
- @gruppen = split ',', $liste;
- # wir legen jetzt fuer jede Gruppe eine Liste an und erzeugen
- # einen Hash %h mit $h{Gruppenname} -> Zeiger auf die Liste
- foreach my $gr (@gruppen) {
- my @temp = ();
- # fuer jeden Datensatz
- foreach my $datensatz (@daten) {
- # zerlege den Datensatz und hole die Gruppe
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- if ($gr eq $gruppe) { push @temp, $datensatz };
- }
- $h{$gr} = \@temp;
- }
- # wir holen uns von jeder Gruppe die Anzahl und erzeugen
- # einen Hash %anz mit $anz{Gruppenname} -> Anzahl
- foreach my $gr (@gruppen) {
- my $ref = $h{$gr};
- my $anz = @$ref;
- $anz{$gr} = $anz
- }
- # eine sortierte Liste der Gruppen erzeugen (groesste zuerst)
- @gruppen = sort {$anz{$b} <=> $anz{$a} or lc($a) cmp lc($b)} keys %anz;
- # wir basteln aus der Liste einen String, Trennzeichen Komma
- $liste = ""; # initialisieren
- foreach my $element (@gruppen) {
- $liste .= $element.','
- } # das letzte Komma wieder weg
- chop($liste); # -> unser erster Rueckgabewert
- # wir sortieren jetzt jede Gruppe nach dem Rechnernamen
- @tmp2 = ();
- foreach my $gr (@gruppen) {
- my $ref = $h{$gr};
- @tmp = @$ref;
- # fuer jeden Datensatz dieser Gruppe
- %namen = ();
- foreach my $datensatz (@tmp) {
- # zerlege den Datensatz und hole den Rechnername und erzeuge
- # einen Hash %namen mit $namen{Rechnername} -> Datensatz
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- $namen{$pc} = $datensatz;
- }
- # fuer jeden Rechnernamen dieser Gruppe hole den Datensatz
- @tmp3 = ();
- foreach my $pc (sort keys %namen) {
- push @tmp3, $namen{$pc}
- }
- push @tmp2, @tmp3
- }
- return ($liste,@tmp2)
- }
- #--------------------------------------------------------------------
- # Funktion: es wird der Gruppenname generiert (RaumXX)
- # Aufruf: $liste2 = &generiere_Gruppennamen($name,$liste);
- # Input: der String $name wird im Konfigurationsteil festgelegt
- # Input: die String $liste enthält die sortierten Gruppennamen
- # Output: der String mit Raum01,Raum02,Raum03,...
- # Update: 25.10.2005
- #--------------------------------------------------------------------
- $liste2 = &generiere_Gruppennamen($name,$liste);
- sub generiere_Gruppennamen {
- my $name = shift;
- my $liste = shift;
- my $liste2 = "";
- my @gruppe = ();
- my $zaehler = 1;
- # wir bauen den Formatstring
- my ($temp,$anz) = split ':', $name;
- my $string = '%0'.$anz.'u';
- # wir zerlegen den String $liste in eine echte Liste
- @gruppe = split ',' , $liste;
- # nun erzeugen wir die Namensliste
- foreach my $gruppe (@gruppe) {
- $temp = sprintf($string,$zaehler);
- $liste2 .= 'Raum'.$temp.',';
- $zaehler++;
- }
- chop ($liste2);
- return $liste2
- }
- #--------------------------------------------------------------------
- # Funktion: # es wird das 4. Feld von @daten ueberschrieben
- # Aufruf: @daten = &setze_Gruppenname($liste,$liste2,$namen,@daten);
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Update: 25.10.2005
- #--------------------------------------------------------------------
- sub setze_Gruppenname {
- my $liste = shift;
- my $liste2 = shift;
- my $namen = shift;
- my @daten = @_;
- my ($ip,$pc,$mac,$gruppe);
- my @neu = ();
- my %namen = ();
- my @neuername = ();
- my @tempnamen = split ',', $liste;
- my @gen_name = split ',', $liste2;
- if (defined($namen)) {
- @neuername = split ',', $namen
- }
- my $help1 = "";
- my $help2 = "";
- foreach my $name (@tempnamen) {
- $help1 = shift @gen_name;
- $help2 = shift @neuername;
- if (defined($help2)) {
- $namen{$name} = $help2
- } else {
- $namen{$name} = $help1
- }
- }
- foreach my $datensatz (@daten) {
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- if (defined($namen{$gruppe})) {
- $gruppe = $namen{$gruppe}
- }
- push @neu, $ip.','.$pc.','.$mac.','.$gruppe;
- }
- return @neu;
- }
- #--------------------------------------------------------------------
- # Funktion: setzt die IP-Werte nach der Vorgabe im Wiki
- # Aufruf: @daten = &setze_ip(@daten);
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Update: 25.10.2005
- #--------------------------------------------------------------------
- sub setze_ip {
- my @daten = @_;
- my $gr = "";
- my ($pc,$ip,$mac,$gruppe,@temp);
- my $start1 = undef;
- my $start2 = 21;
- my $ip1 = $start1;
- my $ip2 = $start2;
- # fuer jeden Datensatz tue
- foreach my $datensatz (@daten) {
- # zerlege den Datensatz und hole die Gruppe
- ($ip,$pc,$mac,$gruppe) = split ',', $datensatz;
- if ($gr ne $gruppe) {
- $gr = $gruppe;
- unless (defined($ip1)) {
- $ip1 = 0
- } else {
- $ip1++
- }
- $ip2 = $start2
- } else {
- $ip2++
- }
- push @temp, '192.168.'.$ip1.'.'.$ip2.','.$pc.','.$mac.','.$gruppe;
- }
- return @temp
- }
- #--------------------------------------------------------------------
- # Funktion: schreibt die gesuchte Datei (normalerweise 'computer')
- # Aufruf: &schreibe_datei($datei,@daten);
- # Input: Pfad zur zur schreibenden Datei
- # Input: die Liste @daten aus "IP,Rechnername,MAC,Gruppe"
- # Output: die Datei 'computer' auf die Festpaltte
- # Update: 25.10.2005
- #--------------------------------------------------------------------
- sub schreibe_datei {
- my $datei = shift;
- my @daten = @_;
- open (DATEI, ">$datei.txt") or die "konnte Datei $datei nicht oeffnen $!";
- foreach my $datensatz (@daten) {
- print DATEI $datensatz."\n"
- }
- close DATEI
- }
--Kirmse 10:11, 25. Okt 2005 (CEST)