/*

 */

#ifndef lint
static char *rcsid_vtest_c = "$Header: /afs/athena.mit.edu/project/net_dev/versions/RCS/vtest.c,v 1.7 97/05/06 17:51:33 jweiss Exp $";
#endif	lint

#include <stdlib.h>
#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 MAX_TRIES 3
#define APP_NAME "TechMail"
#define APP_VERSION "2.0a8"
#define APP_OS "MacOS"
#define APP_MESSAGE ""
#define APP_OPERATION "0"

main(int argc, char** argv)
{
  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];
  int noprompt = 0;
  int c;
  extern int optind, opterr;
  extern char *optarg;

  while ((c = getopt (argc, argv, "n")) != EOF)
    switch (c) {
    case 'n':
      noprompt++;
      break;
    case '?':
      printf("usage: vtest [-a]\n");
      exit (1);
      break;
    }

  memset(&v, 0, sizeof(v));
  memset(&info, 0, 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));
  if ( ! noprompt) {
    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);
  } else {
    strcpy(anbuf, APP_NAME);
    info.appl_name = anbuf;
    strcpy(avbuf, APP_VERSION);
    info.appl_vers = avbuf;
    strcpy(apbuf, APP_OS);
    info.platform = apbuf;
    strcpy(ambuf, APP_MESSAGE);
    info.message = ambuf;
    strcpy(op, APP_OPERATION);
  }
  v.op_code = htons(atoi(op));
  size = v_assemble_pkt(&v, &info);
  init_net();
  send_version_pkt(&v, size);
  if (v.op_code == V_CHECK || v.op_code == V_CHECK_AND_LOG) 
	  {
	  while(!get_version_reply() && (n_tries < MAX_TRIES)) 
		  {
		  send_version_pkt(&v, sizeof(v));
		  n_tries++;
		  } 
	  if (n_tries == MAX_TRIES)
	          {
		  printf("No reply received!!!\n");
		  }
	  }   
  }

init_net()
{
  struct hostent *h;

  memset(src, 0, sizeof(src));
  memset(dst, 0, 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;
  memmove(&dst.sin_addr, h->h_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, (struct sockaddr *) &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, (struct sockaddr *) &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;
  x = sizeof(struct sockaddr);

  tv.tv_sec = 1;
  tv.tv_usec = 0;

  FD_ZERO(&readfs);
  FD_SET(s, &readfs);
  size = sizeof(name);
  getsockname(s,(struct sockaddr *)&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 (reply.op_code == V_ERROR) 
	  {
	  printf("error\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);
}
