diff -u old/sh-utils-2.0j/lib/basename.c sh-utils-2.0j/lib/basename.c
--- old/sh-utils-2.0j/lib/basename.c	Sun Sep 26 19:10:00 1999
+++ sh-utils-2.0j/lib/basename.c	Tue Jul 18 09:55:32 2000
@@ -32,7 +32,11 @@
 #endif
 
 #ifndef ISSLASH
-# define ISSLASH(C) ((C) == '/')
+# ifdef __MSDOS__
+#  define ISSLASH(C) ((C) == '/' || (C) == '\\' || (C) == ':')
+# else
+#  define ISSLASH(C) ((C) == '/')
+# endif
 #endif
 
 char *base_name PARAMS ((char const *name));
diff -u old/sh-utils-2.0j/lib/dirname.c sh-utils-2.0j/lib/dirname.c
--- old/sh-utils-2.0j/lib/dirname.c	Sat Jan 22 22:21:46 2000
+++ sh-utils-2.0j/lib/dirname.c	Tue Jul 18 12:11:42 2000
@@ -59,10 +59,10 @@
       /* Remove any trailing slashes from the result.  */
 #ifdef MSDOS
       char *lim = (path[0] >= 'A' && path[0] <= 'z' && path[1] == ':')
-		  ? path + 2 : path;
+		  ? (char *)(path + 2) : (char *)path;
 
       /* If canonicalized "d:/path", leave alone the root case "d:/".  */
-      while (slash > lim && *slash == '/')
+      while (slash > lim && (*slash == '/' || *slash == '\\'))
 	--slash;
 #else
       while (slash > path && *slash == '/')
diff -u old/sh-utils-2.0j/lib/euidaccess.c sh-utils-2.0j/lib/euidaccess.c
--- old/sh-utils-2.0j/lib/euidaccess.c	Fri Jan  7 14:29:26 2000
+++ sh-utils-2.0j/lib/euidaccess.c	Tue Jul 18 09:58:50 2000
@@ -159,8 +159,10 @@
     return -1;
 
   mode &= (X_OK | W_OK | R_OK);	/* Clear any bogus bits. */
-#if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
-  ?error Oops, portability assumptions incorrect.
+#ifndef __MSDOS__
+# if R_OK != S_IROTH || W_OK != S_IWOTH || X_OK != S_IXOTH
+    ?error Oops, portability assumptions incorrect.
+# endif
 #endif
 
   if (mode == F_OK)
diff -u old/sh-utils-2.0j/lib/getusershell.c sh-utils-2.0j/lib/getusershell.c
--- old/sh-utils-2.0j/lib/getusershell.c	Sun Jun 25 21:16:02 2000
+++ sh-utils-2.0j/lib/getusershell.c	Tue Jul 18 12:39:38 2000
@@ -21,12 +21,15 @@
 # include <config.h>
 #endif
 
-#ifndef SHELLS_FILE
+#ifndef MSDOS
+# ifndef SHELLS_FILE
 /* File containing a list of nonrestricted shells, one per line. */
-# define SHELLS_FILE "/etc/shells"
+#  define SHELLS_FILE "/etc/shells"
+# endif
 #endif
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include "xalloc.h"
 
@@ -43,6 +46,9 @@
 /* List of shells to use if the shells file is missing. */
 static char const* const default_shells[] =
 {
+#ifdef MSDOS
+  "c:/dos/command.com", "c:/windows/command.com", "c:/command.com",
+#endif
   "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", NULL
 };
 
@@ -77,6 +83,7 @@
 
   if (shellstream == NULL)
     {
+#ifdef SHELLS_FILE
       shellstream = fopen (SHELLS_FILE, "r");
       if (shellstream == NULL)
 	{
@@ -84,6 +91,11 @@
 	  default_index = 1;
 	  return xstrdup (default_shells[0]);
 	}
+#else
+      /* No standard place for "/etc/shells"...  */
+      if (shellstream == NULL && getenv ("SHELLS_FILE"))
+	shellstream = fopen (getenv ("SHELLS_FILE"), "r");
+#endif
     }
 
   while (readname (&line, &line_size, shellstream))
@@ -99,11 +111,15 @@
 void
 setusershell ()
 {
+#ifdef SHELLS_FILE
   default_index = 0;
   if (shellstream == NULL)
     shellstream = fopen (SHELLS_FILE, "r");
   else
     fseek (shellstream, 0L, 0);
+#else
+  shellstream = NULL;
+#endif
 }
 
 /* Close the shells file. */
