Reputation: 2711
I'm going through the socket programming and implemented it well.. Now i want to implement a system call ls
in it..
when the input is given as ls
on the client machine, the output of the server should be printed on client machine (i.e the command should execute on the server side and the output should be redirected to the client side..)
How do i collect the output of server machine?
i just need hint.. Thanks
Upvotes: 2
Views: 10128
Reputation: 819
create the empty file like cat > file and ctrl+d the filename is file
client:
Get the Input from the user
ls
n=send(sockfd, msg, 1000,0); //msg contains the ls
send function using send the message to the server
Server:
Receive function using receive the client message
n=receive(sockfd, msg, 1000,0);
FILE *fp;
recvbuf[strlen(recvbuf)-1]=0; // client msg received and delete the \n
strcat(recvbuf,">file"); // add to redirected file
printf("Recvbuf:%s\n",recvbuf); // ls>file
int status=0;
pid_t pid=vfork();
if(pid==0)
execlp("sh","sh","-c",recvbuf,(char *)0); // executed the ls command and redirected to file
else
{
wait(&status);
fp=fopen("file","r"); //open the file read the content and stored to buffer
while((c=getc(fp))!=EOF)
buf1[i++]=c;
buf1[i]='\0';
printf("%s\n",buf1);
fclose(fp);
}
Again server send the buffer to the clientfd so the output redirected to client.
send(sockfd,buf1,1000,0);
Finally client receive the output of command
Upvotes: 1
Reputation: 32240
You can use dup2 to redirect stdout
(or any other existing fd) to your socket fd. Example:
int client_fd = accept(server_fd, 0, 0);
assert(client_fd != -1);
close(0); // Close stdout
dup2(client_fd, 0); // Redirect stdout to client_fd
This should do the trick :-)
EDIT 1 The example below shows a client program that connects to 127.0.0.1:1234, spawns a shell process, and redirects IO so that all communication is handled automatically by the shell for you. You can test it by running netcat -l 1234 in another terminal, then run the program and send a command like ls
from netcat. Adapting it to work on the server-side is left as exercise.
IMPORTANT: This program gives unauthenticated access to the machine's shell.
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int exec_shell(int sock_fd) {
// Redirect IO
dup2(sock_fd, 0);
dup2(sock_fd, 1);
dup2(sock_fd, 2);
// Execute shell
execl("/bin/sh", "sh", NULL);
return 0;
}
int main() {
int fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sa_dst;
memset(&sa_dst, 0, sizeof(struct sockaddr_in));
sa_dst.sin_family = AF_INET;
sa_dst.sin_port = htons(1234);
sa_dst.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = connect(fd, (struct sockaddr *)&sa_dst, sizeof(struct sockaddr));
assert(ret != -1);
exec_shell(fd);
close(fd);
return EXIT_SUCCESS;
}
Upvotes: 7
Reputation: 2020
If I understood the question correctly, my "hint" would be to use the following:
popen()
to execute the ls command on the server.fileno()
.sendfile()
to copy it to the client_fd.Edit: sendfile()
is non-standard and might not be portable. You can replace it with a read-write loop (reading the FILE * writing into client_fd), if you want, but its more work.
Upvotes: 0