/*
 * yepp.c:
 *
 * Copyright (c) 2001 James McKenzie <james@fishsoup.dhs.org>,
 * All rights reserved.
 *
 */

static char rcsid[] =
  "$Id: yepplib.c,v 1.24 2001/10/12 13:51:21 root Exp root $";

/*
 * $Log: yepplib.c,v $
 * Revision 1.24  2001/10/12 13:51:21  root
 * #
 *
 * Revision 1.18  2001/01/07 22:36:20  root
 * #
 *
 * Revision 1.17  2001/01/07 22:26:43  root
 * #
 *
 * Revision 1.16  2001/01/07 17:34:54  root
 * #
 *
 * Revision 1.15  2001/01/07 15:58:38  root
 * #
 *
 * Revision 1.14  2001/01/07 15:58:09  root
 * #
 *
 * Revision 1.13  2001/01/07 15:14:43  root
 * #
 *
 * Revision 1.12  2001/01/07 04:49:58  root
 * #
 *
 * Revision 1.11  2001/01/07 03:48:47  root
 * #
 *
 * Revision 1.10  2001/01/06 18:11:44  root
 * #
 *
 * Revision 1.9  2001/01/06 18:11:23  root
 * #
 *
 * Revision 1.8  2001/01/06 16:51:57  root
 * #
 *
 * Revision 1.7  2001/01/05 03:41:34  root
 * #
 *
 * Revision 1.6  2001/01/04 22:04:57  root
 * #
 *
 * Revision 1.5  2001/01/04 22:01:29  root
 * #
 *
 * Revision 1.4  2001/01/04 15:51:12  root
 * #
 *
 * Revision 1.3  2001/01/04 15:51:02  root
 * #
 *
 * Revision 1.2  2001/01/04 13:52:31  root
 * #
 *
 * Revision 1.1  2001/01/04 06:07:21  root
 * #
 *
 * Revision 1.4  2001/01/04 04:40:44  root
 * #
 *
 * Revision 1.3  2001/01/04 04:39:27  root
 * #
 *
 * Revision 1.2  2001/01/04 02:57:39  root
 * #
 *
 */

#include "project.h"

#define YEPP_WSBS 0x3ff0
#define YEPP_WBBS 0x41f8
#define YEPP_RSBS 0x3ff0
#define YEPP_RBBS 0x41f8


void
yepp_dir_free (struct yepp_dirent *ptr)
{
  struct yepp_dirent *next;

  while (ptr)
    {
      next = ptr->next;
      free (ptr);
      ptr = next;
    }

}

int
yepp_bytes_to_blocks (int bytes)
{
  int blocks = 1;
  bytes -= YEPP_WSBS;

  while (bytes > 0)
    {
      bytes -= YEPP_WBBS;
      blocks++;
    }

  return blocks;

}

int
yepp_blocks_to_bytes (int blocks)
{
  int size;

  blocks--;
  size = YEPP_WSBS;

  while (blocks--)
    {
      size += YEPP_WBBS;
    }

  return size;
}

static int
yepp_send_dword (int i)
{
  unsigned char buf[4];

  buf[0] = i & 0xff;
  i >>= 8;
  buf[1] = i & 0xff;
  i >>= 8;
  buf[2] = i & 0xff;
  i >>= 8;
  buf[3] = i & 0xff;

  return (yepp_write (buf, 4) == 4);
}

static int
yepp_send_word (int i)
{
  unsigned char buf[2];

  buf[0] = i & 0xff;
  i >>= 8;
  buf[1] = i & 0xff;

  return (yepp_write (buf, 2) == 2);
}


static int
yepp_recv_word (int *w)
{
  unsigned char buf[2];

  if (yepp_read(buf,2)!=2) return 0;


  *w=(int) buf[0]+((int) buf[1] <<8)  ;
return 1;
}


static int
yepp_send_filename (char *name)
{
  unsigned char buf[515];

  bzero (buf, 515);
  strncpy (buf, name, 514);

  return (yepp_write (buf, 515) == 515);
}

void
do_progress (char *fname, int writ, int size, int i, int blocks,
             struct timeval *start)
{
  struct timeval end, diff;
  double rate;
  int d;
  int secs, mins;
  float pct = (float) (100 * writ);
  pct = pct / (float) size;

  gettimeofday (&end, NULL);

  timersub (&end, start, &diff);

  rate = (double) diff.tv_usec;
  rate = rate / 1000000.0;
  rate += (double) diff.tv_sec;
  rate = ((double) writ) / rate;

