Martin Schmidt: Pfad der aufrufenden shtml datei ermitteln

Hallo Forumgemeinde,

ich rufe aus einer datei "Kundenbereich.shtml" ein perl script auf. Diese shtml datei liegt dabei in einem durch .htaccess geschützten Ordner z.B. "http://www.domainname/ordnerxy" und der Aufruf erfolgt durch eine Zeile:

<!--#exec cgi="http://www.domainname/cgi-bin/scriptname.pl"-->

Das Script selbst soll den Ordnerinhalt von ordnerxy auf eine dateiendung durchsuchen und, wenn vorhanden, diese als Link(s) innerhalb der shtml datei zurückgeben. Wenn ich das unter IIS lokal teste bekomme ich aber den inhalt meines cgi-bin ordners ausgegeben. hopplahopp!

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

#!/usr/bin/perl -w

use strict;

use CGI;
use CGI::Carp qw(fatalsToBrowser);

aktuelles Verzeichnis dachte ich

my $verzeichnis = '.';

opendir(DH, $verzeichnis) or die "$verzeichnis: $!";
my @liste = grep { ! -d } readdir DH;
closedir DH;

stl filtern

@liste = glob "*.stl";
my $gefunden = @liste;

print "Content-Type: text/html\n\n";
print"<p>Anzahl der gefundenen Dateien: $gefunden</p>\n";

foreach my $dateien (@liste) {
print "<p><a href='$dateien'>$dateien</a></p>\n";
}

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

Wie ermittle ich im script nur den Pfad bzw. Name von "ordnerxy", also des ordners indem sich die aufrufende shtml datei befindet ?

