#ifdef __DJGPP__

#include <ctype.h>
#include <errno.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>

/*
#include "config.h"
#include "general.h"
#include "subst.h"
#include "externs.h"
#include "builtins/common.h"
*/
#include "dosutil.h"

static char *encode_drivename_inplace (char *);

#if defined (__MSDOS__)
#define ROOTDEV_COMPARE strnicmp
#else
#define ROOTDEV_COMPARE strncmp
#endif

int dosutil_path_separator = ';';
int dosutil_path_slash = '/';
int dosutil_path_expand = 0;

const char dev_str[] = "/dev/";
const int dev_str_len = sizeof(dev_str) - 1;
const int dosutil_encoded_drive_len_diff = 4;
char dosutil_tmpdir[PATH_MAX + 1];
size_t dosutil_tmpdir_len;
char *dosutil_tmpdir_template;

int dosutil_test_finds_exe = 0;

static char *need_fix_variables[] =
{
  "PWD",
  "OLDPWD",
  "HOME",
  "PATH",
  "CDPATH",
  "COMSPEC",
  "MAILPATH",
  "TMPDIR",
  NULL,
};

static void dummy(void)
{
  __dosexec_find_on_path (0,0,0);
  __libc_termios_init();
}

char *
dosutil_maybe_encode_drivename (char *path)
{
  return (dosutil_path_separator == ':') ? dosutil_encode_drivename (path) : path;
}

/* Translate filenames of the form 'x:/dir/file' to '/dev/x/dir1/file'.
   Returns a new string. */

char *
dosutil_encode_drivename (char *path)
{
  char *enc_path;
  int len = strlen (path);

  if (dosutil_is_dev_path(path))
    {
      if (path && path[1] == ':')
        strcpy(path, path + 2);
      return path;
    }

  enc_path = (char *)malloc (len + dosutil_encoded_drive_len_diff + 1);
  strcpy (enc_path, dev_str);
  enc_path[5] = path[0];
  strcpy (enc_path + sizeof (dev_str), path + 2);

  free (path);
  return enc_path;
}

/* Translate filenames of the form 'x:/dir/file' to '/dev/x/dir1/file'.
   Returns the same string that was passed in. This function assumes
   there is enough space to handle the modified string. */

static char *
encode_drivename_inplace (char *path)
{
  int len = strlen (path);
  char drive = path[0];

  memmove (path + 6, path + 2, len - 1);
  memcpy (path, dev_str, sizeof(dev_str) - 1);
  path[5] = drive;

  return path;
}

/* Translates filenames of the form '/dev/x/dir/file' into 'x:/dir/file'. */

char *
dosutil_decode_drivename (char *path)
{
  char *p = path;
  p = (path && path[1] == ':') ? (path + 2) : path;
  path[0] = p[5];
  path[1] = ':';
  strcpy (path + 2, p + 6);
  return path;
}

/* Returns whether or not a path starts with '/dev/' */
 
int
dosutil_is_dev_path (const char *path)
{
  if (path && path[1] == ':')
    path += 2;

  return ROOTDEV_COMPARE (dev_str, path, dev_str_len) == 0;
}

/* Returns whether or not a filename is in the form '/dev/x/dir1/file'. */

int
dosutil_is_encoded_drivename (const char *path)
{
  if (path && path[1] == ':')
    path += 2;

  return (ROOTDEV_COMPARE (dev_str, path, dev_str_len) == 0
      && path[dev_str_len]
      && (path[dev_str_len + 1] == '/' || path[dev_str_len + 1] == '\0'));
}

/* Returns whether the pathname is the root directory.  */

