// natFile.cc - Native part of File class for POSIX.

/* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>

#include <stdio.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <string.h>
#include <utime.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <java/io/File.h>
#include <java/io/IOException.h>
#include <java/util/ArrayList.h>
#include <java/lang/String.h>
#include <java/io/FilenameFilter.h>
#include <java/io/FileFilter.h>
#include <java/lang/System.h>

jboolean
java::io::File::access (jint query)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';
  JvAssert (query == READ || query == WRITE || query == EXISTS);
#ifdef HAVE_ACCESS
  int mode;
  if (query == READ)
    mode = R_OK;
  else if (query == WRITE)
    mode = W_OK;
  else
    mode = F_OK;
  return ::access (buf, mode) == 0;
#else
  return false;
#endif
}

jboolean
java::io::File::stat (jint query)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

  if (query == ISHIDDEN)
    return (getName()->charAt(0) == '.');

#ifdef HAVE_STAT
  struct stat sb;
  if (::stat (buf, &sb))
    return false;
  
  JvAssert (query == DIRECTORY || query == ISFILE);
  jboolean r = S_ISDIR (sb.st_mode);
  return query == DIRECTORY ? r : ! r;
#else
  return false;
#endif
}

jlong
java::io::File::attr (jint query)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

#ifdef HAVE_STAT
  struct stat sb;
  // FIXME: not sure about return value here.
  if (::stat (buf, &sb))
    return 0;

  JvAssert (query == MODIFIED || query == LENGTH);
  return query == MODIFIED ? (jlong)sb.st_mtime * 1000 : sb.st_size;
#else
  // There's no good choice here.
  return 23;
#endif
}

jstring
java::io::File::getCanonicalPath (void)
{
  char buf[MAXPATHLEN], buf2[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

#ifdef HAVE_REALPATH
  if (realpath (buf, buf2) == NULL)
    throw new IOException (JvNewStringLatin1 (strerror (errno)));

  // FIXME: what encoding to assume for file names?  This affects many
  // calls.
  return JvNewStringUTF (buf2);
#else
  return JvNewStringUTF (buf);
#endif
}

jboolean
java::io::File::isAbsolute (void)
{
  return path->charAt(0) == '/';
}

#ifdef HAVE_DIRENT_H
#if defined(__JV_POSIX_THREADS__) && defined(HAVE_READDIR_R)

static struct dirent *
get_entry (DIR *dir, struct dirent *e)
{
  struct dirent *r;
  if (readdir_r (dir, e, &r) || r == NULL)
    return NULL;
  return e;
}

#else /* defined(__JV_POSIX_THREADS__) && defined(HAVE_READDIR_R) */

static struct dirent *
get_entry (DIR *dir, struct dirent *)
{
  return readdir (dir);
}

#endif /* defined(__JV_POSIX_THREADS__) && defined(HAVE_READDIR_R) */
#endif /* HAVE_DIRENT_H */

jobjectArray
java::io::File::performList (java::io::FilenameFilter *filter, 
			     java::io::FileFilter *fileFilter, 
			     java::lang::Class *result_type)
{
#ifdef HAVE_DIRENT_H
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

  DIR *dir = opendir (buf);
  if (! dir)
    return NULL;

  java::util::ArrayList *list = new java::util::ArrayList ();
  struct dirent *d, d2;
  while ((d = get_entry (dir, &d2)) != NULL)
    {
      // Omit "." and "..".
      if (d->d_name[0] == '.'
	  && (d->d_name[1] == '\0'
	      || (d->d_name[1] == '.' && d->d_name[2] == '\0')))
	continue;

      jstring name = JvNewStringUTF (d->d_name);
      if (filter && ! filter->accept(this, name))
	continue;
      
      if (result_type == &java::io::File::class$)
        {
	  java::io::File *file = new java::io::File (this, name);
	  if (fileFilter && ! fileFilter->accept(file))
	    continue;

	  list->add(file);
	}
      else
	list->add(name);
    }

  closedir (dir);

  jobjectArray ret = JvNewObjectArray (list->size(), result_type, NULL);
  list->toArray(ret);
  return ret;
#else /* HAVE_DIRENT_H */
  return NULL;
#endif /* HAVE_DIRENT_H */
}

jboolean
java::io::File::performMkdir (void)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

#ifdef HAVE_MKDIR
  return ::mkdir (buf, 0755) == 0;
#else
  return false;
#endif
}

jboolean
java::io::File::performSetReadOnly (void)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

#ifdef HAVE_STAT && HAVE_CHMOD
  struct stat sb;
  if (::stat (buf, &sb))
    return false;

  if (::chmod(buf, sb.st_mode & 0555))
    return false;  
  return true;
#else
  return false;
#endif
}

static JArray<java::io::File *> *unixroot;

JArray< ::java::io::File *>*
java::io::File::performListRoots ()
{
  if (unixroot == NULL)
    {
      ::java::io::File *f = new ::java::io::File (JvNewStringLatin1 ("/"));
      unixroot = reinterpret_cast <JArray<java::io::File *>*> 
		   (JvNewObjectArray (1, &java::io::File::class$, f));
      elements (unixroot) [0] = f;
    }
  return unixroot;
}

jboolean
java::io::File::performRenameTo (File *dest)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';
  char buf2[MAXPATHLEN];
  total = JvGetStringUTFRegion (dest->path, 0, dest->path->length(), buf2);
  // FIXME?
  buf2[total] = '\0';

#ifdef HAVE_RENAME
  return ::rename (buf, buf2) == 0;
#else
  return false;
#endif
}

jboolean
java::io::File::performSetLastModified (jlong time)
{
#ifdef HAVE_UTIME
  utimbuf tb;

  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';
  
  tb.actime = time / 1000;
  tb.modtime = time / 1000;
  return ::utime (buf, &tb);
#else
  return false;
#endif
}

jboolean
java::io::File::performCreate (void)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

  int fd = ::open (buf, O_CREAT | O_EXCL, 0644);

  if (fd < 0)
    {
      if (errno == EEXIST)
        return false;
      throw new IOException (JvNewStringLatin1 (strerror (errno)));
    }
  else
    {
      ::close (fd);
      return true;
    }
}

jboolean
java::io::File::performDelete (void)
{
  char buf[MAXPATHLEN];
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  // FIXME?
  buf[total] = '\0';

#ifdef HAVE_UNLINK
#ifdef HAVE_RMDIR
  if (! ::rmdir (buf))
    return true;
#endif // HAVE_RMDIR
  if (errno == ENOTDIR)
    return ::unlink (buf) == 0;
#endif // HAVE_UNLINK
  return false;
}

void
java::io::File::init_native ()
{
  maxPathLen = MAXPATHLEN;
  caseSensitive = true;
}