diff -u old/sh-utils-2.0j/lib/quotearg.c sh-utils-2.0j/lib/quotearg.c
--- old/sh-utils-2.0j/lib/quotearg.c	Sun Jul  2 20:25:50 2000
+++ sh-utils-2.0j/lib/quotearg.c	Tue Jul 18 12:20:18 2000
@@ -66,6 +66,7 @@
 #else
 # define mbrtowc(pwc, s, n, ps) 1
 # define mbsinit(ps) 1
+#define mbstate_t int
 #endif
 
 #if HAVE_WCTYPE_H
diff -u old/sh-utils-2.0j/lib/stripslash.c sh-utils-2.0j/lib/stripslash.c
--- old/sh-utils-2.0j/lib/stripslash.c	Mon Dec  7 13:50:36 1998
+++ sh-utils-2.0j/lib/stripslash.c	Sat Jul 22 21:29:38 2000
@@ -25,6 +25,16 @@
 # include <strings.h>
 #endif
 
+#ifndef ISSLASH
+# ifdef __MSDOS__
+#  define ISSLASH(C) ((C) == '/' || (C) == '\\' (C) == ':')
+#  define DRIVELETTER 1
+# else
+#  define ISSLASH(C) ((C) == '/')
+#  define DRIVELETTER 0
+# endif
+#endif
+
 /* Remove trailing slashes from PATH.
    This is useful when using filename completion from a shell that
    adds a "/" after directory names (such as tcsh and bash), because
@@ -37,6 +47,13 @@
   int last;
 
   last = strlen (path) - 1;
+#if DRIVELETTER
+  if (last > 2 && path[1] == ':')
+    {
+      path += 2;
+      last -= 2;
+    }
+#endif
   while (last > 0 && path[last] == '/')
     path[last--] = '\0';
 }
diff -u old/sh-utils-2.0j/src/dirname.c sh-utils-2.0j/src/dirname.c
--- old/sh-utils-2.0j/src/dirname.c	Sat May  6 13:38:24 2000
+++ sh-utils-2.0j/src/dirname.c	Sat Jul 22 20:48:38 2000
@@ -31,6 +31,10 @@
 
 #define AUTHORS "David MacKenzie and Jim Meyering"
 
+#ifndef ISSLASH
+# define ISSLASH(C) ((C) == '/')
+#endif
+
 void strip_trailing_slashes ();
 
 /* The name this program was run with. */
@@ -95,12 +99,30 @@
   strip_trailing_slashes (path);
 
   slash = strrchr (path, '/');
+#ifdef BACKSLASHES
+  /* In case a backslash was used, check which one should be
+     stripped. */
+  if (strrchr (path, '\\') != NULL && strrchr (path, '\\') > slash)
+    slash = strrchr (path, '\\');
+  if (slash == NULL && strlen (path) >= 2)
+    {
+      if (path[1] != ':')
+	path = (char *) ".";
+      else
+	path[2] = '\0';
+    }
+#else
   if (slash == NULL)
     path = (char *) ".";
+#endif /* BACKSLASHES */
   else
     {
       /* Remove any trailing slashes and final element. */
-      while (slash > path && *slash == '/')
+#if DRIVELETTER
+      while (slash > path && (*slash == '/' || *slash == '\\'))
+#else
+      while (slash > path && ISSLASH (*slash))
+#endif
 	--slash;
       slash[1] = 0;
     }
diff -u old/sh-utils-2.0j/src/pathchk.c sh-utils-2.0j/src/pathchk.c
--- old/sh-utils-2.0j/src/pathchk.c	Sat May  6 14:16:06 2000
+++ sh-utils-2.0j/src/pathchk.c	Sat Jul 22 18:29:42 2000
@@ -279,6 +279,23 @@
   parent = xstrdup (*path == '/' ? "/" : ".");
 
   slash = path;