int
dosutil_is_root_directory_pathname (const char *path)
{
  const char *p = (path && path[1] == ':') ? (path + 2) : path;

  if (*p == '/' && p[1] == '\0')
    return 1;

  if (dosutil_is_encoded_drivename (path))
    return (p[6] == '/' && p[7] == '\0');
}
char *
dosutil_make_import_path (char *value)
{
  char *p, *newenv;
  int newlen, pos;

  if (value == NULL)
    return NULL;

  /* fix each element */
  newlen = strlen (value) + 1;
  newenv = malloc (newlen);
  if (newenv != NULL)
    {
      char *to, *from;

      /* copy to buffer */
      from = value;
      to = newenv;

      while (*from)
      {
        if (*from != '\\')
          *to = *from;
        else
          *to = '/';
        ++to;
        ++from;
      }
      *to = '\0';

      for (p = newenv; p != NULL && *p; p = strchr (p + 1, ';'))
	{
	  int drive_len = 0;

	  /* replace delimiter */
	  while (*p == ';')
	    *p++ = dosutil_path_separator;
	  if (*p == '\0')
	    break;

	  /* check drive name */
          if (p[0] && p[1] == ':')
	    {
              if (dosutil_path_separator == ':')
		{
                  newlen += dosutil_encoded_drive_len_diff;
		  pos = p - newenv;
		  newenv = realloc (newenv, newlen);
		  if (newenv == NULL)
		    return NULL;
		  p = newenv + pos;
                  encode_drivename_inplace (p);
		}
	    }
	}

      /* may need to convert slash to back-slash */
      if (dosutil_path_slash == '\\')
	dosutil_tobslash (newenv);
    }

  return newenv;
}

char *
dosutil_make_export_path (char *value)
{
  char *p, *newenv;
  int newlen, pos;

  if (value == NULL)
    return NULL;

  /* fix each element */
  newlen = strlen (value) + 1;
  newenv = malloc (newlen);
  if (newenv != NULL)
    {
      /* copy to buffer */
      strcpy (newenv, value);
      /* convert back-slash to slash */
      dosutil_toslash (newenv);

      for (p = newenv; p != NULL && *p; p = strchr (p + 1, dosutil_path_separator))
	{
	  /* replace delimiter */
	  while (*p == dosutil_path_separator)
	    *p++ = ';';
	  if (*p == '\0')
	    break;

            if (p[1] != dosutil_path_separator
                   && dosutil_is_encoded_drivename(p))
	    {
              /* Expand drive name */
              dosutil_decode_drivename (p);
              newlen -= dosutil_encoded_drive_len_diff;
	      pos = p - newenv;
	      newenv = realloc (newenv, newlen);
	      if (newenv == NULL)
		return NULL;
	      p = newenv + pos;
              /* Skip past colon after drive letter. */
	      p += 2;
	    }
	}

      /* convert slash to back-slash */
      dosutil_tobslash (newenv);
    }

  return newenv;
}

void
dosutil_import_environment_variables (void)
{
  char *p;
  int i;

  p = getenv ("PATH_SEPARATOR");
  if (p != NULL)
  {
      if (*p != '\0' && *p != '/' && *p != '\\' && *p < 0x7f)
	dosutil_path_separator = (int) *(unsigned char *) p;
  }
#if 0
  else
  {
    char buf[2];

    buf[0] = dosutil_path_separator;
    buf[1] = '\0';
    setenv("PATH_SEPARATOR", buf, 1);
  }
#endif

  p = getenv ("PATH_EXPAND");
  if (p != NULL)
    {
      if (*p != '\0' && (*p == 'y' || *p == 'Y'))
        dosutil_path_expand = 1;
    }
  else
    dosutil_path_expand = 0;

  p = getenv (DOSUTIL_TEST_VAR_NAME);
  if (p != NULL)
    {
      if (*p == 'y' || *p =='Y')
        dosutil_test_finds_exe = 1;
    }
}

int
dosutil_import_unixy_pathvar (char *name, char **path)
{
  int i;
  char *p;

  for (i = 0; (p = need_fix_variables[i]) != NULL; i++)
    {
      if (strcmp (p, name) == 0)
        break;
    }

  if (p == NULL)
    return 0;

  *path = dosutil_make_import_path (*path);
  return 1;
}

