#include <stdio.h>
#include "config.h"
#include "proto.h"
#include "unixlib.h"

#if defined(ATARI_ST)
#include <stdlib.h>
#include <string.h>
#include <ext.h>

#elif defined(MSDOS)
#include <stdlib.h>
#include <string.h>
#include <sys\stat.h>
#include <dir.h>
#include <dos.h>

#elif defined(SUN)
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/dir.h>

#elif defined(SEQUENT386)

#elif defined(AVIION)

#else
#error Wrong machine type. Edit config.h and follow the instructions.

#endif


/*
 *  Globals
 */

char *optarg=NULL;
int optind=1;
int opterr=0;
int argerr=0;


/*
 *  Prototypes
 */

#if defined(MSDOS) || defined(ATARI_ST)
static int cinstr __P((char c, char *str));
#endif


#if defined(MSDOS) || defined(ATARI_ST)
int scandir (path, namelist, selectfun, sortfun)
 char *path;
 struct direct *(*namelist[]);
 int (*selectfun) __P((struct direct *d));
 int (*sortfun) __P((struct direct **d1, struct direct **d2));

{
  int end;
  int count=0;
  char *name;
  struct ffblk frbuf;
  int i = -1;

  name = malloc (strlen (path)+4);
  strcpy (name, path);
  strcat (name, "*.*");
  end = findfirst (name, &frbuf, FA_DIREC);
  count = 0;
  while (! end)
    {
      count++;
      end = findnext (&frbuf);
    }
  if (count <= 0)
    goto error_exit;
  if (((*namelist) = calloc (count, sizeof (struct direct)+sizeof (struct direct *))) == NULL)
    goto error_exit;
  for (i=0; i<count; i++)
    (*namelist)[i] = (struct direct *)((unsigned long)(*namelist) + count * sizeof (struct direct *) + i * sizeof (struct direct));
  end = findfirst (name, &frbuf, FA_DIREC);
  i = 0;
  while (! end)
    {
      strcpy ((*namelist)[i]->d_name, frbuf.ff_name);
      (*namelist)[i]->d_fileno = i;
      (*namelist)[i]->d_reclen = sizeof (struct direct);
      (*namelist)[i]->d_namlen = strlen (frbuf.ff_name)+1;
      if ((*selectfun)((*namelist)[i]))
        i++;
      end = findnext (&frbuf);
    }
  qsort ((*namelist), i, sizeof (struct direct *), sortfun);

error_exit:
  free (name);
  return (i);
}
#endif


#if defined(ATARI_ST) || defined(MSDOS)

int alphasort (d1, d2)
 struct direct **d1;
 struct direct **d2;

{
  return (strcmp ((*d1)->d_name, (*d2)->d_name));
}

#endif


/*
 *  
 */

int no_pointdir (d)
 struct direct *d;

{
  if (strlen (d->d_name) == 0)
    return (0);
  if ((strcmp(d->d_name, ".") == 0) || (strcmp(d->d_name,"..") == 0))
    return (0);
  return (1);
}


/*
 *  ,needed for ATARI ST & MSDOS
 */

#if defined(ATARI_ST) || defined(MSDOS)

char *getwd(buf)
  char *buf;
{
  return (getcwd(buf, MAXPATH));  
}

#endif


/*
 *  cinstr  -  return index of the first appearence of a char in a string
 *             if found, else -1
 */

static int cinstr(c, str)
 char c;
 char *str;

{
  int i;

  for (i=0; str[i]!=0; i++)
    if (str[i]==c)
      return (i);
  return(-1);
}


/*
 * getopt  -  return the next option of the arg vector, if in opts defined
 *            as a valid option, else OPT_UNKNOWN
 */

int getopt(argc, argv, opts)
 int argc;
 char *argv[];
 char *opts;

{
  static char *optptr = NULL;
  char optc;
  int cpos, oldind;

  opterr=0;
  if (optptr == NULL)
  {
    oldind = optind;
    while ((optind<argc) && ((argv[optind][0]!=OPTCHR) || (argv[optind][1]==0)))
      optind++;
    if (optind>=argc)
      { optind = oldind;
        return(EOF);
      }
    optptr = &argv[optind][1];
  }
  optc= *(optptr++);
  if ((cpos=cinstr(optc, opts))<0)
    return (OPT_UNKNOWN);
  else
    if (opts[cpos+1]==':')
    {
      if (((++optind)>=argc) || ((*optptr)!=0))
      {
        opterr=1;
        return(EOF);
      }
      optarg=argv[optind];
    }
  if (*optptr==0)
  {
    optptr = NULL;
    ++optind;
  }
  return((int)optc);
}


/*
 * getarg  -  return the next argument of the arg vector which is not
 *            defined as a valid option in opts, else NULL
 */

char *getarg (argc, argv, opts)
 int argc;
 char *argv[];
 char *opts;
{
  static int argind = 1;
  char optc, *argptr;
  int cpos;

  argerr=0;
  while ((argind<argc) && (argv[argind][0]==OPTCHR))
  {
    for (argptr=&argv[argind][1]; argptr[1]=='\0'; argptr++)
      optc=argptr[1];
    if ((cpos=cinstr(optc, opts))>=0)
      if (opts[cpos+1]==':')
      {
        argind++;
        if ((argind>=argc) || ((*argptr)!='\0'))
        {
          argerr=1;
          return(NULL);
        }
      }
    argind++;
  }
  if (argind<argc)
    return (argv[argind++]);
  else
    return (NULL);
}
