Ausgabe eines Aufgerufenen Programms in C verwenden



  • Hallo zusammen.

    Ich habe ein hoffentlich kleines Problem.
    Und zwar muss ich ein Tool in C schreiben,
    welches ein weiteres Linux Tool aufruft
    und dessen Ausgabe auf der Shell, bzw Teile davon,
    in zB Variablen meines selbst erstellten Tools abspeichert
    damit ich anschließend Abfragen kann ob die Ausgabe bestimmte Kriterien erfüllt.

    zB: Hat das Tool ausgegeben, dass diese und diese Information so und so ist.

    Tipp: Es geht hier um das Tool Nmap. Wer es kennt, kennt auch die Ausgaben, die es macht.
    Ich muss nun die teilweise sehr sehr lange Ausgabe eines Netzwerkscans auf bestimmte Kriterien von meinem C-Tool analysieren lassen.

    Ich hoffe, dass mir jemand weiterhelfen kann.
    Liebe Grüße,
    Felix



  • Ich mach zwar nix unter Linux, aber ich glaube, dafür gibt es eine Funktion namens popen - einfach mal danach googeln.



  • Belli schrieb:

    Ich mach zwar nix unter Linux, aber ich glaube, dafür gibt es eine Funktion namens popen - einfach mal danach googeln.

    Nein, den Aufruf des Programms Nmap mache ich innerhalb meines C-Tools mit

    char cmd_out[255];
    sprintf(cmd_out, "nmap ... befehle");
    
    System("cmd_out");
    

    Jetzt muss ich nur die Ausgabe, die auf der Shell erscheint weiterverarbeiten bzw brauche einzelne werte und zahlen, die das Programm Nmap auf der Shell ausgibt.

    Wie bekomme ich diese Werte eingelesen in Variablen..?

    LG Felix



  • Indem du das so machst, wie hingewiesen.
    Du hast keine Ahnung von C aber weißt ganz genau, wie was geht und nicht geht?
    Erkläre mal, wie du Probleme löst.



  • Ich kenn nur system als Funktion der Standardlibrary.

    Der Prottyp von system sieht so aus:

    int system (const char* command);
    

    Der Rückgabe wert ist ein int und wird folgendermassen beschrieben:

    system schrieb:

    Return Value
    If command is a null pointer, the function returns a non-zero value in case a command processor is available and a zero value if it is not.

    If command is not a null pointer, the value returned depends on the system and library implementations, but it is generally expected to be the status code returned by the called command, if supported.

    Da ist also nichts mit der Ausgabe von dem aufgerufenen Programm.

    Wie ist dein System deklariert?



  • Wutz schrieb:

    Indem du das so machst, wie hingewiesen.
    Du hast keine Ahnung von C aber weißt ganz genau, wie was geht und nicht geht?
    Erkläre mal, wie du Probleme löst.

    Ich habe mir kurz ne Übersicht zu popen() angeguckt und habe gesehen dass man so eine komplett neue Shellsitzung öffnet und das brauchte ich doch gar nicht oder?
    Ich dachte man kann einfach entweder die Ausgabe in eine Datei schreiben lassen, aus der ich dann die sachen auslese oder dass ich direkt die Terminalausgabe aus demselben lesen kann. Ka. zB mit sscanf() ... aber ich weis ja nicht wie..

    Oder geht das ausschließlich so mit diesem popen?

    Ich habe C nur zwei Jahre in der Schule gehabt und da auch nur eins indem wir ausschließlich Windows Console Applications gemacht haben und das zweite ausschließlich Microprozessoren angesteuert.

    Und da das nur eins von vielen Fächern war habe ich jetzt nicht soo die Kenntnisse 😕
    Habe aber im Praktikum jetzt doofer weise Aufgaben die ausschließlich mit Linux zu tun haben, da das OS der hergestellten Geräte Linux ist.

    Tut mir leid, wenn meine Antworten manchmal so komisch rüberkommen. Ich weis auch nicht warum. Eigentlich will ich ja neues lernen ..

    LG Felix



  • Das einfachste wäre, wenn du über die Shell die Pipe (|) benutzt:

    nmap ... | YourProgramm
    

    (wobei dann ... für die Argumente von nmap steht)

    In deinem Programm kannst du dann über die Standardeingabe (stdin) die Ausgabe von nmap einlesen und interpretieren.



  • Th69 schrieb:

    Das einfachste wäre, wenn du über die Shell die Pipe (|) benutzt:

    nmap ... | YourProgramm
    

    (wobei dann ... für die Argumente von nmap steht)

    In deinem Programm kannst du dann über die Standardeingabe (stdin) die Ausgabe von nmap einlesen und interpretieren.

    Danke das hört sich doch echt gut an! 🙂

    Und das einlesen, wie geht das genau? Also den sscanf() Befehl habe ich bisher nur so als direkten User-Eingaben Scan verstanden ..

    Liebe Grüße,
    Felix



  • sscanf ist zum lesen aus Strings.

    Da mit der Pipe die Standardausgabe von dem linken Programm zur Standardeingabe vom rechten Programm wird, kannst mit den ganz normalen Ein-/Ausgabefunktionen arbeiten: scanf (nur ein s)

    Da bedeutet aber auch, dass dein Programm nmap nicht mehr mit system aufruft.

    mekick schrieb:

    Ich dachte man kann einfach entweder die Ausgabe in eine Datei schreiben lassen, aus der ich dann die sachen auslese oder

    Klar, geht auch.
    Wenn du dein Programm richtig anfängst, gibt es keinen großen unterschied zu der Pipe-Version.

    mekick schrieb:

    ... oder dass ich direkt die Terminalausgabe aus demselben lesen kann. Ka. zB mit sscanf() ... aber ich weis ja nicht wie..

    was ist an "Nutze popen " so schwer zu verstehen.
    Wenn du nicht weiß wie du popen einsetzen kannst, ist das was anderes.
    (Was der Bauer nicht kennt, frisst er nicht)

    das p bei popen steht übrigens für Pipe.
    Und: http://de.wikipedia.org/wiki/Filter_(Unix)



  • DirkB schrieb:

    sscanf ist zum lesen aus Strings.

    Da mit der Pipe die Standardausgabe von dem linken Programm zur Standardeingabe vom rechten Programm wird, kannst mit den ganz normalen Ein-/Ausgabefunktionen arbeiten: scanf (nur ein s)

    Da bedeutet aber auch, dass dein Programm nmap nicht mehr mit system aufruft.

    mekick schrieb:

    Ich dachte man kann einfach entweder die Ausgabe in eine Datei schreiben lassen, aus der ich dann die sachen auslese oder

    Klar, geht auch.
    Wenn du dein Programm richtig anfängst, gibt es keinen großen unterschied zu der Pipe-Version.

    mekick schrieb:

    ... oder dass ich direkt die Terminalausgabe aus demselben lesen kann. Ka. zB mit sscanf() ... aber ich weis ja nicht wie..

    was ist an "Nutze popen " so schwer zu verstehen.
    Wenn du nicht weiß wie du popen einsetzen kannst, ist das was anderes.
    (Was der Bauer nicht kennt, frisst er nicht)

    das p bei popen steht übrigens für Pipe.
    Und: http://de.wikipedia.org/wiki/Filter_(Unix)

    Korrekt. Ich kenne popen nicht ! ^^

    Ok. Gehen wir davon aus ich möchte das mit dem Ausgabe in Datei umlenken machen und danach die Datei durchgehen und daraus die sachen einlesen ...

    how to() ?

    ist das einfach ne while-schleife, die runterläuft bis es keine nächste zeile mehr gibt und von oben alles in einen string schreibt oder wie hab ich mir das vorzustellen?

    LG und DANKE!
    Felix



  • So sieht das ganz realistisch aus, was ich einlesen muss:

    Starting Nmap 6.46 ( http://nmap.org ) at 2014-06-20 16:09 CEST
    Stats: 0:00:05 elapsed; 0 hosts completed (0 up), 256 undergoing Ping Scan
    Ping Scan Timing: About 41.99% done; ETC: 16:09 (0:00:07 remaining)
    Stats: 0:00:05 elapsed; 0 hosts completed (0 up), 256 undergoing Ping Scan
    Ping Scan Timing: About 84.96% done; ETC: 16:09 (0:00:01 remaining)
    Stats: 0:00:07 elapsed; 233 hosts completed (23 up), 23 undergoing Connect Scan
    Connect Scan Timing: About 90.29% done; ETC: 16:09 (0:00:00 remaining)
    Nmap scan report for MarkusB_I5-760.domain.de (192.168.4.85)
    Host is up (0.00086s latency).
    Not shown: 44 filtered ports                                                                                                                                                                                                                                                   
    PORT    STATE SERVICE                                                                                                                                                                                                                                                          
    80/tcp  open  http                                                                                                                                                                                                                                                             
    443/tcp open  https                                                                                                                                                                                                                                                            
    445/tcp open  microsoft-ds                                                                                                                                                                                                                                                     
    
    Nmap scan report for linux-dp.domain.de (192.168.4.121)                                                                                                                                                                                                                    
    Host is up (0.00012s latency).                                                                                                                                                                                                                                                 
    All 47 scanned ports on linux-dp.domain.de (192.168.4.121) are closed                                                                                                                                                                                                      
    
    Nmap scan report for linux-jl2.domain.de (192.168.4.126)                                                                                                                                                                                                                   
    Host is up (0.000089s latency).                                                                                                                                                                                                                                                
    All 47 scanned ports on linux-jl2.domain.de (192.168.4.126) are closed                                                                                                                                                                                                     
    
    Nmap scan report for 192.168.4.140                                                                                                                                                                                                                                             
    Host is up (0.00024s latency).                                                                                                                                                                                                                                                 
    Not shown: 46 closed ports                                                                                                                                                                                                                                                     
    PORT   STATE SERVICE                                                                                                                                                                                                                                                           
    80/tcp open  http                                                                                                                                                                                                                                                              
    
    Nmap scan report for 192.168.4.154                                                                                                                                                                                                                                             
    Host is up (0.00018s latency).                                                                                                                                                                                                                                                 
    Not shown: 46 closed ports                                                                                                                                                                                                                                                     
    PORT    STATE SERVICE                                                                                                                                                                                                                                                          
    445/tcp open  microsoft-ds                                                                                                                                                                                                                                                     
    
    Nmap scan report for 192.168.4.161                                                                                                                                                                                                                                             
    Host is up (0.0100s latency).                                                                                                                                                                                                                                                  
    Not shown: 46 closed ports                                                                                                                                                                                                                                                     
    PORT   STATE SERVICE                                                                                                                                                                                                                                                           
    21/tcp open  ftp                                                                                                                                                                                                                                                               
    
    Nmap scan report for linux-testserver3.domain.de (192.168.4.164)                                                                                                                                                                                                           
    Host is up (0.00033s latency).                                                                                                                                                                                                                                                 
    Not shown: 45 closed ports                                                                                                                                                                                                                                                     
    PORT   STATE SERVICE                                                                                                                                                                                                                                                           
    21/tcp open  ftp                                                                                                                                                                                                                                                               
    80/tcp open  http                                                                                                                                                                                                                                                              
    
    Nmap scan report for linux-testserver4.domain.de (192.168.4.165)                                                                                                                                                                                                           
    Host is up (0.00029s latency).                                                                                                                                                                                                                                                 
    Not shown: 44 closed ports                                                                                                                                                                                                                                                     
    PORT   STATE SERVICE
    21/tcp open  ftp
    53/tcp open  domain
    80/tcp open  http
    
    Nmap scan report for 192.168.4.166
    Host is up (0.00026s latency).
    All 47 scanned ports on 192.168.4.166 are closed
    
    Nmap scan report for 192.168.4.168
    Host is up (0.00026s latency).
    All 47 scanned ports on 192.168.4.168 are closed
    
    Nmap scan report for 192.168.4.207
    Host is up (0.00022s latency).
    Not shown: 40 closed ports
    PORT    STATE SERVICE
    21/tcp  open  ftp
    25/tcp  open  smtp
    80/tcp  open  http
    443/tcp open  https
    445/tcp open  microsoft-ds
    515/tcp open  printer
    631/tcp open  ipp
    
    Nmap scan report for 192.168.4.208
    Host is up (0.00020s latency).
    Not shown: 45 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    515/tcp open  printer
    
    Nmap scan report for asterisk.domain.de (192.168.4.236)
    Host is up (0.00017s latency).
    Not shown: 44 closed ports
    PORT    STATE SERVICE
    21/tcp  open  ftp
    80/tcp  open  http
    443/tcp open  https
    
    Nmap scan report for Server.domain.de (192.168.4.240)
    Host is up (0.00020s latency).
    Not shown: 45 closed ports
    PORT    STATE SERVICE
    445/tcp open  microsoft-ds
    631/tcp open  ipp
    
    Nmap scan report for 192.168.4.243
    Host is up (0.00039s latency).
    Not shown: 44 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    445/tcp open  microsoft-ds
    
    Nmap scan report for 192.168.4.245
    Host is up (0.00017s latency).
    Not shown: 43 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    445/tcp open  microsoft-ds
    631/tcp open  ipp
    
    Nmap scan report for 192.168.4.246
    Host is up (0.00018s latency).
    Not shown: 44 closed ports
    PORT    STATE SERVICE
    443/tcp open  https
    445/tcp open  microsoft-ds
    631/tcp open  ipp
    
    Nmap scan report for mail-test.domain.de (192.168.4.247)
    Host is up (0.00058s latency).
    Not shown: 40 filtered ports
    PORT    STATE  SERVICE
    25/tcp  open   smtp
    80/tcp  open   http
    110/tcp open   pop3
    143/tcp open   imap
    465/tcp closed smtps
    993/tcp open   imaps
    995/tcp open   pop3s
    
    Nmap scan report for dav.mail (192.168.4.248)
    Host is up (0.00072s latency).
    Not shown: 42 filtered ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    465/tcp open  smtps
    993/tcp open  imaps
    995/tcp open  pop3s
    
    Nmap scan report for 192.168.4.249
    Host is up (0.00033s latency).
    Not shown: 46 closed ports
    PORT   STATE SERVICE
    80/tcp open  http
    
    Nmap scan report for 192.168.4.251
    Host is up (0.0011s latency).
    Not shown: 46 closed ports
    PORT   STATE SERVICE
    80/tcp open  http
    
    Nmap scan report for INTEC_EM.domain.de (192.168.4.252)
    Host is up (0.00079s latency).
    Not shown: 43 closed ports
    PORT    STATE SERVICE
    25/tcp  open  smtp
    110/tcp open  pop3
    143/tcp open  imap
    445/tcp open  microsoft-ds
    
    Nmap scan report for Lancom_1611.domain.de (192.168.4.253)
    Host is up (0.00045s latency).
    Not shown: 45 closed ports
    PORT    STATE SERVICE
    80/tcp  open  http
    443/tcp open  https
    
    Nmap done: 256 IP addresses (23 hosts up) scanned in 7.75 seconds
    


  • DirkB schrieb:

    was ist an "Nutze popen " so schwer zu verstehen.

    Mit popen ersparst du dir den Umweg über eine extra Datei; das kann bei deinem überschaubaren C-Wissen nur von Vorteil für Lösung deines Problems sein.



  • mekick schrieb:

    how to() ?

    ist das einfach ne while-schleife, die runterläuft bis es keine nächste zeile mehr gibt und von oben alles in einen string schreibt oder wie hab ich mir das vorzustellen?

    Ja, möglicherweise. Du kannst aber gleich beim lesen auswerten.

    mekick schrieb:

    So sieht das ganz realistisch aus, was ich einlesen muss: ...

    Und was möchtest du davon haben?
    Die Anzahl der Wörter oder die IP-Adressen oder .... ?
    DAvon hängt es dann ab, wie du weiter machst.



  • Ist das ein Rumgeeiere hier! Ich habe hier einmal ein Beispiel für drei mögliche Ansätze:

    1. Ausgabe umleiten in eine Datei.
    2. Ausgabe per popen zeilenweise einlesen
    3. Ausgabe per popen im Block einlesen

    Das Beispiel kann optimiert werden und auf persönliche Anforderungen angepasst werden
    (und es gibt auch noch andere Möglichkeiten), aber es zeigt, wie es gehen kann:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    
    void to_file (char* cmd)
    {
        char redirect[256] = ">tmp.txt ";
        strcat (redirect, cmd);
        system (redirect);
    }
    
    void popen_line_by_line (char* cmd)
    {
        char   psBuffer[128] = {0};
    
        FILE   *pPipe;
        pPipe = popen( "ls -l", "r" );
        if( !pPipe ) exit( 1 );
    
        while(fgets(psBuffer, 128, pPipe))
        {
            printf ("%s",psBuffer);
            fflush (stdout);
        }
        pclose (pPipe);
    }
    
    void popen_to_buffer (char* cmd)
    {
        char   psBuffer[128] = {0};
        char msgBuffer[4096] = {0};
    
        FILE   *pPipe;
        pPipe = popen(cmd , "r" );
        if( !pPipe ) exit( 1 );
    
        while(fgets(psBuffer, 128, pPipe))
        {
            printf ("%s",psBuffer);
            fflush (stdout);
            strcat(msgBuffer,psBuffer);
        }
        pclose (pPipe);
        printf ("%s",msgBuffer);
    }
    
    int main ( void )
    {
        char* cmd = "ls -l";
    
        // Nach Bedarf auskommentieren
        to_file(cmd);
        popen_line_by_line (cmd);
        popen_to_buffer(cmd);
    
        return 0;
    }
    

    Ich persönlich hätte für die Aufgabe eine modernere Skriptsprache (z.B. PHP) gewählt,
    da diese die gewünschte Funktionalität fest und relativ idiotensicher eingebaut haben.

    viele grüße
    ralph


  • Mod

    Die wohl in den meisten Fällen "richtigste" Möglichkeit ist aber immer noch das, was Th69 vorgeschlagen hat. Alles deutet da drauf hin, dass dies auch hier die richtige Wahl wäre.
    Man muss nicht immer die genaue Frage des Threaderstellers beantworten, wenn doch offensichtlich ein X-Y Problem vorliegt.



  • rkhb schrieb:

    ...
    void to_file (char* cmd)
    {
        char redirect[256] = ">tmp.txt ";
        strcat (redirect, cmd);
        system (redirect);
    ...
    
    int main ( void )
    {
        char* cmd = "ls -l";
    
        // Nach Bedarf auskommentieren
        to_file(cmd);
    ...
    }
    

    Was macht denn der Befehl >tmp.txt ls -l ?



  • Das ist ein Deppenbeispiel, und genau so macht man es eben nicht.
    Das Deppenbeispiel setzt voraus, dass im aktuellen Verzeichnis Schreibrechte und ausreichend Platz vorliegen, und wer räumt den Müll da hinterher wieder weg?
    Genau, der Deppenprogrammierer sicherlich nicht.
    All das entfällt, wie oben erwähnt, wenn man die POSIX konforme Funktion popen/pclose verwendet.



  • DirkB schrieb:

    Was macht denn der Befehl >tmp.txt ls -l ?

    Das Gleiche wie in einer Windows-Konsole ">tmp.txt dir". Der Trick: Man kann die Umleitung auch nach vorne bringen.

    viele grüße
    ralph



  • Nur als Hinweis... nmap unterstützt verschiedene Ausgaben. Es gibt so zB grepable- und auch xml-Ausgaben.



  • Nur zur info .. ich habe jetzt folgende Lösung gewählt:

    1. gesamten Output in output.txt schreiben
    2. mit getline() aus dem gcc GNU Compiler Zeilenweise einlesen
    3. mit den strXXX()-Funktionen die Inhalte der einzelnen Zeilen auf Muster vergleichen

    Das schien mir anhand meiner bisherigen Kenntnisse die geeignetste Lösung und da ich mir nochmals die Anwendung des Programms vor Augen geführt habe ist mir klar geworden, dass es gar nicht schlecht ist, dass ich nun eine Ausgabedatei erhalte, da ich im Laufe des Programms mehrere Aufrufe machen müsste oder aber unübersichtliche Variablendefinitionen zwischenschieben müsste, so aber jetzt einfach immer wieder die output.txt als bestehenden Ausgangsstream nutzen kann.

    Ich meine diese Lösung nennt sich jetzt Ausgabe in Datei umlenken und anschließendes Pathen ..?

    Danke für eure Hilfe!!

    Liebe Grüße,
    Felix

    Hier nochmal der Code:

    // Pointer auf Datei = ptoutput
      FILE *ptoutput;
      // Prototyp von getline(): ssize_t getline(char** ReservierterSpeicherFürInputLine, size_t* ByteGrößeDesReserviertenSpeichers, FILE* InputStream)
      // Speicher für Buffer/InputLine festlegen
      char * ptline_in;
      ptline_in = (char *) malloc(70);
    
      // Variable für die Größe der Textzeile in Bytes
      size_t istorage = 70;
    
      // Wenn die Datei output.txt nicht geöffnet werden kann
      // Gebe Error aus
      if ( (ptoutput = fopen("output.txt","r")) == NULL) 
      {
        fprintf(stderr, "\nKonnte Datei 'output.txt' nicht öffnen!");
        return EXIT_FAILURE;
      }
    
      // Zeilenweises Einlesen von output.txt und Ausgeben der Gelesenen Zeilen und der Größe der Zeilen
      while(getline(&ptline_in, &istorage, ptoutput) > 0)
      {
        printf("Line: %s \nBytes: %u \n", ptline_in, istorage);
      }
      return EXIT_SUCCESS;
    

Anmelden zum Antworten