char *
dosutil_add_slash (char *path)
{
  char *top = path;

  path += strlen (path);
  if (path != top && path[-1] != '/')
    {
      *path++ = '/';
      *path++ = '\0';
    }

  return top;
}

char *
dosutil_delete_slash (char *path)
{
  char *top = path;

  path += strlen (path);
  if (path != top && path[-1] == '/')
    path[-1] = '\0';

  return top;
}

char *
dosutil_toslash (char *path)
{
  char *p;
#if defined (USE_MULTIBYTE)
  int mbsize;
#endif

  for (p = path; *p; p++)
    {
#if defined (USE_MULTIBYTE)
      mbsize = mblen (p, MB_CUR_MAX);
      if (mbsize > 1)
	{
	  p += mbsize - 1;
	  continue;
	}
      else if (*p == '\\')
	*p = '/';
#else
      if (*p == '\\')
	*p = '/';
#endif
    }

  return path;
}

char *
dosutil_tobslash (char *path)
{
  char *p;
#if defined (USE_MULTIBYTE)
  int mbsize;
#endif

  for (p = path; *p; p++)
    {
#if defined (USE_MULTIBYTE)
      mbsize = mblen (p, MB_CUR_MAX);
      if (mbsize > 1)
	{
	  p += mbsize - 1;
	  continue;
	}
      else if (*p == '/')
	*p = '\\';
#else
      if (*p == '/')
	*p = '\\';
#endif
    }

  return path;
}

char *
dosutil_tolower (char *path)
{
  char *p;
#if defined (USE_MULTIBYTE)
  int mbsize;
#endif

  for (p = path; *p; p++)
    {
#if defined (USE_MULTIBYTE)
      mbsize = mblen (p, MB_CUR_MAX);
      if (mbsize > 1)
	{
	  p += mbsize - 1;
	  continue;
	}
      else if (isupper (*p))
	*p = tolower (*p);
#else
      if (isupper (*p))
	*p = tolower (*p);
#endif
    }

  return path;
}

char *
dosutil_toupper (char *path)
{
  char *p;
#if defined (USE_MULTIBYTE)
  int mbsize;
#endif

  for (p = path; *p; p++)
    {
#if defined (USE_MULTIBYTE)
      mbsize = mblen (p, MB_CUR_MAX);
      if (mbsize > 1)
	{
	  p += mbsize - 1;
	  continue;
	}
      else if (islower (*p))
	*p = toupper (*p);
#else
      if (islower (*p))
	*p = toupper (*p);
#endif
    }

  return path;
}

char *
dosutil_fix_variable (char *vp)
{
  char *p, *fixp, *newbuf;
  int i;

  if (vp == NULL)
    return NULL;

  p = strchr (vp, '=');
  if (!p)
    return vp;

  *p = '\0';
  fixp = dosutil_make_export_path (p + 1);
  if (fixp != NULL)
  {
     newbuf = malloc (strlen (fixp) + strlen (vp) + 2);
     if (newbuf != NULL)
     {
#if defined (__MSDOS__) && 0
        /* convert upper case */
        if (strcmp (p, "PATH") == 0)
          dosutil_toupper (fixp);
#endif
        sprintf (newbuf, "%s=%s", vp, fixp);
        free (vp);
        vp = newbuf;
      }
    free (fixp);
  }

  return vp;
}

char *
dosutil_export_unixy_pathvar (char *path_var)
{
  return dosutil_fix_variable (path_var);
}

char **
dosutil_get_import_variables (void)
{
  char **p;
  int i;

  /* count need size */
  for (i = 0; need_fix_variables[i] != NULL; i++)
    ;
  p = malloc (i * sizeof (char*));
  if (p != NULL)
    {
      for (i = 0; need_fix_variables[i] != NULL; i++)
	p[i] = dosutil_make_export_path (get_string_value (need_fix_variables[i]));
    }

  return p;
}

