#include <stddef.h>
#include <assert.h>
#include <string.h>

#ifdef unix
#include <pwd.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>

#endif


#include "sysdep.h"

#ifdef athena_unix
#include <hesiod.h>
/* This should be in hesiod.h */
extern struct passwd *hes_getpwnam PROTOTYPE((const char *));
/* This should be in some header file */
extern long time PROTOTYPE((long *));
#endif

#include "sysdep.h"
#include "al.h"
#include "memory.h"
#include "bool.h"
#include "al.h"

#include "OSinter.h"


#ifdef unix

#include "unixprotos.h"

Bool
OSinter_get_directory(file_names, dir_name)
     Darray file_names;
     const char *dir_name;
{
  DIR *dirp;
  struct direct *dp;

  assert(Darray_len(file_names) == 0);

  dirp = opendir(dir_name);
  if (dirp == (DIR *)NULL)
    return Bool_FALSE;
  
  for (dp = readdir(dirp);
       dp != NULL;
       dp = readdir(dirp)) {
    char *temp_buf_ptr = (char *)Memory_allocate(dp->d_namlen + 1);
    (NORET)strcpy(temp_buf_ptr, dp->d_name);
    Darray_addh(file_names, temp_buf_ptr);
  }
  closedir(dirp);
  return Bool_TRUE;
}

Bool
OSinter_get_cwd(buf)
     char *buf;
{
  if (getwd(buf) == 0)
    return Bool_FALSE;
  else
    return Bool_TRUE;
}

Bool
OSinter_set_cwd(newdir)
     const char *newdir;
{
  if (chdir(newdir) != 0)
    return Bool_FALSE;
  else
    return Bool_TRUE;
}

OSinter_UIDtype
OSinter_get_file_uid(fname)
     const char *fname;
{
  struct stat stat_buf;

  if (stat(fname, &stat_buf) != 0)
    return OSINTER_ERROR_UID;
  else
    return stat_buf.st_uid;
}

OSinter_UIDtype
OSinter_name_to_uid(user_name)
     const char *user_name;
{
  struct passwd *pw_buf;

#ifdef athena_unix
  pw_buf = hes_getpwnam(user_name);
#else
  pw_buf = getpwnam(user_name);
#endif
  if (pw_buf == (struct passwd *)NULL)
    return OSINTER_ERROR_UID;
  else
    return pw_buf->pw_uid;
}

Bool
OSinter_remove(fn)
     const char *fn;
{
  if (unlink(fn) == 0)
    return Bool_TRUE;
  else
    return Bool_FALSE;
}

extern Bool 
OSinter_get_user_name(buf)
     char *buf;
{
  const char *up;
  int claimed_uid;

  assert(buf != (char *)NULL);

  up = getenv("USER");
  if (strlen(up) > OSINTER_USER_NAME_LENGTH)
    Al_fatal_error("$USER is too long");

  if ((claimed_uid = OSinter_name_to_uid(up)) == OSINTER_ERROR_UID)
    Al_fatal_error("Could not translate $USER to uid");

  if (claimed_uid != getuid())
    Al_fatal_error("$USER does not match uid");

  strcpy(buf, up);
  return Bool_TRUE;
}

OSinter_TimeType
OSinter_get_current_time(NOARGS)
{
  return time((long)0);
}

OSinter_TimeType
OSinter_get_file_mod_time(fname)
     const char *fname;
{
  struct stat stat_buf;

  if (stat(fname, &stat_buf) != 0)
    return OSINTER_ERROR_UID;
  else
    return stat_buf.st_ctime;

}
#endif /* unix */
