License

Copyright (C) 2008-2021 Oliver Bohlen.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

A copy of the license is included in the section entitled "GNU Free Documentation License".

Introduction

This documentation comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.

Howto: Automatic System Documentation for Gentoo Linux

This howto shows the perl-script(s) to automatically create my system-documentation with all changes in all config-files. So this has been generated with it as well.

If you want to use this solution you need the following howto(s) finished:

Changes in /etc/local.d/01_services.start

File permissions:
Owner: root
Group: root
Permissions: -rwxr-xr-x

Click here for a download of the complete file: /etc/local.d/01_services.start

Changed on 13.01.09
Issued by olli
Beginning line 6

Start the changedocd-daemon at system boot.

#/usr/local/bin/changedocd.pl

Changes in /usr/local/bin/changedocd.pl

File permissions:
Owner: root
Group: apache
Permissions: -rwxr-x---

Click here for a download of the complete file: /usr/local/bin/changedocd.pl

Changed on 27.04.10
Issued by olli
Beginning line 2

This is the daemon for getting the data from the CGI and changeing the Comments directly in the Config-Files

#!/usr/bin/perl


# Daemon start
use Proc::Daemon;
Proc::Daemon::Init;
use Net::SMTP;

while (1) {
$before="";
$after="";
$intro="";
if (-f "/tmp/changedoc") {
 open(CHANGE, "</tmp/changedoc");
 @change=<CHANGE>;
 close(CHANGE);
 
 if ($change[0] =~ /^[0-9]+$/) {

 foreach $line (@change) {
   chomp ($line);
 }
  $linenr=$change[0];
  $file=$change[1];
  $comment=$change[2];
 
  open(FILE, "<$file");
  @file=<FILE>;
  close(FILE);
  $linecount=1;
  #print "<br>$linenr<br>";
  foreach $line (@file) {
   if (($line=~/\|\|\|/) && ($linenr==$linecount)) {
    $found=1;
    $before=$line;
    $line=~s/(.+)\|\|\|.+$/$1|||$comment/;
    $after=$line;
   }
   $linecount++;
  }
  #print "\n$file";
  open(NFILE, ">$file");
  print NFILE @file;
  close(NFILE);
  $mailtxt="Hi,

change in file $file on line $linenr
Before change: 
$before

------------------------------------------

After change:
$after

Bye $0
";
  $mail_pass=`gtc-crypt -a admin -p`;
  chomp($mail_pass);
  $smtp = Net::SMTP->new('localhost') || warn ("Could not connect to Mailserver on localhost\n$!");
  $smtp->auth('admin', $mail_pass ) || warn ("Could not authenticate to Mailserver\n$!");
  $mail_pass="";
  $smtp->mail('mail@example.com') || warn ("Could not enter sender address\n$!");
  $smtp->to('mail@example.com') || warn ("Could not enter recipient\n$!");
  $smtp->data() || warn ("Could not open data channel\n$!");
  $smtp->datasend("To: user1\@example.com\n") || warn ("Could not send header\n$!");
  $smtp->datasend("Subject: Change in $file\n") || warn ("Could not send header\n$!");
  $smtp->datasend("\n") || warn ("Could not send header\n$!");
  $smtp->datasend("$mailtxt") || warn ("Could not send body\n$!");
  $smtp->dataend() || warn ("Could not close data channel\n$!");
  $smtp->quit || warn ("Could not close connection\n$!");
 }
 else {
  $howto=$change[0];
  chomp($howto);
  $change[0]="";
  foreach $line (@change) {
   $intro=$intro . $line;
  }
  $after=$intro;

  open(INTRO, "</usr/local/etc/sysdoc/topics");
  @intro=<INTRO>;
  close(INTRO);
  $set=0;
  $next=0;
  $found=0;
  #print "$howto";
  foreach $line (@intro) {
   if ($next) {
    #print "Next gesetzt\n";
    #print "Zeile: $line";
    if ($line=~/\|\|\|/) {
     #print "next wird unwahr\n";
     $next=0;
     next;
    }
    if ($set) {
     #print "SET ist gesetzt\n";
     $before="$before$line";
     $line="";
     next;
    }
    else {
     #print "ELSE\n";
     $found=1;
     $before=$line;
     $line="$intro\n";
     #print "Zeile $line";
     $set=1;
    }
   }
   if ($line=~/^\|\|\|$howto\|\|\|/) {
    $next=1;
    #print "Howto gefunden";
   }
  }
  if ($found) {
   open(INTRO, ">/usr/local/etc/sysdoc/topics");
   foreach $line (@intro) {
#    while ($line =~ /\n$/) {
     $line=~s/^\n//;
     $line=~s/^\n$//;
#    }
    print INTRO $line;
   }
   close(INTRO);
  }
  $mailtxt="Hi,

change in Howto describtion for $howto
Before change:
$before

----------------------------

After change:
$after

Bye $0
";
  $mail_pass=`gtc-crypt -a admin -p`;
  chomp($mail_pass);
  $smtp = Net::SMTP->new('localhost') || warn ("Could not connect to Mailserver on localhost\n$!");
  $smtp->auth('admin', $mail_pass ) || warn ("Could not authenticate to Mailserver\n$!");
  $mail_pass="";
  $smtp->mail('mail@example.com') || warn ("Could not enter sender address\n$!");
  $smtp->to('mail@example.com') || warn ("Could not enter recipient\n$!");
  $smtp->data() || warn ("Could not open data channel\n$!");
  $smtp->datasend("To: user1\@example.com\n") || warn ("Could not send header\n$!");
  $smtp->datasend("Subject: Change in Howto describtion\n") || warn ("Could not send header\n$!");
  $smtp->datasend("\n") || warn ("Could not send header\n$!");
  $smtp->datasend("$mailtxt") || warn ("Could not send body\n$!");
  $smtp->dataend() || warn ("Could not close data channel\n$!");
  $smtp->quit || warn ("Could not close connection\n$!"); 
 }
 system("/usr/local/bin/sysdoc.pl fast");
 unlink("/tmp/changedoc");
}
sleep 1;
}