  secs = (int) (((double) (size - writ)) / rate);

  mins = secs / 60;
  secs -= mins * 60;

  rate = rate / 1024.0;

  d =
    printf ("%s: %.2f%% %d/%d %d/%d %.2fKb/s ETA %d:%02d   ", fname, pct, i,
            blocks - 1, writ, size, rate, mins, secs);

  while (d--)
    putchar (8);

  fflush (stdout);
}

//Op codes 11
static int
yepp_memory_worker (char *fname, int opcode, int where, int type, char *name,
                    char *rbuf, int size)
{
  int i, mem;
  int blocks;

  unsigned char *buf, *ptr;
  int len;

  blocks = yepp_bytes_to_blocks (size);
  mem = yepp_blocks_to_bytes (blocks);

  ptr = buf = malloc (mem);

  bzero (buf, mem);
  bcopy (rbuf, buf, size);


  if (!buf)
    {
      MOAN ("%s: malloc failed\n", fname);
      return 0;
    }

  fprintf (stderr, "%s: \"%s\" %d bytes, %d blocks\n", fname, name, size,
           blocks);


  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (opcode))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (where))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (type))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_dword (size))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_word (blocks))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  if (!yepp_send_filename (name))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  i = blocks;

  if (yepp_write (ptr, YEPP_WSBS) != YEPP_WSBS)
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  ptr += YEPP_WSBS;

  if (!ieee1284_writebyte (0x0))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  for (i = 1; i < blocks; ++i)
    {

      if (yepp_write (ptr, YEPP_WBBS) != YEPP_WBBS)
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
      ptr += YEPP_WBBS;

      if (!ieee1284_writebyte (0x0))
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
    }

  yepp_phase2 ();

  if (!ieee1284_readbyte (buf))
    {
      yepp_phase3 ();
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  i = buf[0];

  yepp_phase3 ();
  yepp_phase4 ();


  free (buf);
  fprintf (stderr, "%s: file is now in index %d\n", fname, i);

  return i;

}

#ifdef HIFI

//Op codes 1,  12, 13, 14
static int
yepp_hifi_worker (char *fname, int opcode, int where, int type, char *name,
                  CFH h)
{
  int i;
  int blocks;
  int writ = 0;

  struct timeval start;

  unsigned char *buf;
  int size;


  if (!h)
    {
      MOAN ("%s: passed NULL CFH \n", fname);
      return 0;
    }

  size = h->size (h);

  buf = malloc (YEPP_WBBS);


  if (!buf)
    {
      MOAN ("%s: malloc failed\n", fname);
      return 0;
    }

  blocks = yepp_bytes_to_blocks (size);

  fprintf (stderr, "%s: \"%s\" %d bytes, %d blocks\n", fname, name, size,
           blocks);


  gettimeofday (&start, NULL);

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (opcode))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (where))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (type))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_dword (size))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_word (blocks))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  if (!yepp_send_filename (name))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  h->read (h, buf, YEPP_WSBS);

  i = blocks;

  writ += YEPP_WSBS;

  if (yepp_write (buf, YEPP_WSBS) != YEPP_WSBS)
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (0x0))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  for (i = 1; i < blocks; ++i)
    {
      do_progress (fname, writ, size, i, blocks, &start);

      h->read (h, buf, YEPP_WBBS);

      if (yepp_write (buf, YEPP_WBBS) != YEPP_WBBS)
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
      writ += YEPP_WBBS;

      if (!ieee1284_writebyte (0x0))
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
    }

  yepp_phase2 ();

  if (!ieee1284_readbyte (buf))
    {
      yepp_phase3 ();
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  i = buf[0];

  yepp_phase3 ();
  yepp_phase4 ();

  do_progress (fname, writ, size, i, blocks, &start);
  printf ("\n");

  free (buf);
  fprintf (stderr, "%s: file is now in index %d\n", fname, i);

  return i;

}
#endif

