From d60192bbfe69cb3d8e36afaf459f72bb9fa4d288 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 30 Dec 2011 22:44:49 +0000 Subject: [PATCH] -LRN: utf8-ization, #2051 --- src/fs/fs_file_information.c | 14 ++++++++ src/util/disk.c | 52 +++++++++++++++++++-------- src/util/os_installation.c | 18 ++++++---- src/util/os_priority.c | 19 ++++++---- src/util/test_container_bloomfilter.c | 2 +- 5 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 4ea264892..c2ab84ec2 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c @@ -173,10 +173,17 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h, #endif while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR))) fn = ss + 1; +#if !WINDOWS GNUNET_CONTAINER_meta_data_insert (ret->meta, "", EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METAFORMAT_C_STRING, "text/plain", fn, strlen (fn) + 1); +#else + GNUNET_CONTAINER_meta_data_insert (ret->meta, "", + EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", fn, strlen (fn) + 1); +#endif return ret; } @@ -770,10 +777,17 @@ GNUNET_FS_file_information_create_from_directory (struct GNUNET_FS_Handle *h, while ((NULL != (ss = strstr (fn, DIR_SEPARATOR_STR))) && (strlen (ss) > 1)) fn = ss + 1; GNUNET_asprintf (&dn, "%s/", fn); +#if !WINDOWS GNUNET_CONTAINER_meta_data_insert (ret->meta, "", EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, EXTRACTOR_METAFORMAT_C_STRING, "text/plain", dn, strlen (dn) + 1); +#else + GNUNET_CONTAINER_meta_data_insert (ret->meta, "", + EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, + EXTRACTOR_METAFORMAT_UTF8, + "text/plain", dn, strlen (dn) + 1); +#endif GNUNET_free (dn); ret->filename = GNUNET_strdup (filename); return ret; diff --git a/src/util/disk.c b/src/util/disk.c index 0c9093fbc..9e64a3a60 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -397,6 +397,7 @@ GNUNET_DISK_mktemp (const char *t) #endif ) { + /* FIXME: This uses system codepage on W32, not UTF-8 */ tmpdir = getenv ("TMPDIR"); tmpdir = tmpdir ? tmpdir : "/tmp"; GNUNET_asprintf (&tmpl, "%s/%s%s", tmpdir, t, "XXXXXX"); @@ -417,6 +418,9 @@ GNUNET_DISK_mktemp (const char *t) #else fn = tmpl; #endif + /* FIXME: why is this not MKSTEMP()? This function is implemented in plibc. + * It will assume that fn is UTF-8-encoded, if compiled with UTF-8 support. + */ fd = mkstemp (fn); if (fd == -1) { @@ -452,18 +456,26 @@ GNUNET_DISK_get_blocks_available (const char *part) #elif MINGW DWORD dwDummy; DWORD dwBlocks; - char szDrive[4]; + wchar_t szDrive[4]; + wchar_t wpath[MAX_PATH + 1]; char *path; path = GNUNET_STRINGS_filename_expand (part); if (path == NULL) return -1; - memcpy (szDrive, path, 3); + /* "part" was in UTF-8, and so is "path" */ + if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)) + { + GNUNET_free (path); + return -1; + } GNUNET_free (path); + wcsncpy (szDrive, wpath, 3); + GNUNET_free (wpath); szDrive[3] = 0; - if (!GetDiskFreeSpace (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy)) + if (!GetDiskFreeSpaceW (szDrive, &dwDummy, &dwDummy, &dwBlocks, &dwDummy)) { - LOG (GNUNET_ERROR_TYPE_WARNING, _("`%s' failed for drive `%s': %u\n"), + LOG (GNUNET_ERROR_TYPE_WARNING, _("`%s' failed for drive `%S': %u\n"), "GetDiskFreeSpace", szDrive, GetLastError ()); return -1; @@ -621,7 +633,11 @@ GNUNET_DISK_directory_create (const char *dir) #ifndef MINGW ret = mkdir (rdir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); /* 755 */ #else - ret = mkdir (rdir); + wchar_t wrdir[MAX_PATH + 1]; + if (ERROR_SUCCESS == plibc_conv_to_win_pathwconv(rdir, wrdir)) + ret = !CreateDirectoryW (wrdir, NULL); + else + ret = 1; #endif if ((ret != 0) && (errno != EEXIST)) { @@ -874,14 +890,14 @@ GNUNET_DISK_directory_scan (const char *dirName, { LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "opendir", dname); if (dinfo != NULL) - closedir (dinfo); + CLOSEDIR (dinfo); GNUNET_free (dname); return GNUNET_SYSERR; } name_len = 256; n_size = strlen (dname) + name_len + 2; name = GNUNET_malloc (n_size); - while ((finfo = readdir (dinfo)) != NULL) + while ((finfo = READDIR (dinfo)) != NULL) { if ((0 == strcmp (finfo->d_name, ".")) || (0 == strcmp (finfo->d_name, ".."))) @@ -903,7 +919,7 @@ GNUNET_DISK_directory_scan (const char *dirName, 0) ? "" : DIR_SEPARATOR_STR, finfo->d_name); if (GNUNET_OK != callback (callback_cls, name)) { - closedir (dinfo); + CLOSEDIR (dinfo); GNUNET_free (name); GNUNET_free (dname); return GNUNET_SYSERR; @@ -911,7 +927,7 @@ GNUNET_DISK_directory_scan (const char *dirName, } count++; } - closedir (dinfo); + CLOSEDIR (dinfo); GNUNET_free (name); GNUNET_free (dname); return count; @@ -995,12 +1011,12 @@ GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator *iter, GNUNET_assert (iter->next_name == NULL); if (can == GNUNET_YES) { - closedir (iter->directory); + CLOSEDIR (iter->directory); GNUNET_free (iter->dirname); GNUNET_free (iter); return GNUNET_SYSERR; } - while (NULL != (finfo = readdir (iter->directory))) + while (NULL != (finfo = READDIR (iter->directory))) { if ((0 == strcmp (finfo->d_name, ".")) || (0 == strcmp (finfo->d_name, ".."))) @@ -1340,6 +1356,7 @@ GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, DWORD access; DWORD disp; HANDLE h; + wchar_t wexpfn[MAX_PATH + 1]; #else int oflags; int mode; @@ -1418,10 +1435,12 @@ GNUNET_DISK_file_open (const char *fn, enum GNUNET_DISK_OpenFlags flags, disp = OPEN_EXISTING; } - /* TODO: access priviledges? */ - h = CreateFile (expfn, access, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - disp, FILE_ATTRIBUTE_NORMAL, NULL); + if (ERROR_SUCCESS == plibc_conv_to_win_pathwconv(expfn, wexpfn)) + h = CreateFileW (wexpfn, access, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + disp, FILE_ATTRIBUTE_NORMAL, NULL); + else + h = INVALID_HANDLE_VALUE; if (h == INVALID_HANDLE_VALUE) { SetErrnoFromWinError (GetLastError ()); @@ -2155,6 +2174,9 @@ GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags, LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to create an instance of named pipe `%s'\n", name); #endif + /* 1) This might work just fine with UTF-8 strings as it is. + * 2) This is only used by GNUnet itself, and only with latin names. + */ h = CreateNamedPipe (name, openMode | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0, NULL); diff --git a/src/util/os_installation.c b/src/util/os_installation.c index 6d25c5709..c0b7c8583 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -112,15 +112,19 @@ get_path_from_proc_exe () static char * get_path_from_module_filename () { - char path[4097]; - char *idx; + wchar_t path[4097]; + char upath[4097]; + wchar_t *idx; - GetModuleFileName (NULL, path, sizeof (path) - 1); - idx = path + strlen (path); - while ((idx > path) && (*idx != '\\') && (*idx != '/')) + GetModuleFileNameW (NULL, path, sizeof (path) - 1); + idx = path + wcslen (path); + while ((idx > path) && (*idx != L'\\') && (*idx != L'/')) idx--; - *idx = '\0'; - return GNUNET_strdup (path); + *idx = L'\0'; + upath[0] = '\0'; + WideCharToMultiByte (CP_UTF8, 0, path, -1, upath, 4097, NULL, NULL); + + return GNUNET_strdup (upath); } #endif diff --git a/src/util/os_priority.c b/src/util/os_priority.c index 6f5fa5007..e1f64ba0c 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -28,6 +28,7 @@ #include "gnunet_common.h" #include "gnunet_os_lib.h" #include "gnunet_scheduler_lib.h" +#include "gnunet_strings_lib.h" #include "disk.h" #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -653,7 +654,7 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, char *arg; unsigned int cmdlen; char *cmd, *idx; - STARTUPINFO start; + STARTUPINFOW start; PROCESS_INFORMATION proc; HANDLE stdin_handle; @@ -670,6 +671,7 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, char *libdir; char *ptr; char *non_const_filename; + wchar_t wpath[MAX_PATH + 1], wcmd[32768]; /* Search in prefix dir (hopefully - the directory from which * the current module was loaded), bindir and libdir, then in PATH @@ -786,8 +788,10 @@ GNUNET_OS_start_process_va (struct GNUNET_DISK_PipeHandle *pipe_stdin, GNUNET_free (our_env[0]); GNUNET_free (our_env[1]); - if (!CreateProcessA - (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, + if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath) + || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd) + || !CreateProcessW + (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); @@ -973,7 +977,7 @@ GNUNET_OS_start_process_v (const SOCKTYPE *lsocks, char **arg, **non_const_argv; unsigned int cmdlen; char *cmd, *idx; - STARTUPINFO start; + STARTUPINFOW start; PROCESS_INFORMATION proc; int argcount = 0; struct GNUNET_OS_Process *gnunet_proc = NULL; @@ -993,6 +997,7 @@ GNUNET_OS_start_process_v (const SOCKTYPE *lsocks, const struct GNUNET_DISK_FileHandle *lsocks_write_fd; HANDLE lsocks_read; HANDLE lsocks_write; + wchar_t wpath[MAX_PATH + 1], wcmd[32768]; int fail; @@ -1151,8 +1156,10 @@ GNUNET_OS_start_process_v (const SOCKTYPE *lsocks, GNUNET_free_non_null (our_env[2]); GNUNET_free_non_null (our_env[3]); - if (!CreateProcessA - (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, + if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath) + || ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd) + || !CreateProcessW + (wpath, wcmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); diff --git a/src/util/test_container_bloomfilter.c b/src/util/test_container_bloomfilter.c index aad6e99a4..f881bb367 100644 --- a/src/util/test_container_bloomfilter.c +++ b/src/util/test_container_bloomfilter.c @@ -69,7 +69,7 @@ main (int argc, char *argv[]) GNUNET_log_setup ("test-container-bloomfilter", "WARNING", NULL); GNUNET_CRYPTO_seed_weak_random (1); - if (0 == stat (TESTFILE, &sbuf)) + if (0 == STAT (TESTFILE, &sbuf)) if (0 != UNLINK (TESTFILE)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", TESTFILE); bf = GNUNET_CONTAINER_bloomfilter_load (TESTFILE, SIZE, K); -- 2.25.1