Changes in /usr/local/bin/sysdoc.pl

File permissions:
Owner: root
Group: root
Permissions: -rwxr-xr-x

Click here for a download of the complete file: /usr/local/bin/sysdoc.pl

Changed on 27.04.10
Issued by olli
Beginning line 2

This is the script that creates the search engine optimized, W3C validated HTML-documentation incl. Google Sitemap, Meta-Tags from headline, robots.txt, complete.html with all docs in one page,...

#!/usr/bin/perl

# Pfad wo die Webseiten liegen sollen
$webpath="/var/www/doc.example.com/htdocs";

# Impressum:
$impr='<h1>About / Impressum</h1>
<a href="impr.html">Click here for About / Impressum</a>
<h1>Wishlist</h1>
If you want to support my work you can find my Amazon whishlist <a href="http://www.amazon.de/registry/wishlist/308SONKPDDDT2">here</a>
';


# Werbung
$ad="";

# Wenn als Argument fast &uuml;bergeben wird, dann nur die Dateien neu einlesen, die schon eigelesen wurden.
if ($ARGV[0] eq "fast") {
 print "Not searching for new files!!!\n";
 # Kopien der beim letzen Mal analysierten Dateien liegen im Verzeichnis $webpath/files - Sortieren nach Alphabet
 @files=`find $webpath/files/ -type f | sort`;
 # $webpath/files/ aus dem @files-Elementen rausschneiden um dort nur die Dateinamen drin zu haben.
 foreach $f (@files) {
  $f=~s/^$webpath\/files//;
 }
}
else {
# Wenn nicht fast &uuml;bergeben wurde, dann diese Suchpfade benutzen - sortieren nach Alphabet:
 @files=`find /boot/grub/grub.cfg /etc /var/bind /gtc/test/etc /usr/local/bin /usr/local/sbin /usr/local/etc /var/www/www.example.com/htdocs/intern/phpldapadmin/config /gtc/pxe/pxelinux.cfg /var/www/horde.example.com/htdocs/config /var/www/horde.example.com/htdocs/imp/config /var/www/horde.example.com/htdocs/ingo/config /var/www/horde.example.com/htdocs/kronolith/config /var/www/horde.example.com/htdocs/mnemo/config /var/www/horde.example.com/htdocs/nag/config /var/www/horde.example.com/htdocs/passwd/config /var/www/horde.example.com/htdocs/turba/config /var/www/doc.example.com/cgi-bin /var/www/doc.example.com/htdocs/howto.css /gtc/test/usr/lib64/thunderbird/distribution /gtc/test/usr/lib64/thunderbird/defaults/pref /gtc/test/usr/lib64/firefox/distribution /gtc/test/usr/lib64/firefox/defaults/pref -type f | grep -v 'etc/thinclient/profiles' | sort`;
}

# Daten f&uuml;r die Meta-Tags (Suchmaschinenoptimierung)
$metaauthor="Oliver Bohlen";
$metashortdescr="Up-to-date Howto(s) and Documentation(s) for Gentoo Linux.";
# URL &uuml;ber die die Webseite aufgerufen wird
$url="http://doc.example.com";


$jahr=`date +%Y`;
# Lizenz informationen
$license="
  <h1>License</h1>
  <p>Copyright (C) 2008-$jahr $metaauthor.</p>
  <p>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.</p><p>
A copy of the license is included in the section entitled \"<a href=\"/license/fdl.html\">GNU Free Documentation License</a>\".</p>
  <h1>Introduction</h1>
  <p>This documentation comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.</p>
";

# Datum f&uuml;r die Google-Sitemap im speziellen Format. (Suchmaschinenoptimierung)
$sitemapdate=`date +\%Y-\%m-\%d`;
chomp($sitemapdate);
# Header f&uuml;r die Sitemap
$sitemap='<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
';
$sitemap.=" <url>
  <loc>$url/</loc>
  <lastmod>$sitemapdate</lastmod>
  <changefreq>monthly</changefreq>
  <priority>0.2</priority>
 </url>";

