Raghu Srikanth Reddy
Raghu Srikanth Reddy

Reputation: 2711

redirecting output of server to client-socket

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

Answers (3)

loganaayahee
loganaayahee

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

jweyrich
jweyrich

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

thuovila
thuovila

Reputation: 2020

If I understood the question correctly, my "hint" would be to use the following:

  1. Use popen() to execute the ls command on the server.
  2. Get the FILE * streams fd with fileno().
  3. Use 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

Related Questions