diff --git a/contrib/win32/openssh/libssh.vcxproj b/contrib/win32/openssh/libssh.vcxproj
index 1205b58dc..16fff9615 100644
--- a/contrib/win32/openssh/libssh.vcxproj
+++ b/contrib/win32/openssh/libssh.vcxproj
@@ -283,7 +283,6 @@
-
true
diff --git a/contrib/win32/openssh/libssh.vcxproj.filters b/contrib/win32/openssh/libssh.vcxproj.filters
index efb660e02..1959987d5 100644
--- a/contrib/win32/openssh/libssh.vcxproj.filters
+++ b/contrib/win32/openssh/libssh.vcxproj.filters
@@ -282,9 +282,6 @@
Source Files
-
- Source Files
-
Source Files
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index 6039af70c..71c9e7a7e 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -160,6 +160,7 @@
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index 07a88fa4c..eefef7c86 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -19,6 +19,7 @@
+
diff --git a/contrib/win32/win32compat/inc/stdio.h b/contrib/win32/win32compat/inc/stdio.h
index 83aa05b27..269ece845 100644
--- a/contrib/win32/win32compat/inc/stdio.h
+++ b/contrib/win32/win32compat/inc/stdio.h
@@ -5,6 +5,12 @@
FILE* w32_fopen_utf8(const char *, const char *);
#define fopen w32_fopen_utf8
+char* w32_fgets(char *str, int n, FILE *stream);
+#define fgets w32_fgets
+
+int w32_setvbuf(FILE *stream,char *buffer, int mode, size_t size);
+#define setvbuf w32_setvbuf
+
/* stdio.h additional definitions */
#define popen _popen
#define pclose _pclose
@@ -14,4 +20,3 @@ FILE* w32_fdopen(int fd, const char *mode);
int w32_rename(const char *old_name, const char *new_name);
#define rename w32_rename
-
diff --git a/contrib/win32/win32compat/misc.c b/contrib/win32/win32compat/misc.c
index 9e87efa1b..e74dd7160 100644
--- a/contrib/win32/win32compat/misc.c
+++ b/contrib/win32/win32compat/misc.c
@@ -276,6 +276,75 @@ w32_fopen_utf8(const char *path, const char *mode)
return f;
}
+/* fgets to support Unicode input */
+char*
+ w32_fgets(char *str, int n, FILE *stream) {
+ HANDLE h = (HANDLE)_get_osfhandle(_fileno(stream));
+ wchar_t* str_w = NULL;
+ char *ret = NULL, *str_tmp = NULL;
+
+ if (h != NULL && h != INVALID_HANDLE_VALUE
+ && GetFileType(h) == FILE_TYPE_CHAR) {
+ /*
+ * read only n/4 wide chars from console
+ * each UTF-16 char may bloat upto 4 utf-8 chars when converted to utf-8
+ * so we can fit in str[n] provided as input
+ */
+ if ((str_w = malloc((n/4) * sizeof(wchar_t))) == NULL) {
+ errno = ENOMEM;
+ goto cleanup;
+ }
+ /* prepare for Unicode input */
+ _setmode(_fileno(stream), O_U16TEXT);
+ if (fgetws(str_w, n/4, stream) == NULL)
+ goto cleanup;
+ if ((str_tmp = utf16_to_utf8(str_w)) == NULL) {
+ errno = ENOMEM;
+ goto cleanup;
+ }
+ if (strlen(str_tmp) > n - 1) {
+ /* shouldn't happen. but handling in case */
+ errno = EINVAL;
+ goto cleanup;
+ }
+ memcpy(str, str_tmp, strlen(str_tmp) + 1);
+ ret = str;
+ }
+ else
+ ret = fgets(str, n, stream);
+cleanup:
+ if (str_w)
+ free(str_w);
+ if (str_tmp)
+ free(str_tmp);
+ return ret;
+}
+
+/* Account for differences between Unix's and Windows versions of setvbuf */
+int
+w32_setvbuf(FILE *stream, char *buffer, int mode, size_t size) {
+
+ /* BUG: setvbuf on console stream interferes with Unicode I/O */
+ HANDLE h = (HANDLE)_get_osfhandle(_fileno(stream));
+
+ if (h != NULL && h != INVALID_HANDLE_VALUE
+ && GetFileType(h) == FILE_TYPE_CHAR)
+ return 0;
+
+ /* BUG: setvbuf on file stream is interfering with w32_fopen */
+ /* short circuit for now*/
+ return 0;
+
+ /*
+ * if size is 0, set no buffering.
+ * Windows does not differentiate __IOLBF and _IOFBF
+ */
+ if (size == 0)
+ return setvbuf(stream, NULL, _IONBF, 0);
+ else
+ return setvbuf(stream, buffer, mode, size);
+}
+
char *
w32_programdir()
{
diff --git a/contrib/win32/win32compat/win32-utf8.c b/contrib/win32/win32compat/win32-utf8.c
new file mode 100644
index 000000000..56fa236c6
--- /dev/null
+++ b/contrib/win32/win32compat/win32-utf8.c
@@ -0,0 +1,52 @@
+/*
+ * Temporary Windows versions of functions implemented in utf8.c
+ */
+ #include
+#include
+
+int
+vfmprintf(FILE *f, const char *fmt, va_list list)
+{
+ return vfprintf(f, fmt, list);
+}
+
+int
+mprintf(const char *fmt, ...)
+{
+ int ret = 0;
+ va_list valist;
+ va_start(valist, fmt);
+ ret = vfmprintf(stdout, fmt, valist);
+ va_end(valist);
+ return ret;
+}
+
+int
+fmprintf(FILE *f, const char *fmt, ...)
+{
+ int ret = 0;
+ va_list valist;
+ va_start(valist, fmt);
+ ret = vfmprintf(f, fmt, valist);
+ va_end(valist);
+ return ret;
+}
+
+int
+snmprintf(char *buf, size_t len, int *written, const char *fmt, ...)
+{
+ int num;
+ va_list valist;
+ va_start(valist, fmt);
+ num = vsnprintf(buf, len, fmt, valist);
+ va_end(valist);
+ *written = num;
+ return 0;
+}
+
+void
+msetlocale(void)
+{
+ return;
+}
+
diff --git a/scp.c b/scp.c
index 8e734db2f..f6b9bc24c 100644
--- a/scp.c
+++ b/scp.c
@@ -1034,17 +1034,7 @@ rsource(char *name, struct stat *statp)
(void) snprintf(path, sizeof path, "D%04o %d %.1024s\n",
(u_int) (statp->st_mode & FILEMODEMASK), 0, last);
if (verbose_mode)
-#ifdef WINDOWS
- /* TODO - make fmprintf work for Windows */
- {
- printf("Entering directory: ");
- wchar_t* wtmp = utf8_to_utf16(path);
- WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
- free(wtmp);
- }
-#else /* !WINDOWS */
fmprintf(stderr, "Entering directory: %s", path);
-#endif /* !WINDOWS */
(void) atomicio(vwrite, remout, path, strlen(path));
if (response() < 0) {
closedir(dirp);
@@ -1119,17 +1109,7 @@ sink(int argc, char **argv)
} while (cp < &buf[sizeof(buf) - 1] && ch != '\n');
*cp = 0;
if (verbose_mode)
-#ifdef WINDOWS
- /* TODO - make fmprintf work for Windows */
- {
- printf("Sink: ");
- wchar_t* wtmp = utf8_to_utf16(buf);
- WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), wtmp, wcslen(wtmp), 0, 0);
- free(wtmp);
- }
-#else /* !WINDOWS */
fmprintf(stderr, "Sink: %s", buf);
-#endif /* !WINDOWS */
if (buf[0] == '\01' || buf[0] == '\02') {
if (iamremote == 0) {
diff --git a/sftp.c b/sftp.c
index 6510a0138..407703733 100644
--- a/sftp.c
+++ b/sftp.c
@@ -292,27 +292,6 @@ help(void)
"? Synonym for help\n");
}
-#ifdef WINDOWS
-/* printf version to account for utf-8 input */
-/* TODO - merge this with vfmprint */
-static void printf_utf8(char *fmt, ... ) {
- /* TODO - is 1024 sufficient */
- char buf[1024];
- int length = 0;
-
- va_list valist;
- va_start(valist, fmt);
- length = vsnprintf(buf, 1024, fmt, valist);
- va_end(valist);
-
- write(STDOUT_FILENO, buf, length);
-}
-
-/* override mprintf */
-#define mprintf(a,...) printf_utf8((a), __VA_ARGS__)
-#define printf(a,...) printf_utf8((a), __VA_ARGS__)
-#endif /* WINDOWS */
-
static void
local_do_shell(const char *args)
{
@@ -420,7 +399,7 @@ make_absolute(char *p, const char *pwd)
p = abs_str;
}
- /* convert '\\' tp '/' */
+ /* convert '\\' to '/' */
convertToForwardslash(p);
/* Append "/" if needed to the absolute windows path */
@@ -925,23 +904,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
} else
mprintf("%s\n", d[n]->longname);
} else {
-#ifdef WINDOWS
- /* cannot use printf_utf8 becuase of width specification */
- /* printf_utf8 does not account for utf-16 based argument widths */
- char *p = NULL;
- wchar_t buf[1024];
- wchar_t* wtmp = utf8_to_utf16(fname);
- swprintf(buf, 1024, L"%-*s", colspace, wtmp);
-
- if ((p = utf16_to_utf8(buf)) == NULL)
- continue;
-
- write(STDOUT_FILENO, p, strlen(p));
- free(wtmp);
- free(p);
-#else
mprintf("%-*s", colspace, fname);
-#endif
if (c >= columns) {
printf("\n");
c = 1;
@@ -1025,23 +988,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
mprintf("%s\n", lname);
free(lname);
} else {
-#ifdef WINDOWS
- /* cannot use printf_utf8 becuase of width specification */
- /* printf_utf8 does not account for utf-16 based argument widths */
- char *p = NULL;
- wchar_t buf[1024];
- wchar_t* wtmp = utf8_to_utf16(fname);
- swprintf(buf, 1024, L"%-*s", colspace, wtmp);
-
- if ((p = utf16_to_utf8(buf)) == NULL)
- continue;
-
- write(STDOUT_FILENO, p, strlen(p));
- free(wtmp);
- free(p);
-#else
mprintf("%-*s", colspace, fname);
-#endif
if (c >= columns) {
printf("\n");
c = 1;
@@ -2211,20 +2158,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
interactive = !batchmode && isatty(STDIN_FILENO);
err = 0;
-#ifdef WINDOWS
- /* Min buffer size allowed in Windows is 2*/
- setvbuf(stdout, NULL, _IOLBF, 2);
-
- /* We do this only in interactive mode as we are unable to read files with UTF8 BOM */
- if (interactive) {
- setvbuf(infile, NULL, _IOLBF, 2);
- _setmode(_fileno(stdin), O_U16TEXT); /* prepare for Unicode input */
- }
-#else /* !WINDOWS */
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
-#endif /* !WINDOWS */
-
for (;;) {
char *cp;
@@ -2232,25 +2167,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
signal(SIGINT, SIG_IGN);
if (el == NULL) {
-#ifdef WINDOWS
- /* fgets on Windows does not support Unicode input*/
- if (interactive) {
- wchar_t wcmd[2048];
- printf("sftp> ");
- if (fgetws(wcmd, sizeof(cmd)/sizeof(wchar_t), infile) == NULL) {
- printf("\n");
- break;
- }
- else {
- char *pcmd = NULL;
- if ((pcmd = utf16_to_utf8(wcmd)) == NULL)
- fatal("failed to convert input arguments");
- strcpy(cmd, pcmd);
- free(pcmd);
- }
- } else if (fgets(cmd, sizeof(cmd), infile) == NULL)
- break;
-#else /* !WINDOWS */
if (interactive)
printf("sftp> ");
if (fgets(cmd, sizeof(cmd), infile) == NULL) {
@@ -2258,7 +2174,6 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
printf("\n");
break;
}
-#endif/* !WINDOWS */
if (!interactive) { /* Echo command */
mprintf("sftp> %s", cmd);
if (strlen(cmd) > 0 &&
diff --git a/utf8.c b/utf8.c
index 1f0dc44db..6fb05bb42 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: utf8.c,v 1.4 2017/02/02 10:54:25 jsg Exp $ */
+/* $OpenBSD: utf8.c,v 1.5 2017/02/19 00:10:57 djm Exp $ */
/*
* Copyright (c) 2016 Ingo Schwarze
*
@@ -57,16 +57,11 @@ static int vasnmprintf(char **, size_t, int *, const char *, va_list);
static int
dangerous_locale(void) {
-#ifdef WINDOWS
- wchar_t loc[LOCALE_NAME_MAX_LENGTH];
- GetSystemDefaultLocaleName(loc, LOCALE_NAME_MAX_LENGTH);
- return wcscmp(loc, L"US-ASCII") && wcscmp(loc, L"UTF-8");
-#else /* !WINDOWS */
char *loc;
loc = nl_langinfo(CODESET);
- return strcmp(loc, "US-ASCII") && strcmp(loc, "UTF-8");
-#endif /* !WINDOWS */
+ return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 &&
+ strcmp(loc, "ANSI_X3.4-1968") != 0;
}
static int
@@ -337,3 +332,4 @@ msetlocale(void)
/* We can handle this locale */
setlocale(LC_CTYPE, "");
}
+