//Op codes 1,  12, 13, 14
static int
yepp_file_worker (char *fname, int opcode, int where, int type, char *name,
                  FILE * f)
{
  int i;
  int blocks;
  int writ = 0;

  struct timeval start, end, diff;
  double rate;

  unsigned char *buf;
  int size;


  if (!f)
    {
      MOAN ("%s: passed NULL file pointer\n", fname);
      return 0;
    }

  fseek (f, 0L, SEEK_END);
  size = ftell (f);
  fseek (f, 0L, SEEK_SET);

  buf = malloc (YEPP_WBBS);


  if (!buf)
    {
      MOAN ("%s: malloc failed\n", fname);
      return 0;
    }

  blocks = yepp_bytes_to_blocks (size);

  fprintf (stderr, "%s: \"%s\" %d bytes, %d blocks\n", fname, name, size,
           blocks);


  gettimeofday (&start, NULL);

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (opcode))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (where))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  if (!ieee1284_writebyte (type))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_dword (size))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!yepp_send_word (blocks))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  if (!yepp_send_filename (name))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  fread (buf, 1, YEPP_WSBS, f);

  i = blocks;

  writ += YEPP_WSBS;

  if (yepp_write (buf, YEPP_WSBS) != YEPP_WSBS)
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (0x0))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  for (i = 1; i < blocks; ++i)
    {


      do_progress (fname, writ, size, i, blocks - 1, &start);


      fread (buf, 1, YEPP_WBBS, f);

      if (yepp_write (buf, YEPP_WBBS) != YEPP_WBBS)
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
      writ += YEPP_WBBS;

      if (!ieee1284_writebyte (0x0))
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }
    }

  yepp_phase2 ();

  if (!ieee1284_readbyte (buf))
    {
      yepp_phase3 ();
      yepp_phase4 ();
      free (buf);
      return 0;
    }
  i = buf[0];

  yepp_phase3 ();
  yepp_phase4 ();


  do_progress (fname, writ, size, i, blocks, &start);
  printf ("\n");

  free (buf);
  fprintf (stderr, "%s: file is now in index %d\n", fname, i);

  return i;

}


//Op code 1
int
yepp_put (int where, int type, char *name, FILE * file)
{
  return yepp_file_worker ("yepp_put", 0x1, where, type, name, file);
}

#ifdef HIFI
int
yepp_hifi_put (int where, int type, char *name, CFH h)
{
  return yepp_hifi_worker ("yepp_hifi_put", 0x1, where, type, name, h);
}
#endif




//Op code 2
int
yepp_get (int index, FILE * f)
{
  unsigned char *buf, *ptr;
  int size;
  int blocks;
  int i;
  int red, togo;
  struct timeval start;



  if (!f)
    {
      MOAN ("yepp_get: passed null file pointer\n");
      return 0;
    }
  buf = malloc (YEPP_RBBS);

  if (!buf)
    {
      MOAN ("malloc failed\n");
      return 0;
    }

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }


  if (!ieee1284_writebyte (0x2))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  if (!ieee1284_writebyte (index))
    {
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  yepp_phase2 ();

  if (yepp_read (buf, 4) != 4)
    {
      yepp_phase3 ();
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  gettimeofday (&start, NULL);

  togo = size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
  red = 0;

  fprintf (stderr, "yepp_get: %d is %d bytes long\n", index, size);

  bzero (buf, YEPP_RBBS);
  i = yepp_read (buf, YEPP_RSBS);

  if (i != YEPP_RSBS)
    {
      yepp_phase3 ();
      yepp_phase4 ();
      free (buf);
      return 0;
    }

  fwrite (buf, 1, (togo > i) ? i : togo, f);

  togo -= i;
  red += i;

  while (togo > 0)
    {
      yepp_phase3 ();

      do_progress ("yepp_get", red, size, 0, 0, &start);

      if (!ieee1284_writebyte (0x0))
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }

      yepp_phase2 ();

      if (!ieee1284_readbyte (buf))
        {
          yepp_phase4 ();
          free (buf);
          return 0;
        }


      i = yepp_read (buf, YEPP_RBBS);

      if (i != YEPP_RBBS)
        {
          yepp_phase3 ();
          yepp_phase4 ();
          free (buf);
          return 0;
        }


      fwrite (buf, 1, (togo > i) ? i : togo, f);
      red += i;
      togo -= i;
    }

  printf ("\n");


  yepp_phase3 ();
  yepp_phase4 ();
  free (buf);

  fprintf (stderr, "yepp_put: done\n");

  return size;
}