# Erstellungsdatum holen
$createdate=`date +\%Y-\%m-\%d`;
chomp($createdate);
# Erstellungsdatm f&uuml;r Metatags im speziellen Format (Suchmaschinenoptimierung)
$metadate=`date +\%Y-\%m-\%m:\%S\%:z`;
chomp($metadate);
# Ende des Titels f&uuml;r jede Seite
$htmltitle="for Gentoo Linux";
# Doctype f&uuml;r saubere HTML-Spezifikation
$doctype='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">';
# L&ouml;schen der "alten" Dateiversionen
`rm -rf $webpath/files/*`;
# Liste von Konfigurationsdateien durchgehen.
foreach $file (@files) {
 chomp($file);
 # libpicker.pl ignorieren ???
 if ($file =~ /libpicker.pl/) { next }
 # Dateien nur einlesen wenn der Dateityp am text, bzw. XML ist, also wenn es sich um Textdateien handelt
 if (`file -b $file` =~ /[text|XML|text, with very long lines]\n$/) {
  # Zeilenz&auml;hler auf 0 setzen. ( Wegen vorheriger durchl&auml;ufe)
  $linenr=0;
  # Konfigurationsdatei &ouml;ffnen und zeilenweise in Array @lines speichern
  open(CONF, "<$file");
  @lines=<CONF>;
  close(CONF);
  # Dateiinhaltsvariable initialisieren bzw. wegen ggf. vorheriger druchl&auml;ufe l&ouml;schen.
  $filecontent="";
  # Pr&uuml;fvariable ob es sich um den Anfang einer &Auml;nderung (before-Markierung) vom default handelt wegen ggf. vorheriger Druchl&auml;ufe auf false setzen.
  $ischangefile=0;
  # Zeilen der Konfigurationsdatei durchgehen.
  foreach $line (@lines) {
   # Wenn am Anfang der zeile keine before usw. -Markierung steht, dann bestimmte Schl&uuml;sselString filtern bzw. durch Dummy-Werte ersetzen
   unless ($line=~/before\|\|\|.*\|\|\|.*\|\|\|/) {
    # Filterungen von Passw&ouml;rtern, Telefonnummern usw. aus den Konfigurationsdateien. - Diese Filterungen ggf. in Extra Datei speichern
    #----------- FILTER -----------
    $line=~s/dyndns.kontent.com\/ipchange.php\?domain=example.com.*$/URL/g;
    $line=~s/PHONENUMBER:PASSWORD/PHONENUMBER:PASSWORD/g;
    $line=~s/PHONENUMBER2:PASSWORD2/PHONENUMBER2:PASSWORD2/g;
    $line=~s/SIP-PROVIDER-HOSTNAME/SIP-PROVIDER-HOSTNAME/g;
    $line=~s/PHONENUMBER/PHONENUMBER/g;
    $line=~s/PHONENUMBER2/PHONENUMBER2/g;
    $line=~s/DIALPREFIX/DIALPREFIX/g;
    $line=~s/PHONENUMBER/PHONENUMBER/g;
    $line=~s/PHONENUMBER2/PHONENUMBER2/g;
    $line=~s/MOBILEPHONENUMBER/MOBILEPHONENUMBER/g;
    $line=~s/secret=PASSWORD
    $line=~s/[a-z-]+\@[a-z-\.]+/mail\@example.com/g;
    $line=~s/relay.mail.server/relay.mail.server/g;
    $line=~s/DeviceURI smb\:\/\/.*$/DeviceURI smb\:\/\/user\:password\@server\/printername/;
    $line=~s/&auml;/&auml;/g;
    $line=~s/whitelist_from mail@example.com
    $line=~s/&ouml;/&ouml;/g;
    $line=~s/&uuml;/&uuml;/g;
    $line=~s/&Auml;/&Auml;/g;
    $line=~s/&Ouml;/&Ouml;/g;
    $line=~s/&Uuml;/&Uuml;/g;
    $line=~s/&szlig;/&szlig;/g;
    $line=~s/&/&amp;/g;
    $line=~s/^HOTP.+$/HOTP\/T30\/6 username - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/g;
    $line=~s/gabosh\.net/example\.com/g;
    $line=~s/dc=example,dc=com/dc=example,dc=com/g;
    $line=~s/my.lan.ip.addr/my.lan.ip.addr/g;
    $line=~s/my.lan.network.ip/my.lan.network.ip/g;
    $line=~s/my.default.route.ip/my.default.route.ip/g;
    $line=~s/my.dmz.ip.addr/my.dmz.ip.addr/g;
    $line=~s/my.dmz.network.ip/my.dmz.network.ip/g;
    $line=~s/conf_passwdkey="12345678901234567890123456789012";
    $line=~s/conf_passwdfile="/path/for/passwd/dbfile";
    $line=~s/conf_passwddiv='1234567890123456'
    $line=~s/wpa_passphrase=secret
    $line=~s/\{SSHA\}.*$/\{SSHA\}XXXXXXXXXXXXXXXXXXXXXXXXX/;
    $line=~s/^\$key\=\"31894.*/\$key\=\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\;/;
    $line=~s/psk="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    $line=~s/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/g;
    $line=~s/\/usr\/local\/sbin\/gentoolydyndns.sh/ez-ipupdate -q -a `wget -q -O - http:\/\/getip.dyndns.org | sed -e "s\/^.*: \/\/" -e "s\/<.*\$\/\/"` -S dyndns-custom -h yourhostname.dyndns.org -m yourmailmx.example.com -u dyndnsuser:dyndnspass`/g;
    $line=~s/password'] = 'XXXXXXXX'
    unless (($line=~/0.0.0.0/) || ($line=~/127.0.0.1/) || $line=~/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\./) {
     $line=~s/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/XXX\.XXX\.XXX\.XXX/g;
    }
    $line=~s/23\.172/XXX.XXX/g;
    $line=~s/1\.1\.10/XXX.XXX.XXX/g;
    $line=~s/1\.168\.192/XXX.XXX.XXX/g;
    if ($line=~/^[0-9]+\.[0-9]+.*IN.*PTR/) {
     $line=~s/^[0-9]+\.[0-9]+/XXX.XXX\t/;
    }
    if ($line=~/^[0-9]+.*IN.*PTR/) {
     $line=~s/^[0-9]+/XXX\t/;
    }
    if (($file=~/\/var\/bind\/zones\//) && ($line=~/^\;/) && ($line!~/^\; before/) && ($line!~/^\; after/) && ($line!~/^\; \-\-\-\-/)) { $line="" }
    $line=~s/..\:..\:..\:..\:..\:../XX\:XX\:XX\:XX\:XX\:XX/g;
    $line=~s/username_ppp0='provideruser'
    $line=~s/password_ppp0='providerpass'
    $line=~s/user1/user1/ig;
    $line=~s/user2/user2/ig;
    $line=~s/user3/user3/ig;
    #----------- FILTER ENDE -----------
   }
   # Zeile an Variable f&uuml;r Dateiinhalt nach der Filterung anf&uuml;gen.
   $filecontent.=$line;
   # Zeilennummer hochz&auml;hlen
   $linenr++;
   # Newline (\n) von Zeile entfernen
   chomp($line);
   # Zeile f&uuml;r weitere Pr&uuml;fungen kopieren...???
   $cline=$line;
   # Wenn es sim um eine Endmarkierung f&uuml;r eine &Auml;nderung handelt und die doc-Pr&uuml;fvariable gesetzt ist, es sich also tats&auml;chlich um eine &Auml;nderung handelt, dann die Ausgabe in der Doku hier beenden.
   if ((($line =~ /# \----/) || ($line =~ /; \----/) || ($line =~ / \----$/) || ($line =~ /\<!-- END --\>/) || ($line =~ /\%\% \----$/)) && ($doc)) {
    # HTML-Code zum beenden der &Auml;nderungsdarstellung.
    $topics{$topic}.="</pre>\n <br>\n";
    # Ab jetzt handelt es sich nicht mehr um einen Teil, der dokumentiert werden muss, da das Ende der &Auml;nderung erreicht ist.
    $doc=0;
    # Weiter mit der n&auml;chsten Zeile...
    next;
   }
   # Wenn wir uns in einer Zeile, die zu einem zu dokumentierenden Bereich, also nach der before-Zeile befinden, dann...
   if ($doc) {
    # ... und wenn in der Zeile ein after ohne das dahinter steht ...
    if ($line =~ / after$/) {
     # ... und wenn es sich um eine Datei&auml;nderung handelt, ohne dass sich eine vorhandene Zeile ge&auml;ndert hat ...
     if ($noprintafterchange) {
      # ... dann die After-Change-Markierung in die Doku einf&uuml;gen
      $topics{$topic}.="</pre>\n  After change<pre class=\"after\">\n";
     }
     else {
      # ansonsten ohne die After-Change-Markierung in die Doku einf&uuml;gen
      $topics{$topic}.="  <pre class=\"after\">\n";
     }
     # Pr&uuml;fvariable setzen um zu markieren, dass die After-Zeile durchlaufen wurde - Jetzt kommt also das Ge&auml;nderte, nicht mehr der alte Zustand.
     $nachher=1;
     # In der n&auml;chsten Zeile fortfahren...
     next;
    }
    # Hier handelt es sich also um den Bereich zwischen before und ----, aber nicht die after-Zeile
    # Ein paar HTML-Standarf-Konforme anpassungen f&uuml;r Sonderzeichen
    $line =~ s/</\&lt;/g;
    $line =~ s/>/\&gt;/g;
    # Wenn es sich um Inhalte zwischen before und after handelt, dann die zus&auml;tzlichen Kommentarzeichen am Zeilenanfang l&ouml;schen.
    unless ($nachher) {
     $line=~s/^# //;
     $line=~s/^; //;
    }
    # Zeile der Doku zu diesem Thema hinzuf&uuml;gen
    $topics{$topic}.="$line\n";
    # In der n&auml;chsten Zeile fortfahren....
    next;
   }
   # Wenn in der Zeile echo<IRGENDWAS>before steht, dann mit der n&auml;chsten Zeile fortfahren...???
   if ( $cline =~ /echo.*before/ ) { 
   # $topics{$topic}.="$line\n";
    next;
   }
   # Wenn es sich um eine before-Zeile handelt.
   if ( $cline =~ / before\|\|\|/) {
    # Markierung f&uuml;r die ver&auml;nderte Datei setzen.
    $ischangefile=1;
    # Markierung setzen, dass die After-Zeile noch nicht durchlaufen wurde.
    $nachher=0;
    # Die Zeile in an den |||-Trennern aufsplitten
    @line=split(/\|\|\|/, $cline);
    # &Auml;nderungsdatum dieser &Auml;nderung aus dem Split holen.
    $date=$line[1];
    # ggf. Leerzeichen in dem Datum entfernen
    $date=~s/[ ]+//g;
    # ggf. folgende Zeichen #, <!--, ; entfernen...?
    $date=~s/^[#|<!--|;]//; 
    # Person die diese &Auml;nderung vorgenommen hat aus dem Split holen.
    $editor=$line[2];
    # Thema zu dem diese &Auml;nderung geh&ouml;rt aus dem Split holen.
    $topic=$line[3];
    # Kommentar zu dieser &Auml;nderung aus dem Split holen.
    $comment=$line[4];
    # Falls topic nicht gesetzt ist auf "not defined" setzen
    $topic="not defined" unless $topic;
    # Datei und Thema zusammenf&uuml;gen um ...
    $filetopic=$file . $topic;
    # ... zu pr&uuml;fen ob schon eine &Auml;nderung zu diesem Topic in dieser Datei gab, damit die Daten &uuml;ber die Datei selbst nicht mehrmals pro Thema aufgef&uuml;hrt werden
    if ($oldfiletopic ne $filetopic) {
     # ... Daten &uuml;ber die datei ermitteln und als HTML-Code der Doku hinzuf&uuml;gen
     # Eigent&uuml;mer/Gruppe und Zugriffsrechte der Dtaei besorgen
     $rights=`ls -ld $file`;
     @rights=split(/ /, $rights);
     # Erstellen des Headers mit Infos &uuml;ber die Datei und dem link zur Ansicht der kompletten Datei 
     $topics{$topic}.="  <h2><a class=\"h2link\" name=\"$file-$topic\">Changes in $file</a></h2>
  <p><i>File permissions:</i> <br>
  <b>Owner</b>: $rights[2]<br>
  <b>Group</b>: $rights[3]<br>
  <b>Permissions</b>: $rights[0]<br>
  </p>
  <p><a download href=\"http://doc.example.com/files$file\">Click here for a download of the complete file: $file</a></p>\n";
     # Erstelle einen File-Eintrag auf der Startseite f&uuml;r den File Index
     $index .= "  <a href=\"#$file-$topic\">$file ($topic)</a><br>\n";
     # Da die HTML-Datei f&uuml;r das Thema wegen Suchmaschinenoptimierung m&ouml;glichst so heissen sollte wie das Thema selbst wird der Topic-Name mit ein paar Einschr&auml;nkungen (Sonderzeichen in internationalen-Browsern in Dateinamen sind ung&uuml;nstig) &uuml;bernommen 
     $topic_file=$topic;
     # ggf. alle nicht latein-alphanummerischen Zeichen in _ umwandeln
     $topic_file=~s/[^a-zA-Z0-9]/_/g;
     # ggf. mehrere _ hintereinander durch ein _ ersetzen.
     $topic_file=~s/_+/_/g;
     # Markierung in HTML-Code f&uuml;r direkte Links von der Startseite (index.html) auf die Datei in der entsprechenden Doku/Howto
     $pindex .= "  <a href=\"http://doc.example.com/howto_$topic_file.html#$file-$topic\">$file ($topic)</a><br>\n";
    }
    # HTML-Code mit Infos &uuml;ber die &Auml;nderung.
    $topics{$topic}.="  <i class=\"small\">Changed on $date</i><br>
  <i class=\"small\">Issued by $editor</i><br>
  <i class=\"small\">Beginning line $linenr</i><br>
  <!-- $file|||$linenr --><p class=\"comment\">$comment</p>\n";
    # Grunds&auml;tzlich davon ausgehen, dass es sich nicht um eine &Auml;nderung einer vorhandenen Zeile handelt
    $noprintafterchange=0;
    # Wenn in der n&ouml;chsten Zeile ein after steht, dann handelt es sich doch um eine hinzugef&uuml;gte Zeile und nicht um eine &auml;nderung einer vorhandenen Zeile
    unless ($lines[$linenr] =~ /after$/) {
     # ... Die Before change &Uuml;berschrift einf&uuml;gen um die Zeile(n) die ge&auml;ndert wurden auszugeben.
     $topics{$topic}.="  <br>Before change<pre class=\"before\">\n";
     # entsprechende MArkierung setzen also daf&uuml;r, dass es es sich un eine &Auml;nderung einer existierenden Zeile handelt.
     $noprintafterchange=1;
    } 
    # Oldfiletopic setzen um mit der n&auml;chsten Anderung zu vergleichen
    $oldfiletopic=$file . $topic;
    # Markierung, dass ab hier die Doku zur &Auml;nderung beginnt
    $doc=1;
   }
  }
  if ($ischangefile) {
   print "$file\n";
   $path=$file;
   @pathparts=split(/\//, $path);
   pop(@pathparts);
   $path="";
   foreach $pathpart (@pathparts) {
    $path.="/$pathpart";
   }
   $path=~s/^\/\//\//;
   `mkdir -p $webpath/files$path`;
   open(FILE, ">$webpath/files$file") || warn "Konnte Datei $webpath/files$file nicht &ouml;ffnen";
   print FILE $filecontent;
   close(FILE);
  }
 }
}

$topics="  <h1><a class=h1link name=howtos>Howto listing</a></h1>\n";
$itopics="  <h1><a class=h1link name=howtos>Howto listing</a></h1>\n";
#`rm -rf $webpath/howto_*`;
foreach $topic (sort keys %topics) {
 $content .= "  <h1><a class=\"h1link\" name=\"t-$topic\">$topic</a></h1>\n";
 $metakeywords.="$topic, ";
 $tfile="$doctype
<html>
 <head>
  <title>Howto: $topic $htmltitle</title>
  <meta name=\"description\" content=\"$topic - $metashortdescr\">
  <meta name=\"date\" content=\"$metadate\">
  <meta name=\"author\" content=\"$metaauthor\">
  <meta name=\"keywords\" content=\"$topic, howto, documentation, gentoo, linux, up to date, up-to-date, new\">
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">
  <meta name=\"robots\" content=\"all\">
  <meta http-equiv=\"expires\" content=\"0\">
  <link rel=\"stylesheet\" type=\"text/css\" href=\"/howto.css\">
 </head>
 <body><div class=\"frame\">
  $ad
  $license
  <h1>Howto: $topic $htmltitle</h1>\n ";
 open (TOPICSFILE, "</usr/local/etc/sysdoc/topics");
 @topicsfile=<TOPICSFILE>;
 close(TOPICSFILE);
 $topicfile_desc=0;
 $topicdesc="";
 $topicfile_deps="";
 $topicfile_hw="";
 $topicfile_sw="";
 $topicfile_service="";
 $topicfile_topic="";
 if ($topic =~ /^Thinclient - /) {
  $prefix="chroot /gtc/test /bin/bash -c 'env-update &>/dev/null && source /etc/profile && ";
  $end="'";
 }
 else {
  $prefix="";
  $end="";
 }
 foreach $topicsfileline (@topicsfile) {
  if ($topicsfileline =~ /^\#/) { next }
  if ($topicsfileline =~ /^\|\|\|$topic/) {
   chomp($topicsfileline);
   @topicsfileline=split(/\|\|\|/, $topicsfileline);
   $topicfile_topic = $topicsfileline[1];
   $topicfile_deps = $topicsfileline[2];
   $topicfile_sw = $topicsfileline[3];
   $topicfile_service = $topicsfileline[4];
   $topicfile_hw = $topicsfileline[5];
   $topicfile_desc=1;
   $topicsfileline="";
   next;
  }
  if ($topicfile_desc) {
   if ($topicsfileline =~ /^\|\|\|/) {
    last;
   }
   $topicsfileline=~s/\n/\<br\>/g;
   $topicdesc.=$topicsfileline;
  }
 }
 $content .= $topicdesc;
 $topicdesc=~s/\n/<br>/g;
 $tfile .= "<!-- $topic --><p class=\"intro\">$topicdesc</p>\n";
 if ($topicfile_deps) {
  $content .= "  <p>If you want to use this solution you need the following howto(s) finished:</p>\n  <ul>";
  $tfile .= "  <p>If you want to use this solution you need the following howto(s) finished:</p>\n  <ul>";
  @needtopics=split(/\,/, $topicfile_deps);
  foreach $topicdep (@needtopics) {
   $content .= "   <li><a href=\"#t-$topicdep\">$topicdep</a></li>\n";
   $tfile .= "   <li><a href=\"index.html#howtos\">$topicdep</a></li>\n";
  }
  $content .= "  </ul>";
  $tfile .= "  </ul>";
 }
 if ($topicfile_hw) {
  $content .= "<h2>Required hardware</h2>
  For this topic you need the following hardware: $topicfile_hw";
  $tfile .= "<h2>Required hardware</h2>
  For this topic you need the following hardware: $topicfile_hw";
 }
 if ($topicfile_sw) {
  $content .= "<h2>Required software</h2>
  The required software has to be installed with the following command(s):<pre>";
  $tfile .= "<h2>Required software</h2>
  The required software has to be installed with the following command(s):<pre>";
  @needsw=split(/ /, $topicfile_sw);
  foreach $swdep (@needsw) {
   $content .= $prefix."emerge $swdep"."$end\n";
   $tfile .= $prefix."emerge $swdep"."$end\n";
  }
  $content .= "</pre>";
  $tfile .= "</pre>";
 }
 $content .= $ad;
 $content .= $topics{$topic};
 $tfile .= $topics{$topic};
 if ($topicfile_service) {
  $content .= "<h2>Setting up services</h2>\n<p>For starting the new service after system reboot you should add it to a runlevel with the following command(s):</p>\n <pre>";
  $tfile .= "<h2>Setting up services</h2>\n<p>For starting the new service after system reboot you should add it to a runlevel with the following command(s):</p>\n <pre>";
  @needservice=split(/ /, $topicfile_service);
  $runlevel="";
  foreach $service (@needservice) {
   $runlevel=`$prefix rc-update show | grep " $service |"$end`;
   chomp($runlevel);
   $runlevel=~s/^*.\|//;
   $runlevel=~s/$service//g;
   $runlevel=~s/ //g;
   $content .= $prefix."rc-update add $service $runlevel"."$end\n";
   $tfile .= $prefix."rc-update add $service $runlevel"."$end\n";
  }
  $content .= "</pre>";
  $tfile .= "</pre>";
 }
 $topics .= "  <a href=\"#t-$topic\">$topic</a><br>\n";
 $itopic=$topic;
 $itopic=~s/[^a-zA-Z0-9]/_/g;
 $itopic=~s/_+/_/g;
 $itopics .= "  <a href=\"howto_$itopic.html\">$topic</a><br>\n";
 $content .= "  <p>
Please send a feedback to: <b>doc&lt;at&gt;example.com</b></p>
  <a href=\"#howtos\">Howto listing</a><br>
  <a href=\"#Index\">File Index</a>\n";
 $tfile .= "  $ad
 <p>
Please send a feedback to: <b>doc&lt;at&gt;example.com</b></p>
  <a href=\"index.html#howtos\">Howto listing</a><br>
  <a href=\"index.html#Index\">File Index</a><br><br>
  <p><a href=\"http://forums.gentoo.org\">Here</a> you can find the official Gentoo Linux Forums where you can find a lot of answers.</p>
  <p><a href=\"http://www.gentoo.org\">Here</a> a link to the official Gentoo Linux Homepage.</p>
  <p><a href=\"https://doc.example.com/edit/howto_$itopic.html\">Edit Howto</a></p>
  $impr
  </div>
 </body>
</html>";
 $tfilename=$topic;
 $tfilename=~s/[^a-zA-Z0-9]/_/g;
 $tfilename=~s/_+/_/g;
 $tfilename .= ".html";
 $oldtfile="";
 open(OLDTFILE, "<$webpath/howto_$tfilename");
 @oldtfile=<OLDTFILE>;
 close(OLDTFILE);
 foreach $line (@oldtfile) {
  $oldtfile.=$line;
 }
 $newtfile=$tfile;
 $oldtfile=~s/meta name=\"date\" content=.*\"\>//;
 $newtfile=~s/meta name=\"date\" content=.*\"\>//;
 open(TMP, ">/tmp/t1");
 print TMP $oldtfile;
 close(TMP);
 open(TMP, ">/tmp/t2");
 print TMP $newtfile;
 close(TMP);
 $diff=system("diff /tmp/t1 /tmp/t2");
 if ($diff) {
  print "Updateing $webpath/howto_$tfilename\n";
  open(TFILE, ">$webpath/howto_$tfilename");
  print TFILE $tfile;
  close(TFILE);
 }
 push(@tfilelist,"howto_$tfilename");
 $sitemap.="\n <url>
  <loc>$url/howto_$tfilename</loc>
  <lastmod>$sitemapdate</lastmod>
  <changefreq>monthly</changefreq>
  <priority>0.7</priority>
 </url>";
}
@oldtfilelist=`ls $webpath/howto_*`;
foreach $checkoldfile (@oldtfilelist) {
 chomp($checkoldfile);
 $newtfile=0;
 $createdtfile="";
 foreach $createdtfile (@tfilelist) {
  $createdtfiletest="$webpath/$createdtfile";
  if ($checkoldfile eq $createdtfiletest) { $newtfile=1 }
 }
 unless ($newtfile) {
  print "Deleting $checkoldfile\n";
  `rm $checkoldfile`;
 }
}
$html="$doctype
<html>
 <head>
  <title>Howtos $htmltitle</title>
  <meta name=\"description\" content=\"$metashortdescr\">
  <meta name=\"date\" content=\"$metadate\">
  <meta name=\"author\" content=\"$metaauthor\">
  <meta name=\"keywords\" content=\"gentoo, howto, documentation, linux, traffic, shaping, firewall, ldap, thin, up-to-date, up to date, new\">
  <meta name=\"robots\" content=\"all\">
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">
  <meta http-equiv=\"expires\" content=\"0\">
  <link rel=\"stylesheet\" type=\"text/css\" href=\"/howto.css\">
 </head>
 <body><div class=\"frame\">
  <h1>Howtos $htmltitle (latest version created: $createdate)</h1>
  <p>$metashortdescr</p>
<p>The special thing of this is that the Documentation generates automatically from my running system, so it is <b>every time up to date</b>.<br>Further this Howto is build <b>modular</b>. The Howtos are sorted in alphabetical order. Every topic has its dependencies. For example: You have to finish Webserver Howto for building webbased statistics.</p>
  <p>I hope to give something back to the community with this document.</p>
  <p>Please enjoy and send any ideas, wishes or advancements to: <b>doc&lt;at&gt;example.com</b>";
$hindex=$html;
$clicense="
  <h1>License</h1>
  <p>Copyright (C) 2008-$jahr $metaauthor.</p>
  <p>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.</p><p>
A copy of the license is included in the section entitled \"<a href=\"#FDL\">GNU Free Documentation License</a>\".</p>
  <h1>Introduction</h1>
  <p>This documentation comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.</p>
";
$html.=$clicense;
$html.=$topics;
$hindex.=$license;
$hindex.=$ad;
$hindex.="<h1>All in one page</h1>
 <a href=complete.html>Here</a> you can find the complete documentation in one page<br>
 $itopics";
$hindex.=$ad;
$html.=$content;
$html.="  <h1><a class=h1link name=Index>File Index</a></h1>" . $index . "\n";
open(LICENSE, "</usr/local/etc/sysdoc/license");
@license = <LICENSE>;
close(LICENSE);
$html .= "<h1><a class=h1link name=FDL>GNU Free Documentation License</a></h1>
@license";
$hindex .= "<h1><a class=h1link name=Index>File Index</a></h1>$pindex\n";
$html .= " </div></body>\n</html>";
$hindex .= "$impr\n</div></body>\n</html>";
open(DOC, ">$webpath/complete.html");
print DOC $html;
close(DOC);
$sitemap.="\n <url>
  <loc>$url/complete.html</loc>
  <lastmod>$sitemapdate</lastmod>
  <changefreq>weekly</changefreq>
  <priority>0.1</priority>
 </url>
</urlset>\n";

$oldifile="";
open(OLDIFILE, "<$webpath/index.html");
@oldifile=<OLDIFILE>;
close(OLDIFILE);
foreach $line (@oldifile) {
 $oldifile.=$line;
}
$newifile=$hindex;
$oldifile=~s/meta name=\"date\" content=.*\"\>//;
$newifile=~s/meta name=\"date\" content=.*\"\>//;
$oldifile=~s/created\:.*\>//;
$newifile=~s/created\:.*\>//;
open(TMP, ">/tmp/1");
print TMP $oldifile;
close(TMP);
open(TMP, ">/tmp/2");
print TMP $newifile;
close(TMP);
$diff=system("diff /tmp/1 /tmp/2");
if ($diff) {
 print "Updateing $webpath/index.html\n";
 open(IFILE, ">$webpath/index.html");
 print IFILE $hindex;
 close(IFILE);
}

`mkdir -p $webpath/license`;
open(LICENSE, ">$webpath/license/fdl.html");
print LICENSE "<html><head><title>FDL-License for example.com</title></head><body>@license</body></html>";

open(SITEMAP, ">$webpath/sitemap.xml");
print SITEMAP $sitemap;
close(SITEMAP);

# Create Editor
#system "/usr/local/bin/mkeditdoc.pl";
`rm $webpath/../edit/*`;
$howtodir=$webpath;
@howtos=`cd $howtodir; ls howto_*.html`;

foreach $howto (@howtos) {
 print $howto;
 chomp($howto);
 open(HOWTO, "<$howtodir/$howto") || die "Failed to open $howtodir/$howto";
 @howto=<HOWTO>;
 close(HOWTO);
 open(EHOWTO, ">$howtodir/../edit/$howto");
 foreach $howtoline (@howto) {
  if (($howtoline=~/<p class="comment"/) || ($howtoline=~/<p class="intro"/)) {
   if ($howtoline=~/-- .+ --./) {
    $target=$howtoline;
    @target=split(/--/, $howtoline);
    $target=$target[1];
    $target=~s/^ +//;
    $target=~s/ +$//;
   }
   $howtoline=~s/<br>/\n/g;
   $howtoline=~s/<p class=\"comment\">/<form action=\"\/cgi-bin\/changedoc.pl\" method=\"POST\"><textarea name=\"comment\" cols=\"115\" rows=\"25\">/;
   $howtoline=~s/<p class=\"intro\">/<form action=\"\/cgi-bin\/changedoc.pl\" method=\"POST\"><textarea name=\"intro\" cols=\"115\" rows=\"25\">/;
   if ($howtoline=~/textarea name="comment"/) {
    $howtoline=~s/<\/p>$/<\/textarea><input type="hidden" name="file" value="$target"><input type="submit" value="Submit"><\/form>/;
   }
   elsif ($howtoline=~/textarea name="intro"/) {
    $howtoline=~s/<\/p>$/<\/textarea><input type="hidden" name="howto" value="$target"><input type="submit" value="Submit"><\/form>/;
   }
   else {$howtoline=~s/<\/p>$/<\/textarea>/ }
   print EHOWTO $howtoline;
  }
  else {
   print EHOWTO $howtoline;
  }
 }
 close(EHOWTO);
}


`rsync -av --delete "$webpath"/ wlan-unten:/data/www/doc.example.com/htdocs/`;

unlink("/tmp/t1");
unlink("/tmp/t2");
unlink("/tmp/1");
unlink("/tmp/2");


Changes in /var/www/doc.gabosh.net/cgi-bin/changedoc.pl

File permissions:
Owner: root
Group: root
Permissions: -rwxr-xr-x

Click here for a download of the complete file: /var/www/doc.gabosh.net/cgi-bin/changedoc.pl

Changed on 27.04.10
Issued by olli
Beginning line 2

This is the CGI-script for editing the documentation

#!/usr/bin/perl

# Get the Data
read(STDIN, $line, $ENV{'CONTENT_LENGTH'});
@post = split(/&/, $line);

# Header for HTML output
print "Content-type:text/html\n\n";

$back=5;

if (-e "/tmp/changedoc") {
 $text="Working...</div></body></html>";
 $exit=1;
}
elsif ($ENV{HTTP_REFERER} !~ /https:\/\/doc\.gabosh\.net\/edit\/howto_/ ) {
 $text="</div><body></html>";
 $exit=1;
 $back="0;http://doc.example.com";
}


print "<html>
 <head>
  <title>Data submitted</title>
  <meta http-equiv=\"refresh\" content=\"$back\">
  <link rel=\"stylesheet\" type=\"text/css\" href=\"/howto.css\">
 </head>
 <body><div class=\"frame\"><h1>
 $text
 ";

if ($exit) {
 exit 0;
}

print "Hi $ENV{AUTHENTICATE_UID}, Working... Please wait...";

foreach $post (@post) {
 # Make + to Space
 $post=~s/\+/ /g;
 # Make Hex-Strings to ASCII
 $post=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
 if ($post=~/^intro\=/) {
  $intro=1;
 }
 if ($post=~/^comment\=/) {
  $comment=1;
 }
}

if ($intro) {
 $intro=$post[0];
 $howto=$post[1];
 $howto=~s/^howto\=//;
 $intro=~s/^intro\=//;
 $intro=~s/\r\n/\n/g;

 open(FILE, ">/tmp/changedoc");
 print FILE "$howto\n";
 print FILE "$intro\n";
 close(FILE);
}	   

if ($comment) {
 $comment=$post[0];
 $fileline=$post[1];
 $fileline=~s/^file\=//;
 @fileline=split(/\|\|\|/, $fileline);
 $file=$fileline[0];
 $linenr=$fileline[1];
 $comment=~s/^comment\=//;
 $comment=~s/[\r]//g;
 $comment=~s/[\n]/<br>/g;
 chomp($comment);
 open(FILE, ">/tmp/changedoc");
 print FILE "$linenr\n";
 print FILE "$file\n";
 print FILE "$comment";
 close(FILE);
}

print "</div></body></html>\n";

Changes in /var/www/doc.gabosh.net/htdocs/howto.css

File permissions:
Owner: root
Group: root
Permissions: -rw-r--r--

Click here for a download of the complete file: /var/www/doc.gabosh.net/htdocs/howto.css

Changed on 27.04.10
Issued by olli
Beginning line 2

The Cascading Style Sheet for the design of the sysdoc HTML Output

*/
body {
 background-color:#dddaec;
 font-family: sans-serif, Verdana, Arial, Helvetica;
 font-size:small;
 color:#000000;
}
h1 {
 background-color:#7a5ada;
 color:#ffffff;
 padding-left:2px;
 font-size:large;
}
h2 {
 background-color:#dddaec;
 padding-left:2px;
 font-size:medium;
}
.h1link {
 color:#ffffff;
 text-decoration:none;
}
.h1link:visited {
 color:#ffffff;
 text-decoration:none;
}
.h1link:active {
 color:#ffffff;
 text-decoration:none;
}
.h1link:hover {
 color:#ffffff;
 text-decoration:underline;
}
.h2link:hover {
 color:#000000;
 text-decoration:none;
}
a:link {
 color:#7a5ada;
 text-decoration:none;
}
a:visited {
 color:#7a5ada;
 text-decoration:none;
}
a:active {
 color:#7a5ada;
 text-decoration:none;
}
a:hover {
 color:#7a5ada;
 text-decoration:underline;
}
.frame {
 width:950px;
 background-color:white;
 padding:10px;
}
.before {
 background-color:#FF8080;
}
.after {
 background-color:#80FF80;
}
.small {
 font-size:smaller;
}
pre {
 overflow:visible;
 background-color:#FFFF80;
 font-size:larger;
}
/* 

Please send a feedback to: doc<at>gabosh.net

Howto listing
File Index

Here you can find the official Gentoo Linux Forums where you can find a lot of answers.

Here a link to the official Gentoo Linux Homepage.

Edit Howto

About / Impressum

Click here for About / Impressum

Wishlist

If you want to support my work you can find my Amazon whishlist here