CSync: Split csync_vio_local.c

This is to make room for further improvements #880
This commit is contained in:
Markus Goetz 2015-07-13 15:48:53 +02:00
Родитель aabad22cef
Коммит cd64d3ae2c
3 изменённых файлов: 237 добавлений и 151 удалений

Просмотреть файл

@ -58,9 +58,19 @@ set(csync_SRCS
vio/csync_vio.c
vio/csync_vio_file_stat.c
vio/csync_vio_local.c
)
if (WIN32)
list(APPEND csync_SRCS
vio/csync_vio_local_win.c
)
else()
list(APPEND csync_SRCS
vio/csync_vio_local_unix.c
)
endif()
if(USE_NEON)
list(APPEND csync_SRCS
csync_owncloud.c

Просмотреть файл

@ -0,0 +1,225 @@
/*
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdio.h>
#include "c_private.h"
#include "c_lib.h"
#include "c_string.h"
#include "csync_util.h"
#include "csync_log.h"
#include "csync_vio.h"
#include "vio/csync_vio_local.h"
/*
* directory functions
*/
typedef struct dhandle_s {
DIR *dh;
char *path;
} dhandle_t;
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));
dirname = c_utf8_path_to_locale(name);
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 csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
dhandle_t *handle = NULL;
int rc = -1;
if (dhandle == NULL) {
errno = EBADF;
return -1;
}
handle = (dhandle_t *) dhandle;
rc = _tclosedir(handle->dh);
SAFE_FREE(handle->path);
SAFE_FREE(handle);
return rc;
}
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
dhandle_t *handle = NULL;
csync_vio_file_stat_t *file_stat = NULL;
handle = (dhandle_t *) dhandle;
errno = 0;
file_stat = csync_vio_file_stat_new();
if (file_stat == NULL) {
goto err;
}
file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
struct _tdirent *dirent = NULL;
dirent = _treaddir(handle->dh);
if (dirent == NULL) {
goto err;
}
file_stat->name = c_utf8_from_locale(dirent->d_name);
/* Check for availability of d_type, see manpage. */
#ifdef _DIRENT_HAVE_D_TYPE
switch (dirent->d_type) {
case DT_FIFO:
case DT_SOCK:
case DT_CHR:
case DT_BLK:
break;
case DT_DIR:
case DT_REG:
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
if (dirent->d_type == DT_DIR) {
file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
} else {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
break;
case DT_UNKNOWN:
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
default:
break;
}
#endif
return file_stat;
err:
SAFE_FREE(file_stat);
return NULL;
}
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
csync_stat_t sb;
mbchar_t *wuri = c_utf8_path_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;
}
#ifdef __APPLE__
if (sb.st_flags & UF_HIDDEN) {
buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
}
#endif
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->size = sb.st_size;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
c_free_locale_string(wuri);
return 0;
}

Просмотреть файл

@ -2,6 +2,7 @@
* libcsync -- a library to sync a directory with another
*
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2013- by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -25,9 +26,7 @@
#include <dirent.h>
#include <stdio.h>
#ifdef _WIN32
#include "windows.h"
#endif
#include "c_private.h"
#include "c_lib.h"
@ -44,13 +43,9 @@
*/
typedef struct dhandle_s {
#if defined _WIN32
WIN32_FIND_DATA ffd;
HANDLE hFind;
int firstFind;
#else
DIR *dh;
#endif
char *path;
} dhandle_t;
@ -60,7 +55,6 @@ csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
handle = c_malloc(sizeof(dhandle_t));
#ifdef _WIN32
// the file wildcard has to be attached
int len_name = strlen(name);
if( len_name ) {
@ -85,16 +79,7 @@ csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
}
handle->firstFind = 1; // Set a flag that there first fileinfo is available.
#else
dirname = c_utf8_path_to_locale(name);
handle->dh = _topendir( dirname );
if (handle->dh == NULL) {
c_free_locale_string(dirname);
SAFE_FREE(handle);
return NULL;
}
#endif
handle->path = c_strdup(name);
c_free_locale_string(dirname);
@ -111,14 +96,10 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
}
handle = (dhandle_t *) dhandle;
#ifdef _WIN32
// FindClose returns non-zero on success
if( FindClose(handle->hFind) != 0 ) {
rc = 0;
}
#else
rc = _tclosedir(handle->dh);
#endif
SAFE_FREE(handle->path);
SAFE_FREE(handle);
@ -140,7 +121,6 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
}
file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
#ifdef _WIN32
// the win32 functions get the first valid entry with the opendir
// thus we must not jump to next entry if it was the first find.
if( handle->firstFind ) {
@ -163,41 +143,6 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
} else {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
#else
struct _tdirent *dirent = NULL;
dirent = _treaddir(handle->dh);
if (dirent == NULL) {
goto err;
}
file_stat->name = c_utf8_from_locale(dirent->d_name);
/* Check for availability of d_type, see manpage. */
#ifdef _DIRENT_HAVE_D_TYPE
switch (dirent->d_type) {
case DT_FIFO:
case DT_SOCK:
case DT_CHR:
case DT_BLK:
break;
case DT_DIR:
case DT_REG:
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
if (dirent->d_type == DT_DIR) {
file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
} else {
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
}
break;
case DT_UNKNOWN:
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
default:
break;
}
#endif
#endif // non WIN32
return file_stat;
@ -207,8 +152,6 @@ err:
return NULL;
}
#ifdef _WIN32
static time_t FileTimeToUnixTime(FILETIME *filetime, DWORD *remainder)
{
long long int t = filetime->dwHighDateTime;
@ -320,95 +263,3 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
return 0;
}
#else
int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
csync_stat_t sb;
mbchar_t *wuri = c_utf8_path_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;
}
#ifdef __APPLE__
if (sb.st_flags & UF_HIDDEN) {
buf->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
}
#endif
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->size = sb.st_size;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
c_free_locale_string(wuri);
return 0;
}
#endif