/*
    This is a very quick hack to substitute for some EMAS routines
    which are missing on Linux.  This is not an ideal implementation!
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int debug = (0!=0);

char *cstring(char *name)
{
  int l = *name;
  static char cname[1024];

if (debug) fprintf(stderr, "name is %p, *name = %d\n", name, *name);

  cname[l] = '\0';
  while (--l >= 0) {
    cname[l] = name[l+1];
  }
  return(cname);
}

char *cliparam(void)
{
  return("test.imp");
}

void readprofile(char *key, void *info, int *version, int *uflag)
{
  if (debug) fprintf(stderr, "readprofile: %s\n", key);
  *version = 0;
  *uflag = 5;
}

#define maxopt 16
typedef struct pformat {
  char a[maxopt+21];
} pformat;

void writeprofile(int keylen, char *key, pformat *p, int *version, int *uflag)
{
  int i;
  fprintf(stderr, "#define %s ", cstring(key));
  for (i = 0; i < maxopt+21; i++) {
    fprintf(stderr, "%d,", p->a[i]);
  }
  fprintf(stderr, "\n");
}

void prompt(int smax, char *s)
{
  fprintf(stderr, "%s", cstring(s)); fflush(stderr);
}
 
typedef struct chdr {
  int conad, filetype, datastart, dataend;
} chdr;

typedef struct fhdr {
  int dataend, datastart, filesize, filetype;
} fhdr;

static int nextfree = 0;
int conad[100];
char *filename[100];

void fakeconnect(char *fn, fhdr *fh)
{
  // no error checking yet
  conad[nextfree] = (int)fh;
  filename[nextfree] = strdup(fn);
  nextfree++;
}

int getfile(char *fn)
{
  int i;
  for (i = 0; i < nextfree; i++) {
    if (strcmp(fn, filename[i]) == 0) return(conad[i]);
  }
  fprintf(stderr, "unconnected file error\n");
}

void connect(int maxnamelen, char *name, int mode, int hole, int prot,
             chdr *rec, int *eflag) {
  char *ptr;
  fhdr *emasfilehdr;
  char cname[128];
  int flen, l;
  FILE *f;

  *eflag = 0;

  if (mode == 3) {
    /* write-mode for reconnecting after changing file size */
    fprintf(stderr, "REconnect(%s)\n", cstring(name));
    return;
  } else if (mode != 0) {
    fprintf(stderr, "Unsupported connect mode\n");
  }

  f = fopen(cstring(name), "r");

  (void)fseek(f, (off_t)0L, SEEK_END);
  flen = (int)ftell(f);
  (void)fseek(f, (off_t)0L, SEEK_SET);
if (debug) fprintf(stderr, "File length = %ld\n", flen);

if (debug) fprintf(stderr, "connect(%s)\n", cstring(name));

  emasfilehdr = (fhdr *)ptr = (char *)malloc(flen+32+(1024*1024)/*HACK*/);
  emasfilehdr->dataend = flen+32;
  emasfilehdr->datastart = 32;
  emasfilehdr->filesize = flen;
  emasfilehdr->filetype = 3;

  ptr += 32;
  for (l = 0; l < flen; l++) *ptr++ = fgetc(f);

  rec->conad = (int)emasfilehdr;
  rec->filetype = 3;
  rec->datastart = 32;
  rec->dataend = 32+flen;
  fakeconnect(cstring(name), emasfilehdr);
}
 
void trim(char *file, int *eflag) {
//  fprintf(stderr, "UNIMPLEMENTED: trim\n");
}
 
void setfname(char *file) {
  fprintf(stderr, "UNIMPLEMENTED: setfname\n");
}
 
char *nexttemp() {
  static int next = 0;
  char *impstring = malloc(12);
  sprintf(impstring+1, "%06d", ++next);
  *impstring = strlen(impstring+1);
  return(impstring);
}
 
void sendfile(char *file, char *device, char *header,
              int copies, int form, int *eflag) {
  //fprintf(stderr, "UNIMPLEMENTED: sendfile\n");
  // should list T#xxxxxxx to stdout
}
 
int devcode(char *name) {
  //fprintf(stderr, "UNIMPLEMENTED: devcode\n");
  return 1;
}
 
void disconnect(int filenamelen, char *filename, int *eflag) {
  char *ptr;
  fhdr *f;
  FILE *outf;
  *eflag = 0;
//fprintf(stderr, "Disconnecting (and dumping) %s\n", cstring(filename));
  if (debug) fprintf(stderr, "dumping memory to %s\n", cstring(filename));
  f = (fhdr *)getfile(cstring(filename));
//fprintf(stderr, "data from %d to %d\n", (int)f+f->datastart, (int)f+f->dataend);
  outf = fopen(cstring(filename), "w");
  for (ptr = (char *)(int)f+f->datastart; ptr != (char *)(int)f+f->dataend; ptr++) {
    fputc(*ptr, outf);
  }
  fclose(outf);
}
 
char *failuremessage(int type) {
static char imess[128];
  fprintf(stderr, "UNIMPLEMENTED: failure message\n");
  sprintf(imess+1, "Unknown error");
  *imess = strlen(imess+1);
}
 
void changefilesize(int maxfnamelen, char *filename, int filesize, int *eflag) {
  //fprintf(stderr, "UNIMPLEMENTED: changefilesize\n");
  /* changes the size of the file WHILE STILL CONNECTED IN VM */
  /* fails only if the VM hole isn't big enough. */
  /* Need to fix this.  currently using 1Mb of slop, and unchecked. */
  /* Thank goodness for large modern machines! */
  *eflag = 0;
}
 
void newgen(int fl, char *filename, int nfl, char *newfilename, int *eflag) {
  char cmd[1024];
  char *s;
  s = cmd+sprintf(cmd, "mv ");
  s = s+sprintf(s, cstring(filename));
  s = s+sprintf(s, " ");
  s = s+sprintf(s, cstring(newfilename));
//  fprintf(stderr, "COMMAND: %s\n", cmd);
  system(cmd);
  *eflag = 0;
}
 
void outfile(int filenamelen, char *filename, int size, int hole, int prot,
             int *conad, int *eflag) {
  fhdr *h;
  *conad = (int)h = (fhdr *)malloc(size+(1024*1024)/*HACK*/);
  *eflag = 0;
  if (h == NULL) {
    fprintf(stderr, "BAD MALLOC\n");
  }
  h->dataend = 32;
  h->datastart = 32;
  h->filesize = size;
  h->filetype = 3;
//  fprintf(stderr, "outfile(%s) -> %d\n", cstring(filename), h);
  fakeconnect(cstring(filename), h);
}
 

