/*

 */

#ifndef lint
static char *rcsid_vtest_c = "$Header: $";
#endif	lint

#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;
  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());
  printf("\nApplication Name: ");
  gets(info.appl_name = anbuf);
  printf("\nVersion         : ");
  gets(info.appl_vers = avbuf);
  printf("\nPlatform        : ");
  gets(info.platform = apbuf);
  printf("\nMessage         : ");
  gets(info.message = ambuf);
  info.status = "?";
  printf("\nCheck = 0, Check & Log = 2, Log Alert = 3");
  printf("\nOperation         : ");
  gets(op);
  v.op_code = htons(atoi(op));
  v_assemble_pkt(&v, &info);
  v_parse_pkt(&v, &info);
  
  init_net();
  send_version_pkt(&v, sizeof(v));
  if (v.op_code == V_CHECK || v.op_code == V_CHECK_AND_LOG) 
	  {
	  while(!get_version_reply() && (n_tries++ < 2)) 
		  {
		  send_version_pkt(&v, sizeof(v));
		  } 
	  }   
  }

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 = 1;
  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 = recvfrom(s, &reply, sizeof(reply), 0, &f, &x);
  printf("cc = %d\n",cc);
  if (cc < 0) 
	  {
	  perror ("recvfrom");
	  return(0);
	  }
  
  printf("Reply from %s\n", inet_ntoa(f.sin_addr));
  v_parse_pkt(&reply, &info);

  if (reply.op_code == V_ERROR) 
	  {
	  printf("error\n");
	  return(1);
	  }

  printf("Prot version %d Packet %d of %d\nseq %d status %s\n", 
	 ntohs(reply.protocol_version), ntohs(reply.packet_number), 
	 ntohs(reply.number_of_packets), ntohl(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);
}