void
dosutil_put_export_variables (char **vp)
{
  SHELL_VAR *var;
  int i;

  if (vp == NULL)
    return;

  for (i = 0; need_fix_variables[i] != NULL; i++)
    {
      var = find_variable (need_fix_variables[i]);
      if (var != NULL)
	{
	  if (var->value != NULL)
	    free (var->value);
	  var->value = dosutil_make_import_path (vp[i]);
	}
      if (vp[i] != NULL)
	free (vp[i]);
    }
  free (vp);
  set_working_directory (get_string_value ("PWD"));
}

void dosutil_set_tmpdir(const char *bashpath)
{
  char *tmpdirs[] = {"$TMPDIR", "$TEMP", "$TMP", "c:/tmp", ".", NULL};
  char *tmp, *dir;

#if 0
  char *tmpf;
#endif
  int fd, i, len;

  dosutil_tmpdir[0] = '\0';
  dosutil_tmpdir_len = 0;

  i = 0;
  while (tmpdirs[i] != NULL)
  {
    if (tmpdirs[i][0] == '$')
    {
      dir = getenv(tmpdirs[i] + 1);
      if (!(dir && *dir))
      {
        ++i;
        continue;
      }
    }
    else
    {
      dir = tmpdirs[i];
    }


    if (*dir && dir[1] == ':' && dir[2] == '\0')
    {
      dir[2] = '/';
      dir[3] = '\0';
    }

    if (access(dir, D_OK) >= 0)
      break;

    ++i;
  }

  if (tmpdirs[i] == NULL)
    return;

#if 0
  /* Now check and see if the directory is writeable. */
  tmpf = tempnam(dir, "dj");
  fd = open (tmpf, O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd < 0)
    continue;
  close(fd);
  remove(tmpf);
#endif

  _fixpath (dir, dosutil_tmpdir);
  setenv("TMPDIR", dosutil_tmpdir, 1);
  dosutil_tmpdir_len = strlen(dosutil_tmpdir);
}

#if defined (__DJGPP__)
#define _DEV_STDIN  0x0001
#define _DEV_STDOUT 0x0002
#define _DEV_NUL    0x0004
#define _DEV_CLOCK  0x0008
#define _DEV_RAW    0x0020
#define _DEV_CDEV   0x0080
#define _DEV_IOCTRL 0x4000

void
dosutil_reserve_fds (void)
{
  int fd;
  short devmod;

  /* don't use fd 5 and 6. these are used by configure script. */
  if ((devmod = _get_dev_info (5)) == -1)
    {
      fd = open ("NUL", O_RDWR);
      if (fd != 5)
	{
	  dup2 (fd, 5);
	  close (fd);
	}
    }

  if ((devmod = _get_dev_info (6)) == -1)
    {
      fd = open ("NUL", O_RDWR);
      if (fd != 6)
	{
	  dup2 (fd, 6);
	  close (fd);
	}
    }
}
#else
void
dosutil_reserve_fds (void)
{
}
#endif

#if defined (__DJGPP__)
static char dosutil_oldcwd[PATH_MAX + 1] = { '\0' };

static void
dosutil_restore_cwd (void)
{
  if (dosutil_oldcwd[0] != '\0')
    (void) (chdir) (dosutil_oldcwd);
}

void
dosutil_save_cwd (void)
{
  (void) (getcwd) (dosutil_oldcwd, sizeof (dosutil_oldcwd));
  atexit (dosutil_restore_cwd);
}
#else
void
dosutil_save_cwd (void)
{
}
#endif

void
dosutil_save_std_fds (int fds[3])
{
  int i;

  /* save stdin/out/err */
  for (i = 0; i < 3; i++)
#if defined (__DJGPP__)
    if ((fds[i] = fcntl (i, F_DUPFD, 20)) < 0)
#else
    if ((fds[i] = dup (i)) < 0)
#endif
      internal_error ("Cannot duplicate fd %d: %s",
		      i, strerror (errno));
}

