static void check_csync_vio_rename_dir(void **state) { CSYNC *csync = *state; csync_stat_t sb; int rc; mbchar_t *dir = c_utf8_to_locale("test"); mbchar_t *dir2 = c_utf8_to_locale("test2"); assert_non_null(dir); assert_non_null(dir2); rc = _tmkdir(dir, MKDIR_MASK); assert_int_equal(rc, 0); rc = csync_vio_rename(csync, "test", "test2"); assert_int_equal(rc, 0); rc = _tstat(dir2, &sb); assert_int_equal(rc, 0); c_free_locale_string(dir); c_free_locale_string(dir2); }
int c_utimes(const char *uri, const struct timeval *times) { FILETIME LastAccessTime; FILETIME LastModificationTime; HANDLE hFile; mbchar_t *wuri = c_utf8_path_to_locale( uri ); if(times) { UnixTimevalToFileTime(times[0], &LastAccessTime); UnixTimevalToFileTime(times[1], &LastModificationTime); } else { GetSystemTimeAsFileTime(&LastAccessTime); GetSystemTimeAsFileTime(&LastModificationTime); } hFile=CreateFileW(wuri, FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hFile==INVALID_HANDLE_VALUE) { switch(GetLastError()) { case ERROR_FILE_NOT_FOUND: errno=ENOENT; break; case ERROR_PATH_NOT_FOUND: case ERROR_INVALID_DRIVE: errno=ENOTDIR; break; /*case ERROR_WRITE_PROTECT: //CreateFile sets ERROR_ACCESS_DENIED on read-only devices * errno=EROFS; * break;*/ case ERROR_ACCESS_DENIED: errno=EACCES; break; default: errno=ENOENT; //what other errors can occur? } return -1; } if(!SetFileTime(hFile, NULL, &LastAccessTime, &LastModificationTime)) { //can this happen? errno=ENOENT; CloseHandle(hFile); c_free_locale_string(wuri); return -1; } CloseHandle(hFile); c_free_locale_string(wuri); return 0; }
int c_mkdirs(const char *path, mode_t mode) { int tmp; csync_stat_t sb; mbchar_t *wpath = c_utf8_to_locale(path); mbchar_t *swpath = NULL; if (path == NULL) { errno = EINVAL; return -1; } if (_tstat(wpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { errno = ENOTDIR; c_free_locale_string(wpath); return -1; } } tmp = strlen(path); while(tmp > 0 && path[tmp - 1] == '/') --tmp; while(tmp > 0 && path[tmp - 1] != '/') --tmp; while(tmp > 0 && path[tmp - 1] == '/') --tmp; if (tmp > 0) { char subpath[tmp + 1]; memcpy(subpath, path, tmp); subpath[tmp] = '\0'; swpath = c_utf8_to_locale(subpath); if (_tstat(swpath, &sb) == 0) { if (! S_ISDIR(sb.st_mode)) { c_free_locale_string(swpath); c_free_locale_string(wpath); errno = ENOTDIR; return -1; } } else if (errno != ENOENT) { c_free_locale_string(wpath); c_free_locale_string(swpath); return -1; } else if (c_mkdirs(subpath, mode) < 0) { c_free_locale_string(swpath); c_free_locale_string(wpath); return -1; } } tmp = _tmkdir(wpath, mode); c_free_locale_string(swpath); c_free_locale_string(wpath); if ((tmp < 0) && (errno == EEXIST)) { return 0; } return tmp; }
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information But we still need to fetch the file ID. Possible optimisation: only fetch the file id when we need it (for new files) */ HANDLE h; BY_HANDLE_FILE_INFORMATION fileInfo; ULARGE_INTEGER FileIndex; mbchar_t *wuri = c_utf8_path_to_locale( uri ); h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS+FILE_FLAG_OPEN_REPARSE_POINT, NULL ); if( h == INVALID_HANDLE_VALUE ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "CreateFileW failed on %s", uri ); errno = GetLastError(); c_free_locale_string(wuri); return -1; } if(!GetFileInformationByHandle( h, &fileInfo ) ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_CRIT, "GetFileInformationByHandle failed on %s", uri ); errno = GetLastError(); c_free_locale_string(wuri); CloseHandle(h); return -1; } /* Get the Windows file id as an inode replacement. */ FileIndex.HighPart = fileInfo.nFileIndexHigh; FileIndex.LowPart = fileInfo.nFileIndexLow; FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF; /* printf("Index: %I64i\n", FileIndex.QuadPart); */ buf->inode = FileIndex.QuadPart; if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) { buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; } if (!(buf->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) { DWORD rem; buf->mtime = FileTimeToUnixTime(&fileInfo.ftLastWriteTime, &rem); /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */ buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; } c_free_locale_string(wuri); CloseHandle(h); return 0; }
static void check_csync_vio_utimes(void **state) { CSYNC *csync = *state; csync_stat_t sb; struct timeval times[2]; long modtime = 0; mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_FILE); int rc; rc = _tstat(file, &sb); assert_int_equal(rc, 0); modtime = sb.st_mtime + 10; times[0].tv_sec = modtime; times[0].tv_usec = 0; times[1].tv_sec = modtime; times[1].tv_usec = 0; rc = csync_vio_utimes(csync, CSYNC_TEST_FILE, times); assert_int_equal(rc, 0); rc = _tstat(file, &sb); assert_int_equal(rc, 0); assert_int_equal(modtime, sb.st_mtime); c_free_locale_string(file); }
/* This function takes a relative path, prepends it with the CSYNC_TEST_DIR * and creates each sub directory. */ static void create_dirs( const char *path ) { int rc; char *mypath = c_malloc( 2+strlen(CSYNC_TEST_DIR)+strlen(path)); *mypath = '\0'; strcat(mypath, CSYNC_TEST_DIR); strcat(mypath, "/"); strcat(mypath, path); char *p = mypath+strlen(CSYNC_TEST_DIR)+1; /* start behind the offset */ int i = 0; assert_non_null(path); while( *(p+i) ) { if( *(p+i) == '/' ) { p[i] = '\0'; mbchar_t *mb_dir = c_utf8_path_to_locale(mypath); /* wprintf(L"OOOO %ls (%ld)\n", mb_dir, strlen(mypath)); */ rc = _tmkdir(mb_dir, MKDIR_MASK); c_free_locale_string(mb_dir); assert_int_equal(rc, 0); p[i] = '/'; } i++; } SAFE_FREE(mypath); }
static void setup_testenv(void **state) { int rc; rc = wipe_testdir(); assert_int_equal(rc, 0); mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); rc = _tmkdir(dir, MKDIR_MASK); assert_int_equal(rc, 0); assert_non_null(_tgetcwd(wd_buffer, WD_BUFFER_SIZE)); rc = _tchdir(dir); assert_int_equal(rc, 0); c_free_locale_string(dir); /* --- initialize csync */ statevar *mystate = malloc( sizeof(statevar) ); mystate->result = NULL; csync_create(&(mystate->csync), "/tmp/csync1", "/tmp/csync2"); mystate->csync->replica = LOCAL_REPLICA; *state = mystate; }
static void check_logging(void **state) { int rc; csync_stat_t sb; mbchar_t *path; path = c_utf8_path_to_locale("/tmp/check_csync1/cb_called"); (void) state; /* unused */ assert_non_null(path); rc = csync_set_log_level(1); assert_int_equal(rc, 0); rc = csync_set_log_callback(check_log_callback); assert_int_equal(rc, 0); csync_log(1, __func__, "rc = %d", rc); rc = _tstat(path, &sb); c_free_locale_string(path); assert_int_equal(rc, 0); }
static void stat_local_file( csync_stat_t *sb, const char *file ) { _TCHAR *mpath = NULL; mpath = c_multibyte(file); assert_int_not_equal(_tstat(mpath, sb), -1); c_free_locale_string(mpath); assert_null(mpath); }
int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) { wchar_t *pat = NULL; wchar_t *name = NULL; BOOL match; (void) __flags; name = c_utf8_to_locale(__name); pat = c_utf8_to_locale(__pattern); match = PathMatchSpec(name, pat); c_free_locale_string(pat); c_free_locale_string(name); if(match) return 0; else return 1; }
static void check_csync_vio_mkdirs_some_exist(void **state) { CSYNC *csync = *state; csync_stat_t sb; mbchar_t *this_dir = c_utf8_to_locale("/tmp/csync_test/this"); mbchar_t *stat_dir = c_utf8_to_locale(CSYNC_TEST_DIRS); int rc; rc = _tmkdir(this_dir, MKDIR_MASK); assert_int_equal(rc, 0); rc = csync_vio_mkdirs(csync, CSYNC_TEST_DIRS, MKDIR_MASK); assert_int_equal(rc, 0); rc = _tstat(stat_dir, &sb); assert_int_equal(rc, 0); _trmdir(stat_dir); c_free_locale_string(this_dir); c_free_locale_string(stat_dir); }
int c_isdir(const char *path) { csync_stat_t sb; mbchar_t *wpath = c_utf8_to_locale(path); int re = 0; if (_tstat (wpath, &sb) == 0 && S_ISDIR(sb.st_mode)) { re = 1; } c_free_locale_string(wpath); return re; }
static void check_to_multibyte(void **state) { int rc = -1; mbchar_t *mb_string = c_utf8_path_to_locale( TESTSTRING ); mbchar_t *mb_null = c_utf8_path_to_locale( NULL ); (void) state; #ifdef _WIN32 assert_int_equal( wcscmp( LTESTSTRING, mb_string), 0 ); #else assert_string_equal(mb_string, TESTSTRING); #endif assert_true( mb_null == NULL ); assert_int_equal(rc, -1); c_free_locale_string(mb_string); c_free_locale_string(mb_null); }
static void output( const char *text ) { mbchar_t *wtext = c_utf8_string_to_locale(text); #ifdef _WIN32 wprintf(L"OOOO %ls (%ld)\n", wtext, strlen(text)); #else printf("%s\n", wtext); #endif c_free_locale_string(wtext); }
csync_vio_handle_t *csync_vio_local_opendir(const char *name) { dhandle_t *handle = NULL; mbchar_t *dirname = c_utf8_to_locale(name); handle = c_malloc(sizeof(dhandle_t)); if (handle == NULL) { c_free_locale_string(dirname); return NULL; } handle->dh = _topendir( dirname ); if (handle->dh == NULL) { c_free_locale_string(dirname); SAFE_FREE(handle); return NULL; } handle->path = c_strdup(name); c_free_locale_string(dirname); return (csync_vio_handle_t *) handle; }
int c_rename( const char *src, const char *dst ) { mbchar_t *nuri; mbchar_t *ouri; int rc; nuri = c_utf8_to_locale(dst); if (nuri == NULL) { return -1; } ouri = c_utf8_to_locale(src); if (ouri == NULL) { return -1; } #ifdef _WIN32 { BOOL ok; ok = MoveFileExW(ouri, nuri, MOVEFILE_COPY_ALLOWED + MOVEFILE_REPLACE_EXISTING + MOVEFILE_WRITE_THROUGH); if (!ok) { /* error */ rc = -1; } } #else rc = rename(ouri, nuri); #endif c_free_locale_string(nuri); c_free_locale_string(ouri); return rc; }
static void check_csync_vio_rename_file(void **state) { CSYNC *csync = *state; mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_DIR "file2.txt"); csync_stat_t sb; int rc; rc = csync_vio_rename(csync, CSYNC_TEST_FILE, CSYNC_TEST_DIR "file2.txt"); assert_int_equal(rc, 0); rc = _tstat(file, &sb); assert_int_equal(rc, 0); c_free_locale_string(file); }
static void check_csync_vio_unlink(void **state) { CSYNC *csync = *state; csync_stat_t sb; mbchar_t *file = c_utf8_to_locale(CSYNC_TEST_FILE); int rc; rc = csync_vio_unlink(csync, CSYNC_TEST_FILE); assert_int_equal(rc, 0); rc = _tstat(file, &sb); assert_int_equal(rc, -1); c_free_locale_string(file); }
static void setup_dir(void **state) { int rc; mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); setup(state); rc = _tmkdir(dir, MKDIR_MASK); c_free_locale_string(dir); assert_int_equal(rc, 0); assert_non_null(getcwd(wd_buffer, WD_BUFFER_SIZE)); rc = chdir(CSYNC_TEST_DIR); assert_int_equal(rc, 0); }
static void check_csync_vio_mkdir(void **state) { CSYNC *csync = *state; csync_stat_t sb; int rc; mbchar_t *dir = c_utf8_to_locale(CSYNC_TEST_DIR); rc = csync_vio_mkdir(csync, CSYNC_TEST_DIR, MKDIR_MASK); assert_int_equal(rc, 0); rc = _tstat(dir, &sb); assert_int_equal(rc, 0); _trmdir(dir); c_free_locale_string(dir); }
static void create_file( const char *path, const char *name, const char *content) { #ifdef _WIN32 char *filepath = c_malloc( 2+strlen(CSYNC_TEST_DIR)+strlen(path) + strlen(name) ); *filepath = '\0'; strcpy(filepath, CSYNC_TEST_DIR); strcat(filepath, "/"); strcat(filepath, path); strcat(filepath, name); DWORD dwWritten; // number of bytes written to file HANDLE hFile; mbchar_t *w_fname = c_utf8_path_to_locale(filepath); hFile=CreateFile(w_fname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); assert_int_equal( 0, hFile==INVALID_HANDLE_VALUE ); int len = strlen(content); mbchar_t *dst = NULL; dst = c_utf8_string_to_locale(content); WriteFile(hFile, dst, len * sizeof(mbchar_t), &dwWritten, 0); CloseHandle(hFile); SAFE_FREE(dst); c_free_locale_string(w_fname); #else char *filepath = c_malloc( 1+strlen(path) + strlen(name) ); *filepath = '\0'; strcpy(filepath, path); strcat(filepath, name); FILE *sink; sink = fopen(filepath,"w"); fprintf (sink, "we got: %s",content); fclose(sink); SAFE_FREE(filepath); #endif }
static void check_iconv_to_native_normalization(void **state) { mbchar_t *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_utf8_path_to_locale(in); assert_string_equal(out, exp_out); c_free_locale_string(out); assert_null(out); (void) state; /* unused */ }
static void check_csync_vio_opendir_perm(void **state) { CSYNC *csync = *state; csync_vio_handle_t *dh; int rc; mbchar_t *dir = c_utf8_path_to_locale(CSYNC_TEST_DIR); assert_non_null(dir); rc = _tmkdir(dir, (S_IWUSR|S_IXUSR)); assert_int_equal(rc, 0); dh = csync_vio_opendir(csync, CSYNC_TEST_DIR); assert_null(dh); assert_int_equal(errno, EACCES); _tchmod(dir, MKDIR_MASK); c_free_locale_string(dir); }
csync_vio_handle_t *csync_vio_local_opendir(const char *name) { dhandle_t *handle = NULL; mbchar_t *dirname = NULL; handle = c_malloc(sizeof(dhandle_t)); // the file wildcard has to be attached int len_name = strlen(name); if( len_name ) { char *h = NULL; // alloc an enough large buffer to take the name + '/*' + the closing zero. h = c_malloc(len_name+3); strncpy( h, name, 1+len_name); strncat(h, "/*", 2); dirname = c_utf8_path_to_locale(h); SAFE_FREE(h); } if( dirname ) { handle->hFind = FindFirstFile(dirname, &(handle->ffd)); } if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) { int retcode = GetLastError(); if( retcode == ERROR_FILE_NOT_FOUND ) { errno = ENOENT; } else { errno = EACCES; } SAFE_FREE(handle); return NULL; } handle->firstFind = 1; // Set a flag that there first fileinfo is available. handle->path = c_strdup(name); c_free_locale_string(dirname); return (csync_vio_handle_t *) handle; }
static int _csync_config_copy_default (const char *config) { int rc = 0; #ifdef _WIN32 /* For win32, try to copy the conf file from the directory from where the app was started. */ mbchar_t tcharbuf[MAX_PATH+1]; char *buf; int len = 0; /* Get the path from where the application was started */ len = GetModuleFileNameW(NULL, tcharbuf, MAX_PATH); if(len== 0) { rc = -1; } else { char *last_bslash; buf = c_utf8_from_locale(tcharbuf); /* cut the trailing filename off */ if ((last_bslash = strrchr(buf, '\\')) != NULL) { *last_bslash='\0'; } strncat(buf, "\\" CSYNC_CONF_FILE, MAX_PATH); if(c_copy(buf, config, 0644) < 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Could not copy /%s to %s", buf, config ); rc = -1; } c_free_locale_string(buf); } #else CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Copy %s/config/%s to %s", SYSCONFDIR, CSYNC_CONF_FILE, config); if (c_copy(SYSCONFDIR "/ocsync/" CSYNC_CONF_FILE, config, 0644) < 0) { if (c_copy(BINARYDIR "/config/" CSYNC_CONF_FILE, config, 0644) < 0) { rc = -1; } } #endif return rc; }
/* Set the hide attribute in win32. That makes it invisible in normal explorers */ static void _csync_win32_hide_file( const char *file ) { #ifdef _WIN32 mbchar_t *fileName; DWORD dwAttrs; if( !file ) return; fileName = c_utf8_to_locale( file ); dwAttrs = GetFileAttributesW(fileName); if (dwAttrs==INVALID_FILE_ATTRIBUTES) return; if (!(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributesW(fileName, dwAttrs | FILE_ATTRIBUTE_HIDDEN ); } c_free_locale_string(fileName); #else (void) file; #endif }
static void check_csync_statedb_close(void **state) { CSYNC *csync = *state; csync_stat_t sb; time_t modtime; mbchar_t *testdb = c_utf8_path_to_locale(TESTDB); int rc; /* statedb not written */ csync_statedb_load(csync, TESTDB, &csync->statedb.db); rc = _tstat(testdb, &sb); assert_int_equal(rc, 0); modtime = sb.st_mtime; rc = csync_statedb_close(csync); assert_int_equal(rc, 0); rc = _tstat(testdb, &sb); assert_int_equal(rc, 0); assert_int_equal(modtime, sb.st_mtime); csync_statedb_load(csync, TESTDB, &csync->statedb.db); rc = _tstat(testdb, &sb); assert_int_equal(rc, 0); modtime = sb.st_mtime; /* wait a sec or the modtime will be the same */ sleep(1); /* statedb written */ rc = csync_statedb_close(csync); assert_int_equal(rc, 0); rc = _tstat(testdb, &sb); assert_int_equal(rc, 0); c_free_locale_string(testdb); }
static void check_iconv_ascii(void **state) { #ifdef _WIN32 const mbchar_t *in = L"abc/ABC\\123"; // UTF-8 #else #ifdef __APPLE__ const mbchar_t *in = "abc/ABC\\123"; // UTF-8-MAC #else const mbchar_t *in = "abc/ABC\\123"; // UTF-8 #endif #endif char *out = NULL; const char *exp_out = "abc/ABC\\123"; out = c_utf8_from_locale(in); assert_string_equal(out, exp_out); c_free_locale_string(out); assert_null(out); (void) state; /* unused */ }
static void check_iconv_from_native_normalization(void **state) { char *out = NULL; #ifdef _WIN32 const mbchar_t *in = L"\x48\xc3\xa4"; // UTF-8 #else #ifdef __APPLE__ const mbchar_t *in = "\x48\x61\xcc\x88"; // UTF-8-MAC #else const mbchar_t *in = "\x48\xc3\xa4"; // UTF-8 #endif #endif const char *exp_out = "\x48\xc3\xa4"; // UTF-8 out = c_utf8_from_locale(in); assert_string_equal(out, exp_out); c_free_locale_string(out); assert_null(out); (void) state; /* unused */ }
void csync_win32_set_file_hidden( const char *file, bool h ) { #ifdef _WIN32 const mbchar_t *fileName; DWORD dwAttrs; if( !file ) return; fileName = c_utf8_to_locale( file ); dwAttrs = GetFileAttributesW(fileName); if (dwAttrs==INVALID_FILE_ATTRIBUTES) return; if (h && !(dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributesW(fileName, dwAttrs | FILE_ATTRIBUTE_HIDDEN ); } else if (!h && (dwAttrs & FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributesW(fileName, dwAttrs & ~FILE_ATTRIBUTE_HIDDEN ); } c_free_locale_string(fileName); #else (void) h; (void) file; #endif }