9 Replies - 301 Views - Last Post: 28 January 2013 - 09:47 AM Rate Topic: -----

#1 fredszky  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 28-January 13

String/argument error in my test-server

Posted 28 January 2013 - 06:47 AM

Firstly, i'm really new to all this C/bash/unix stuff so i will probably get some word meanings wrong here, but anyway:

Im trying to make a client pass simple shell commands to the server, which executes them. They communicate locally on the same machine through a socket.

I can make the server perform "ls -l" and "mkdir test" for example, but not "ls", e.g just one argument.

If i only send one command like "ls", the server will try "ls ¤"#"#%" <-- random data. So i think it's really a string problem. I've tried different ideas for a week now, but i am not closer to a solution, and my C-programming skills are not that good at all, so i thought i try asking for some help.


Server:

	#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
	int s, s2, t, len;
	struct sockaddr_un local, remote;
	char str[100];
	char* arg_list[222];
	char str1[100], str2[100];

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		exit(1);
	}

	local.sun_family = AF_UNIX;
	strcpy(local.sun_path, SOCK_PATH);
	unlink(local.sun_path);
	len = strlen(local.sun_path) + sizeof(local.sun_family);
	if (bind(s, (struct sockaddr *)&local, len) == -1) {
		perror("bind");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		perror("listen");
		exit(1);
	}

	for(;;)/>/> {
		int active,done, sent, n;
		printf("Waiting for a connection...\n");
		t = sizeof(remote);
		if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
			perror("accept");
			exit(1);
		}

		printf("Connected.\n");
		active = 0;
		done = 0;
		sent = 0;
		do {
			n = recv(s2, str, 100, 0);
			if (n <= 0) {
				if (n < 0) perror("recv");
				done = 1;
			}


			str[strcspn ( str, "\n" )] = '\0';
			strcpy(str1,str);

			int i=0,k=0;

			while (str1[i] != ' ')
				i++;

			while (str1[i] != '\0'){
				str2[k] = str1[i+1];
				k++;
				i++;
			}

			i=0;

			while (str1[i] != ' ')
				i++;

			str1[i] = '\0';


			int spawn (char* program, char** arg_list)
			{
				pid_t child_pid;
				child_pid = fork ();
				if (child_pid != 0)
					return child_pid;

				else{
					execvp (program, arg_list);
				}
				fprintf (stderr, "an error occurred in execvp\n");
				abort ();




				char* arg_list[222];
				char kommando[222];
				char * tmp;

				i=0;

				tmp = strtok (kommando," ");
				arg_list[0] = tmp;
				while (tmp != NULL)
				{
					tmp = strtok (NULL, " ");
					arg_list[i+1] = tmp;
					i++;
				}

				char* arg[] = {
						str1,
						str2,
						NULL
				};


				spawn (str1, arg);


				if (!done && sent == 0 && active == 0)
					if (send(s2, str, n, 0) < 0) {
						perror("send");
						sent = 1;
					}

				if (!done && sent == 0 && active == 1)
					if (send(s2, str, n, 0) < 0) {
						perror("send");
						sent = 1;
					}
				sent = 0;
			} while (!done);

			close(s2);
		}

		return 0;
	}




Client:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
	int s, t, len;
	struct sockaddr_un remote;
	char str[100];

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		exit(1);
	}

	printf("Trying to connect...\n");

	remote.sun_family = AF_UNIX;
	strcpy(remote.sun_path, SOCK_PATH);
	len = strlen(remote.sun_path) + sizeof(remote.sun_family);
	if (connect(s, (struct sockaddr *)&remote, len) == -1) {
		perror("connect");
		exit(1);
	}

	printf("Connected.\n");

	while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
		if (send(s, str, strlen(str), 0) == -1) {
			perror("send");
			exit(1);
		}

		if ((t=recv(s, str, 100, 0)) > 0) {
			str[t] = '\0';
			printf("echo> %s", str);
		} else {
			if (t < 0) perror("recv");
			else printf("Server closed connection\n");
			exit(1);
		}
	}

	close(s);

	return 0;
}


Is This A Good Question/Topic? 0
  • +

Replies To: String/argument error in my test-server

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3161
  • View blog
  • Posts: 9,541
  • Joined: 05-May 12

Re: String/argument error in my test-server

Posted 28 January 2013 - 06:56 AM

Does your code even compile? I see a do loop starting on line 53, but corresponding while on line 58 to close off the loop.
Was This Post Helpful? 0
  • +
  • -

#3 fredszky  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 28-January 13

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:16 AM

View PostSkydiver, on 28 January 2013 - 06:56 AM, said:

Does your code even compile? I see a do loop starting on line 53, but corresponding while on line 58 to close off the loop.


oh, yes it compiles, the corresponding while is at 136, something went wrong when i pasted it into the forum, intendation perhaps.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3161
  • View blog
  • Posts: 9,541
  • Joined: 05-May 12

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:20 AM

Oh, I see. The inconsistent indentation was confusing me.
Was This Post Helpful? 0
  • +
  • -

#5 jimblumberg  Icon User is offline

  • member icon


Reputation: 3845
  • View blog
  • Posts: 11,735
  • Joined: 25-December 09

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:30 AM

Actually the code you posted for your server doesn't compile. Here are the errors I got when I tried compiling:

Quote