void
dosutil_restore_std_fds (int fds[3])
{
  int i;

  /* restore stdin/out/err */
  for (i = 0; i < 3; i++)
    if (fds[i] >= 0)
      {
	if (dup2 (fds[i], i) < 0)
	  internal_error ("cannot duplicate fd %d to fd %d: %s",
			  fds[i], i, strerror (errno));
	close (fds[i]);
	fds[i] = -1;
      }
}

#include <dos.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <sys/exceptn.h>

/* default stack size */
unsigned _stklen = 1024 * 1024;

static int dosutil_cbrk_vector = -1;

/* The list of executable suffixes that add_executable_suffix
   will look for. */

static const char *executable_suffixes[] =
{
  "com",
  "exe",
  "bat",
  "btm",
#if 1
  "sh",
  "ksh",
  "pl",
  "sed",
  "awk",
#endif
  NULL,
};

static const char *script_suffixes[] =
{
  "sh",
  "ksh",
  "pl",
  "sed",
  "awk",
  NULL,
};

/* Returns the command string if a suffix was added,
   or NULL if one wasn't added. */ 

/* _USE_LFN is a macro in DJGPP's fcntl.h that reports if LFN is enabled. */

#ifndef _USE_LFN
/* Assume no LFNs when not using DJGPP. */
#define _USE_LFN 0
#endif

/* Try to find an executable extension.  */
char * find_executable_ext (const char *command, char *buffer)
{
  /* If file already exists and it isn't a directory,
     don't bother checking for extensions.  */
  if (access (command, R_OK) == 0 && access (command, D_OK) != 0)
  {
    if (command != buffer)
      strcpy (buffer, command);
    return buffer;
  }

#if defined(__DJGPP__) && 0
  __dosexec_find_on_path (command, NULL, buffer);
#else
  {
    int len;
    int index = 0;
    int errno_save = errno;
    char *ext;

    strcpy (buffer, command);
    len = strlen (buffer);

    ext = buffer + len;
    if (len > 0 && buffer[len - 1] != '.')
    {
      *ext = '.';
      ++ext;
    }

    while (executable_suffixes[index])
    {
      strcpy (ext, executable_suffixes[index]);
      if (access (buffer, R_OK) == 0 && access (buffer, D_OK) != 0)
      {
        errno_save = errno;
        return buffer;
      }
      ++index;
    }

    if (ext != command + len)
      ext[-1] = '\0';

    errno_save = errno;
  }
#endif

  return NULL;
}

#if 0
char *
dosutil_add_executable_suffix (char *command)
{
  int len, index;
  char *ext;
  struct stat finfo;
  int lfn = _USE_LFN;
  int has_dot = 0;
  char *path = command;
  int attr;
  /* If file already exists and it isn't a directory,
     don't bother checking for extensions. */
  if ((attr = _chmod(command, 0)) >= 0 && !(attr & 0x10))
#if 0
  if ((stat (command, &finfo) == 0) && !S_ISDIR(finfo.st_mode))
#endif
    return command;

  index = len = strlen(command);

  if (command[0] && (command[1] == ':'))
  {
    index -= 2;
    len -= 2;
    path += 2;
  }

  /* Find extension of command, if any. */
  while ((--index >= 0) && (path[index] != '/') && path[index] != '.')
  ;

  /* If a dot is the first character found and has characters following it,
     then an extension is already present and don't do the search. */

  has_dot = ( (index >= 0) && (path[index] == '.') );
  if ((has_dot) && (index+1 == len) && !lfn)
    return command;

  if (has_dot && !lfn)
    return command;
  else
  {
    ext = path + len;
    *ext++ = '.';
  }

  for (index = 0; executable_suffixes[index] != NULL; index++)
  {
    strcpy (ext, executable_suffixes[index]);
    if ((attr = _chmod(command, 0)) >= 0 && !(attr & 0x10))
#if 0
    if ((stat (command, &finfo) == 0) && !S_ISDIR(finfo.st_mode))
#endif
      return command;
  }

  /* If a period was added, erase it. */
  path[len] = '\0';
  return command;
}
#endif