//Op code 3
struct yepp_dirent *
yepp_dir (void)
{
  unsigned char buf[522];
  struct yepp_dirent *ret = NULL, *next;
  int i;
  int merror = 0;



  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return NULL;
    }

  if (!ieee1284_writebyte (0x3))
    {
      yepp_phase4 ();
      return NULL;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase3 ();
      yepp_phase4 ();
      return NULL;
    }

  while (1)
    {

      if (yepp_read (buf, 522) != 522)
        {
          yepp_dir_free (ret);
          yepp_phase3 ();
          yepp_phase4 ();
          return NULL;
        }


      for (i = 0; i < 522; ++i)
        {
          if (buf[i])
            break;
        }


      if (i == 522)
        {
          ieee1284_readbyte (buf); //0xff on end

          yepp_phase3 ();
          yepp_phase4 ();

          if (merror)
            {
              yepp_dir_free (ret);
              MOAN ("yepp_dir: malloc failed\n");
              return NULL;
            }
          return ret;
        }

      next = (struct yepp_dirent *) malloc (sizeof (struct yepp_dirent));

      if (next)
        {
          next->user = 0;
          next->index = buf[0];
          next->type = buf[1];
          next->size =
            buf[2] | (buf[3] << 8) | (buf[4] << 16) | (buf[5] << 24);

          bcopy (buf + 6, next->name, 515);
          bcopy (buf + 6, next->name, 515);

          next->attr = buf[521];

          next->next = ret;

          ret = next;
        }
      else
        {
          merror++;
        }

    }

}


//Op code 4
struct yepp_status *
yepp_status (void)
{
  unsigned char buf[8];
  struct yepp_status *ret;
  int i;


  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return NULL;
    }

  if (!ieee1284_writebyte (0x4))
    {
      yepp_phase4 ();
      return NULL;
    }

  if (!yepp_phase2 ())
    return 0;

  if (yepp_read (buf, 8) != 8)
    {
      yepp_phase3 ();
      yepp_phase4 ();
      return NULL;
    }

  yepp_phase3 ();
  yepp_phase4 ();

  ret = (struct yepp_status *) malloc (sizeof (struct yepp_status));

  if (!ret)
    {
      MOAN ("yepp_status: malloc failed\n");
      return NULL;
    }

  ret->main.size = ((buf[1] << 8) | buf[0]) * 16;
  ret->main.free = ((buf[3] << 8) | buf[2]) * 16;
  ret->card.size = ((buf[5] << 8) | buf[4]) * 16;
  ret->card.free = ((buf[7] << 8) | buf[6]) * 16;

  return ret;
}

//Op code 5
int
yepp_erase (int f)
{
  unsigned char c;
  int ret;

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0x5))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (f))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();

      return 0;
    }
  ret = ieee1284_readbyte (&c);


  yepp_phase3 ();
  yepp_phase4 ();

  if (!ret)
    return 0;

  fprintf (stderr, "yepp_erase: status %d\n", c);

  return (c == 0);

}

//Op code 6
int
yepp_format (int where)
{
  unsigned char c;
  int ret;

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0x32))
    {
      yepp_phase4 ();
      return 0;
    }
#if 0
  if (!ieee1284_writebyte (0x6))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (where))
    {
      yepp_phase4 ();
      return 0;
    }
#endif

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();

      return 0;
    }
  ret = ieee1284_readbyte (&c);


  yepp_phase3 ();
  yepp_phase4 ();

  if (!ret)
    return 0;

  fprintf (stderr, "yepp_format: status %d\n", c);

  return (c == 0xff);

}

//Op code 7
int
yepp_get_config (char *p1, unsigned char *order)
{
  unsigned char gunk[] = { 0x3a, 0x68, 0xa0, 0x00, 0x00, 0x01, 0x03, 0x09 };
  unsigned char buf[256];
  char *ret;


  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0x7))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (yepp_read (buf, 8) != 8)
    {
      yepp_phase3 ();
      yepp_phase4 ();
      return 0;
    }

  if (bcmp (buf, gunk, sizeof (gunk)))
    fprintf (stderr,
             "yepp_getconfig: gunk is different: %02x %02x %02x %02x %02x %02x %02x %02x\n",
             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);


  if (p1)
    bcopy (buf, p1, 8);

  if (yepp_read (buf, 252) != 252)
    {
      yepp_phase3 ();
      yepp_phase4 ();
      return 0;
    }

  yepp_phase3 ();
  yepp_phase4 ();


  if (order)
    {
      bcopy (buf, order, 252);
    }
  return 1;

}


//Op code 10
int
yepp_ping (void)
{
  unsigned char c;
  int ret;

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0xa))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();

      return 0;
    }
  ret = ieee1284_readbyte (&c);


  yepp_phase3 ();
  yepp_phase4 ();

  if ((!ret) || (c != 1))
    {
      MOAN ("yepp_ping: failed\n");
      return 0;
    }

  fprintf (stderr, "yepp_ping: ok\n");
  return 1;

}

