/* $VER: vlink dir.c V0.5d (22.08.98)
 *
 * This file is part of vlink, a portable linker for multiple
 * object formats.
 * Copyright (c) 1997-99  Frank Wille
 *
 * vlink is freeware and part of the portable and retargetable ANSI C
 * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
 * vlink may be freely redistributed as long as no modifications are
 * made and nothing is charged for it. Non-commercial usage is allowed
 * without any restrictions.
 * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
 * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
 *
 *
 * v0.5d (22.08.98) phx
 *       New function chk_file(), to check for the presence of a file.
 * v0.2  (28.02.98) phx
 *       Replaced AllocMem() for AMIGAOS by malloc(), to avoid
 *       problems with PowerPC.
 * v0.1  (27.02.98) phx
 *       First version that seems to link AmigaOS ADOS and EHF
 *       objects and libraries. Many common features, like linking
 *       sections together which have relative references, are
 *       still missing. Also, PowerPC-ELF32 support is about to come.
 * v0.0  (02.12.97) phx
 *       File created.
 */


#define DIR_C
#include "vlink.h"

#ifdef AMIGAOS
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <proto/dos.h>

struct Dir {
  struct FileInfoBlock fib;
  BPTR lock;
  char name[FNAMEBUFSIZE];
};

#else
#include <dirent.h>
#endif


char *open_dir(char *);
char *read_dir(char *);
void close_dir(char *);
bool chk_file(char *);



#ifdef AMIGAOS

char *open_dir(char *dirname)
/* open a directory for examination */
{
  struct Dir *d;

  if (d = malloc(sizeof(struct Dir))) {
    strcpy(d->name,dirname);
    if (!strcmp(d->name,".")) {  /* current directory? */
      d->name[0] = 0;
    }
    if (d->lock = Lock(d->name,ACCESS_READ)) {
      if (Examine(d->lock,&(d->fib))) {
        return ((char *)d);
      }
      UnLock(d->lock);
    }
    free(d);
  }
  return (NULL);
}


char *read_dir(char *d)
/* get next file name from opened directory, NULL if no more entries */
{
  if (ExNext(((struct Dir *)d)->lock,&(((struct Dir *)d)->fib)))
    return (((struct Dir *)d)->fib.fib_FileName);
  if (IoErr() != ERROR_NO_MORE_ENTRIES)
    error(10,((struct Dir *)d)->name);
  return (NULL);
}


void close_dir(char *d)
/* finish directory access */
{
  if (d) {
    UnLock(((struct Dir *)d)->lock);
    free(d);
  }
}


#else /* UNIX */

char *open_dir(char *dirname)
/* open a directory for examination */
{
  return ((char *)opendir(dirname));
}


char *read_dir(char *d)
/* get next file name from opened directory, NULL if no more entries */
{
  struct dirent *dp;

  if (dp = readdir((DIR *)d))
    return (dp->d_name);
  return (NULL);
}


void close_dir(char *d)
/* finish directory access */
{
  if (d)
    closedir((DIR *)d);
}

#endif


bool chk_file(char *path)
/* Check if file is present */
{
  FILE *f;

#ifdef AMIGAOS
  if (!strncmp(path,"./",2))
    path += 2;
#endif
  if (f = fopen(path,"r"))
    fclose(f);
  return (f != NULL);
}
