Index: trunk/src/kmk/Makefile.am
===================================================================
--- trunk/src/kmk/Makefile.am	(revision 3112)
+++ trunk/src/kmk/Makefile.am	(revision 3114)
@@ -58,4 +58,5 @@
 		../lib/kDep.c \
 		../lib/kbuild_version.c \
+		../lib/dos2unix.c \
 		../lib/maybe_con_fwrite.c \
 		\
Index: trunk/src/kmk/kmkbuiltin/install.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/install.c	(revision 3112)
+++ trunk/src/kmk/kmkbuiltin/install.c	(revision 3114)
@@ -91,4 +91,5 @@
 #include "kmkbuiltin.h"
 #include "k/kDefs.h"	/* for K_OS */
+#include "dos2unix.h"
 
 
@@ -102,9 +103,4 @@
 #ifndef MAXBSIZE
 # define MAXBSIZE 0x20000
-#endif
-
-/* Bootstrap aid - this doesn't exist in most older releases */
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)	/* from <sys/mman.h> */
 #endif
 
@@ -137,4 +133,5 @@
 static int ignore_perm_errors;
 static int hard_link_files_when_possible;
+static int dos2unix;
 
 static struct option long_options[] =
@@ -146,9 +143,11 @@
     { "hard-link-files-when-possible",			no_argument, 0, 265 },
     { "no-hard-link-files-when-possible",		no_argument, 0, 266 },
+    { "dos2unix",					no_argument, 0, 267 },
+    { "unix2dos",					no_argument, 0, 268 },
     { 0, 0,	0, 0 },
 };
 
 
-static int	copy(int, const char *, int, const char *, off_t);
+static int	copy(int, const char *, int *, const char *);
 static int	compare(int, const char *, size_t, int, const char *, size_t);
 static int	create_newfile(const char *, int, struct stat *);
@@ -160,4 +159,6 @@
 static int	usage(FILE *);
 static char    *last_slash(const char *);
+static KBOOL	needs_dos2unix_conversion(const char *pszFilename);
+static KBOOL	needs_unix2dos_conversion(const char *pszFilename);
 
 int
@@ -173,19 +174,20 @@
 	(void)envp;
 
-        /* reinitialize globals */
-        mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
-        suffix = BACKUP_SUFFIX;
-        gid = 0;
-        uid = 0;
-        dobackup = docompare = dodir = dopreserve = dostrip = nommap = safecopy = verbose = mode_given = 0;
+	/* reinitialize globals */
+	mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+	suffix = BACKUP_SUFFIX;
+	gid = 0;
+	uid = 0;
+	dobackup = docompare = dodir = dopreserve = dostrip = nommap = safecopy = verbose = mode_given = 0;
 	ignore_perm_errors = geteuid() != 0;
-        hard_link_files_when_possible = 0;
-
-        /* reset getopt and set progname. */
-        g_progname = argv[0];
-        opterr = 1;
-        optarg = NULL;
-        optopt = 0;
-        optind = 0; /* init */
+	hard_link_files_when_possible = 0;
+	dos2unix = 0;
+
+	/* reset getopt and set progname. */
+	g_progname = argv[0];
+	opterr = 1;
+	optarg = NULL;
+	optopt = 0;
+	optind = 0; /* init */
 
 	iflags = 0;
@@ -264,4 +266,10 @@
                         hard_link_files_when_possible = 0;
                         break;
+		case 267:
+			dos2unix = 1;
+			break;
+		case 268:
+			dos2unix = -1;
+			break;
 		case '?':
 		default:
@@ -280,4 +288,16 @@
 	if (argc == 0 || (argc == 1 && !dodir))
 		return usage(stderr);
+
+	/*   and unix2dos doesn't combine well with a couple of other options. */
+	if (dos2unix != 0) {
+		if (docompare) {
+			warnx("-C/-p and --dos2unix/unix2dos may not be specified together");
+			return usage(stderr);
+		}
+		if (dostrip) {
+			warnx("-s and --dos2unix/unix2dos may not be specified together");
+			return usage(stderr);
+		}
+	}
 
 	/* need to make a temp copy so we can compare stripped version */
