#include <stdio.h>
#include <sys/time.h>
#include "Connect.h"
#include "inet-udp.h"
#include "Code.h"
#include "literal.h"
#include "machdefs.h"
#include "slw.h"

char pname[100];

void printError(die)
     int die;
{
  int fatal = 0;

  while (Error_Exists)
    {
#ifdef DEBUG
      if (1)
#else
      if (Error_Severity == S_FATAL)
#endif
	{
	  fprintf(stderr, "%s: ", pname);
	  fprintf(stderr, Error_String(Error), Error_Info);
	  fputc('\n', stderr);
	}
      if (Error_Severity == S_FATAL)
	fatal++;
      Error_Pop();
    }

  if (fatal && die)
    exit(1);
}

#define E(x) if (x) printError(1)
#define ED(x) if (x) printError(0)

main(argc, argv)
     char **argv;
{
  Addr local;
  char *message;
  int i;
  Packet req, repl;
  CodeBlock *request, *reply;
  char name[50];
  char from[50];
  char *program, *version, *vendor, *path;
  struct timeval t;
  Card16 ptype;
  char *keyptr;
  int keysize;

  /*
   * Random initialization
   */
  sprintf(pname, "wrapper(%s)", argv[0]);

  if (argc < 5)
    {
      fprintf(stderr, "usage: %s program version vendor executable [args]\n",
	      pname);
      exit(1);
    }

  program = argv[1];
  version = argv[2];
  vendor = argv[3];
  path = argv[4];

  E(Connect_Initialize());
  E(Connect_RegisterDomain(&inetudp));

  E(Code_Initialize());
  E(Code_RegisterDomain(&literal));

  sprintf(from, "%s:.", PORTDOMAIN);
  E(Connect_NameToAddress(from, &local));

  /*
   * Create the request packet we want to send.
   */
  gettimeofday(&t, NULL);

  E(Code_CreateBlock(&request, CODEDOMAIN, NULL, 0));
  E(Code_PutCard16(request, PROTOVERSION0));	/* protocol version */
  E(Code_PutCard16(request, REQUEST_KEY));	/* request type */

  E(Code_PutString(request, SYSTEM));		/* key identifier */
  E(Code_PutString(request, program));
  E(Code_PutString(request, version));
  E(Code_PutString(request, vendor));

  E(Code_PutString(request, path));		/* so we can find it */
  E(Code_PutCard32(request, t.tv_sec));		/* partial key generator */

  req.Source = local;
  req.packet = Code_BlockData(request);
  req.length = Code_BlockLength(request);

  if (askQuestionOfServer(&req, &repl))
    exit(1);

  E(Code_CreateBlock(&reply, CODEDOMAIN, repl.packet, repl.length));
#ifdef DEBUG
  Connect_AddressToName(repl.Source, name, sizeof(name));
  fprintf(stdout, "From: %d - %s\n", repl.Source, name);
  fprintf(stdout, "length: %d\n", repl.length);
#endif
  E(Code_GetCard16(reply, &ptype));
#ifdef DEBUG
  fprintf(stdout, "type: %d\n", ptype);
#endif
  switch(ptype)
    {
    case REPLY_KEY:
      E(Code_GetMemory(reply, &keyptr, &keysize));
      if (keysize != 8)
	fprintf(stderr, "keysize = %d\n");
      else
	{
#ifdef DEBUG
	  for (i = 0; i < 8; i++)
	    fprintf(stdout, "%02x", keyptr[i]&0xff);
	  fputc('\n', stdout);
#endif
	  decrypt_key(keyptr, t.tv_sec);
	  for (i = 0; i < 8; i++)
	    fprintf(stdout, "%02x", keyptr[i]&0xff);
	  fputc('\n', stdout);
	}
      break;

    default:
      fprintf(stderr, "ptype = %d\n", ptype);
      break;
    }

  E(Code_FreeBlock(reply));
  exit(0);
}
