#include "amiga.h"
#include "fibstat.h"
#include "dir_data.h"
#include <sys/stat.h>
#include <string.h>

static int attach (char *dest, int dlen, char *dirname, char *name)
{
  char *dirnamep = dirname;
  
  while (*dirnamep && --dlen > 0)
    *dest++ = *dirnamep++;
  /* Add '/' if `dirname' doesn't already end with it. */
  if (dirnamep > dirname && dirnamep[-1] != '/' && dirnamep[-1] != ':' && --dlen > 0)
    *dest++ = '/';
  
  while (*name && --dlen > 0)
    *dest++ = *name++;
  *dest = 0;
  
  return dlen > 0;
}

static struct FileInfoBlock fakefib;

static int fakestat(int soft, char *name, struct stat *sbuf)
{
  /* See if we want information on the last file returned from readdir */
  if (last_dir)
    {
      iDIR *last_info = (iDIR *)last_dir->dd_buf;
  
      if (last_info->cdir == _get_cd() &&
	  attach(_temp_fname, FNAMESIZE - 1, last_info->dirname,
		 last_entry->entry.d_name) &&
	  strcmp(_temp_fname, name) == 0 &&
	  (soft || last_entry->type != ST_SOFTLINK))
	{
	  if (last_entry->type == ST_LINKFILE || last_entry->type == ST_LINKDIR)
	    {
	      /* Find real block, this allows tar to detect hard links */
	      BPTR cd = CurrentDir(last_dir->dd_fd);
	      BPTR l = Lock(last_entry->entry.d_name, ACCESS_READ);

	      if (l)
		{
		  Examine(l, &fakefib);
		  UnLock(l);
		}
	      CurrentDir(cd);
	    }
	  else
	    fakefib.fib_DiskKey = last_entry->entry.d_ino;

	  fakefib.fib_NumBlocks = last_entry->numblocks;
	  fakefib.fib_Size = last_entry->size;
	  fakefib.fib_Date = last_entry->date;
	  fakefib.fib_DirEntryType = last_entry->type;
	  fakefib.fib_Protection = last_entry->protection;
      
	  _lfibstat(name, &fakefib, last_info->task, 0, sbuf);

	  return 1;
	}
    }
  return 0;
}

int stat(char *name, struct stat *sbuf)
{
  chkabort();
  if (fakestat(0, name, sbuf)) return 0;
  return _fibstat(name, sbuf);
}

int lstat(char *name, struct stat *sbuf)
{
  chkabort();
  if (fakestat(1, name, sbuf)) return 0;
  if (readlink(name, _temp_fname, FNAMESIZE - 1) < 0) return _fibstat(name, sbuf);

  /* Symbolic link, fake a stat block */
  sbuf->st_dev = 0;
  sbuf->st_rdev = 0;
  sbuf->st_uid = AMIGA_UID; sbuf->st_gid = AMIGA_GID;
  sbuf->st_blksize = 512;
  sbuf->st_nlink = 1;		
  sbuf->st_blocks = 0;
  sbuf->st_size = strlen(_temp_fname);
  sbuf->st_ino = 0;
  /* 1-Jan-1978 */
  sbuf->st_ctime = sbuf->st_atime = sbuf->st_mtime = 252460800;
  sbuf->st_mode = S_IFLNK | 0777;

  return 0;
}