Vielen Dank für jeden Tip oder Hinweis,
Martin S.

  1. Hallo Martin!

    Hallo Forumgemeinde,

    ich rufe aus einer datei "Kundenbereich.shtml" ein perl script auf. Diese shtml datei liegt dabei in einem durch .htaccess geschützten Ordner z.B. "http://www.domainname/ordnerxy" und der Aufruf erfolgt durch eine Zeile:

    <!--#exec cgi="http://www.domainname/cgi-bin/scriptname.pl"-->

    Wie ermittle ich im script nur den Pfad bzw. Name von "ordnerxy", also des ordners indem sich die aufrufende shtml datei befindet ?

    Thema auf SERVER geändert, weil:

    WILLKOMMEN BEI DEN (UNMÖGLICHEN) UMGEBUNGSVARIABLEN!

    Tja... je nach Server sind diese andere, und so kann ich dir nur raten, es einfach mit:

    lokal (Xitami auf Windows) = SCRIPT_NAME

    Atomic Eggs (Apache auf UNIX) = DOCUMENT_URI (mein alter Webhoster)

    Atomic Eggs (Apache auf Linux) = SCRIPT_URL (jetziger Webhoster 1&1)

    einer von diesen drei zu probieren!

    Viele Grüße aus Frankfurt/Main,
    Patrick

    --

    _ - jenseits vom delirium - _
    [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
    Nichts ist unmöglich? Doch!
    Heute schon gegökt?
    1. Hallo Patrick,

      erst mal vielen Dank für die schnelle Hilfe. Ich habe jetzt folgendes Konstrukt und das funktioniert lokal mit IIS, sofern man sich im ordnerxy befindet. Jedoch nicht auf dem Apache unter Unix (hoster allinkl, Variable vorhanden und identisch mit IIS)

      my $self_url = '../'.$ENV{'SCRIPT_NAME'};
      $self_url =~ s{[^/]*$}{};       #trennt den namen der shtml datei ab
      chdir($self_url);

      das schlimme ist ohne den manuellen verzeichniswechsel mit chdir bekomme ich auch auf IIS nicht den richtigen Ordnerinhalt sondern nur den des cgi-bin ordners. Insbesondere wenn das Script direkt aufgerufen wird ohne dass sich der User im geschützten Ordner befindet, also so:

      http://www.domainname/cgi-bin/scriptname.pl

      Habe bei meinem hoster verschiedene $ENV probiert und alle erfolgreich ausgelesen. Wenn ich den pfad explizit angebe. Bei meinem Scriptaufruf von der shtml datei erhalte ich beim apache aber immer:

      [an error occurred while processing this directive]

      während es mit IIS einwandfrei läuft. Kann es sein dass mein Provider den chdir Befehl deaktiviert hat ?

      Grüsse und Danke nochmal,
      MartinS.

      1. Hallo Martin!

        [an error occurred while processing this directive]

        während es mit IIS einwandfrei läuft. Kann es sein dass mein Provider den chdir Befehl deaktiviert hat ?

        Du musst im Skript den Pfad absolut zum Root angeben. Bei mir ist es (Username gefaked):

        $foo = "/kunden/homepages/12/d1234567890/htdocs/aec/z_testdir/files/faked.log.current";

        (als Beispiel).

        Allerdings musste ich feststellen, dass bei einem Virtual Hosts (ich habe bei 1&1 die möglichkeit, 5 Domains zu verwalten, habe derzeit 4, eine Domain ist - sach ich mal - als Root eingerichtet, die anderen als VH), bei einem Testskript, was ich hier fürs Forum (siehe hier) zum Test anbiete, dieser Pfad nichts brachte... wäre das Skript im cgi-bin, würde das gehen. Statt dessen musste ich auf folgendes Konstrukt zurückgreifen:

        use Cwd;
        $cwd = cwd();
        $log = "$cwd/faked.log.current";

        Wenn ich $cwd »printen« lasse, kommt:

        /homepages/12/d1234567890/htdocs/aec/z_testdir/files
        also »/kunden« ist weg...

        In anderen Skripten, die unter aec (Virtual Host-Root für Atomic Eggs) im cgi-bin sind, muss dagegen den kompletten Pfad mit »/kunden« zu Beginn notiert werden. Ich verstehe selbst nur Bahnhof. Nur: mit Perl hat es nichts zu tun ;)

        Viele Grüße aus Frankfurt/Main,
        Patrick

        --

        _ - jenseits vom delirium - _
        [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
        Nichts ist unmöglich? Doch!
        Heute schon gegökt?
        1. Hallo Patrick,

          nochmals Dank für die Tips. Ich habe jetzt durch Zufall herausgefunden woher der Fehler [an error occurred while processing this directive] kommt. Wenn ich in der shtml datei beim Aufruf des Scriptes den domainnamen weglasse, gehts wie gewünscht, also so:

          <!--#exec cgi="/cgi-bin/simple.pl"-->

          Soweit zur Ausgabe innerhalb shtml. Den richtigen Pfad im Script zu finden habe ich mit DOCUMENT_ROOT und DOCUMENT_URI erhalten, beim Durchsuchen wird aber immer der cgi-bin ordner ausgegeben wenn ich nicht manuell mit chdir in das gewünschte Verzeichnis wechsle.
          Ohne chdir gehts bei mir weder unter IIS noch dem Apache.

          Wichtig zu erwähnen ist aber dass man im script genau prüfen sollte woher der Aufruf kommt, sonst kann man damit leicht den Inhalt eines geschützten Ordners ausgeben ohne sich jemals angemeldet zu haben!

          ist das normal ?

          Grüsse und nochmals Danke für die Hilfestellungen !
          MartinS.

          1. Hallo Martin!

            Wenn ich in der shtml datei beim Aufruf des Scriptes den domainnamen weglasse, gehts wie gewünscht, also so:

            <!--#exec cgi="/cgi-bin/simple.pl"-->

            Mein Fehler, hätte ich erwähnen müssen. Es sind »Server Side Includes« für serverinterne Arbeiten - das hat nichts mit HTTP zu tun.

            DOCUMENT_ROOT

            gibt den serverinternen Pfad bis zum Wurzelverzeichnis, ja

            und DOCUMENT_URI

            reagiert je nach Server unterschiedlich, wie in meinem vorigen Post erwähnt. Nach dem Umzug vom alten Hoster zu 1&1 musste ich erstmal alle Skripte anpassen, die mittels SSI in .shtml-Dateien eingebunden waren und den Namen/Pfad der aufrufenden Datei brauchten. Wie gesagt, auf meinem Server brauche ich SCRIPT_URL.

            wenn ich nicht manuell mit chdir in das gewünschte Verzeichnis wechsle.
            Ohne chdir gehts bei mir weder unter IIS noch dem Apache.

            Das verstehe ich nicht. Es dürfte reichen, dem Skript den Pfad bekannt zu geben, oder? Nehmen wir an, Du willst die Bilder Deiner Haustiere suchen, die im folgenden Ordner sind:

            /root/myhtml/mypics/mypets/

            dann reicht im Skript:

            $path = "/root/myhtml/mypics/mypets/";

            und:

            opendir (ORDNER, "$dirpath") or die "SOMETHING WRONG: $!";
            my @FILES = sort grep(!/^.{1,2}$/, readdir(ORDNER));
            closedir (ORDNER);

            da brauchst Du IMHO kein: chdir $path or die "Huh?";

            sonst kann man damit leicht den Inhalt eines geschützten Ordners ausgeben ohne sich jemals angemeldet zu haben!
            ist das normal ?

            Wenn Du mit »geschützten Ordnern« solche meinst, die eine HTTP-Auth erfordern (User muss sich mit Username/Pw einloggen), dann ja. Denn das Skript arbeitet auf dem Server, und hat mit HTTP nichts am Hut.

            Viele Grüße aus Frankfurt/Main,
            Patrick

            --

            _ - jenseits vom delirium - _
            [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
            Nichts ist unmöglich? Doch!
            Heute schon gegökt?
            1. Hallo Patrick,

              Das verstehe ich nicht. Es dürfte reichen, dem Skript den Pfad bekannt zu geben, oder? Nehmen wir an, Du willst die Bilder Deiner Haustiere suchen, die im folgenden Ordner sind:

              /root/myhtml/mypics/mypets/

              dann reicht im Skript:

              $path = "/root/myhtml/mypics/mypets/";

              und:

              opendir (ORDNER, "$dirpath") or die "SOMETHING WRONG: $!";
              my @FILES = sort grep(!/^.{1,2}$/, readdir(ORDNER));
              closedir (ORDNER);

              Leider geht das bei mir nicht, weder lokal auf IIS noch online. Selbst wenn ich den Pfad explizit angebe, das aufgelistete Verzeichnis ist immer mein cg-bin ordner und nicht der ordner des angegebenen pfades.

              PS. Was bedeutet in Deinem obigen beispiel der Ausdruck "ORDNER" ? Ich kenne nur "DIR" für win und "DH" für unix. Derzeit verwende ich "DH" weil es auf IIS und Apache funktioniert.

              Ich werde mal beim Provider nachfragen warum der pfad nicht verwendet wird. Ist nicht schön wenn user anfangen das Verzeichnis zu wechseln.

              Vielen Dank für die schnelle Hilfe !
              MartinS.

              1. Hallo Martin!

                Leider geht das bei mir nicht, weder lokal auf IIS noch online.

                Lokal musst Du den Pfad vermutlich komplett angeben. Um beim Beispiel zu bleiben:

                $path = "D:\webverzeichnis\myhtml\mypics\mypets";

                Selbst wenn ich den Pfad explizit angebe, das aufgelistete Verzeichnis ist immer mein cg-bin ordner und nicht der ordner des angegebenen pfades.

                hm, was gibst du dann für chdir an? Pfad ist Pfad, ob er bei chdir angegeben wird oder als Variable gespeichert wird, dürfte egal sein...

                PS. Was bedeutet in Deinem obigen beispiel der Ausdruck "ORDNER" ?

                Nichts. Du kannst diese Handles selbst vergeben:

                opendir HUSSELDIGUGGEL, "$path" or die "Aaaargh: $!";

                open FILE, "datei.txt" or die "Japs, da ist was faul: $!";

                open MAMAMIA, ">>dateizumschreiben.txt" or die "Bin müde, mir Gründe auszudenken: $!";

                Ich kenne nur "DIR" für win und "DH" für unix. Derzeit verwende ich "DH" weil es auf IIS und Apache funktioniert.

                Ich kenne IIS nicht, aber es dürfte keine Rolle spielen. Perl ist es egal, wie Du Deine Handles nennst. Auch die Großschreibung ist nur eine Konvention, sein müssen tut sie nicht, wenn auch übersichtlicher, wenn Handles, Labels o.Ä. sich vom Rest unterscheiden...

                Viele Grüße aus Frankfurt/Main,
                Patrick

                --

                _ - jenseits vom delirium - _
                [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                Nichts ist unmöglich? Doch!
                Heute schon gegökt?
                1. Re!

                  Nichts. Du kannst diese Handles selbst vergeben:
                  opendir HUSSELDIGUGGEL, "$path" or die "Aaaargh: $!";

                  Schau mal hier:

                  http://goek.atomic-eggs.com/goek/opendir.pl

                  goek.atomic-eggs.com ist eine subdomain.
                  /goek ist dort das cgi-bin :)

                  Das Skript listet den Inhalt des Verzeichnisses /roadster/leo, Unterverzeichnis von atomic-eggs.com, auf dem Server aber auf der selben Ebene (Ordner enthält einige JEPG-Bilder, eine Datei, ein Unterverzeichnis) und sieht so aus (Zahlen im Pfad für hier gefaked):

                    
                  #!/usr/bin/perl -w  
                    
                  use strict;  
                    
                  print "Content-type: text/html\n\n";  
                    
                  print "<br><br>", $/;  
                    
                  my $dirpath = "/kunden/homepages/12/d123456789/htdocs/aec/roadster/leo";  
                    
                  opendir (SPONGEBOB, "$dirpath") or die "Drecksackblase und Mantarochen haben hier aufgeraeumt: $!";  
                  my @FILES = sort grep(!/^\.\.?$/, readdir(SPONGEBOB));  
                  closedir (SPONGEBOB);  
                  $, = "<br>\n";  
                  print  @FILES;  
                  
                  

                  Kein chdir nötig oder ich verstehe nicht, wie Du das meinst ;)

                  Viele Grüße aus Frankfurt/Main,
                  Patrick

                  --

                  _ - jenseits vom delirium - _
                  [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
                  Nichts ist unmöglich? Doch!
                  Heute schon gegökt?
                  1. Hallo Struppi und Patrick,

                    SUPER ! Vielen Dank an euch für die Hilfstellung. Das grep ist wirklich schuld. Wenn ich es weglasse gehts auch ohne den chdir Befehl. Ist es ohne grep irgendwie möglich die dateierweiterungen *.stl und *.jpg aus meiner @liste herausfiltern ?

                    Grüsse,
                    MartinS.

                    1. ...ups sorry, ich meine natürlich das "glob" und nicht grep ! Bin schon total verwirrt...aber trotzdem happy jetzt ohne chdir zu arbeiten. :o)

                      Grüsse,
                      MartinS.

              2. opendir (ORDNER, "$dirpath") or die "SOMETHING WRONG: $!";
                my @FILES = sort grep(!/^.{1,2}$/, readdir(ORDNER));
                closedir (ORDNER);

                Leider geht das bei mir nicht, weder lokal auf IIS noch online. Selbst wenn ich den Pfad explizit angebe, das aufgelistete Verzeichnis ist immer mein cg-bin ordner und nicht der ordner des angegebenen pfades.

                Kann es sein, dass du noch den Code den du im Orginalposting gezeigt hast nutzt?

                opendir(DH, $verzeichnis) or die "$verzeichnis: $!";  
                my @liste = grep { ! -d } readdir DH;  
                closedir DH;  
                  
                # stl filtern  
                @liste = glob "*.stl";  
                my $gefunden = @liste;  
                
                

                Du liest durch das glob explizit den aktuellen Pfad und überschreibst die richtigen Werte, die du mit opendir eingelesen hast.

                Struppi.