+#if DRIVELETTER
+  if (path [0] && path[1] == ':')
+    {
+      /* If we have a pathname with a drive, make sure it's explicit
+	 (i.e. instead of "d:foo/bar" get "d:/curdir/foo/bar").  */
+      char *normalized_path = alloca(PATH_MAX + 1);
+      int c;
+
+      _fixpath (path, normalized_path);
+      c = normalized_path[3];
+      normalized_path[3] = 0;
+      parent = xstrdup (normalized_path);
+      normalized_path[3] = c;
+      path = normalized_path;
+      slash = path + 2;		/* point to the leftmost slash */
+    }
+#endif
   last_elem = 0;
   while (1)
     {
diff -u old/sh-utils-2.0j/src/su.c sh-utils-2.0j/src/su.c
--- old/sh-utils-2.0j/src/su.c	Sat May  6 14:17:20 2000
+++ sh-utils-2.0j/src/su.c	Sat Jul 22 21:01:54 2000
@@ -128,7 +128,11 @@
 #ifdef _PATH_DEFPATH
 # define DEFAULT_LOGIN_PATH _PATH_DEFPATH
 #else
-# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin"
+# ifdef MSDOS
+#  define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin"
+# else
+#  define DEFAULT_LOGIN_PATH "c:/dos;c:/windows;c:/"
+#endif
 #endif
 
 /* The default PATH for simulated logins to superuser accounts.  */
@@ -139,7 +143,11 @@
 #endif
 
 /* The shell to run if none is given in the user's passwd entry.  */
-#define DEFAULT_SHELL "/bin/sh"
+#ifdef MSDOS
+# define DEFAULT_SHELL "command.com"
+#else
+# define DEFAULT_SHELL "/bin/sh"
+#endif
 
 /* The user to become if none is specified.  */
 #define DEFAULT_USER "root"
@@ -285,6 +293,10 @@
     correct = sp->sp_pwdp;
   else
 #endif
+#if SINGLEUSER
+    /* Assume that the password is always correct. */
+    return 1;
+#else
     correct = pw->pw_passwd;
 
   if (getuid () == 0 || correct == 0 || correct[0] == '\0')
@@ -299,6 +311,7 @@
   encrypted = crypt (unencrypted, correct);
   memset (unencrypted, 0, strlen (unencrypted));
   return strcmp (encrypted, correct) == 0;
+#endif
 }
 
 /* Update `environ' for the new shell based on PW, with SHELL being
@@ -362,6 +375,7 @@
 
 /* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
    If COMMAND is nonzero, pass it to the shell with the -c option.
+   In case of MSDOS shells, pass it with the /c option.
    If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
    arguments.  */
 
@@ -393,8 +407,21 @@
     args[argno++] = "-f";
   if (command)
     {
+#ifdef __DJGPP__
+      if (_is_dos_shell (shell))
+	{
+	  args[argno++] = "/c";
+	  args[argno++] = command;
+	}
+      else
+	{
+	  args[argno++] = "-c";
+	  args[argno++] = command;
+	}
+#else
       args[argno++] = "-c";
       args[argno++] = command;
+#endif
     }
   if (additional_args)
     for (; *additional_args; ++additional_args)
