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_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; }
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); }
static void check_logging(void **state) { int rc; csync_stat_t sb; mbchar_t *path; path = c_utf8_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, __FUNCTION__, "rc = %d", rc); rc = _tstat(path, &sb); c_free_locale_string(path); assert_int_equal(rc, 0); }
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; }
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_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 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 setup_dir(void **state) { int rc; mbchar_t *dir = c_utf8_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 check_csync_vio_opendir_perm(void **state) { CSYNC *csync = *state; csync_vio_method_handle_t *dh; int rc; mbchar_t *dir = c_utf8_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); }
/* 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_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); }
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; }
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 }
int csync_statedb_close(const char *statedb, sqlite3 *db, int jwritten) { char *statedb_tmp = NULL; mbchar_t* wstatedb_tmp = NULL; int rc = 0; mbchar_t *mb_statedb = NULL; /* deallocate query resources */ rc = sqlite3_finalize(_by_hash_stmt); _by_hash_stmt = NULL; /* close the temporary database */ sqlite3_close(db); if (asprintf(&statedb_tmp, "%s.ctmp", statedb) < 0) { return -1; } /* If we successfully synchronized, overwrite the original statedb */ /* * Check the integrity of the tmp db. If ok, overwrite the old database with * the tmp db. */ if (jwritten) { /* statedb check returns either * 0 : database exists and is fine * 1 : new database was set up * -1 : error. */ if (_csync_statedb_check(statedb_tmp) >= 0) { /* New statedb is valid. */ mb_statedb = c_utf8_to_locale(statedb); /* Move the tmp-db to the real one. */ if (c_rename(statedb_tmp, statedb) < 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Renaming tmp db to original db failed. (errno=%d)", errno); rc = -1; } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Successfully moved tmp db to original db."); } } else { mb_statedb = c_utf8_to_locale(statedb_tmp); _tunlink(mb_statedb); /* new statedb_tmp is not integer. */ CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, " ## csync tmp statedb corrupt. Original one is not replaced. "); rc = -1; } c_free_locale_string(mb_statedb); } wstatedb_tmp = c_utf8_to_locale(statedb_tmp); if (wstatedb_tmp) { _tunlink(wstatedb_tmp); c_free_locale_string(wstatedb_tmp); } SAFE_FREE(statedb_tmp); return rc; }
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { csync_stat_t sb; mbchar_t *wuri = c_utf8_to_locale( uri ); if( _tstat(wuri, &sb) < 0) { c_free_locale_string(wuri); return -1; } buf->name = c_basename(uri); if (buf->name == NULL) { csync_vio_file_stat_destroy(buf); c_free_locale_string(wuri); return -1; } buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; switch(sb.st_mode & S_IFMT) { case S_IFBLK: buf->type = CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE; break; case S_IFCHR: buf->type = CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE; break; case S_IFDIR: buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; break; case S_IFIFO: buf->type = CSYNC_VIO_FILE_TYPE_FIFO; break; case S_IFREG: buf->type = CSYNC_VIO_FILE_TYPE_REGULAR; break; case S_IFLNK: buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; break; case S_IFSOCK: buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; break; default: buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; break; } buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; buf->mode = sb.st_mode; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MODE; if (buf->type == CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK) { /* FIXME: handle symlink */ buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; } else { buf->flags = CSYNC_VIO_FILE_FLAGS_NONE; } buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; buf->device = sb.st_dev; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE; buf->inode = sb.st_ino; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; buf->atime = sb.st_atime; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; buf->mtime = sb.st_mtime; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; buf->ctime = sb.st_ctime; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; buf->nlink = sb.st_nlink; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT; buf->size = sb.st_size; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; c_free_locale_string(wuri); return 0; }
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { HANDLE h, hFind; FILETIME ftCreate, ftAccess, ftWrite; BY_HANDLE_FILE_INFORMATION fileInfo; WIN32_FIND_DATAW FindFileData; ULARGE_INTEGER FileIndex; mbchar_t *wuri = c_utf8_to_locale( uri ); h = CreateFileW( wuri, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, 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; } buf->flags = CSYNC_VIO_FILE_FLAGS_NONE; do { // Check first if it is a symlink (code from c_islink) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { hFind = FindFirstFileW(wuri, &FindFileData ); if (hFind != INVALID_HANDLE_VALUE) { if( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && (FindFileData.dwReserved0 & IO_REPARSE_TAG_SYMLINK) ) { buf->flags = CSYNC_VIO_FILE_FLAGS_SYMLINK; buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; break; } } FindClose(hFind); } if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DEVICE || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE || fileInfo.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) { buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; break; } if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { buf->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; break; } // fallthrough: buf->type = CSYNC_VIO_FILE_TYPE_REGULAR; break; } while (0); buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; buf->device = fileInfo.dwVolumeSerialNumber; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DEVICE; /* 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; buf->size = (fileInfo.nFileSizeHigh * (int64_t)(MAXDWORD+1)) + fileInfo.nFileSizeLow; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; /* Get the file time with a win32 call rather than through stat. See * http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting * for deeper explanation. */ if( GetFileTime(h, &ftCreate, &ftAccess, &ftWrite) ) { DWORD rem; buf->atime = FileTimeToUnixTime(&ftAccess, &rem); buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; buf->mtime = FileTimeToUnixTime(&ftWrite, &rem); /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */ buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; buf->ctime = FileTimeToUnixTime(&ftCreate, &rem); buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME; } CloseHandle(h); return 0; }
int c_rmdirs(const char *path) { _TDIR *d; struct _tdirent *dp; csync_stat_t sb; char *fname = NULL; mbchar_t *wfname = NULL; mbchar_t *wpath = c_utf8_to_locale(path); char *rd_name = NULL; if ((d = _topendir(wpath)) != NULL) { while( _tstat(wpath, &sb) == 0) { /* if we can remove the directory we're done */ if (_trmdir(wpath) == 0) { break; } switch (errno) { case ENOTEMPTY: case EEXIST: case EBADF: break; /* continue */ default: _tclosedir(d); c_free_locale_string(wpath); return 0; } while ((dp = _treaddir(d)) != NULL) { size_t len; rd_name = c_utf8_from_locale(dp->d_name); /* skip '.' and '..' */ if( c_streq( rd_name, "." ) || c_streq( rd_name, ".." ) ) { c_free_locale_string(rd_name); continue; } len = strlen(path) + strlen(rd_name) + 2; fname = c_malloc(len); if (fname == NULL) { _tclosedir(d); c_free_locale_string(rd_name); c_free_locale_string(wpath); return -1; } snprintf(fname, len, "%s/%s", path, rd_name); wfname = c_utf8_to_locale(fname); /* stat the file */ if (_tstat(wfname, &sb) != -1) { #ifdef __unix__ if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { #else if (S_ISDIR(sb.st_mode)) { #endif if (_trmdir(wfname) < 0) { /* can't be deleted */ if (errno == EACCES) { _tclosedir(d); SAFE_FREE(fname); c_free_locale_string(wfname); c_free_locale_string(rd_name); c_free_locale_string(wpath); return -1; } c_rmdirs(fname); } } else { _tunlink(wfname); } } /* lstat */ SAFE_FREE(fname); c_free_locale_string(wfname); c_free_locale_string(rd_name); } /* readdir */ _trewinddir(d); } } else { c_free_locale_string(wpath); return -1; } c_free_locale_string(wpath); _tclosedir(d); return 0; }
int c_compare_file( const char *f1, const char *f2 ) { mbchar_t *wf1, *wf2; int fd1 = -1, fd2 = -1; size_t size1, size2; char buffer1[BUFFER_SIZE]; char buffer2[BUFFER_SIZE]; csync_stat_t stat1; csync_stat_t stat2; int rc = -1; if(f1 == NULL || f2 == NULL) return -1; wf1 = c_utf8_to_locale(f1); if(wf1 == NULL) { return -1; } wf2 = c_utf8_to_locale(f2); if(wf2 == NULL) { return -1; } /* compare size first. */ rc = _tstat(wf1, &stat1); if(rc< 0) { goto out; } rc = _tstat(wf2, &stat2); if(rc < 0) { goto out; } /* if sizes are different, the files can not be equal. */ if( stat1.st_size != stat2.st_size ) { rc = 0; goto out; } #ifdef _WIN32 _fmode = _O_BINARY; #endif fd1 = _topen(wf1, O_RDONLY); if(fd1 < 0) { rc = -1; goto out; } fd2 = _topen(wf2, O_RDONLY); if(fd2 < 0) { rc = -1; goto out; } while( (size1 = read(fd1, buffer1, BUFFER_SIZE)) > 0 ) { size2 = read( fd2, buffer2, BUFFER_SIZE ); if( size1 != size2 ) { rc = 0; goto out; } if(memcmp(buffer1, buffer2, size1) != 0) { /* buffers are different */ rc = 0; goto out; } } rc = 1; out: if(fd1 > -1) close(fd1); if(fd2 > -1) close(fd2); c_free_locale_string( wf1 ); c_free_locale_string( wf2 ); return rc; }
/* check if path is a file */ int c_isfile(const char *path) { csync_stat_t sb; mbchar_t *wpath = c_utf8_to_locale(path); int re = _tstat(wpath, &sb); c_free_locale_string(wpath); if (re< 0) { return 0; } #ifdef __unix__ if (S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) { #else if (S_ISREG(sb.st_mode)) { #endif return 1; } return 0; } /* copy file from src to dst, overwrites dst */ int c_copy(const char* src, const char *dst, mode_t mode) { int srcfd = -1; int dstfd = -1; int rc = -1; ssize_t bread, bwritten; csync_stat_t sb; char buf[4096]; #ifdef _WIN32 if(src && dst) { mbchar_t *wsrc = c_utf8_to_locale(src); mbchar_t *wdst = c_utf8_to_locale(dst); if (CopyFileW(wsrc, wdst, FALSE)) { rc = 0; } errno = GetLastError(); return -1; } #else /* Win32 does not come here. */ if (c_streq(src, dst)) { return -1; } if (lstat(src, &sb) < 0) { return -1; } if (S_ISDIR(sb.st_mode)) { errno = EISDIR; return -1; } if (mode == 0) { mode = sb.st_mode; } if (lstat(dst, &sb) == 0) { if (S_ISDIR(sb.st_mode)) { errno = EISDIR; return -1; } } if ((srcfd = open(src, O_RDONLY, 0)) < 0) { rc = -1; goto out; } if ((dstfd = open(dst, O_CREAT|O_WRONLY|O_TRUNC, mode)) < 0) { rc = -1; goto out; } for (;;) { bread = read(srcfd, buf, sizeof(buf)); if (bread == 0) { /* done */ break; } else if (bread < 0) { errno = ENODATA; rc = -1; goto out; } bwritten = write(dstfd, buf, bread); if (bwritten < 0) { errno = ENODATA; rc = -1; goto out; } if (bread != bwritten) { errno = EFAULT; rc = -1; goto out; } } #ifdef __unix__ fsync(dstfd); #endif rc = 0; out: if (srcfd > 0) { close(srcfd); } if (dstfd > 0) { close(dstfd); } if (rc < 0) { unlink(dst); } return rc; #endif }
int csync_exclude_load(CSYNC *ctx, const char *fname) { int fd = -1; int i = 0; int rc = -1; off_t size; char *buf = NULL; char *entry = NULL; mbchar_t *w_fname; if (ctx == NULL || fname == NULL) { return -1; } #ifdef _WIN32 _fmode = _O_BINARY; #endif w_fname = c_utf8_to_locale(fname); if (w_fname == NULL) { return -1; } fd = _topen(w_fname, O_RDONLY); c_free_locale_string(w_fname); if (fd < 0) { return -1; } size = lseek(fd, 0, SEEK_END); if (size < 0) { rc = -1; goto out; } lseek(fd, 0, SEEK_SET); if (size == 0) { rc = 0; goto out; } buf = c_malloc(size + 1); if (buf == NULL) { rc = -1; goto out; } if (read(fd, buf, size) != size) { rc = -1; goto out; } buf[size] = '\0'; /* FIXME: Use fgets and don't add duplicates */ entry = buf; for (i = 0; i < size; i++) { if (buf[i] == '\n') { if (entry != buf + i) { buf[i] = '\0'; if (*entry != '#' || *entry == '\n') { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Adding entry: %s", entry); rc = _csync_exclude_add(ctx, entry); if (rc < 0) { goto out; } } } entry = buf + i + 1; } } rc = 0; out: SAFE_FREE(buf); close(fd); return rc; }
static int _csync_statedb_check(const char *statedb) { int fd = -1, rc; ssize_t r; char buf[BUF_SIZE] = {0}; sqlite3 *db = NULL; csync_stat_t sb; mbchar_t *wstatedb = c_utf8_to_locale(statedb); if (wstatedb == NULL) { return -1; } /* check db version */ #ifdef _WIN32 _fmode = _O_BINARY; #endif fd = _topen(wstatedb, O_RDONLY); if (fd >= 0) { /* Check size. Size of zero is a valid database actually. */ rc = _tfstat(fd, &sb); if (rc == 0) { if (sb.st_size == 0) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Database size is zero byte!"); close(fd); } else { r = read(fd, (void *) buf, sizeof(buf) - 1); close(fd); if (r >= 0) { buf[BUF_SIZE - 1] = '\0'; if (c_streq(buf, "SQLite format 3")) { if (sqlite3_open(statedb, &db ) == SQLITE_OK) { rc = _csync_check_db_integrity(db); if( sqlite3_close(db) != 0 ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "WARN: sqlite3_close error!"); } if( rc >= 0 ) { /* everything is fine */ c_free_locale_string(wstatedb); return 0; } CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Integrity check failed!"); } else { /* resources need to be freed even when open failed */ sqlite3_close(db); CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "database corrupted, removing!"); } } else { CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "sqlite version mismatch"); } } } } /* if it comes here, the database is broken and should be recreated. */ _tunlink(wstatedb); } c_free_locale_string(wstatedb); /* create database */ rc = sqlite3_open(statedb, &db); if (rc == SQLITE_OK) { sqlite3_close(db); _csync_win32_hide_file(statedb); return 1; } sqlite3_close(db); CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite3_open failed: %s %s", sqlite3_errmsg(db), statedb); return -1; }