//Op code 11
int
yepp_put_config (int where, int type, char *name, char *buf, int len)
{
  return yepp_memory_worker ("yepp_put_config", 0xb, where, type, name, buf,
                             len);
}

//Op code 12
int
yepp_put_encode (int where, int type, char *name, FILE * file)
{
  return yepp_file_worker ("yepp_put_encode", 0xc, where, type, name, file);
}

//Op code 13
int
yepp_put_decode (int where, int type, char *name, FILE * file)
{
  return yepp_file_worker ("yepp_put_decode", 0xd, where, type, name, file);
}

//Op code 14
int
yepp_put_serial (int where, int type, char *name, FILE * file)
{
  return yepp_file_worker ("yepp_put_serial", 0xe, where, type, name, file);
}

//Opcode 32
int yepp_op_32(void)
{
  int w;
  int ret;

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0x32))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();

      return 0;
    }
  ret = yepp_recv_word(&w);

  yepp_phase3 ();
  yepp_phase4 ();

  if (!ret)
    return 0;

  fprintf (stderr, "yepp_op_32: returns %d\n", w);
  return 1;
}
//Opcode 33
int yepp_op_33(void)
{
  unsigned char c;
  int ret;

  if (!yepp_phase1 ())
    {
      yepp_phase4 ();
      return 0;
    }

  if (!ieee1284_writebyte (0x33))
    {
      yepp_phase4 ();
      return 0;
    }

  if (!yepp_phase2 ())
    {
      yepp_phase4 ();

      return 0;
    }

  ret = ieee1284_readbyte (&c);

  yepp_phase3 ();
  yepp_phase4 ();

  if (ret<0)
    return 0;

  fprintf (stderr, "yepp_op_33: returns %d\n", c);
  return 1;
}






char *
yepp_getorder ()
{
  unsigned char buf[252], *ret;

  if (!yepp_get_config (NULL, buf))
    return NULL;

  ret = (unsigned char *) malloc (YEPP_ORDER_LEN);

  if (!ret)
    return NULL;

  bzero (ret, YEPP_ORDER_LEN);
  bcopy (buf, ret, 250);
  return ret;

}

char *
yepp_getnamebyindex (int index)
{
  struct yepp_dirent *yd, *ptr;

  if (!yepp_ping ())
    return NULL;

  ptr = yd = yepp_dir ();

  if (!yd)
    return NULL;

  while (ptr)
    {


      if (ptr->index == index)
        {
          char *ret = strdup (ptr->name);

          yepp_dir_free (yd);


          return (ret);

        }


      ptr = ptr->next;
    }

  yepp_dir_free (yd);

  return NULL;

}


int
yepp_putorder (unsigned char *order)
{
  unsigned char buf[260];
  unsigned char *name, *ptr;
  int i = 0, j;

  if (!order)
    {
      fprintf (stderr, "yepp_putorder: passed null order\n");
      return 0;
    }


  j = YEPP_ORDER_LEN;
  ptr = order;
  while (j--)
    {
      if (!*ptr)
        break;
      if (*ptr > i)
        i = *ptr;
      ptr++;
    }

  name = yepp_getnamebyindex (YEPP_CONFIG_INDEX);

  if (name)
    {

      if (strcmp (name, "config.dat"))
        {
          fprintf (stderr, "yepp_putorder: index %d is not config.dat\n",
                   YEPP_CONFIG_INDEX);
          return 0;
        }

      free (name);

      yepp_erase (YEPP_CONFIG_INDEX);
    }

  bzero (buf, sizeof (buf));

  bcopy (order, buf,
         (sizeof (buf) > YEPP_ORDER_LEN) ? YEPP_ORDER_LEN : sizeof (buf));


  buf[250] = i;
  buf[251] = i;
  buf[252] = 0x01;
  buf[253] = 0x00;
  buf[254] = 0xff;
  buf[255] = 0xff;
  buf[256] = 0x0;
  buf[257] = 0x0;
  buf[258] = 0x0;
  buf[259] = 0x0;

  if (!yepp_put_config (YEPP_WHERE_BASE, YEPP_TYPE_DATA, "config.dat",
                        buf, sizeof (buf)))
    {
      fprintf (stderr, "yepp_putorder: put_config failed\n");
      return 0;
    }

  return 1;
}


int
yepp_init (int port)
{
  return ieee1284_init (port);
}
