this is a server client “rsh”program.This rsh (remote shell) allows me to execute a series of sh commands on a remote Unix system.
something like: if the command on client is
client linux03 uname -a
it should get an answer like:
Linux linux03 2.4.9-12 #1 Tue Oct 30 18:41:57 EST 2001 i686 unknown
the program is upposed to support till 3 pipes.
am spending so much time on it and i cant think clearly anymore.
any suggest please
server code:
#include <stdio.h>                                                              
#include <sys/types.h>                                                          
#include <sys/socket.h>                                                         
#include <netinet/in.h>                                                         
#include <netdb.h>                                                              
//#include <iostream.h>                                                         
#include <unistd.h>                                                             
#define SADDR struct sockaddr *                                                 
#define MAXCMDS 3                                                               
#define MAXARGS 3                                                               
//function to output err to stderr and exit                                     
void xerror(char msg[])                                                         
//function to parse char array into tokens based on passed delimiters           
int parse (char *line, char *delimitor, char *token[])                          
  int i=1;                                                                      
  strtok(line, delimitor);                                                      
  while((token[i]=(char *)strtok(NULL, delimitor))!=NULL)                       
      while (*token[i] == ' ') token[i]++; /* eliminate leading spaces */       
  return i;                                                                     
int execute_cmds(char commands[], char buffer[]) {                              
  int i, k; //loop variables                                                    
  int no_cmds, no_args, op_size; //number of commands, arguments, & output size 
  char *cmd[MAXCMDS]; //pointer to array of command 'strings'  
  char *args[MAXARGS];  // pointer to array of arguments                        
  int pfds[MAXCMDS][2]; //array of pipe file descriptors                        
  printf("in execute_cmds \n");                                                 
  for(i=0 ; i<MAXCMDS ; i++) pipe(pfds[i]); //setup pipes                       
  printf("pipes done \n");                                                      
  for(i=0 ; i<MAXCMDS ; i++) cmd[i] = NULL;                                     
  no_cmds = parse(commands, "|", cmd);  //null cmd array, parse command string  
  printf("Number of commands = %d\n", no_cmds);                                 
  for (i=0 ; i<no_cmds ; i++) printf("cmd[%d]=%s\n", i, cmd[i]);                
  for(i=0 ; i<no_cmds ; i++) //loop for numebr of commands' times               
      if(!fork()) //fork new child                                              
          printf("in child pid %d \n", getpid());                               
          close(1);                     //close child stdout                    
           no_args = parse(cmd[i], " ", args); //parse each command             
          args[no_args]=NULL; dup(pfds[i][1]);          //make stdout = pfds[i][1] - input of pipe i                                                            
          close(pfds[i][0]);            //close input of same pipe              
            //if not child 1 connect child stdin to o/p of previous pipe        
              close(0);                 //close child stdin                     
              dup(pfds[i-1][0]);        //make stdin = pfds[i-1][0] - output of pipe before                                                                     
              close(pfds[i-1][1]);      //close input of pipe before            
          for(k=0 ; k<MAXCMDS ; k++)                                            
              if(k!=i && k!=i-1) { close(pfds[k][0]); close(pfds[k][1]);}       
          no_args = parse(cmd[i], " ", args); //parse each command              
          fprintf(stderr, "%s\n", cmd[i]);                                      
          for(i=0 ; i<no_args ; i++) fprintf(stderr, "%s\n", args[i]);          
          execvp(cmd[i], args); //execute command i with args                   
  for(i=0 ; i<MAXCMDS ; i++){ //close all unwanted pipes in parent              
          if(i!=(no_cmds-1)) { close(pfds[i][0]); close(pfds[i][1]);}           
  op_size = read(pfds[no_cmds-1][0],buffer,500); //store o/p in last pipe in buffer                                                                             
  buffer[op_size] = '\0';                                                       
  printf("buffer = %s ; size = %d\n", buffer, op_size);                         
  printf("leaving execute_cmds\n");                                             
  return op_size;    
int main(int argc, char *argv[])                                                
  struct sockaddr_in sa; //struct to hold socket address variables              
  char cmd_line[501], buf[501]; //arrays for command line and data buffer       
  int s, new_s, length_recv, length_send, n = sizeof(sa);                       
  if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0) xerror("socket"); // make socket   
  sa.sin_family = AF_INET;                            // set type               
  sa.sin_addr.s_addr = htonl(INADDR_ANY);             // set wildcard           
  sa.sin_port = htons(6001);                          // set port               
  if ( bind(s, (SADDR)&sa, n) < 0 ) xerror("bind");   // bind address           
  listen(s, 5);                                       // queue callers          
  for( ; ; )                                                                    
      if ( ( new_s = accept(s, (SADDR)0, 0) ) < 0 ) xerror("accept");// accept call                                                                             
     {  // child process                                                     
          printf("in child server pid %d \n", getpid());                        
          length_recv = recv(new_s, cmd_line, 501, 0);      // read             
          cmd_line[length_recv] = '\0';                     // delimit string   
          printf("Command string recieved\n");                                  
          length_send = execute_cmds(cmd_line, buf);                            
          //execute commands, store results in buffer buf[]                     
          printf("Message being returned - %s\n", buf);                         
          send(new_s, buf, length_send, 0);               // return message     
          //send(new_s, "done something \0", 20, 0);                            
          printf("Returned result\n");                                          
          close(new_s); //close server socket                                   
    // parent process                                                         
      close(new_s);   //close server socket                                     
  printf("Have exited forever loop!!!\n");                                      
client code which works fine
#include <sys/types.h>                                                          
#include <sys/socket.h>                                                         
#include <netinet/in.h>                                                         
#include <netdb.h>                                                              
#include <string.h>                                                             
#include <unistd.h>                                                             
int main(int argc, char *argv[]) {                                              
  struct hostent *hp; struct sockaddr_in sa;                                    
  int    s, n_chars, n = sizeof(struct sockaddr_in);                            
  char   buf[501];                                                              
  if ((s=socket(AF_INET,SOCK_STREAM,0)) < 0) exit(1);// make socket  
  if ( (hp = gethostbyname(argv[1])) == 0 ) exit(1); // get host struct         
  memset(&sa, 0, n);                                 // init struct             
  memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);    // set host                
  sa.sin_port = htons(6001);                         // set port                
  sa.sin_family = AF_INET;                           // set type                
  if (connect(s,(struct sockaddr *)&sa,n)<0) exit(1);// connect                 
  send(s, argv[2], strlen(argv[2]), 0);                // write message         
  printf("\nSent command string\n");                                            
  n_chars=recv(s, buf, 500, 0);                                                 
  printf("%d chars output returned, o/p=%s\n", n_chars, buf);