netcat like file transfer

Hi Folks

I am not a c programmer .But i need help in writing a program which can do this any ideas on how to go about it .

i start a server on the target server where files need to be copied

start-server -port 5006 & ---start the server and listen it on a partcular port

on the source server do this

if=/usr/myfile |copress start-cliwnt -server target-server -port 500 of=/home/myfile

I need help in writing the client and the2server.

I looked up the unix forums and netcat was close to what i wanted .But not exactly the prog for my need.Anywhere from whe i can start.

regards
Hrishy

Hi Guys

I looked up the unix man pages and Beejs guide to socket programming.I just need your opinion is the c function sendfile the answer to my question ?

man sendfile

regards
Hrishy

Hi Folks

This is what i managed to write server.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>


int main(int argc, char **argv)
{
  int port = 9000;           /* port number to use */
  int sock;                  /* socket desciptor */
  int desc;                  /* file descriptor for socket */
  int in_fd;                 /* input file descriptor */
  int out_fd;		     /*  output file descriptor */
  struct sockaddr_in addr;   /* socket parameters for bind */
  struct sockaddr_in addr1;  /* socket parameters for accept */
  int    addrlen;            /* argument to accept */
  struct stat stat_buf;      /* argument to fstat */
  off_t offset = 0;          /* file offset */
  char filename[PATH_MAX];   /* filename to send */
  int rc;                    /* holds return code of system calls */

  /* check command line arguments, handling an optional port number */
  if (argc == 2) {
    port = atoi(argv[1]);
    if (port <= 1024) { /* dont want root to run this :-) */
      fprintf(stderr, "invalid port: %s\n", argv[1]);
      exit(1);
    }
  } else if (argc != 1) {
    fprintf(stderr, "usage: %s [port]\n", argv[0]);
    exit(1);
  }

  /* create Internet domain socket */
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock == -1) {
    fprintf(stderr, "unable to create socket: %s\n", strerror(errno));
    exit(1);
  }

  /* fill in socket structure */
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(port);

  /* bind socket to the port */
  rc =  bind(sock, (struct sockaddr *)&addr, sizeof(addr));
  if (rc == -1) {
    fprintf(stderr, "unable to bind to socket: %s\n", strerror(errno));
    exit(1);
  }

  /* listen for clients on the socket */
  rc = listen(sock, 1);
  if (rc == -1) {
    fprintf(stderr, "listen failed: %s\n", strerror(errno));
    exit(1);
  }

  while (1) {

    /* wait for a client to connect */
    desc = accept(sock, (struct sockaddr *)  &addr1, &addrlen);
    if (desc == -1) {
      fprintf(stderr, "accept failed: %s\n", strerror(errno));
      exit(1);
    }

    /* get the file name from the client */
    rc = recv(desc, filename, sizeof(filename), 0);
    if (rc == -1) {
      fprintf(stderr, "recv failed: %s\n", strerror(errno));
      exit(1);
    }

    /* null terminate and strip any \r and \n from filename */
		filename[rc] = '\0';
    if (filename[strlen(filename)-1] == '\n')
      filename[strlen(filename)-1] = '\0';
    if (filename[strlen(filename)-1] == '\r')
      filename[strlen(filename)-1] = '\0';

    /* exit server if filename is "quit" */
    if (strcmp(filename, "quit") == 0) {
      fprintf(stderr, "quit command received, shutting down server\n");
      break;
    }

    /* fprintf(stderr, "received request to send file %s\n", filename); */

    /* open the file to be sent */
    in_fd = open(filename, O_RDONLY);
    if (in_fd == -1) {
      fprintf(stderr, "unable to open '%s': %s\n", filename, strerror(errno));
      exit(1);
    }

    /* get the size of the file to be sent */
    fstat(in_fd, &stat_buf);

    /* copy file using sendfile */
    offset = 0;
    rc = sendfile (desc, in_fd, &offset, stat_buf.st_size);
    if (rc == -1) {
      fprintf(stderr, "error from sendfile: %s\n", strerror(errno));
      exit(1);
    }
    if (rc != stat_buf.st_size) {
      fprintf(stderr, "incomplete transfer from sendfile: %d of %d bytes\n",
              rc,
              (int)stat_buf.st_size);
      exit(1);
    }

    /* close descriptor for file that was sent */
    close(in_fd);

    /* close socket descriptor */
    close(desc);
  }

  /* close socket */
  close(sock);
  return 0;
}

For the client part

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>

int main (int argc, char** argv)
{
  int src;               	/* file descriptor for source file */
  int dest;              	/* file descriptor for destination file */
  struct stat stat_buf;  	/* hold information about input file */
  off_t offset = 0;      	/* byte offset used by sendfile */
  int rc;                	/* return code from sendfile */
  int port;		 	/* port on the remote server to connect to */
  struct sockaddr_in server;    /* socket address */
  int s ;			/* client socket */
  /* check for two command line arguments */
  if (argc != 4) {
    fprintf(stderr, "usage: %s <hostname> <port> <source> <destination> \n", argv[0]);
    exit(1);
  }

  /* check command line arguments, handling an optional port number */
  if (argc == 4) {
    port = atoi(argv[1]);
    if (port <= 1024) { /* dont want root to run this :-) */
      fprintf(stderr, "invalid port: %s\n", argv[1]);
      exit(1);
    }
  } 

  if ((he=gethostbyname(argv[1])) == NULL) {  /* get the host info */
            herror("gethostbyname");
            exit(1);
        }

  strcpy( buf, "Hello there!"); /* create the message */

  /* create stream socket using TCP */
  fprintf(stderr, "Creating datagram socket.\n");
  s = socket(AF_INET, SOCK_STREAM, 0);
  if( s == -1 ) {
  fprintf(stderr, "Socket was not created.\n");
  exit(1);
  }
  else
  fprintf(stderr, "Socket created successfully.\n");
  server.sin_family = AF_INET; /* set up the server name */
  server.sin_port = htons(port);
  server.sin_addr.s_addr = inet_addr( argv[1] );

  /* connect to the server */
  if( connect(s, &server, sizeof(server)) < 0) {
  fprintf(stderr, "Failed to connect to socket.\n");
  exit(1);
  }

  printf("Sending the message: %s\n", buf); /* send the message */
  if( send(s, buf, sizeof(buf), 0) < 0 ) {
  fprintf(stderr, "Failed to send data to socket.\n");
  exit(1);
  }

   /* receive the echoed message from the server */
  if( recv(s, buf, sizeof(buf), 0) < 0 ) {
  fprintf(stderr, "Failed to receive data from socket.\n");
  exit(1);
  }
  printf("The message from the server was: %s\n", buf);
  
  close(s); /* close the socket */
  printf("Client closed successfully\n"); /* successfully exit */
  exit(0);
}

The problem i have now is what message the client should pass to the server ?

I just passed strcpy( buf, "Hello there!"); but i actually need to pass the file descriptor of the file which i need to get .

And when the server responds i need to copy that file to some path on the client.

I hope somebody helps me now .Please i have a feeling i am very close.

regards
Hrishy