/*
a simple test of the version server it requires the test record to be in the 
database though.
 */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

#include "v.h"

int s = 0;
struct sockaddr_in dst, src;

#define APP_NAME "Techmail"
#define APP_VERSION "1.0"

main()
{
  struct v_pkt v;
  char op[10];
  int n_tries = 0;
  int size;
  struct v_info info;
  char anbuf[100], avbuf[100], ambuf[100], apbuf[100];

  bzero(&v, sizeof(v));
  bzero(&info, sizeof(info));
  v.protocol_version = htons(VERSION_PROTOCOL_VERSION);
  v.packet_number = htons(1);
  v.number_of_packets = htons(1);
  v.seq = htonl(time(NULL));
  info.appl_name = "TechMail";
  info.appl_vers = "2.0a8";
  info.platform = "MacOS";
  info.message = "This is a test";
  info.status = "?";
  v.op_code = htons(1);
  size = v_assemble_pkt(&v, &info);
  init_net();
  send_version_pkt(&v, size);
  while(!get_version_reply() && (n_tries++ < 3)) 
    {
      send_version_pkt(&v, sizeof(v));
    } 
  if (n_tries >= 3)
    printf("No rely received!!!\n");
}

init_net()
{
  struct hostent *h;

  bzero(src, sizeof(src));
  bzero(dst, sizeof(dst));

  h = gethostbyname(VERSION_SERVER_HOST);
  if (h == NULL) {
    printf("Host lookup failed for %s\n", VERSION_SERVER_HOST);
    exit(555);
  }

  dst.sin_family = AF_INET;
  bcopy(h->h_addr,&dst.sin_addr, h->h_length);
  dst.sin_port = htons(VERSION_SERVER_PORT);

  s = socket(AF_INET, SOCK_DGRAM, 0);
  if (s < 0) {
    perror ("socket");
    exit(333);
  }

  src.sin_family = AF_INET;
  if (bind(s, &src, sizeof(src)) < 0) {
    perror ("bind");
    exit(444);
  }
}

send_version_pkt(pkt, size)
     char *pkt;
     int size;
{
  int cc;

  cc = sendto(s, pkt, size, 0, &dst, sizeof(dst));
  if (cc != size) {
    perror ("sendto");
    exit(132);
  }

  fprintf(stderr, "Sent packet to %s\n", inet_ntoa(dst.sin_addr));
}

int get_version_reply()
{
  struct timeval tv;
  int nfound, cc, x, size;
  fd_set readfs;
  struct sockaddr_in f;
  struct v_pkt reply;
  struct v_info info;
  struct sockaddr_in name;
  

  tv.tv_sec = 5;
  tv.tv_usec = 0;

  FD_ZERO(&readfs);
  FD_SET(s, &readfs);
  size = sizeof(name);
  getsockname(s,&name,&size);
  printf("port = %d\n",ntohs(name.sin_port));
  nfound = select(FD_SETSIZE, &readfs, 0, 0, &tv);
  if (nfound < 0)  {
    perror ("select");
    exit(665);
  }
  
  if (nfound == 0) return(0); /* timeout */

  if (!FD_ISSET(s, &readfs)) {
    printf("select returns 1 but not the right fd!!!!\n");
    return(0);
  }
  cc = v_read_pkt(s, &reply, &info, &f, &x);
  printf("cc = %d\n",cc);
  if (cc < 0) 
	  {
	  perror ("recvfrom");
	  return(0);
	  }
  
  printf("Reply from %s\n", inet_ntoa(f.sin_addr));

  if (ntohs(reply.op_code)== V_ERROR) 
	  {
	  printf("error, couldn't find entry in database\n");
	  return(1);
	  }

  printf("Prot version %d Packet %d of %d\nseq %ld status %s\n", 
	 reply.protocol_version, reply.packet_number, 
	 reply.number_of_packets, reply.seq, 
	 info.status);

  printf("Application name -- <%s>\n", info.appl_name);
  printf ("Application version -- <%s>\n", info.appl_vers);  
  printf ("Platform -- <%s>\n", info.platform);
  printf ("Message -- <%s>\n", info.message);

  return(1);
}