@@ -478,4 +498,8 @@
 		} else if (gid != (gid_t)-1 && gid != from_sb.st_gid) {
 			why_not = "gid mismatch";
+		} else if (dos2unix > 0 && needs_dos2unix_conversion(from_name)) {
+			why_not = "dos2unix";
+		} else if (dos2unix < 0 && needs_unix2dos_conversion(from_name)) {
+			why_not = "unix2dos";
 		} else {
 			int rcLink = link(from_name, to_name);
@@ -544,6 +568,5 @@
 		}
 		if (!devnull) {
-			rc = copy(from_fd, from_name, to_fd,
-			          tempcopy ? tempfile : to_name, from_sb.st_size);
+			rc = copy(from_fd, from_name, &to_fd, tempcopy ? tempfile : to_name);
 			if (rc)
     				goto l_done;
@@ -880,16 +903,41 @@
 
 /*
+ * Write error handler.
+ */
+static int write_error(int *ptr_to_fd, const char *to_name, int nw)
+{
+    int serrno = errno;
+    (void)close(*ptr_to_fd);
+    *ptr_to_fd = -1;
+    (void)unlink(to_name);
+    errno = nw > 0 ? EIO : serrno;
+    return err(EX_OSERR, "%s", to_name);
+}
+
+/*
+ * Read error handler.
+ */
+static int read_error(const char *from_name, int *ptr_to_fd, const char *to_name)
+{
+    int serrno = errno;
+    (void)close(*ptr_to_fd);
+    *ptr_to_fd = -1;
+    (void)unlink(to_name);
+    errno = serrno;
+    return err(EX_OSERR, "%s", from_name);
+}
+
+/*
  * copy --
  *	copy from one file to another
  */
 static int
-copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
-    off_t size)
-{
+copy(int from_fd, const char *from_name, int *ptr_to_fd, const char *to_name)
+{
+	KBOOL fPendingCr = K_FALSE;
+	KSIZE cchDst;
 	int nr, nw;
-	int serrno;
 	char buf[MAXBSIZE];
-
-	(void)size;
+	int to_fd = *ptr_to_fd;
 
 	/* Rewind file descriptors. */
@@ -899,18 +947,61 @@
 		return err(EX_OSERR, "lseek: %s", to_name);
 
-	while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
-		if ((nw = write(to_fd, buf, nr)) != nr) {
-			serrno = errno;
-			(void)unlink(to_name);
-			errno = nw > 0 ? EIO : serrno;
-			return err(EX_OSERR, "%s", to_name);
-		}
-	if (nr != 0) {
-		serrno = errno;
-		(void)unlink(to_name);
-		errno = serrno;
-		return err(EX_OSERR, "%s", from_name);
-	}
-	return EX_OK;
+	if (dos2unix == 0) {
+		/*
+		 * Copy bytes, no conversion.
+		 */
+		while ((nr = read(from_fd, buf, sizeof(buf))) > 0)
+			if ((nw = write(to_fd, buf, nr)) != nr)
+				return write_error(ptr_to_fd, to_name, nw);
+	} else if (dos2unix > 0) {
+		/*
+		 * CRLF -> LF is a reduction, so we can work with full buffers.
+		 */
+		while ((nr = read(from_fd, buf, sizeof(buf))) > 0) {
+			if (   fPendingCr
+				&& buf[0] != '\n'
+				&& (nw = write(to_fd, "\r", 1)) != 1)
+				return write_error(ptr_to_fd, to_name, nw);
+
+			fPendingCr = dos2unix_convert_to_unix(buf, nr, buf, &cchDst);
+
+			nw = write(to_fd, buf, cchDst);
+			if (nw != (int)cchDst)
+				return write_error(ptr_to_fd, to_name, nw);
+		}
+	} else {
+		/*
+		 * LF -> CRLF is an expansion, so we work with half buffers, reading
+		 * into the upper half of the buffer and expanding into the full buffer.
+		 * The conversion will never expand to more than the double size.
+		 *
+		 * Note! We do not convert valid CRLF line endings.  This gives us
+		 *       valid DOS text, but no round-trip conversion.
+		 */
+		char * const pchSrc = &buf[sizeof(buf) / 2];
+		while ((nr = read(from_fd, pchSrc, sizeof(buf) / 2)) > 0) {
+			if (   fPendingCr
+				&& pchSrc[0] != '\n'
+				&& (nw = write(to_fd, "\r", 1))!= 1)
+				return write_error(ptr_to_fd, to_name, nw);
+
+			fPendingCr = dos2unix_convert_to_dos(pchSrc, nr, buf, &cchDst);
+
+			nw = write(to_fd, buf, cchDst);
+			if (nw != (int)cchDst)
+				return write_error(ptr_to_fd, to_name, nw);
+		}
+	}
+
+	/* Check for read error. */
+	if (nr != 0)
+		return read_error(from_name, ptr_to_fd, to_name);
+
+	/* When converting, we might have a pending final CR to write. */
+    if (   fPendingCr
+		&& (nw = write(to_fd, "\r", 1))!= 1)
+		return write_error(ptr_to_fd, to_name, nw);
+
+    return EX_OK;
 }
 
@@ -1009,6 +1100,6 @@
 	fprintf(pf,
 "usage: %s [-bCcpSsv] [--[no-]hard-link-files-when-possible]\n"
-"            [--[no-]ignore-perm-errors] [-B suffix] [-f flags]\n"
-"            [-g group] [-m mode] [-o owner] file1 file2\n"
+"            [--[no-]ignore-perm-errors] [-B suffix] [-f flags] [-g group]\n"
+"            [-m mode] [-o owner] [--dos2unix|--unix2dos] file1 file2\n"
 "   or: %s [-bCcpSsv] [--[no-]ignore-perm-errors] [-B suffix] [-f flags]\n"
 "            [-g group] [-m mode] [-o owner] file1 ... fileN directory\n"
@@ -1044,2 +1135,30 @@
 }
 
+/**
+ * Checks if @a pszFilename actually needs dos2unix conversion.
+ *
+ * @returns boolean.
+ * @param	pszFilename		The name of the file to check.
+ */
+static KBOOL needs_dos2unix_conversion(const char *pszFilename)
+{
+	KU32 fStyle = 0;
+	int iErr = dos2unix_analyze_file(pszFilename, &fStyle, NULL, NULL);
+	return iErr != 0
+		|| (fStyle & (DOS2UNIX_STYLE_MASK | DOS2UNIX_F_BINARY)) != DOS2UNIX_STYLE_UNIX;
+}
+
+/**
+ * Checks if @a pszFilename actually needs unix2dos conversion.
+ *
+ * @returns boolean.
+ * @param	pszFilename		The name of the file to check.
+ */
+static KBOOL needs_unix2dos_conversion(const char *pszFilename)
+{
+	KU32 fStyle = 0;
+	int iErr = dos2unix_analyze_file(pszFilename, &fStyle, NULL, NULL);
+	return iErr != 0
+		|| (fStyle & (DOS2UNIX_STYLE_MASK | DOS2UNIX_F_BINARY)) != DOS2UNIX_STYLE_DOS;
+}
+
Index: trunk/src/kmk/main.c
===================================================================
--- trunk/src/kmk/main.c	(revision 3112)
+++ trunk/src/kmk/main.c	(revision 3114)
@@ -1414,9 +1414,16 @@
 # endif /* !ELECTRIC_HEAP */
 
+# ifdef KMK
+  /* Clear the SEM_NOGPFAULTERRORBOX flag so WER will generate dumps when we run
+     under cygwin.  To void popups, set WER registry value DontShowUI to 1. */
+  if (getenv("KMK_NO_SET_ERROR_MODE") == NULL)
+    SetErrorMode(GetErrorMode() & ~SEM_NOGPFAULTERRORBOX);
+# endif
+
   /* start off assuming we have no shell */
   unixy_shell = 0;
   no_default_sh_exe = 1;
 #endif
-# ifdef CONFIG_WITH_FAST_IS_SPACE /* bird */
+#ifdef CONFIG_WITH_FAST_IS_SPACE /* bird */
   memset (space_map, '\0', sizeof(space_map));
   set_space_map_entry (' ');
@@ -1426,5 +1433,5 @@
   set_space_map_entry ('\t');
   set_space_map_entry ('\v');
-# endif /* CONFIG_WITH_FAST_IS_SPACE */
+#endif /* CONFIG_WITH_FAST_IS_SPACE */
 
 #ifdef CONFIG_WITH_PRINT_TIME_SWITCH
Index: trunk/src/lib/Makefile.kmk
===================================================================
--- trunk/src/lib/Makefile.kmk	(revision 3112)
+++ trunk/src/lib/Makefile.kmk	(revision 3114)
@@ -41,4 +41,5 @@
 	maybe_con_write.c \
 	maybe_con_fwrite.c \
+       dos2unix.c \
 	kbuild_version.c
 kUtil_SOURCES.win = \
Index: trunk/src/lib/dos2unix.c
===================================================================
--- trunk/src/lib/dos2unix.c	(revision 3114)
+++ trunk/src/lib/dos2unix.c	(revision 3114)
@@ -0,0 +1,302 @@
+/* $Id$ */
+/** @file
+ * dos2unix - Line ending conversion routines.
+ */
+
+/*
+ * Copyright (c) 2017 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Alternatively, the content of this file may be used under the terms of the
+ * GPL version 2 or later, or LGPL version 2.1 or later.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "dos2unix.h"
+#include <k/kDefs.h>
+#include <errno.h>
+#include <fcntl.h>
+#if K_OS == K_OS_WINDOWS
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+#include <assert.h>
+
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY   _O_BINARY
+# else
+#  define O_BINARY   0
+# endif
+#endif
+
+
+/*********************************************************************************************************************************
+*   Defined Constants And Macros                                                                                                 *
+*********************************************************************************************************************************/
+#define STACK_BUF_SIZE  0x20000
+
+#define DOS2UNIX_LF     0x0a
+#define DOS2UNIX_CR     0x0d
+
+
+
+/**
+ * Does a line ending analysis of the given file.
+ *
+ * @returns 0 on success, errno value on open or read error.
+ * @param   pszFilename         The path to the file
+ * @param   pfStyle             Where to return the DOS2UNIX_STYLE_XXX and
+ *                              DOS2UNIX_F_XXX flags.
+ * @param   pcDosEols           Where to return the number of DOS end-of-line
+ *                              sequences found.  Optional.
+ * @param   pcUnixEols          Where to return the number of UNIX end-of-line
+ *                              sequences found.
+ */
+int dos2unix_analyze_file(const char *pszFilename, KU32 *pfStyle, KSIZE *pcDosEols, KSIZE *pcUnixEols)
+{
+    int iRet = 0;
+    int fd = open(pszFilename, O_RDONLY | O_BINARY);
+    if (fd >= 0)
+    {
+        iRet = dos2unix_analyze_fd(fd, pfStyle, pcDosEols, pcUnixEols);
+        close(fd);
+    }
+    else
+    {
+        iRet = errno;
+        *pfStyle = DOS2UNIX_STYLE_NONE;
+        if (pcUnixEols)
+            *pcUnixEols = 0;
+        if (pcDosEols)
+            *pcDosEols = 0;
+    }
+    return iRet;
+}
+
+/**
+ * Does a line ending analysis of the given file descriptor.
+ *
+ * @returns 0 on success, errno value on open or read error.
+ * @param   fd                  The file descriptor to analyze.  Caller must
+ *                              place this as the desired position.
+ * @param   pfStyle             Where to return the DOS2UNIX_STYLE_XXX and
+ *                              DOS2UNIX_F_XXX flags.
+ * @param   pcDosEols           Where to return the number of DOS end-of-line
+ *                              sequences found.  Optional.
+ * @param   pcUnixEols          Where to return the number of UNIX end-of-line
+ *                              sequences found.
+ */
+int dos2unix_analyze_fd(int fd, KU32 *pfStyle, KSIZE *pcDosEols, KSIZE *pcUnixEols)
+{
+    KSIZE   cUnixEols  = 0;
+    KSIZE   cDosEols   = 0;
+    KSIZE   cLoneCrs   = 0;
+    KBOOL   fPendingCr = K_FALSE;
+    int     iRet       = 0;
+
+    /*
+     * Do the analysis.
+     */
+    *pfStyle = DOS2UNIX_STYLE_NONE;
+    for (;;)
+    {
+        char achBuf[STACK_BUF_SIZE];
+        int  cchRead = read(fd, achBuf, sizeof(achBuf));
+        if (cchRead > 0)
+        {
+            int off = 0;
+            if (fPendingCr)
+            {
+                if (achBuf[0] == DOS2UNIX_LF)
+                {
+                    off++;
+                    cDosEols++;
+                }
+                else
+                    cLoneCrs++;
+                fPendingCr = K_FALSE;
+            }
+
+            while (off < cchRead)
+            {
+                char ch = achBuf[off++];
+                if ((unsigned char)ch > (unsigned char)DOS2UNIX_CR)
+                { /* likely */ }
+                else if (ch == DOS2UNIX_CR)
+                {
+                    if (off < cchRead && achBuf[off] == DOS2UNIX_CR)
+                        cDosEols++;
+                    else
+                    {
+                        fPendingCr = K_TRUE;
+                        while (off < cchRead)
+                        {
+                            ch = achBuf[off++];
+                            if (ch != DOS2UNIX_CR)
+                            {
+                                if (ch == DOS2UNIX_LF)
+                                    cDosEols++;
+                                else
+                                    cLoneCrs++;
+                                fPendingCr = K_FALSE;
+                                break;
+                            }
+                            cLoneCrs++;
+                        }
+                    }
+                }
+                else if (ch == DOS2UNIX_LF)
+                    cUnixEols++;
+                else if (ch == '\0')
+                    *pfStyle |= DOS2UNIX_F_BINARY;
+            }
+        }
+        else
+        {
+            if (cchRead < 0)
+                iRet = errno;
+            if (fPendingCr)
+                cLoneCrs++;
+            break;
+        }
+    }
+
+    /*
+     * Set return values.
+     */
+    if (cUnixEols > 0 && cDosEols == 0)
+        *pfStyle |= DOS2UNIX_STYLE_UNIX;
+    else if (cDosEols > 0 && cUnixEols == 0)
+        *pfStyle |= DOS2UNIX_STYLE_DOS;
+    else if (cDosEols != 0 && cUnixEols != 0)
+        *pfStyle |= DOS2UNIX_STYLE_MIXED;
+    if (pcUnixEols)
+        *pcUnixEols = cUnixEols;
+    if (pcDosEols)
+        *pcDosEols = cDosEols;
+
+    return iRet;
+}
+
+
+/**
+ * Converts a buffer to unix line (LF) endings.
+ *
+ * @retval  K_TRUE if pending CR.  The caller must handle this case.
+ * @retval  K_FALSE if no pending CR.
+ *
+ * @param   pchSrc          The input buffer.
+ * @param   cchSrc          Number of characters to convert from the input
+ *                          buffer.
+ * @param   pchDst          The output buffer.  This must be at least as big as
+ *                          the input.  It is okay if this overlaps with the
+ *                          source buffer, as long as this is at the same or a
+ *                          lower address.
+ * @param   pcchDst         Where to return the number of characters in the
+ *                          output buffer.
+ */
+KBOOL dos2unix_convert_to_unix(const char *pchSrc, KSIZE cchSrc, char *pchDst, KSIZE *pcchDst)
+{
+    KSIZE offDst = 0;
+    while (cchSrc-- > 0)
+    {
+        char ch = *pchSrc++;
+        if ((unsigned char)ch != (unsigned char)DOS2UNIX_CR)
+            pchDst[offDst++] = ch;
+        else if (cchSrc > 0 && *pchSrc == DOS2UNIX_LF)
+        {
+            pchDst[offDst++] = DOS2UNIX_LF;
+            cchSrc--;
+            pchSrc++;
+        }
+        else if (cchSrc == 0)
+        {
+            *pcchDst = offDst;
+            return K_TRUE;
+        }
+        else
+            pchDst[offDst++] = ch;
+    }
+
+    *pcchDst = offDst;
+    return K_FALSE;
+}
+
+
+/**
+ * Converts a buffer to DOS (CRLF) endings.
+ *
+ * @retval  K_TRUE if pending CR.  The caller must handle this case.
+ * @retval  K_FALSE if no pending CR.
+ *
+ * @param   pchSrc          The input buffer.
+ * @param   cchSrc          Number of characters to convert from the input
+ *                          buffer.
+ * @param   pchDst          The output buffer.  This must be at least _twice_ as
+ *                          big as the input.  It is okay if the top half of the
+ *                          buffer overlaps with the source buffer.
+ * @param   pcchDst         Where to return the number of characters in the
+ *                          output buffer.
+ */
+KBOOL dos2unix_convert_to_dos(const char *pchSrc, KSIZE cchSrc, char *pchDst, KSIZE *pcchDst)
+{
+    KSIZE offDst = 0;
+    while (cchSrc-- > 0)
+    {
+        char ch = *pchSrc++;
+        if ((unsigned char)ch > (unsigned char)DOS2UNIX_CR)
+            pchDst[offDst++] = ch;
+        else if (ch == DOS2UNIX_CR)
+        {
+            /* We treat CR kind of like an escape character. */
+            do
+            {
+                if (cchSrc > 0)
+                {
+                    pchDst[offDst++] = ch;
+                    cchSrc--;
+                    ch = *pchSrc++;
+                }
+                else
+                {
+                    *pcchDst = offDst;
+                    return K_TRUE;
+                }
+            } while (ch == DOS2UNIX_CR);
+            pchDst[offDst++] = ch;
+        }
+        else if (ch == DOS2UNIX_LF)
+        {
+            pchDst[offDst++] = DOS2UNIX_CR;
+            pchDst[offDst++] = DOS2UNIX_LF;
+        }
+        else
+            pchDst[offDst++] = ch;
+    }
+
+    *pcchDst = offDst;
+    return K_FALSE;
+}
+
Index: trunk/src/lib/dos2unix.h
===================================================================
--- trunk/src/lib/dos2unix.h	(revision 3114)
+++ trunk/src/lib/dos2unix.h	(revision 3114)
@@ -0,0 +1,50 @@
+/* $Id$ */
+/** @file
+ * dos2unix - Line ending conversion routines.
+ */
+
+/*
+ * Copyright (c) 2017 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Alternatively, the content of this file may be used under the terms of the
+ * GPL version 2 or later, or LGPL version 2.1 or later.
+ */
+
+#ifndef ___lib_dos2unix_h___
+#define ___lib_dos2unix_h___
+
+#include <k/kTypes.h>
+
+#define DOS2UNIX_STYLE_NONE     0x00
+#define DOS2UNIX_STYLE_DOS      0x01
+#define DOS2UNIX_STYLE_UNIX     0x02
+#define DOS2UNIX_STYLE_MIXED    0x03
+#define DOS2UNIX_STYLE_MASK     0x03
+#define DOS2UNIX_F_BINARY       0x80 /**< Probably a binary file. */
+
+int dos2unix_analyze_file(const char *pszFilename, KU32 *pfStyle, KSIZE *pcDosEols, KSIZE *pcUnixEols);
+int dos2unix_analyze_fd(int fd, KU32 *pfStyle, KSIZE *pcDosEols, KSIZE *pcUnixEols);
+
+KBOOL dos2unix_convert_to_unix(const char *pchSrc, KSIZE cchSrc, char *pchDst, KSIZE *pcchDst);
+KBOOL dos2unix_convert_to_dos(const char *pchSrc, KSIZE cchSrc, char *pchDst, KSIZE *pcchDst);
+
+#endif
+
Index: trunk/src/lib/kDep.c
===================================================================
--- trunk/src/lib/kDep.c	(revision 3112)
+++ trunk/src/lib/kDep.c	(revision 3114)
@@ -69,5 +69,5 @@
 /* For the GNU/hurd weirdo. */
 #if !defined(PATH_MAX) && !defined(_MAX_PATH)
-# define PATH_MAX 2048
+# define PATH_MAX 4096
 #endif
 
Index: trunk/src/lib/testcase/dos-text.txt
===================================================================
--- trunk/src/lib/testcase/dos-text.txt	(revision 3114)
+++ trunk/src/lib/testcase/dos-text.txt	(revision 3114)
@@ -0,0 +1,35 @@
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+Aenean commodo ligula eget dolor. Aenean massa. Cum sociis
+natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec
+quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat
+massa quis enim. Donec pede justo, fringilla vel, aliquet nec,
+vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
+a,
+venenatis
+vitae, justo. Nullam dictum
+felis eu pede mollis pretium. Integer tincidunt. Cras dapibus.
+Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo
+ligula, porttitor eu, consequat vitae, eleifend ac, enim.
+
+Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra
+
+
+nulla ut metus varius
+ laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
+
+
+   Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
+	eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.
+Nam 		quam nunc, blandit vel,
+	luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
+	tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis
+	ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla
+
+
+
+
+mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales,
+augue
+velit
+cursus
+nunc,
Index: trunk/src/lib/testcase/dos2unix-test.cmd
===================================================================
--- trunk/src/lib/testcase/dos2unix-test.cmd	(revision 3114)
+++ trunk/src/lib/testcase/dos2unix-test.cmd	(revision 3114)
@@ -0,0 +1,46 @@
+@setlocal
+
+@set INSPROG="E:\kBuild\svn\trunk\out\win.amd64\debug\stage\kBuild\bin\win.amd64\kmk_install.exe"
+@set TMPFILE="e:\tmp\tmp.txt"
+@set CMPPROG="E:\kBuild\svn\trunk\kBuild\bin\win.amd64\kmk_cmp.exe"
+@set RMPROG="E:\kBuild\svn\trunk\kBuild\bin\win.amd64\kmk_rm.exe"
+
+@%RMPROG% -f -- %TMPFILE%
+
+@echo ... dos2unix ...
+%INSPROG% --dos2unix dos-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% unix-text.txt
+@if not errorlevel 0 goto end
+
+%INSPROG% --dos2unix unix-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% unix-text.txt
+@if not errorlevel 0 goto end
+
+%INSPROG% --dos2unix mixed-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% unix-text.txt
+@if not errorlevel 0 goto end
+
+@echo ... unix2dos ...
+%INSPROG% --unix2dos unix-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% dos-text.txt
+@if not errorlevel 0 goto end
+
+%INSPROG% --unix2dos dos-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% dos-text.txt
+@if not errorlevel 0 goto end
+
+%INSPROG% --unix2dos mixed-text.txt %TMPFILE%
+@if not errorlevel 0 goto end
+%CMPPROG% -- %TMPFILE% dos-text.txt
+@if not errorlevel 0 goto end
+
+
+@%RMPROG% -f -- %TMPFILE%
+:end
+@endlocal
+
Index: trunk/src/lib/testcase/mixed-text.txt
===================================================================
--- trunk/src/lib/testcase/mixed-text.txt	(revision 3114)
+++ trunk/src/lib/testcase/mixed-text.txt	(revision 3114)
@@ -0,0 +1,35 @@
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+Aenean commodo ligula eget dolor. Aenean massa. Cum sociis
+natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec
+quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat
+massa quis enim. Donec pede justo, fringilla vel, aliquet nec,
+vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
+a,
+venenatis
+vitae, justo. Nullam dictum
+felis eu pede mollis pretium. Integer tincidunt. Cras dapibus.
+Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo
+ligula, porttitor eu, consequat vitae, eleifend ac, enim.
+
+Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra
+
+
+nulla ut metus varius
+ laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
+
+
+   Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
+	eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.
+Nam 		quam nunc, blandit vel,
+	luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
+	tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis
+	ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla
+
+
+
+
+mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales,
+augue
+velit
+cursus
+nunc,
Index: trunk/src/lib/testcase/unix-text.txt
===================================================================
--- trunk/src/lib/testcase/unix-text.txt	(revision 3114)
+++ trunk/src/lib/testcase/unix-text.txt	(revision 3114)
@@ -0,0 +1,35 @@
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+Aenean commodo ligula eget dolor. Aenean massa. Cum sociis
+natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec
+quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat
+massa quis enim. Donec pede justo, fringilla vel, aliquet nec,
+vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
+a,
+venenatis
+vitae, justo. Nullam dictum
+felis eu pede mollis pretium. Integer tincidunt. Cras dapibus.
+Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo
+ligula, porttitor eu, consequat vitae, eleifend ac, enim.
+
+Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra
+
+
+nulla ut metus varius
+ laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
+
+
+   Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
+	eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum.
+Nam 		quam nunc, blandit vel,
+	luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
+	tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis
+	ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla
+
+
+
+
+mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales,
+augue
+velit
+cursus
+nunc,
