#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <netdb.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>

int main(int argc, char * argv[]) {
      if(argc != 2) {
            printf("usage:    %s portnumber\n", argv[0]);
            exit( EXIT_FAILURE );
      }
      int port = atoi(argv[1]);
      if(port < 1) {
            printf("Invalid port : %d (from %s)\n", port, argv[1]);
            exit( EXIT_FAILURE );
      }

      int sock = socket(AF_INET, SOCK_STREAM, 0);
      if(sock < 0) {
            perror( "socket" );
            exit( EXIT_FAILURE );
      }

      struct hostent * server = gethostbyname("localhost");
      if(server == NULL) {
            perror("localhost not found");
            exit( EXIT_FAILURE );
      }

      struct sockaddr_in serv_addr;
      memset(&serv_addr, 0, sizeof(serv_addr));
      serv_addr.sin_family = AF_INET;
      memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);
      serv_addr.sin_port = htons(port);

      int ret = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
      if(ret < 0) {
            perror( "connect" );
            exit( EXIT_FAILURE );
      }

      char buffer[256];
      struct iovec iov = { buffer, 0 };
      struct msghdr msg;
      msg.msg_name = NULL;
      msg.msg_namelen = 0;
      msg.msg_control = NULL;
      msg.msg_controllen = 0;
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      msg.msg_flags = 0;


      int rd;
      while(0 != (rd = read(STDIN_FILENO, buffer, 256))) {
            if(rd < 0) {
                  perror( "read" );
                  exit( EXIT_FAILURE );
            }

            iov.iov_len = rd;
            int sent = sendmsg(sock, &msg, 0);
            if( sent < 0 ) {
                  perror( "read" );
                  exit( EXIT_FAILURE );
            }

            if(sent != rd) {
                  printf("Expected to send %d bytes, sent %d\n", rd, sent);
                  exit( EXIT_FAILURE );
            }
      }

      ret = close(sock);
      if(ret < 0) {
            perror( "close" );
            exit( EXIT_FAILURE );
      }

      exit( EXIT_SUCCESS );
}