static
int
dosutil_has_matching_suffix (const char *command, const char *suffixes[])
{
  int len, index;
  const char *ext;
  int has_dot = 0;

  index = len = strlen(command);

/* Find extension of command, if any. */
  while ((--index >= 0) && (command[index] != '/') && (command[index] != '.'))
  ;

  /* Return false when no dot or no suffix after the dot. */
  has_dot = ( (index >= 0) && (command[index] == '.') );
  if (!has_dot || (has_dot && (index+1 == len)))
    return 0;

  ext = command + index + 1;

  for (index = 0; suffixes[index] != NULL; index++)
  {
    /* If we find an executable extension, then return success. */
    if (stricmp (ext, suffixes[index]) == 0)
      return 1;
  }

  /* Failed to find suffix in the executable suffix list. */
  return 0;
}

int
dosutil_has_executable_suffix (const char *command)
{
  return dosutil_has_matching_suffix (command, executable_suffixes);
}

int
dosutil_has_script_suffix (const char *command)
{
  return dosutil_has_matching_suffix (command, script_suffixes);
}

int
dosutil_has_suffix (const char *command)
{
  int len, index;
  const char *ext;
  int has_dot = 0;

  index = len = strlen(command);

  /* Find extension of command, if any. */
  while ((--index >= 0) && (command[index] != '/') && (command[index] != '.'))
  ;

  /* Return false when no dot. */
  has_dot = ( (index >= 0) && (command[index] == '.') );
  if (has_dot)
    return -1;
  else
    return len;
}

void
dosutil_save_exceptions (OLDEXCEPTBUF *exceptionp)
{
  int i;

  if (dosutil_cbrk_vector < 0)
    {
      if (ScreenPrimary != 0xa0000)
	dosutil_cbrk_vector = 0x1b;
      else
	dosutil_cbrk_vector = 0x06;
    }

  for (i = 0; i < DOSUTIL_EXCEPTION_COUNT; i++)
    __dpmi_get_processor_exception_handler_vector (i, &exceptionp->except_original[i]);
  __dpmi_get_protected_mode_interrupt_vector (9, &exceptionp->kbd_original);
  __dpmi_get_protected_mode_interrupt_vector (0x75, &exceptionp->npx_original);
  __dpmi_get_real_mode_interrupt_vector (dosutil_cbrk_vector, &exceptionp->cbrk_original);
}

void
dosutil_restore_exceptions (OLDEXCEPTBUF *exceptionp)
{
  int i;

  for (i = 0; i < DOSUTIL_EXCEPTION_COUNT; i++)
    __dpmi_set_processor_exception_handler_vector (i, &exceptionp->except_original[i]);
  __dpmi_set_protected_mode_interrupt_vector (9, &exceptionp->kbd_original);
  __dpmi_set_protected_mode_interrupt_vector (0x75, &exceptionp->npx_original);
  __dpmi_set_real_mode_interrupt_vector (dosutil_cbrk_vector, &exceptionp->cbrk_original);
}

#define CHECK_SELS 15
int *
dosutil_check_dpmi_selectors (void)
{
  int *p;
  int i;

  p = malloc (sizeof (int) * CHECK_SELS);
  if (p != NULL)
    {
      for (i = 0; i < CHECK_SELS; i++)
	p[i] = __dpmi_allocate_ldt_descriptors (1);
      for (i = 0; i < CHECK_SELS; i++)
	__dpmi_free_ldt_descriptor (p[i]);
    }

  return p;
}

