Firstly, i'm really new to all this bash/unix/c stuff so i will probably get some words 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 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;
}