From b152b39e673a420ba957f27f1e13f763e8ad771c Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Fri, 12 Oct 2012 16:38:33 +0200 Subject: [PATCH] ownCloud: Use wide char aware file system functions. Reviewed-by: Andreas Schneider --- modules/csync_owncloud.c | 36 ++++++++++++++++++++++++++++++++---- src/std/c_dir.c | 12 +++++++----- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/modules/csync_owncloud.c b/modules/csync_owncloud.c index bfd1ba19d..49cf090a1 100644 --- a/modules/csync_owncloud.c +++ b/modules/csync_owncloud.c @@ -815,6 +815,10 @@ static csync_vio_method_handle_t *owncloud_open(const char *durl, #ifdef _WIN32 int gtp = 0; char tmpname[13]; + _TCHAR winTmp[PATH_MAX]; + const _TCHAR *winUrlMB = NULL; + const char *winTmpUtf8 = NULL; + csync_stat_t sb; #endif struct transfer_context *writeCtx = NULL; @@ -877,18 +881,37 @@ static csync_vio_method_handle_t *owncloud_open(const char *durl, /* open a temp file to store the incoming data */ #ifdef _WIN32 memset( tmpname, '\0', 13 ); - gtp = GetTempPath( PATH_MAX, getUrl ); - DEBUG_WEBDAV(("win32 tmp path: %s\n", getUrl )); + gtp = GetTempPathW( PATH_MAX, winTmp ); + winTmpUtf8 = c_utf8( winTmp ); + strcpy( getUrl, winTmpUtf8 ); + DEBUG_WEBDAV("win32 tmp path: %s", getUrl); + if ( gtp > MAX_PATH || (gtp == 0) ) { DEBUG_WEBDAV(("Failed to compute Win32 tmp path, trying /tmp\n")); strcpy( getUrl, "/tmp/"); } strcpy( tmpname, "csync.XXXXXX" ); if( c_tmpname( tmpname ) == 0 ) { + /* Set the windows file mode to Binary. */ _fmode = _O_BINARY; + /* append the tmp file name to tmp path */ strcat( getUrl, tmpname ); writeCtx->tmpFileName = c_strdup( getUrl ); - writeCtx->fd = open( writeCtx->tmpFileName, O_RDWR | O_CREAT | O_EXCL, 0600 ); + + /* Open the file finally. */ + winUrlMB = c_multibyte( getUrl ); + + /* check if the file exists by chance. */ + if( _tstat( winUrlMB, &sb ) == 0 ) { + /* the file exists. Remove it! */ + _tunlink( winUrlMB ); + } + + writeCtx->fd = _topen( winUrlMB, O_RDWR | O_CREAT | O_EXCL, 0600 ); + + /* free the extra bytes */ + c_free_multibyte( winUrlMB ); + c_free_utf8( winTmpUtf8 ); } else { writeCtx->fd = -1; } @@ -1003,6 +1026,7 @@ static int owncloud_close(csync_vio_method_handle_t *fhandle) { int rc; int ret = 0; size_t len = 0; + const _TCHAR *tmpFileName = 0; writeCtx = (struct transfer_context*) fhandle; @@ -1040,8 +1064,9 @@ static int owncloud_close(csync_vio_method_handle_t *fhandle) { if( writeCtx->fileWritten ) { DEBUG_WEBDAV(("Putting file through file cache.\n")); /* we need to go the slow way and close and open the file and read from fd. */ + tmpFileName = c_multibyte( writeCtx->tmpFileName ); - if (( writeCtx->fd = open( writeCtx->tmpFileName, O_RDONLY )) < 0) { + if (( writeCtx->fd = _topen( tmpFileName, O_RDONLY )) < 0) { errno = EIO; ret = -1; } else { @@ -1071,6 +1096,7 @@ static int owncloud_close(csync_vio_method_handle_t *fhandle) { ret = -1; } } + c_free_multibyte(tmpFileName); } else { /* all content is in the buffer. */ DEBUG_WEBDAV(("Putting file through memory cache.\n")); @@ -1113,6 +1139,7 @@ static ssize_t owncloud_read(csync_vio_method_handle_t *fhandle, void *buf, size struct transfer_context *writeCtx; size_t len = 0; csync_stat_t st; + const _TCHAR *tmpFileName; writeCtx = (struct transfer_context*) fhandle; @@ -1134,6 +1161,7 @@ static ssize_t owncloud_read(csync_vio_method_handle_t *fhandle, void *buf, size errno = EIO; return -1; } else { + c_free_multibyte(tmpFileName); if (fstat( writeCtx->fd, &st ) < 0) { DEBUG_WEBDAV(("Could not stat file %s\n", writeCtx->tmpFileName )); errno = EIO; diff --git a/src/std/c_dir.c b/src/std/c_dir.c index 4341e73fc..1514ae1ec 100644 --- a/src/std/c_dir.c +++ b/src/std/c_dir.c @@ -94,6 +94,7 @@ int c_rmdirs(const char *path) { char *fname = NULL; const _TCHAR *wfname = NULL; const _TCHAR *wpath = c_multibyte(path); + char *rd_name = NULL; if ((d = _topendir(wpath)) != NULL) { while( _tstat(wpath, &sb) == 0) { @@ -113,20 +114,20 @@ int c_rmdirs(const char *path) { while ((dp = _treaddir(d)) != NULL) { size_t len; + rd_name = c_utf8(dp->d_name); /* skip '.' and '..' */ - if (dp->d_name[0] == '.' && - (dp->d_name[1] == '\0' || - (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) { + if( c_streq( rd_name, "." ) || c_streq( rd_name, ".." ) ) { + c_free_utf8(rd_name); continue; } - len = strlen(path) + _tcslen(dp->d_name) + 2; + len = strlen(path) + strlen(rd_name) + 2; fname = c_malloc(len); if (fname == NULL) { closedir(d); return -1; } - snprintf(fname, len, "%s/%s", path, dp->d_name); + snprintf(fname, len, "%s/%s", path, rd_name); wfname = c_multibyte(fname); /* stat the file */ @@ -151,6 +152,7 @@ int c_rmdirs(const char *path) { } /* lstat */ SAFE_FREE(fname); c_free_multibyte(wfname); + c_free_utf8(rd_name); } /* readdir */ _trewinddir(d);