void
dosutil_free_dpmi_selectors (int *selectors)
{
  int sel1;
  int i;

  if (selectors != NULL)
    {
      sel1 = __dpmi_allocate_ldt_descriptors (1);
      __dpmi_free_ldt_descriptor (sel1);
      if (sel1 != selectors[0])
	{
	  for (i = 0; i < CHECK_SELS; i++)
	    __dpmi_free_ldt_descriptor (selectors[i]);
	}
      free (selectors);
    }
}

char *
dosutil_make_response_file (char **argv)
{
  char *tname, *name_ptr;

  name_ptr = tname = malloc (dosutil_tmpdir_len + sizeof ("/rsXXXXXX"));
  if (tname != NULL)
    {
      strcpy (tname, dosutil_tmpdir);
      strcpy (tname + dosutil_tmpdir_len, "/rsXXXXXX");
      tname = mktemp (tname);
      if (tname == NULL)
        {
          free (name_ptr);
          return tname;
        }
      else
	{
	  FILE *fp;
	  char *p;
	  int i;

	  fp = fopen (tname, "wt");
	  if (fp == NULL)
	    {
	      free (tname);
	      return NULL;
	    }

	  for (i = 1; (p = argv[i]) != NULL; i++)
	    {
	      if (i != 1)
		fputc (' ', fp);
	      if (strchr (p, '"') == NULL)
		{
		  fputc ('"', fp);
		  fputs (p, fp);
		  fputc ('"', fp);
		}
	      else
		{
		  fputc ('"', fp);
		  while (*p)
		    {
		      if (*p == '"')
			fputc ('\\', fp);
		      fputc (*p, fp);
		      p++;
		    }
		  fputc ('"', fp);
		}
	    }
	  fclose (fp);
	}
    }

  return tname;
}

#define _DEV_STDIN  0x0001
#define _DEV_STDOUT 0x0002
#define _DEV_NUL    0x0004
#define _DEV_CLOCK  0x0008
#define _DEV_RAW    0x0020
#define _DEV_EOF    0x0040
#define _DEV_CDEV   0x0080
#define _DEV_IOCTRL 0x4000

#define _REG_STATUS_CF 0x01
#define _REG_STATUS_ZF 0x40
void
dosutil_reset_console (void)
{
  unsigned short devinfo;
  int handle;
  __dpmi_regs r;

  handle = 0; /* STDIN (CON) */

  r.x.ax = 0x4400;
  r.x.bx = handle;
  __dpmi_int (0x21, &r);
  if (r.x.flags & _REG_STATUS_CF)
    return;
  devinfo = r.x.dx;

  if ((devinfo & _DEV_CDEV) && (devinfo & _DEV_STDIN) && (devinfo & _DEV_EOF) == 0)
    {
      r.x.ax = 0x4000; /* WRITE */
      r.x.bx = handle; /* STDIN (CON) */
      r.x.cx = 0; /* zero byte */
      r.x.dx = 0; /* dummy offset */
      r.x.ds = 0; /* dummy segment */
      __dpmi_int(0x21, &r);
      if (r.x.flags & _REG_STATUS_CF)
	return;
    }
}
#endif

/* If PATH_EXPAND=y, then change '/dev' names to their canonical forms.  */
void
dosutil_expand_argv_words (WORD_LIST *list)
{
  char fixed_name[PATH_MAX + 1];

  if (!dosutil_path_expand)
    return;

  /* Skip over command name. */
  list = list->next;

  while (list)
  {
    if (list->word->flags != W_QUOTED)
      if ((*(list->word->word) != '-')
          && dosutil_is_dev_path (list->word->word))
        {
          int size = _put_path (list->word->word);
          int len = strlen (list->word->word);
          if (size <= len)
          {
            dosmemget(__tb, size, list->word->word);
            (list->word->word)[size] = '\0';
          }
          else
          {
            char buffer[FILENAME_MAX];
            dosmemget(__tb, size, buffer);
            free (list->word->word);
            buffer[size] = '\0';
            list->word->word = strdup (buffer);
          }
        }
    list = list->next;
  }

  return;
}