main.c||In function ‘main’:|
main.c|44|error: pointer targets in passing argument 3 of ‘accept’ differ in signedness [-Wpointer-sign]|
/usr/include/i386-linux-gnu/sys/socket.h|214|note: expected ‘socklen_t * restrict’ but argument is of type ‘int *’|
main.c|83|error: ISO C forbids nested functions [-pedantic]|
main.c||In function ‘spawn’:|
main.c|83|warning: declaration of ‘arg_list’ shadows a previous local [-Wshadow]|
main.c|18|warning: shadowed declaration is here [-Wshadow]|
main.c|99|error: ‘arg_list’ redeclared as different kind of symbol|
main.c|83|note: previous definition of ‘arg_list’ was here|
main.c|99|warning: variable ‘arg_list’ set but not used [-Wunused-but-set-variable]|
main.c||In function ‘main’:|
main.c|141|error: expected ‘while’ before ‘return’|
main.c|142|error: expected declaration or statement at end of input|
main.c|18|warning: unused variable ‘arg_list’ [-Wunused-variable]|
||=== Build finished: 7 errors, 4 warnings ===|


I didn't actually try compiling the client code.


Jim
Was This Post Helpful? 0
  • +
  • -

#6 fredszky  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 28-January 13

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:37 AM

perhaps a } was missing. this should work:


#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
        int s, s2, t, len;
        struct sockaddr_un local, remote;
        char str[100];
        char* arg_list[222];
    char str1[100], str2[100];

        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }

        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, SOCK_PATH);
        unlink(local.sun_path);
        len = strlen(local.sun_path) + sizeof(local.sun_family);
        if (bind(s, (struct sockaddr *)&local, len) == -1) {
                perror("bind");
                exit(1);
        }

        if (listen(s, 5) == -1) {
                perror("listen");
                exit(1);
        }

        for(;;)/> {
                int active,done, sent, n;
                printf("Waiting for a connection...\n");
                t = sizeof(remote);
                if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
                        perror("accept");
                        exit(1);
                }

                printf("Connected.\n");
        active = 0;
                done = 0;
                sent = 0;
                do {
                        n = recv(s2, str, 100, 0);
                        if (n <= 0) {
                                if (n < 0) perror("recv");
                                done = 1;
                        }





            if(str[0]=='s' && str[1]=='t' && str[2]=='o' && str[3]=='p')
                done = 1;
            if(str[0]=='s' && str[1]=='t' && str[2]=='a' && str[3]=='r'&&
str[4]=='t')
                active = 1;


    str[strcspn ( str, "\n" )] = '\0';
    strcpy(str1,str);

    int i=0,k=0;

    while (str1[i] != ' ')
        i++;

    while (str1[i] != '\0'){
        str2[k] = str1[i+1];
        k++;
        i++;
    }

    i=0;

    while (str1[i] != ' ')
        i++;

    str1[i] = '\0';





    int spawn (char* program, char** arg_list)
    {


      printf("\n%s!!!\n%s!!!",program,arg_list);


        pid_t child_pid;
        child_pid = fork ();
        if (child_pid != 0)
            return child_pid;





        else{
                execvp (program, arg_list);
            }
            fprintf (stderr, "an error occurred in execvp\n");
            abort ();
        }



        char* arg_list[222];
        char kommando[222];
        char * tmp;

        i=0;

        tmp = strtok (kommando," ");
        arg_list[0] = tmp;
        while (tmp != NULL)
        {
            tmp = strtok (NULL, " ");
            arg_list[i+1] = tmp;
            i++;
        }

        char* arg[] = {
        str1,
        str2,
        NULL
        };


        spawn (str1, arg);


                        if (!done && sent == 0 && active == 0)
                                if (send(s2, str, n, 0) < 0) {
                                        perror("send");
                                        sent = 1;
                                }

                        if (!done && sent == 0 && active == 1)
                                if (send(s2, str, n, 0) < 0) {
                                        perror("send");
                                        sent = 1;
                                }
            sent = 0;
                } while (!done);

                close(s2);
        }

        return 0;
}

Was This Post Helpful? 0
  • +
  • -

#7 jimblumberg  Icon User is offline

  • member icon


Reputation: 3845
  • View blog
  • Posts: 11,735
  • Joined: 25-December 09

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:49 AM

Nope, try again. Look at closely at this error:

Quote

main.c|83|error: ISO C forbids nested functions [-pedantic]|
main.c||In function ‘spawn’:|


You may want try running your program trough a code formatter. Using proper indentation will make spotting this error very easy.


Jim
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3161
  • View blog
  • Posts: 9,541
  • Joined: 05-May 12

Re: String/argument error in my test-server

Posted 28 January 2013 - 07:56 AM

Once you fix your code formatting and compile errors, the core of your problem is that str2 is uninitialized in the case when there is a single command. (See lines 76-83, and 136-143 in post #6.)
Was This Post Helpful? 1
  • +
  • -

#9 fredszky  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 28-January 13

Re: String/argument error in my test-server

Posted 28 January 2013 - 09:29 AM

View PostSkydiver, on 28 January 2013 - 07:56 AM, said:

Once you fix your code formatting and compile errors, the core of your problem is that str2 is uninitialized in the case when there is a single command. (See lines 76-83, and 136-143 in post #6.)


this indeed was the problem, i was able to program around this in my servercode, now i have a working (but ugly) solution.

i did something like this:

        if(str2[0] >= '+' && str2[0] <= 'DEL')
            spawn2 (str1, arg2);
        else
            spawn1 (str1, arg1);


...where spawn 1 takes 1 less argument than spawn 2, and runs exevpc(...).

so, if str2 happends to contain: "a@@££@££" because its uninitialized, the program will fail, but anyway...

i dont find the "edit post" button here, but i forgot to say thanks for putting me in the right direction!
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3161
  • View blog
  • Posts: 9,541
  • Joined: 05-May 12

Re: String/argument error in my test-server

Posted 28 January 2013 - 09:47 AM

Why not simply initialize str2 to be zero filled?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1