Socket _popen() linux



  • Hey.

    Folgender Codeausschnitt:

    void* handle (void* socket)
    {
    	socket = (int) socket;
    	send (socket, "Connected", strlen("Connected"), 0);
    
    	for (;;)
    	{
    		// Wait for incomming commands
    		bytes = recv(socket, name, sizeof(name) - 1, 0);
    		name[bytes] = '\0';
    
    		FILE *p = popen("ls -la", "r");
    
            if(p == NULL)
            {
            	// Error! I don't fucking care!
            }
    
            while(feof(p)==0)
            {
            	memset(buf, 0, strlen(buf));
            	fgets(buf, 100, p);
            	strcat(erg, buf);
            	//printf("%s\n", name);
            	//send(client,buf,100,0);
            }
            printf("%s\n", erg);
            pclose(p); 	
    	}
    }
    

    So funktioniert es prima, wenn ich aber anstatt:

    FILE *p = popen("ls -la", "r");
    

    das hier schreibe:

    FILE *p = popen(name, "r");
    

    Bekomme ich Command not found!
    Ich verstehe nicht warum, name enthält die Übergebenen Werte per socket (der string kommt auch an, schon überprüft) und wird dann auch mit \0 terminiert. Eigentlich sollte popen das doch übernehmen?

    Danke für eure Hilfe

    Lg



  • ist dir klar das du bei tcp einen byte stream bekommst den du selbst in "pakete" zerlegen musst?



  • for (;;)
    	{
    		// Wait for incomming commands
    		bytes = recv(socket, name, sizeof(name) - 1, 0);
    		name[bytes] = '\0';
    		printf("HIER KOMMT DAS ZEUGS ÜBERS NETZ\n");
    		printf("%s\n\n", name);
    		printf("\r\n");
    		exit(1);
    

    bringt mir die Ausgabe

    HIER KOMMT DAS ZEUGS ÜBERS NETZ
    hallo

    Und ich habe "hallo" eingeben, warum sollte jetzt das nicht von popen() verwendet werden können, bzw. was soll daran falsch sein???



  • hi,
    also das hier solltest du dir mal genauer anschauen:

    socket = (int) socket;
    

    du castest ein *void ** nach int und speicherst es wieder in einem *void ** ?
    das kann so nicht funktionieren.

    mfg blan



  • Dummer Fehler 😃
    Hab ich jetzt ausgebessert, jedoch bekomme ich nun:

    : not found

    : not found

    : not found

    : not found

    Bei folgendem Quelltext

    void* handle (void* socket)
    {
    	int sock;
    	sock = (int) socket;
    
    	send (socket, "Connected", strlen("Connected"), 0);
    
    	for (;;)
    	{
    		// Wait for incomming commands
    		bytes = recv(socket, name, sizeof(name) - 1, 0);
    		name[bytes] = '\0';
    
    		FILE *p = popen(name, "r");
    
            if(p == NULL)
            {
            	// Error! I don't fucking care!
            }
    
            while(feof(p)==0)
            {
            	memset(buf, 0, strlen(buf));
            	fgets(buf, 100, p);
            	strcat(erg, buf);
            	//printf("%s\n", name);
            	//send(client,buf,100,0);
            }
            printf("%s\n", erg);
            pclose(p); 	
    	}
    }
    


  • hi,
    na so sollte der code aber auch nicht unbedingt aussehen 😉
    probiers mal damit:

    void* handle (void* socket)
    {
        int *sock;
        sock = ( int * ) socket;
    
        send (*sock, "Connected", strlen("Connected"), 0);
    

    solltest evtl. noch abfragen ob socket NULL ist.

    blan



  • wenn ichs so mache wie du dann:

    Segmentation fault (core dumped)

    😃
    liegt der fehler nicht wo anderst?
    weil der socket empfängt den befehl ja, nur popen() verarbeitet den wohl irgendwie falsch, bzw. liest den falsch ein, dass

    : not found

    kommt!



  • zeig mal mehr von dem code. mein code stimmt aber wie gesagt, wenn deine void *handle( void *socket ) methode mit NULL aufgerufen wird kommt natürlich ein Segmentation fault.

    blan



  • #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <pthread.h>
    #include <time.h>
    #include <string.h>
    #include <sys/stat.h>
    
    #define BUFFER_SIZE 1024
    
    char name[BUFFER_SIZE];
    char buf[BUFFER_SIZE];
    char erg[BUFFER_SIZE];
    
    int bytes = 0;
    
    void* handle (void* socket)
    {
    	int *sock;
        sock = ( int * ) socket; 
    
    	send (*sock, "Connected", strlen("Connected"), 0);
    
    	for (;;)
    	{
    		// Wait for incomming commands
    		bytes = recv(socket, name, sizeof(name) - 1, 0);
    		name[bytes] = '\0';
    
    		FILE *p = popen(name, "r");
    
            if(p == NULL)
            {
            	// Error! I don't fucking care!
            }
    
            while(feof(p)==0)
            {
            	memset(buf, 0, strlen(buf));
            	fgets(buf, 100, p);
            	strcat(erg, buf);
            	//printf("%s\n", name);
            	//send(client,buf,100,0);
            }
            printf("%s\n", erg);
            pclose(p); 	
    	}
    }
    
    int startsocks ()
    {
    	int s, c;
        struct sockaddr_in srv, cli;
        socklen_t cli_size;
    
        s = socket(AF_INET, SOCK_STREAM, 0);
    
        srv.sin_addr.s_addr = INADDR_ANY;
        srv.sin_port = htons( (unsigned short int) 1337);
        srv.sin_family = AF_INET;
    
        if (bind(s,(struct sockaddr*) &srv, sizeof(srv)) == -1)
        {
                perror("bind() failed");
                return 3;
        }
    
        if (listen(s, 3) == -1)
        {
                perror("listen() failed");
                return 4;
        }
    
        for(;;)
        {
    
                cli_size = sizeof(cli);
                c = accept(s, (struct sockaddr *) &cli, &cli_size);
                // Start the tread to handle the client
                pthread_t tid;
                pthread_create(&tid, NULL, handle, (void *) c);
                //close(c);
        }	
    }
    
    int main ()
    {
    	startsocks();
    
    	return 0;
    }
    


  • okay, du machst in deinem code grundlegende fehler. ich empfehle dir mal die option -Wall in deine compilerparamter einzubinden dann siehst du auch alle fehlermeldungen.

    bytes = recv(socket, name, sizeof(name) - 1, 0);
    

    kann nicht funktionieren, da socket ein void-pointer ist.

    pthread_create(&tid, NULL, handle, (void *) c);
    

    durch dein *void **-cast wird eine hilfreiche warnung unterbunden. bei *void ** muss man nicht extra casten ( bitte jetzt keine diskussionen ^^ )
    außerdem musst du wenn schon die adresse von c übergeben.

    schau dir ambesten nochmal die grundlagen von pointern in C an.

    p.s: mit den änderungen läuft dein programm bei mir ohne probleme. allerdings geht dein code davon aus, dass die befehle immer mit einem paket ankommen - das ist unter umständen nicht so.

    blan



  • kannst du mir erklären, was ich genau ändern muss?

    ich verstehe dass bytes integer werte erwartet jedoch ein void * bekommen würde....



  • danke1 schrieb:

    ich verstehe dass bytes integer werte erwartet jedoch ein void * bekommen würde....

    was ist "bytes" ?



  • int bytes = 0;

    Also eine Integer Variable



  • asdfdsaf schrieb:

    int bytes = 0;

    Also eine Integer Variable

    die variable bytes würde überhaupt kein *void ** bekommen. irgendwas hast du da noch nicht ganz verstanden.

    also meine änderungen waren:

    bytes = recv(*sock, name, sizeof(name) - 1, 0);
    

    und

    pthread_create(&tid, NULL, handle, &c);
    

    blan



  • aja ok jetzt verstehe ich,m was du mir sagen wolltest.
    danke!

    der fehler bleibt jedoch konstant:

    : not found

    : not found



  • zeig mal dein aufruf. netzwerk oder internet?



  • Also hier der komplette Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <pthread.h>
    #include <time.h>
    #include <string.h>
    #include <sys/stat.h>
    
    #define BUFFER_SIZE 1024
    
    char name[BUFFER_SIZE];
    char buf[BUFFER_SIZE];
    char erg[BUFFER_SIZE];
    
    int bytes = 0;
    
    void* handle (void* socket)
    {
        int *sock;
        sock = ( int * ) socket; 
    
    	send (*sock, "Connected", strlen("Connected"), 0);
    
    	for (;;)
    	{
    		// Wait for incomming commands
    		bytes = recv(*sock, name, sizeof(name) - 1, 0);
    		name[bytes] = '\0';
    		printf("Name hat den Wert: \n");
    		printf("%s\n", name);
    		printf("\r\n");
    		FILE *p = popen(name, "r");
    
            if(p == NULL)
            {
            	// Error! I don't fucking care!
            }
    
            while(feof(p)==0)
            {
            	memset(buf, 0, strlen(buf));
            	fgets(buf, 100, p);
            	strcat(erg, buf);
            	//printf("%s\n", name);
            	//send(client,buf,100,0);
            }
            printf("%s\n", erg);
            pclose(p); 	
    	}
    }
    
    int startsocks ()
    {
    	int s, c;
        struct sockaddr_in srv, cli;
        socklen_t cli_size;
    
        s = socket(AF_INET, SOCK_STREAM, 0);
    
        srv.sin_addr.s_addr = INADDR_ANY;
        srv.sin_port = htons( (unsigned short int) 1337);
        srv.sin_family = AF_INET;
    
        if (bind(s,(struct sockaddr*) &srv, sizeof(srv)) == -1)
        {
                perror("bind() failed");
                return 3;
        }
    
        if (listen(s, 3) == -1)
        {
                perror("listen() failed");
                return 4;
        }
    
        for(;;)
        {
    
                cli_size = sizeof(cli);
                c = accept(s, (struct sockaddr *) &cli, &cli_size);
                // Start the tread to handle the client
                pthread_t tid;
                //pthread_create(&tid, NULL, handle, (void *) c);
    	    pthread_create(&tid, NULL, handle, &c);
                //close(c);
        }	
    }
    
    int main ()
    {
    	startsocks();
    
    	return 0;
    }
    

    Gestartet wird der Server mit:

    ./server

    Der Client:

    telnet localhost 1337

    Dann bekomm ich den String "Connected" zu sehen. Tippe ls ein und dann kommt der Fehler not found beim Server!



  • ich tipp einfach mal drauf, dass dein telnet client den string nicht richtig sendet bzw anders. probier mal:

    netcat localhost 1337
    

    blan



  • Hallo,

    Ja wirklich, mit nc funktioniert es!
    hast du eine Idee, was telnet denn da sendet?
    Oder soll ich einfach mal sniffen und mir die packets ansehen?

    Würd mich ja mal wirklich interessieren was da lost ist.

    thx für die hilfe



  • Jetzt hab ich aber noch ein kleines Problemchen:

    char* pipe (char *command)
    {
        // Pipe stuff
        char buffer[10000];
    
        FILE *pPipe;
    
        if( (pPipe = _popen( command, "rt" )) == NULL )
        {
            exit( 1 );
        } 
    
        while(!feof(pPipe)) 
        {
         if( fgets(buffer, 128, pPipe ) != NULL )
         {
          // printf("%s", buffer);
          strcat(lese, buffer);
         }
        }
        _pclose( pPipe );
         return lese;
    
    }
    
    int handling (int sock)
    {
        // WICHTIG PRÜFEN OB DAS SENDEN ERFOLGREICH IST ODERN NICHT
        // WENN SENDEN NICHT ERFOLGREICH => VERBINDUNG GETRENNT
        // => RETURN 1 DANN WIRD AUS DER FUNKTION RAUSGESPRUNGEN UND DIE
        // MAIN FUNKTION KANN IM 10 SEKUNDEN TAKT VERSUCHEN SICH ZU VERBINDEN!!
        char buffer[BUFFER_SIZE];
    	int bytes;
    
        send (sock, "Connected", sizeof("Connected"), 0);
    
        for (;;)
        {
    	 bytes = recv (sock, buffer, sizeof(buffer) -1, 0);
    	 if (bytes == -1)
    	 {
          return -1;          
         }
    	 buffer[bytes] = '\0';
    	 pipe (buffer);
    
    	 send (sock, lese, sizeof(lese), 0);
        }
    	return 0;   
    }
    

    Wenn ich nun einen Befehl über den Socket schicke, dann bekomme ich die Antwort also z.B. für dir bekomme ich dann die Verzeichnisauflistung gesendet, das einzige Problem daran ist die Formatierung. Irgendwie bekomme ich 50 /n mitgesendet.
    Sprich es kommt das Ergebnis des Befehles in der Konsole an und dann noch 50 neue leere Zeilen.

    Weiß jemand mit was das zusammenhängt bzw. wie ich das ändern kann?

    Danke für die Hilfe
    LG


Anmelden zum Antworten