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 my $conf; # alte dhcpd.conf my $leases; # alte dhcpd.leases
# =================== 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 'conf=s' => \$conf, # Pfad fuer alte dhcpd.conf 'leases=s' => \$leases); # Pfad fuer alte dhcpd.leases
# wenn Regex uebergeben, dann wird Voreinstellung ueberschrieben
if (defined($reg)) { $regex = $reg }
# wenn leases-Datei uebergeben, dann wird Voreinstellung ueberschrieben
if (defined($leases)) { $leasedatei = $leases }
# ------- 2. Schritt: Einlesen der Daten ------------------------
# wenn eine conf-Datei uebergeben wurde, dann wird diese genommen
if (defined($conf)) {
@daten = &einlesen_conf($conf)
} else {
@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
unless (defined($conf) or defined($leases)) {
@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: Liest alte(!) dhcpd.conf ein und erstellt eine Datenliste
# Aufruf: @daten = &einlesen_conf($pfad);
# Input: Pfad zu einer Datei dhcpd.conf
# 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_conf {
my $datei = shift; # Pfad zur lease-Datei
my ($hostname, $mac, $ip, @daten, @temp, @tmp);
# die Datei einlesen open (DATEI,'<'.$datei) or die "die Datei $datei wurde nicht gefunden \n$!"; @daten = <DATEI>; close DATEI;
# wir vernichten jetzt alle Kommentar
@temp = @tmp = ();
foreach my $zeile (@daten) {
if ($zeile =~ /#/) {
@tmp = split '#', $zeile;
push @temp, $tmp[0]."\n"
} else {
push @temp, $zeile
}
}
@daten = @temp;
# jetzt holen wir uns die Daten
$hostname = $mac = $ip = "";
@temp = @tmp = ();
foreach my $z (@daten) {
if ($z =~ /host\s+(\S+)\s*{/) { $hostname = $1 };
if ($z =~ /hardware ethernet\s+(\w+:\w+:\w+:\w+:\w+:\w+)/){$mac = $1}
if ($z =~ /fixed-address\s/) {
if ($z =~ /fixed-address\s+(\d+\.\d+\.\d+\.\d+);?/){
$ip = $1
} else {
$ip = '192.168.X.XX' # falls die IP im DNS steht
}
}
if (($z =~ /}/) and ($mac ne "")) {
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") or die "konnte Datei $datei nicht oeffnen $!";
foreach my $datensatz (@daten) {
print DATEI $datensatz."\n"
}
close DATEI
}
Achja, ich programmiere nicht auf Arktur 4, deshalb im Konfigurationsteil die Pfade anpassen
--Kirmse 22:20, 25. Okt 2005 (CEST)