iconv support

This allows for files on mac to automatically be converted to UNC
This commit is contained in:
Daniel Molkentin 2012-12-07 13:02:46 +01:00
parent 82acccf333
commit 49d2fd685b
20 changed files with 377 additions and 80 deletions

View File

@ -39,6 +39,7 @@ macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source buil
include(MacroAddPlugin)
include(MacroCopyFile)
find_package(iconv)
find_package(CMocka)
if (CMOCKA_FOUND AND UNIT_TESTING)
include(AddCMockaTest)

View File

@ -1,2 +1,3 @@
option(WITH_ICONV "Build csync with iconv support" ON)
option(UNIT_TESTING "Build with unit tests" OFF)
option(MEM_NULL_TESTS "Enable NULL memory testing" OFF)

View File

@ -53,8 +53,11 @@ at LOCAL with the ones at REMOTE.\n\
--disable-statedb Disable the usage and creation of a statedb.\n\
--dry-run This runs only update detection and reconcilation.\n\
\n\
--exclude-file=<file> Add an additional exclude file\n\
--test-statedb Test creation of the statedb. Runs update\n\
--exclude-file=<file> Add an additional exclude file\n"
#ifdef WITH_ICONV
" --iconv=codec Request charset conversion of local filenames\n"
#endif
" --test-statedb Test creation of the statedb. Runs update\n\
detection.\n\
--test-update Test the update detection\n\
-?, --help Give this help list\n\
@ -68,6 +71,9 @@ static const struct option long_options[] =
{"exclude-file", required_argument, 0, 0 },
{"debug-level", required_argument, 0, 'd' },
{"disable-statedb", no_argument, 0, 0 },
#ifdef WITH_ICONV
{"iconv", required_argument, 0, 0 },
#endif
{"dry-run", no_argument, 0, 0 },
{"test-statedb", no_argument, 0, 0 },
{"conflict-copies", no_argument, 0, 'c' },
@ -82,6 +88,7 @@ struct argument_s {
char *args[2]; /* SOURCE and DESTINATION */
char *exclude_file;
int debug_level;
char *iconv;
int disable_statedb;
int create_statedb;
int update;
@ -149,7 +156,9 @@ static int parse_args(struct argument_s *csync_args, int argc, char **argv)
csync_args->reconcile = 1;
csync_args->propagate = 0;
/* printf("Argument: dry-run\n" ); */
} else if(c_streq(opt->name, "iconv")) {
csync_args->iconv = c_strdup(optarg);
/* printf("Argument: iconv\n" ); */
} else if(c_streq(opt->name, "test-statedb")) {
csync_args->create_statedb = 1;
csync_args->update = 1;
@ -158,7 +167,6 @@ static int parse_args(struct argument_s *csync_args, int argc, char **argv)
/* printf("Argument: test-statedb\n"); */
} else {
fprintf(stderr, "Argument: No idea what!\n");
}
break;
default:
@ -181,6 +189,7 @@ int main(int argc, char **argv) {
/* Default values. */
arguments.exclude_file = NULL;
arguments.debug_level = 4;
arguments.iconv = NULL;
arguments.disable_statedb = 0;
arguments.create_statedb = 0;
arguments.update = 1;
@ -227,6 +236,12 @@ int main(int argc, char **argv) {
csync_disable_statedb(csync);
}
#ifdef WITH_ICONV
if (arguments.iconv) {
csync_set_iconv_codec(arguments.iconv);
}
#endif
if(arguments.with_conflict_copys)
{
csync_enable_conflictcopys(csync);

View File

@ -0,0 +1,80 @@
# - Try to find Iconv
# Once done this will define
#
# ICONV_FOUND - system has Iconv
# ICONV_INCLUDE_DIR - the Iconv include directory
# ICONV_LIBRARIES - Link these to use Iconv
# ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const
#
include(CheckCCompilerFlag)
include(CheckCSourceCompiles)
IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
# Already in cache, be silent
SET(ICONV_FIND_QUIETLY TRUE)
ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
IF(APPLE)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h
PATHS
/opt/local/include/
NO_CMAKE_SYSTEM_PATH
)
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c
PATHS
/opt/local/lib/
NO_CMAKE_SYSTEM_PATH
)
ENDIF(APPLE)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h PATHS /opt/local/include /sw/include)
string(REGEX REPLACE "(.*)/include/?" "\\1" ICONV_INCLUDE_BASE_DIR "${ICONV_INCLUDE_DIR}")
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c HINTS "${ICONV_INCLUDE_BASE_DIR}/lib" PATHS /opt/local/lib)
IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
SET(ICONV_FOUND TRUE)
ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
IF(ICONV_FOUND)
check_c_compiler_flag("-Werror" ICONV_HAVE_WERROR)
set (CMAKE_C_FLAGS_BACKUP "${CMAKE_C_FLAGS}")
if(ICONV_HAVE_WERROR)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif(ICONV_HAVE_WERROR)
check_c_source_compiles("
#include <iconv.h>
int main(){
iconv_t conv = 0;
const char* in = 0;
size_t ilen = 0;
char* out = 0;
size_t olen = 0;
iconv(conv, &in, &ilen, &out, &olen);
return 0;
}
" ICONV_SECOND_ARGUMENT_IS_CONST )
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BACKUP}")
ENDIF(ICONV_FOUND)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
IF(ICONV_FOUND)
IF(NOT ICONV_FIND_QUIETLY)
MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}")
ENDIF(NOT ICONV_FIND_QUIETLY)
ELSE(ICONV_FOUND)
IF(Iconv_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find Iconv")
ENDIF(Iconv_FIND_REQUIRED)
ENDIF(ICONV_FOUND)
MARK_AS_ADVANCED(
ICONV_INCLUDE_DIR
ICONV_LIBRARIES
ICONV_SECOND_ARGUMENT_IS_CONST
)

View File

@ -11,6 +11,7 @@
#cmakedefine HAVE_CLOCK_GETTIME
#cmakedefine WITH_LOG4C 1
#cmakedefine WITH_ICONV 1
#cmakedefine HAVE_ARGP_H 1

View File

@ -41,6 +41,11 @@ set(CSYNC_LINK_LIBRARIES
${SQLITE3_LIBRARIES}
)
if(ICONV_FOUND AND WITH_ICONV)
list(APPEND CSYNC_PRIVATE_INCLUDE_DIRS ${ICONV_INCLUDE_DIRS})
list(APPEND CSYNC_LINK_LIBRARIES ${ICONV_LIBRARIES})
endif()
set(csync_SRCS
csync.c
csync_config.c

View File

@ -32,6 +32,10 @@
#include <sys/types.h>
#include <stdbool.h>
#ifdef WITH_ICONV
#include <iconv.h>
#endif
#include "c_lib.h"
#include "csync_private.h"
#include "csync_config.h"
@ -42,6 +46,8 @@
#include "csync_util.h"
#include "csync_misc.h"
#include "c_jhash.h"
#include "std/c_private.h"
#include "csync_update.h"
#include "csync_reconcile.h"
@ -717,6 +723,10 @@ int csync_destroy(CSYNC *ctx) {
SAFE_FREE(ctx->options.config_dir);
SAFE_FREE(ctx->statedb.file);
#ifdef WITH_ICONV
c_close_iconv();
#endif
SAFE_FREE(ctx);
SAFE_FREE(lock);
@ -1002,6 +1012,19 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
return csync_vio_set_property(ctx, key, value);
}
#ifdef WITH_ICONV
int csync_set_iconv_codec(const char *from)
{
c_close_iconv();
if (from != NULL) {
c_setup_iconv(from);
}
return 0;
}
#endif
int csync_set_progress_callback(CSYNC* ctx, csync_progress_callback cb)
{
if (ctx == NULL || cb == NULL) {

View File

@ -35,6 +35,7 @@
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <config.h>
#ifdef __cplusplus
extern "C" {
@ -462,6 +463,18 @@ int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int fi
*/
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
#ifdef WITH_ICONV
/**
* @brief Set iconv source codec for filenames.
*
* @param from Source codec.
*
* @return 0 on success, or an iconv error number.
*/
int csync_set_iconv_codec(const char *from);
#endif
/**
* @brief Get the error code from the last operation.
*
@ -469,7 +482,6 @@ int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int f
*/
CSYNC_ERROR_CODE csync_get_error(CSYNC *ctx);
/* dirty stuff from here on - EXPERIMENTAL */
/* read the information if a file is known to csync ie. if it has an entry in the database */
bool csync_file_known( char *statedb_file, const char* url );
@ -487,7 +499,6 @@ bool csync_file_known( char *statedb_file, const char* url );
*/
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
enum csync_notify_type_e { CSYNC_NOTIFY_START_DOWNLOAD, CSYNC_NOTIFY_START_UPLOAD, CSYNC_NOTIFY_PROGRESS,
CSYNC_NOTIFY_FINISHED, CSYNC_NOTFY_ERROR };

View File

@ -40,6 +40,10 @@
#include "c_private.h"
#include "csync.h"
#ifdef WITH_ICONV
#include <iconv.h>
#endif
#include "vio/csync_vio_method.h"
#include "csync_macros.h"
@ -128,6 +132,9 @@ struct csync_s {
bool local_only_mode;
bool remote_push_atomar;
int log_verbosity;
#ifdef WITH_ICONV
iconv_t iconv_cd;
#endif
} options;
struct {

View File

@ -55,7 +55,7 @@ int csync_get_statedb_exists(CSYNC *ctx) {
/* Set the hide attribute in win32. That makes it invisible in normal explorers */
static void _csync_win32_hide_file( const char *file ) {
#ifdef _WIN32
const _TCHAR *fileName;
_TCHAR *fileName;
if( !file ) return;
fileName = c_multibyte( file );

View File

@ -15,8 +15,8 @@
int c_mkdirs(const char *path, mode_t mode) {
int tmp;
csync_stat_t sb;
const _TCHAR *wpath = c_multibyte(path);
const _TCHAR *swpath = NULL;
_TCHAR *wpath = c_multibyte(path);
_TCHAR *swpath = NULL;
if (path == NULL) {
errno = EINVAL;
@ -72,8 +72,8 @@ int c_rmdirs(const char *path) {
struct _tdirent *dp;
csync_stat_t sb;
char *fname = NULL;
const _TCHAR *wfname = NULL;
const _TCHAR *wpath = c_multibyte(path);
_TCHAR *wfname = NULL;
_TCHAR *wpath = c_multibyte(path);
if ((d = _topendir(wpath)) != NULL) {
while( _tstat(wpath, &sb) == 0) {
@ -145,7 +145,7 @@ int c_rmdirs(const char *path) {
int c_isdir(const char *path) {
csync_stat_t sb;
const _TCHAR *wpath = c_multibyte(path);
_TCHAR *wpath = c_multibyte(path);
if (_tstat (wpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
return 1;

View File

@ -39,7 +39,7 @@
/* check if path is a file */
int c_isfile(const char *path) {
csync_stat_t sb;
const _TCHAR *wpath = c_multibyte(path);
_TCHAR *wpath = c_multibyte(path);
int re = _tstat(wpath, &sb);
c_free_multibyte(wpath);
@ -69,8 +69,8 @@ int c_copy(const char* src, const char *dst, mode_t mode) {
#ifdef _WIN32
if(src && dst) {
const _TCHAR *wsrc = c_multibyte(src);
const _TCHAR *wdst = c_multibyte(dst);
_TCHAR *wsrc = c_multibyte(src);
_TCHAR *wdst = c_multibyte(dst);
if (CopyFileW(wsrc, wdst, FALSE)) {
rc = 0;
}

View File

@ -31,7 +31,6 @@
#include <winbase.h>
#endif
#ifdef _WIN32
#define EDQUOT 0
#define ENODATA 0
@ -114,6 +113,13 @@ typedef char _TCHAR;
#define _trewinddir rewinddir
#endif
#ifdef WITH_ICONV
/** @internal */
int c_setup_iconv(const char* to);
/** @internal */
int c_close_iconv(void);
#endif
#endif //_C_PRIVATE_H
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */

View File

@ -20,6 +20,7 @@
* vim: ts=2 sw=2 et cindent
*/
#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
@ -39,6 +40,78 @@
#include <windows.h>
#endif
#ifdef WITH_ICONV
#include <iconv.h>
typedef struct {
iconv_t to;
iconv_t from;
} iconv_conversions;
static iconv_conversions _iconvs = { NULL, NULL };
int c_setup_iconv(const char* to) {
_iconvs.to = iconv_open(to, "UTF-8");
_iconvs.from = iconv_open("UTF-8", to);
if (_iconvs.to == (iconv_t)-1 || _iconvs.from == (iconv_t)-1)
return -1;
return 0;
}
int c_close_iconv() {
int ret_to = iconv_close(_iconvs.to);
int ret_from = iconv_close(_iconvs.from);
if (ret_to == -1 || ret_from == -1)
return -1;
_iconvs.to = (iconv_t) 0;
_iconvs.from = (iconv_t) 0;
return 0;
}
enum iconv_direction { iconv_from_native, iconv_to_native };
static char *c_iconv(const char* str, enum iconv_direction dir)
{
char *in = (char*)str;
size_t size;
size_t outsize;
char *out;
char *out_in;
size_t ret;
if (str == NULL)
return NULL;
if(_iconvs.from == NULL && _iconvs.to == NULL) {
#ifdef __APPLE__
c_setup_iconv("UTF-8-MAC");
#else
return c_strdup(str);
#endif
}
size = strlen(in);
outsize = size*2;
out = c_malloc(outsize);
out_in = out;
if (dir == iconv_to_native) {
ret = iconv(_iconvs.to, &in, &size, &out, &outsize);
} else {
ret = iconv(_iconvs.from, &in, &size, &out, &outsize);
}
assert(ret != (size_t)-1);
return out_in;
}
#endif
int c_streq(const char *a, const char *b) {
register const char *s1 = a;
register const char *s2 = b;
@ -197,9 +270,9 @@ char *c_lowercase(const char* str) {
}
/* Convert a wide multibyte String to UTF8 */
const char* c_utf8(const _TCHAR *wstr)
char* c_utf8(const _TCHAR *wstr)
{
const char *dst = NULL;
char *dst = NULL;
#ifdef _WIN32
char *mdst = NULL;
@ -214,48 +287,37 @@ const char* c_utf8(const _TCHAR *wstr)
WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
dst = mdst;
}
#else
#ifdef WITH_ICONV
dst = c_iconv(wstr, iconv_from_native);
#else
dst = wstr;
#endif
#endif
return dst;
}
/* Convert a an UTF8 string to multibyte */
const _TCHAR* c_multibyte(const char *str)
_TCHAR* c_multibyte(const char *str)
{
_TCHAR *dst = NULL;
#ifdef _WIN32
_TCHAR *wstrTo = NULL;
if(!str) return NULL;
size_t len = strlen( str );
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
if(size_needed > 0) {
int size_char = (size_needed+1)*sizeof(_TCHAR);
wstrTo = c_malloc(size_char);
memset( (void*)wstrTo, 0, size_char);
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstrTo, size_needed);
dst = c_malloc(size_char);
memset( (void*)dst, 0, size_char);
MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed);
}
return wstrTo;
#else
return str;
#ifdef WITH_ICONV
dst = c_iconv(str, iconv_to_native);
#else
dst = str;
#endif
return dst;
#endif
}
void c_free_utf8(char* buf)
{
#ifdef _WIN32
SAFE_FREE(buf);
#else
(void)buf;
#endif
}
void c_free_multibyte(const _TCHAR* buf)
{
#ifdef _WIN32
SAFE_FREE(buf);
#else
(void)buf;
#endif
}

View File

@ -34,6 +34,9 @@
#define _C_STR_H
#include "c_private.h"
#include "c_macro.h"
#include <stdlib.h>
struct c_strlist_s; typedef struct c_strlist_s c_strlist_t;
@ -146,7 +149,7 @@ char *c_lowercase(const char* str);
*
* @return The malloced converted string or NULL on error.
*/
const char* c_utf8(const _TCHAR *str);
char* c_utf8(const _TCHAR *str);
/**
* @brief Convert a utf8 encoded string to multibyte (Win32).
@ -155,7 +158,16 @@ const char* c_utf8(const _TCHAR *str);
*
* @return The malloced converted multibyte string or NULL on error.
*/
const _TCHAR* c_multibyte(const char *wstr);
_TCHAR* c_multibyte(const char *wstr);
#if defined(_WIN32) || defined(WITH_ICONV)
/**
* @brief Free buffer malloced by c_multibyte.
*
* @param buf The buffer to free.
*/
#define c_free_multibyte(x) SAFE_FREE(x)
/**
* @brief Free buffer malloced by c_utf8.
@ -163,14 +175,12 @@ const _TCHAR* c_multibyte(const char *wstr);
* @param buf The buffer to free.
*
*/
void c_free_utf8(char* buf);
#define c_free_utf8(x) SAFE_FREE(x)
#else
#define c_free_multibyte(x) (void)x
#define c_free_utf8(x) (void)x
#endif
/**
* @brief Free buffer malloced by c_multibyte.
*
* @param buf The buffer to free.
*/
void c_free_multibyte(const _TCHAR* buf);
/**
* }@

View File

@ -69,7 +69,10 @@ double c_secdiff(struct timespec clock1, struct timespec clock0) {
#ifdef HAVE_UTIMES
int c_utimes(const char *uri, const struct timeval *times) {
return utimes(uri, times);
_TCHAR *wuri = c_multibyte(uri);
int ret = utimes(wuri, times);
c_free_multibyte(wuri);
return ret;
}
#else // HAVE_UTIMES
@ -93,7 +96,7 @@ int c_utimes(const char *uri, const struct timeval *times) {
FILETIME LastAccessTime;
FILETIME LastModificationTime;
HANDLE hFile;
const _TCHAR *wuri = c_multibyte( uri );
_TCHAR *wuri = c_multibyte( uri );
if(times) {
UnixTimevalToFileTime(times[0], &LastAccessTime);

View File

@ -57,10 +57,10 @@ int csync_vio_init(CSYNC *ctx, const char *module, const char *args) {
char *err = NULL;
csync_vio_method_t *m = NULL;
csync_vio_method_init_fn init_fn;
const _TCHAR *mpath = NULL;
_TCHAR *mpath = NULL;
#ifdef _WIN32
_TCHAR tbuf[MAX_PATH];
const _TCHAR *pathBuf = NULL;
_TCHAR *pathBuf = NULL;
char *buf = NULL;
char *last_bslash = NULL;
#endif

View File

@ -47,7 +47,7 @@
csync_vio_method_handle_t *csync_vio_local_open(const char *durl, int flags, mode_t mode) {
fhandle_t *handle = NULL;
int fd = -1;
const _TCHAR *url = c_multibyte(durl);
_TCHAR *url = c_multibyte(durl);
if ((fd = _topen(url, flags, mode)) < 0) {
return NULL;
@ -69,7 +69,7 @@ csync_vio_method_handle_t *csync_vio_local_open(const char *durl, int flags, mod
csync_vio_method_handle_t *csync_vio_local_creat(const char *durl, mode_t mode) {
fhandle_t *handle = NULL;
int fd = -1;
const _TCHAR *url = c_multibyte(durl);
_TCHAR *url = c_multibyte(durl);
if(( fd = _tcreat( url, mode)) < 0) {
return NULL;
@ -159,7 +159,7 @@ typedef struct dhandle_s {
csync_vio_method_handle_t *csync_vio_local_opendir(const char *name) {
dhandle_t *handle = NULL;
const _TCHAR *dirname = c_multibyte(name);
_TCHAR *dirname = c_multibyte(name);
handle = c_malloc(sizeof(dhandle_t));
if (handle == NULL) {
return NULL;
@ -170,11 +170,7 @@ csync_vio_method_handle_t *csync_vio_local_opendir(const char *name) {
SAFE_FREE(handle);
return NULL;
}
#ifdef _WIN32
handle->path = c_utf8(dirname);
#else
handle->path = c_strdup(dirname);
#endif
return (csync_vio_method_handle_t *) handle;
}
@ -220,11 +216,7 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_method_handle_t *dhandl
goto err;
}
#ifdef _WIN32
file_stat->name = c_utf8(dirent->d_name);
#else
file_stat->name = c_strdup(dirent->d_name);
#endif
file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
#ifndef _WIN32
@ -264,7 +256,7 @@ int csync_vio_local_mkdir(const char *uri, mode_t mode) {
}
int csync_vio_local_rmdir(const char *uri) {
const _TCHAR *dirname = c_multibyte(uri);
_TCHAR *dirname = c_multibyte(uri);
int re = -1;
re = _trmdir(dirname);
@ -295,7 +287,7 @@ static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
csync_stat_t sb;
const _TCHAR *wuri = c_multibyte( uri );
_TCHAR *wuri = c_multibyte( uri );
if( _tstat(wuri, &sb) < 0) {
c_free_multibyte(wuri);
return -1;
@ -433,10 +425,10 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
}
int csync_vio_local_rename(const char *olduri, const char *newuri) {
#ifdef _WIN32
const _TCHAR *nuri = c_multibyte(newuri);
const _TCHAR *ouri = c_multibyte(olduri);
_TCHAR *nuri = c_multibyte(newuri);
_TCHAR *ouri = c_multibyte(olduri);
#ifdef _WIN32
if(ouri && nuri) {
if (MoveFileExW(ouri, nuri, MOVEFILE_COPY_ALLOWED + MOVEFILE_REPLACE_EXISTING + MOVEFILE_WRITE_THROUGH )) {
return 0;
@ -445,24 +437,23 @@ int csync_vio_local_rename(const char *olduri, const char *newuri) {
} else {
errno = ENOENT;
}
#else
return rename(ouri, nuri);
#endif
c_free_multibyte(nuri);
c_free_multibyte(ouri);
return -1;
#else
return rename(olduri, newuri);
#endif
}
int csync_vio_local_unlink(const char *uri) {
const _TCHAR *nuri = c_multibyte(uri);
_TCHAR *nuri = c_multibyte(uri);
int re = _tunlink( nuri );
c_free_multibyte(nuri);
return re;
}
int csync_vio_local_chmod(const char *uri, mode_t mode) {
const _TCHAR *nuri = c_multibyte(uri);
_TCHAR *nuri = c_multibyte(uri);
int re = -1;
re = _tchmod(nuri, mode);

View File

@ -158,10 +158,11 @@ static void teardown_toplevel_dir( void **state ) {
static void stat_local_file( csync_stat_t *sb, const char *file )
{
const _TCHAR *mpath = NULL;
_TCHAR *mpath = NULL;
mpath = c_multibyte(file);
assert_int_not_equal(_tstat(mpath, sb), -1);
c_free_multibyte(mpath);
assert_null(mpath);
}
#define BUFSIZE 4096

View File

@ -1,6 +1,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "torture.h"
@ -173,6 +174,82 @@ static void check_c_uppercase_null(void **state)
assert_null(str);
}
static void check_iconv_setup(void **state)
{
int rc = 0;
(void) state; /* unused */
#ifdef __APPLE__
rc = c_setup_iconv("UTF-8-MAC");
assert_int_equal(rc, 0);
#endif
}
static void check_iconv_teardown(void **state)
{
int rc = 0;
(void) state; /* unused */
// this must never crash
rc = c_close_iconv();
assert_int_equal(rc, 0);
}
static void check_iconv_to_native_normalization(void **state)
{
const char *out = NULL;
const char *in= "\x48\xc3\xa4"; // UTF8
#ifdef __APPLE__
const char *exp_out = "\x48\x61\xcc\x88"; // UTF-8-MAC
#else
const char *exp_out = "\x48\xc3\xa4"; // UTF8
#endif
out = c_multibyte(in);
assert_string_equal(out, exp_out);
c_free_multibyte(out);
assert_null(out);
(void) state; /* unused */
}
static void check_iconv_from_native_normalization(void **state)
{
const char *out = NULL;
#ifdef __APPLE__
const char* in = "\x48\x61\xcc\x88"; // UTF-8-MAC
#else
const char *in = "\x48\xc3\xa4"; // UTF-8
#endif
const char *exp_out = "\x48\xc3\xa4"; // UTF-8
out = c_utf8(in);
assert_string_equal(out, exp_out);
c_free_utf8(out);
assert_null(out);
(void) state; /* unused */
}
static void check_iconv_ascii(void **state)
{
const char *out = NULL;
const char* in = "abc/ABC\\123";
const char *exp_out = "abc/ABC\\123";
out = c_utf8(in);
assert_string_equal(out, exp_out);
c_free_utf8(out);
assert_null(out);
(void) state; /* unused */
}
int torture_run_tests(void)
{
const UnitTest tests[] = {
@ -189,6 +266,9 @@ int torture_run_tests(void)
unit_test(check_c_uppercase),
unit_test(check_c_uppercase_empty),
unit_test(check_c_uppercase_null),
unit_test_setup_teardown(check_iconv_ascii, check_iconv_setup, check_iconv_teardown),
unit_test_setup_teardown(check_iconv_to_native_normalization, check_iconv_setup, check_iconv_teardown),
unit_test_setup_teardown(check_iconv_from_native_normalization, check_iconv_setup, check_iconv_teardown),
};
return run_tests(tests);