@@ -413,6 +440,14 @@
 {
   char *line;
 
+#if BACKSLASHES
+  /* Convert all slashes to forward style, make sure the
+     letter case in both SHELL and LINE is consistent.  */
+  char shellbuf[PATH_MAX];
+
+  _fixpath (shell, shellbuf);
+  shell = shellbuf;
+#endif
   setusershell ();
   while ((line = getusershell ()) != NULL)
     {
@@ -459,7 +494,11 @@
 main (int argc, char **argv)
 {
   int optc;
+#if SINGLEUSER
+  char *new_user = getlogin ();
+#else
   const char *new_user = DEFAULT_USER;
+#endif
   char *command = 0;
   char **additional_args = 0;
   char *shell = 0;
@@ -522,9 +561,28 @@
   if (optind < argc)
     additional_args = argv + optind;
 
+#if SINGLEUSER
+  pw = getpwnam (getlogin());
+#else
   pw = getpwnam (new_user);
+#endif
   if (pw == 0)
+#ifdef __DJGPP__
+    {
+      /* On MSDOS, allow them to become anyone.  */
+      extern char * __dosexec_find_on_path (const char *, char **, char *);
+      char found_at[PATH_MAX];
+
+      pw = (struct passwd *)alloca (sizeof (struct passwd));
+      pw->pw_name = new_user;
+      pw->pw_dir = "c:/";
+      pw->pw_shell = __dosexec_find_on_path ("command.com", environ, found_at);
+      pw->pw_uid = getuid ();
+      pw->pw_gid = getgid ();
+    }
+#else
     error (1, 0, _("user %s does not exist"), new_user);
+#endif
   endpwent ();
 
   /* Make sure pw->pw_shell is non-NULL.  It may be NULL when NEW_USER
@@ -558,6 +616,13 @@
 
   if (shell == 0 && change_environment == 0)
     shell = getenv ("SHELL");
+
+#ifdef MSDOS
+  /* $SHELL is not guaranteed to be defined on MSDOS.  */
+  if (shell == 0 && change_environment == 0)
+    shell = getenv ("COMSPEC");
+#endif
+
   if (shell != 0 && getuid () && restricted_shell (pw->pw_shell))
     {
       /* The user being su'd to has a nonstandard shell, and so is
diff -u old/sh-utils-2.0j/src/system.h sh-utils-2.0j/src/system.h
--- old/sh-utils-2.0j/src/system.h	Wed Apr 19 21:41:24 2000
+++ sh-utils-2.0j/src/system.h	Sat Jul 22 21:14:10 2000
@@ -166,6 +166,21 @@
 # undef O_TEXT
 #endif
 
+#ifdef __MSDOS__
+# define BACKSLASHES 1
+# define DRIVELETTER 1
+# define SINGLEUSER 1
+# define ISSLASH(C) ((C) == '/' | (C) == '\\' | (C) == ':')
+#else
+# define BACKSLASHES 0
+#define DRIVELETTER 0
+#define SINGLEUSER 0
+#endif
+
+#ifdef __DJGPP__
+extern int _is_dos_shell (const char *);
+#endif
+
 #if O_BINARY
 # ifndef __DJGPP__
 #  define setmode _setmode
diff -u old/sh-utils-2.0j/src/tee.c sh-utils-2.0j/src/tee.c
--- old/sh-utils-2.0j/src/tee.c	Sat May  6 13:27:26 2000
+++ sh-utils-2.0j/src/tee.c	Tue Jul 18 12:43:32 2000
@@ -166,7 +166,11 @@
   char buffer[BUFSIZ];
   int bytes_read, i;
   int ret = 0;
+#ifdef MSDOS
+  const char *mode_string = (append ? "ab" : "wb");
+#else
   const char *mode_string = (append ? "a" : "w");
+#endif
 
   descriptors = (FILE **) xmalloc ((nfiles + 1) * sizeof (descriptors[0]));
 
@@ -175,6 +179,8 @@
   for (i = nfiles; i >= 1; i--)
     files[i] = files[i - 1];
 
+  SET_BINARY2(0, 1);
+
   /* In the array of NFILES + 1 descriptors, make
      the first one correspond to standard output.   */
   descriptors[0] = stdout;
diff -u old/sh-utils-2.0j/src/test.c sh-utils-2.0j/src/test.c
--- old/sh-utils-2.0j/src/test.c	Sat May  6 14:21:08 2000
+++ sh-utils-2.0j/src/test.c	Tue Jul 18 12:05:40 2000
@@ -156,6 +156,11 @@
   struct stat st;
   static int euid = -1;
 
+#ifdef __MSDOS__
+  /* The bits in MODE are different for `access' and `stat'.
+     Besides, MSDOS doesn't care about uid/euid issues.  */
+  return access (path, mode);
+#else /* not MSDOS */
   if (test_stat (path, &st) < 0)
     return (-1);
 
@@ -183,6 +188,7 @@
     return (0);
 
   return (-1);
+#endif /* MSDOS */
 }
 
 /* Increment our position in the argument list.  Check that we're not
@@ -656,6 +662,18 @@
     case 'x':			/* File is executable? */
       unary_advance ();
       value = -1 != eaccess (argv[pos - 1], X_OK);
+#ifdef __DJGPP__
+      /* Shell scripts say ``test -x prog'', but DOS executables are
+	 called `prog.exe', `prog.com' etc.  Make so they are found.  */
+      {
+	extern char * __dosexec_find_on_path (const char *, char *[], char *);
+	char arg_path[PATH_MAX];
+
+	if (value == FALSE &&
+	    __dosexec_find_on_path (argv[pos -1], (char **)0, arg_path))
+	  value = -1 != eaccess (arg_path, X_OK);
+      }
+#endif
       return (TRUE == value);
 
     case 'O':			/* File is owned by you? */
