#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <alloca.h>

#include "global.h"
#include "sha1.h"

inline void error(const char *a, int n)
{
  fprintf(stderr,"ERROR: %s\n",a);
  exit(n);
}

void randGen(uchar *buffer, int nbytes, const char *filename)
{
  int nhashes = ((nbytes-1)/20) + 1;

  FILE *in = fopen(filename,"rb");
  if (!in) { perror("ERROR"); error("Error opening temp file",-5); }

  SHA1 *hashes = (SHA1 *)alloca(sizeof(SHA1)*nhashes);
  uchar *buf = (uchar *)alloca(sizeof(uchar)*nhashes);

  while (!feof(in)) {
    int i, j;

    for (i=0; !feof(in) && i<nhashes; i++) buf[i]=getc(in);

    if (feof(in)) break;

    for (i=0; i<nhashes; i++) {
      uchar buf2=0;

      for (j=0; j<8; j++) {
	/* Set the jth bit of buf2 to bit j*nhashes+i */
	buf2 |= (((buf[(j*nhashes+i)/8] >> ((j*nhashes+i)%8))) & 0x1) << j;
      }

      hashes[i].addChar(buf2);
    }
  }

  fclose(in);

  int i;

  for (i=0; i<nhashes; i++) hashes[i].finalize();

  for (i=0; i<nbytes; i++) buffer[i] = hashes[i/20][i%20];
}

void getRandomSeed(uchar *buf, int nbytes, const char *script_name)
{
  if (strchr(script_name,'"'))
    error("Script name may not contain quotes",-1);

  char *filename = tmpnam(NULL);

  if (filename) filename = strdup(filename);
  else error("Unable to generate a temporary filename",-2);

  char *cmd = (char *)malloc(sizeof(char)*(strlen(script_name)+strlen(filename)+9));
  if (!cmd) error("Error allocating memory",-3);

  sprintf(cmd,"\"%s\" \"%s\"",script_name,filename);
  if (system(cmd)) error("Error running script",-4);
  free(cmd);

  randGen(buf,nbytes,filename);

  if (unlink(filename)) {
    perror("ERROR");
    error("Error removing temp file",-6);
  }

  free(filename);
}

/*
int main(int argc, char *argv[])
{
  if (argc != 2) {
    printf("Usage:\t%s <script>\n"
	   "  Where <script> takes one argument -- the name of an output file.\n",
	   argv[0]);
    return -5;
  }

  uchar buf[256];
  makeRandomNumber(buf,256,argv[1]);
  for (int i=0; i<256; i++) printf("%02X%c",buf[i],i%20==19?'\n':'\0');
  printf("\n");
}
*/

