/* _tempnam.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
/*                         Copyright (c) 1991-1993 by Kolja Elsaesser */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <errno.h>
#include <sys/param.h>
#include <emx/io.h>
#include <emx/syscalls.h>
#include "_tmp.h"


/* Create absolute path name from src, copy it to dst and return 1 if
   it's a directory. Note that this works also with a trailing backslash! */

static int _isdir (char *dst, const char *src)
{
  int attr;

  if (_fullpath (dst, src, MAXPATHLEN) != 0)
    return 0;
  attr = __chmod (dst, 0, 0);
  return attr >= 0 && (attr & _A_SUBDIR);
}


char *_tempnam (const char *dir, const char *prefix)
{
  const char *tmpdir;
  char *tmpname, *p, buf[MAXPATHLEN];
  size_t len;
  int saved_errno, idx_start;

  saved_errno = errno;
  if (strlen (prefix) > 5)
    {
      errno = EINVAL;
      return NULL;
    }
  tmpdir = NULL;
  p = getenv ("TMP");
  if (tmpdir == NULL && p != NULL && _isdir (buf, p))
    tmpdir = buf;
  if (tmpdir == NULL && dir != NULL && _isdir (buf, dir))
    tmpdir = buf;
  if (tmpdir == NULL)
    tmpdir = P_tmpdir;
  tmpname = malloc (strlen (tmpdir) + 1 + L_tmpnam);
  if (tmpname == NULL)
    {
      errno = ENOMEM;
      return NULL;
    }

  len = strlen (tmpdir);
  memcpy (tmpname, tmpdir, len);
  if (len > 0 && !_trslash (tmpname, len, 0))
    tmpname[len++] = '/';
  p = tmpname + len;

  TMPIDX_LOCK;
  idx_start = _tmpidx;
  for (;;)
    {
      if (_tmpidx == IDX_HI)
        _tmpidx = IDX_LO;
      else
        ++_tmpidx;
      if (_tmpidx == idx_start)
        {
          TMPIDX_UNLOCK;
          free (tmpname);
          errno = EINVAL;
          return NULL;
        }
      _itoa (_tmpidx, p, 10);
      strcat (p, ".tmp");
      memmove (p, prefix, strlen (prefix));
      errno = 0;
      if (_access (tmpname, 0) != 0)
        {
          if (errno == ENOENT)
            break;
          TMPIDX_UNLOCK;
          free (tmpname);
          return NULL;
        }
    }
  TMPIDX_UNLOCK;
  errno = saved_errno;
  if (_fullpath (buf, tmpname, sizeof (buf)) != 0)
    {
      free (tmpname);
      errno = ENOENT;
      return NULL;
    }
  free (tmpname);
  p = _strdup (buf);
  if (p == NULL)
    errno = ENOMEM;
  return p;
}
