return fName;
}
+QByteArray Utility::normalizeEtag(QByteArray etag)
+{
+ /* strip "XXXX-gzip" */
+ if(etag.startsWith('"') && etag.endsWith("-gzip\"")) {
+ etag.chop(6);
+ etag.remove(0, 1);
+ }
+ /* strip trailing -gzip */
+ if(etag.endsWith("-gzip")) {
+ etag.chop(5);
+ }
+ /* strip normal quotes */
+ if (etag.startsWith('"') && etag.endsWith('"')) {
+ etag.chop(1);
+ etag.remove(0, 1);
+ }
+ etag.squeeze();
+ return etag;
+}
+
bool Utility::hasDarkSystray()
{
return hasDarkSystray_private();
OCSYNC_EXPORT QString fileNameForGuiUse(const QString &fName);
+ OCSYNC_EXPORT QByteArray normalizeEtag(QByteArray etag);
+
/**
* @brief timeAgoInWords - human readable time span
*
csync_rename.cpp
vio/csync_vio.cpp
- vio/csync_vio_file_stat.cpp
)
if (WIN32)
#include <stdint.h>
#include <sys/types.h>
#include <config_csync.h>
+#include <memory>
#include <QByteArray>
enum csync_status_codes_e {
CSYNC_STATUS_TIMESKEW, /* OBSOLETE */
CSYNC_STATUS_FILESYSTEM_UNKNOWN, /* UNUSED */
CSYNC_STATUS_TREE_ERROR, /* csync trees could not be created */
- CSYNC_STATUS_MEMORY_ERROR, /* not enough memory problem */
CSYNC_STATUS_PARAM_ERROR, /* parameter is zero where not expected */
CSYNC_STATUS_UPDATE_ERROR, /* general update or discovery error */
CSYNC_STATUS_RECONCILE_ERROR, /* general reconcile error */
// currently specified at https://github.com/owncloud/core/issues/8322 are 9 to 10
#define REMOTE_PERM_BUF_SIZE 15
-typedef struct csync_vio_file_stat_s csync_vio_file_stat_t;
-
-enum csync_vio_file_flags_e {
- CSYNC_VIO_FILE_FLAGS_NONE = 0,
- CSYNC_VIO_FILE_FLAGS_SYMLINK = 1 << 0,
- CSYNC_VIO_FILE_FLAGS_HIDDEN = 1 << 1
-};
-
-enum csync_vio_file_type_e {
- CSYNC_VIO_FILE_TYPE_UNKNOWN,
- CSYNC_VIO_FILE_TYPE_REGULAR,
- CSYNC_VIO_FILE_TYPE_DIRECTORY,
- CSYNC_VIO_FILE_TYPE_FIFO,
- CSYNC_VIO_FILE_TYPE_SOCKET,
- CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
- CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
- CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
-};
-
-enum csync_vio_file_stat_fields_e {
- CSYNC_VIO_FILE_STAT_FIELDS_NONE = 0,
- CSYNC_VIO_FILE_STAT_FIELDS_TYPE = 1 << 0,
- CSYNC_VIO_FILE_STAT_FIELDS_MODE = 1 << 1, // local POSIX mode
- CSYNC_VIO_FILE_STAT_FIELDS_FLAGS = 1 << 2,
-// CSYNC_VIO_FILE_STAT_FIELDS_DEVICE = 1 << 3,
- CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4,
-// CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5,
- CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6,
-// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */
-// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8, /* will be removed */
- CSYNC_VIO_FILE_STAT_FIELDS_ATIME = 1 << 9,
- CSYNC_VIO_FILE_STAT_FIELDS_MTIME = 1 << 10,
- CSYNC_VIO_FILE_STAT_FIELDS_CTIME = 1 << 11,
-// CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME = 1 << 12,
-// CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM = 1 << 13,
-// CSYNC_VIO_FILE_STAT_FIELDS_ACL = 1 << 14,
-// CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15,
-// CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16,
- CSYNC_VIO_FILE_STAT_FIELDS_ETAG = 1 << 17,
- CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID = 1 << 18,
- CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL = 1 << 19,
- CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES = 1 << 20,
- CSYNC_VIO_FILE_STAT_FIELDS_PERM = 1 << 21 // remote oC perm
-
-};
-
-
-struct csync_vio_file_stat_s {
- char *name;
- char *etag; // FIXME: Should this be inlined like file_id and perm?
- char file_id[FILE_ID_BUF_SIZE+1];
- char *directDownloadUrl;
- char *directDownloadCookies;
- char remotePerm[REMOTE_PERM_BUF_SIZE+1];
-
- time_t atime;
- time_t mtime;
- time_t ctime;
- int64_t size;
-
- mode_t mode;
-
- uint64_t inode;
-
- int fields; // actually enum csync_vio_file_stat_fields_e fields;
- enum csync_vio_file_type_e type;
-
- int flags;
-
- char *original_name; // only set if locale conversion fails
-
- // For remote file stats: the highest quality checksum the server provided
- // in the "SHA1:324315da2143" form.
- char *checksumHeader;
-};
-
typedef struct csync_file_stat_s csync_file_stat_t;
struct csync_file_stat_s {
enum csync_ftw_type_e type : 4;
bool child_modified : 1;
bool has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
+ bool is_hidden : 1; // Not saved in the DB, only used during discovery for local files.
QByteArray path;
QByteArray rename_path;
QByteArray directDownloadUrl;
QByteArray directDownloadCookies;
QByteArray remotePerm;
+ QByteArray original_path; // only set if locale conversion fails
// In the local tree, this can hold a checksum and its type if it is
// computed during discovery for some reason.
, type(CSYNC_FTW_TYPE_SKIP)
, child_modified(false)
, has_ignored_files(false)
+ , is_hidden(false)
, error_status(CSYNC_STATUS_OK)
, instruction(CSYNC_INSTRUCTION_NONE)
{ }
};
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
-
-void OCSYNC_EXPORT csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
-
-void OCSYNC_EXPORT csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
-
-void OCSYNC_EXPORT csync_vio_set_file_id(char* dst, const char *src );
-
-
/**
* CSync File Traversal structure.
*
typedef void csync_vio_handle_t;
typedef csync_vio_handle_t* (*csync_vio_opendir_hook) (const char *url,
void *userdata);
-typedef csync_vio_file_stat_t* (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
+typedef std::unique_ptr<csync_file_stat_t> (*csync_vio_readdir_hook) (csync_vio_handle_t *dhhandle,
void *userdata);
typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
void *userdata);
*/
int OCSYNC_EXPORT csync_abort_requested(CSYNC *ctx);
-char OCSYNC_EXPORT *csync_normalize_etag(const char *);
time_t OCSYNC_EXPORT oc_httpdate_parse( const char *date );
/**
#include "c_lib.h"
#include "c_private.h"
+#include "c_utf8.h"
#include "csync_private.h"
#include "csync_exclude.h"
return status;
}
-
-/* Remove possible quotes, and also the -gzip at the end
- * Remove "-gzip" at the end (cf. https://github.comowncloud/client/issues/1195)
- * The caller must take ownership of the resulting string.
- */
-char *csync_normalize_etag(const char *etag)
-{
- int len = 0;
- char *buf = NULL;
- if (!etag)
- return NULL;
-
- len = strlen(etag);
- /* strip "XXXX-gzip" */
- if(len >= 7 && etag[0] == '"' && c_streq(etag + len - 6, "-gzip\"")) {
- etag++;
- len -= 7;
- }
- /* strip leading -gzip */
- if(len >= 5 && c_streq(etag + len - 5, "-gzip")) {
- len -= 5;
- }
- /* strip normal quotes */
- if (etag[0] == '"' && etag[len-1] == '"') {
- etag++;
- len -= 2;
- }
-
- buf = (char*)c_malloc( len+1 );
- strncpy( buf, etag, len );
- buf[len] = '\0';
- return buf;
-}
-
#include "c_string.h"
#include "c_jhash.h"
+#include "c_utf8.h"
#include "csync_time.h"
#define CSYNC_LOG_CATEGORY_NAME "csync.statedb"
return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW;
}
-/*
- * This static method is needed because the type members of the two structs use
- * different enum values. A direct comparion is not neccessarily correct.
- *
- * tmp is csync_file_stat_t
- * fs is csync_vio_file_stat_t with this vio type:
- * enum csync_vio_file_type_e {
- * CSYNC_VIO_FILE_TYPE_UNKNOWN,
- * CSYNC_VIO_FILE_TYPE_REGULAR,
- * CSYNC_VIO_FILE_TYPE_DIRECTORY,
- * CSYNC_VIO_FILE_TYPE_FIFO,
- * CSYNC_VIO_FILE_TYPE_SOCKET,
- * CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE,
- * CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE,
- * CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK
- * };
- *
- * csync_file_stat_t can be:
- * CSYNC_FTW_TYPE_SKIP, CSYNC_FTW_TYPE_FILE
- * CSYNC_FTW_TYPE_DIR, CSYNC_FTW_TYPE_SLINK
- */
-static bool _csync_filetype_different( const csync_file_stat_t *tmp, const csync_vio_file_stat_t *fs)
-{
- if( !(tmp && fs)) return false;
-
- if( tmp->type == CSYNC_FTW_TYPE_SKIP ) return true;
-
- if( tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY )
- return true;
- if( tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR )
- return true;
- if( tmp->type == CSYNC_FTW_TYPE_SLINK && fs->type != CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK )
- return true;
-
- return false; // both are NOT different.
-}
-
/* Return true if two mtime are considered equal
* We consider mtime that are one hour difference to be equal if they are one hour appart
* because on some system (FAT) the date is changing when the daylight saving is changing */
* See doc/dev/sync-algorithm.md for an overview.
*/
static int _csync_detect_update(CSYNC *ctx, const char *file,
- const csync_vio_file_stat_t *fs, enum csync_ftw_type_e type) {
+ const csync_file_stat_t *fs, enum csync_ftw_type_e type) {
uint64_t h = 0;
const char *path = NULL;
std::unique_ptr<csync_file_stat_t> st;
* because it's a hidden file that should not be synced.
* This code should probably be in csync_exclude, but it does not have the fs parameter.
* Keep it here for now */
- if (ctx->ignore_hidden_files && (fs->flags & CSYNC_VIO_FILE_FLAGS_HIDDEN)) {
+ if (ctx->ignore_hidden_files && (fs->is_hidden)) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file excluded because it is a hidden file: %s", path);
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
}
st.reset(new csync_file_stat_t);
if (type == CSYNC_FTW_TYPE_FILE ) {
- if (fs->mtime == 0) {
+ if (fs->modtime == 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
}
}
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Database entry found, compare: %" PRId64 " <-> %" PRId64
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
- ((int64_t) fs->mtime), ((int64_t) tmp->modtime),
- fs->etag, tmp->etag.constData(), (uint64_t) fs->inode, (uint64_t) tmp->inode,
- (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm.constData(), tmp->has_ignored_files );
- if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
+ ((int64_t) fs->modtime), ((int64_t) tmp->modtime),
+ fs->etag.constData(), tmp->etag.constData(), (uint64_t) fs->inode, (uint64_t) tmp->inode,
+ (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm.constData(), tmp->remotePerm.constData(), tmp->has_ignored_files );
+ if (ctx->current == REMOTE_REPLICA && fs->etag != tmp->etag) {
st->instruction = CSYNC_INSTRUCTION_EVAL;
// Preserve the EVAL flag later on if the type has changed.
- if (_csync_filetype_different(tmp.get(), fs)) {
+ if (tmp->type != fs->type) {
st->child_modified = true;
}
goto out;
}
if (ctx->current == LOCAL_REPLICA &&
- (!_csync_mtime_equal(fs->mtime, tmp->modtime)
+ (!_csync_mtime_equal(fs->modtime, tmp->modtime)
// zero size in statedb can happen during migration
|| (tmp->size != 0 && fs->size != tmp->size))) {
}
// Preserve the EVAL flag later on if the type has changed.
- if (_csync_filetype_different(tmp.get(), fs)) {
+ if (tmp->type != fs->type) {
st->child_modified = true;
}
st->instruction = CSYNC_INSTRUCTION_EVAL;
goto out;
}
- bool metadata_differ = (ctx->current == REMOTE_REPLICA && (!c_streq(fs->file_id, tmp->file_id)
- || !c_streq(fs->remotePerm, tmp->remotePerm)))
+ bool metadata_differ = (ctx->current == REMOTE_REPLICA && (fs->file_id != tmp->file_id
+ || fs->remotePerm != tmp->remotePerm))
|| (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
if (type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
&& !metadata_differ && ctx->read_remote_from_db) {
st->instruction = CSYNC_INSTRUCTION_NONE;
}
} else {
- enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
-
/* check if it's a file and has been renamed */
if (ctx->current == LOCAL_REPLICA) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
return -1;
}
- /* translate the file type between the two stat types csync has. */
- if( tmp && tmp->type == CSYNC_FTW_TYPE_FILE ) {
- tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR;
- } else if( tmp && tmp->type == CSYNC_FTW_TYPE_DIR) {
- tmp_vio_type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
- } else if( tmp && tmp->type == CSYNC_FTW_TYPE_SLINK ) {
- tmp_vio_type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
- } else {
- tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
- }
-
// Default to NEW unless we're sure it's a rename.
st->instruction = CSYNC_INSTRUCTION_NEW;
bool isRename =
- tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type
- && (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY)
+ tmp && tmp->inode == fs->inode && tmp->type == fs->type
+ && (tmp->modtime == fs->modtime || fs->type == CSYNC_FTW_TYPE_DIR)
#ifdef NO_RENAME_EXTENSION
&& _csync_sameextension(tmp->path, path)
#endif
// Verify the checksum where possible
if (isRename && !tmp->checksumHeader.isEmpty() && ctx->callbacks.checksum_hook
- && fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
+ && fs->type == CSYNC_FTW_TYPE_FILE) {
st->checksumHeader = ctx->callbacks.checksum_hook(
file, tmp->checksumHeader,
ctx->callbacks.checksum_userdata);
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
/* inode found so the file has been renamed */
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
- if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
+ if (fs->type == CSYNC_FTW_TYPE_DIR) {
csync_rename_record(ctx, tmp->path, path);
}
}
return -1;
}
if(tmp ) { /* tmp existing at all */
- if ( _csync_filetype_different(tmp.get(), fs)) {
+ if (tmp->type != fs->type) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
st->instruction = CSYNC_INSTRUCTION_NEW;
goto out;
}
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s %s", tmp->path.constData(), file);
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
- if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
+ if (fs->type == CSYNC_FTW_TYPE_DIR) {
csync_rename_record(ctx, tmp->path, path);
} else {
- if( !c_streq(tmp->etag, fs->etag) ) {
+ if( tmp->etag != fs->etag ) {
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ETags are different!"); */
/* File with different etag, don't do a rename, but download the file again */
st->instruction = CSYNC_INSTRUCTION_NEW;
/* file not found in statedb */
st->instruction = CSYNC_INSTRUCTION_NEW;
- if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
+ if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path, fs->remotePerm)) {
return 1;
}
st->inode = fs->inode;
st->size = fs->size;
- st->modtime = fs->mtime;
+ st->modtime = fs->modtime;
st->type = type;
- st->etag = NULL;
- if( fs->etag ) {
- st->etag = fs->etag;
- }
+ st->is_hidden = fs->is_hidden;
+ st->etag = fs->etag;
st->file_id = fs->file_id;
- if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL) {
- st->directDownloadUrl = fs->directDownloadUrl;
- }
- if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES) {
- st->directDownloadCookies = fs->directDownloadCookies;
- }
- if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM) {
- st->remotePerm = fs->remotePerm;
- }
+ st->directDownloadUrl = fs->directDownloadUrl;
+ st->directDownloadCookies = fs->directDownloadCookies;
+ st->remotePerm = fs->remotePerm;
// For the remote: propagate the discovered checksum
- if (fs->checksumHeader && ctx->current == REMOTE_REPLICA) {
+ if (ctx->current == REMOTE_REPLICA) {
st->checksumHeader = fs->checksumHeader;
}
return 0;
}
-int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs,
+int csync_walker(CSYNC *ctx, const char *file, const csync_file_stat_t *fs,
int flag) {
int rc = -1;
enum csync_ftw_type_e type = CSYNC_FTW_TYPE_SKIP;
switch (flag) {
case CSYNC_FTW_FLAG_FILE:
if (ctx->current == REMOTE_REPLICA) {
- if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id, fs->size);
- } else {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=UNKNOWN]", file, fs->file_id);
- }
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [file_id=%s size=%" PRIu64 "]", file, fs->file_id.constData(), fs->size);
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s [inode=%" PRIu64 " size=%" PRIu64 "]", file, fs->inode, fs->size);
}
break;
case CSYNC_FTW_FLAG_DIR: /* enter directory */
if (ctx->current == REMOTE_REPLICA) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id);
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [file_id=%s]", file, fs->file_id.constData());
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "directory: %s [inode=%" PRIu64 "]", file, fs->inode);
}
/* File tree walker */
int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
unsigned int depth) {
- char *filename = NULL;
- char *d_name = NULL;
+ QByteArray filename;
+ QByteArray d_name;
csync_vio_handle_t *dh = NULL;
- csync_vio_file_stat_t *dirent = NULL;
+ std::unique_ptr<csync_file_stat_t> dirent;
csync_file_stat_t *previous_fs = NULL;
int read_from_db = 0;
int rc = 0;
if (!depth) {
mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_INDIVIDUAL_TOO_DEEP);
- goto done;
+ return 0;
}
read_from_db = ctx->remote.read_from_db;
ctx->status_code = CSYNC_STATUS_OPENDIR_ERROR;
goto error;
}
- goto done;
+ return 0;
}
if ((dh = csync_vio_opendir(ctx, uri)) == NULL) {
if (errno == EACCES) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied.");
if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
- goto done;
+ return 0;
}
} else if(errno == ENOENT) {
asp = asprintf( &ctx->error_string, "%s", uri);
else if(errno == ERRNO_FORBIDDEN) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)");
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
- goto done;
+ return 0;
}
/* if current_fs is not defined here, better throw an error */
}
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) {
- goto done;
+ return 0;
}
/* if current_fs is not defined here, better throw an error */
} else {
}
while ((dirent = csync_vio_readdir(ctx, dh))) {
- int flen;
int flag;
/* Conversion error */
- if (dirent->name == NULL && dirent->original_name) {
+ if (dirent->path.isEmpty() && !dirent->original_path.isEmpty()) {
ctx->status_code = CSYNC_STATUS_INVALID_CHARACTERS;
- ctx->error_string = dirent->original_name; // take ownership
- dirent->original_name = NULL;
+ ctx->error_string = c_strdup(dirent->original_path);
+ dirent->original_path.clear();
goto error;
}
- d_name = dirent->name;
- if (d_name == NULL) {
+ d_name = dirent->path;
+ if (d_name.isEmpty()) {
ctx->status_code = CSYNC_STATUS_READDIR_ERROR;
goto error;
}
/* skip "." and ".." */
- if ( (d_name[0] == '.' && d_name[1] == '\0')
- || (d_name[0] == '.' && d_name[1] == '.' && d_name[2] == '\0')) {
- csync_vio_file_stat_destroy(dirent);
- dirent = NULL;
+ if ( d_name == "." || d_name == "..") {
+ dirent.reset();
continue;
}
if (uri[0] == '\0') {
- filename = c_strdup(d_name);
- flen = strlen(d_name);
+ filename = d_name;
} else {
- flen = asprintf(&filename, "%s/%s", uri, d_name);
- }
- if (flen < 0 || !filename) {
- csync_vio_file_stat_destroy(dirent);
- dirent = NULL;
- ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
- goto error;
+ /* For the local replica, dirent->path only contains the file name */
+ filename = uri;
+ filename += '/';
+ filename += d_name;
}
/* Only for the local replica we have to stat(), for the remote one we have all data already */
if (ctx->replica == LOCAL_REPLICA) {
- res = csync_vio_stat(ctx, filename, dirent);
+ res = csync_vio_stat(ctx, filename, dirent.get());
} else {
res = 0;
}
* local stat function.
*/
if( d_name[0] == '.' ) {
- if (strcmp(".sys.admin#recall#", d_name) != 0) { /* recall file shall not be ignored (#4420) */
- dirent->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+ if (d_name == ".sys.admin#recall#") { /* recall file shall not be ignored (#4420) */
+ dirent->is_hidden = true;
}
}
+ flag = CSYNC_FTW_FLAG_NSTAT;
if( res == 0) {
switch (dirent->type) {
- case CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK:
+ case CSYNC_FTW_TYPE_SLINK:
flag = CSYNC_FTW_FLAG_SLINK;
break;
- case CSYNC_VIO_FILE_TYPE_DIRECTORY:
+ case CSYNC_FTW_TYPE_DIR:
flag = CSYNC_FTW_FLAG_DIR;
break;
- case CSYNC_VIO_FILE_TYPE_BLOCK_DEVICE:
- case CSYNC_VIO_FILE_TYPE_CHARACTER_DEVICE:
- case CSYNC_VIO_FILE_TYPE_SOCKET:
- flag = CSYNC_FTW_FLAG_SPEC;
- break;
- case CSYNC_VIO_FILE_TYPE_FIFO:
- flag = CSYNC_FTW_FLAG_SPEC;
+ case CSYNC_FTW_TYPE_FILE:
+ flag = CSYNC_FTW_FLAG_FILE;
break;
default:
- flag = CSYNC_FTW_FLAG_FILE;
break;
};
- } else {
- flag = CSYNC_FTW_FLAG_NSTAT;
}
previous_fs = ctx->current_fs;
/* Call walker function for each file */
- rc = fn(ctx, filename, dirent, flag);
+ rc = fn(ctx, filename, dirent.get(), flag);
/* this function may update ctx->current and ctx->read_from_db */
if (rc < 0) {
ctx->current_fs = previous_fs;
ctx->remote.read_from_db = read_from_db;
- SAFE_FREE(filename);
- csync_vio_file_stat_destroy(dirent);
- dirent = NULL;
+ dirent.reset();
}
csync_vio_closedir(ctx, dh);
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, " <= Closing walk for %s with read_from_db %d", uri, read_from_db);
-done:
- csync_vio_file_stat_destroy(dirent);
- SAFE_FREE(filename);
return rc;
+
error:
ctx->remote.read_from_db = read_from_db;
if (dh != NULL) {
csync_vio_closedir(ctx, dh);
}
- SAFE_FREE(filename);
return -1;
}
CSYNC_FTW_FLAG_DNR, /* Unreadable directory. */
CSYNC_FTW_FLAG_NSTAT, /* Unstatable file. */
CSYNC_FTW_FLAG_SLINK, /* Symbolic link. */
- CSYNC_FTW_FLAG_SPEC, /* Special file (fifo, ...). */
/* These flags are only passed from the `nftw' function. */
CSYNC_FTW_FLAG_DP, /* Directory, all subdirs have been visited. */
CSYNC_FTW_FLAG_SLN /* Symbolic link naming non-existing file. */
};
typedef int (*csync_walker_fn) (CSYNC *ctx, const char *file,
- const csync_vio_file_stat_t *fs, int flag);
+ const csync_file_stat_t *fs, int flag);
/**
* @brief The walker function to use in the file tree walker.
*
* @return 0 on success, < 0 on error.
*/
-int csync_walker(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs, int flag);
+int csync_walker(CSYNC *ctx, const char *file, const csync_file_stat_t *fs, int flag);
/**
* @brief The file tree walker.
#include "c_alloc.h"
#include "c_path.h"
#include "c_string.h"
+#include "c_utf8.h"
/*
* dirname - parse directory component.
*/
void c_strlist_destroy(c_strlist_t *strlist);
-/**
- * @brief Convert a platform locale string to utf8.
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * To convert path names returned by these functions to the internally used
- * utf8 format this function has to be used. The returned string has to
- * be freed by c_free_locale_string(). On some platforms this method allocates
- * memory and on others not but it has never to be cared about.
- *
- * @param str The multibyte encoded string to convert
- *
- * @return The malloced converted string or NULL on error.
- *
- * @see c_free_locale_string()
- * @see c_utf8_to_locale()
- *
- */
- char* c_utf8_from_locale(const mbchar_t *str);
-
-/**
- * @brief Convert a utf8 encoded string to platform specific locale.
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * To convert strings as input for the cross platform functions from the
- * internally used utf8 format, this function has to be used.
- * The returned string has to be freed by c_free_locale_string(). On some
- * platforms this method allocates memory and on others not but it has never
- * sto be cared about.
- *
- * If the string to convert is a path, consider using c_utf8_path_to_locale().
- *
- * @param str The utf8 string to convert.
- *
- * @return The malloced converted multibyte string or NULL on error.
- *
- * @see c_free_locale_string()
- * @see c_utf8_from_locale()
- *
- */
-mbchar_t* c_utf8_string_to_locale(const char *wstr);
-
-/**
- * @brief Free buffer malloced by c_utf8_from_locale or c_utf8_to_locale().
- *
- * This function is part of the multi platform abstraction of basic file
- * operations to handle various platform encoding correctly.
- *
- * Instead of using the standard file operations the multi platform aliases
- * defined in c_private.h have to be used instead.
- *
- * This function frees the memory that was allocated by a previous call to
- * c_utf8_to_locale() or c_utf8_from_locale().
- *
- * @param buf The buffer to free.
- *
- * @see c_utf8_from_locale(), c_utf8_to_locale()
- *
- */
-#define c_free_locale_string(x) SAFE_FREE(x)
-
-
/**
* }@
*/
#include "c_path.h"
#include "c_time.h"
+#include "c_utf8.h"
struct timespec c_tspecdiff(struct timespec time1, struct timespec time0) {
struct timespec ret;
*/
#include "config_csync.h"
+#include "c_utf8.h"
#ifdef _WIN32
#include <ctype.h>
#include <QtCore/QFile>
#endif
-extern "C" {
#include "c_alloc.h"
#include "c_string.h"
/* Convert a locale String to UTF8 */
-char* c_utf8_from_locale(const mbchar_t *wstr)
+QByteArray c_utf8_from_locale(const mbchar_t *wstr)
{
if (wstr == NULL) {
- return NULL;
+ return QByteArray();
}
#ifdef _WIN32
- char *dst = NULL;
- char *mdst = NULL;
+ QByteArray dst;
int size_needed;
size_t len;
len = wcslen(wstr);
/* Call once to get the required size. */
size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
if (size_needed > 0) {
- mdst = (char*)c_malloc(size_needed + 1);
-
- memset(mdst, 0, size_needed + 1);
- WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
- dst = mdst;
+ dst.resize(size_needed);
+ WideCharToMultiByte(CP_UTF8, 0, wstr, len, dst.data(), size_needed, NULL, NULL);
}
return dst;
#else
if (s.isEmpty() || dec.hasFailure()) {
/* Conversion error: since we can't report error from this function, just return the original
string. We take care of invalid utf-8 in SyncEngine::treewalkFile */
- return c_strdup(wstr);
+ return QByteArray(wstr);
}
#ifdef __APPLE__
s = s.normalized(QString::NormalizationForm_C);
#endif
- return c_strdup(std::move(s).toUtf8().constData());
+ return std::move(s).toUtf8();
#endif
}
+extern "C" {
+
/* Convert a an UTF8 string to locale */
mbchar_t* c_utf8_string_to_locale(const char *str)
{
--- /dev/null
+/*
+ * cynapses libc functions
+ *
+ * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
+ * Copyright (c) 2012-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
+ */
+
+/**
+ * @file c_string.h
+ *
+ * @brief Interface of the cynapses string implementations
+ *
+ * @defgroup cynStringInternals cynapses libc string functions
+ * @ingroup cynLibraryAPI
+ *
+ * @{
+ */
+#ifndef _C_UTF8_H
+#define _C_UTF8_H
+
+#include "c_private.h"
+#include "c_macro.h"
+
+#ifdef __cplusplus
+#include <QByteArray>
+
+/**
+ * @brief Convert a platform locale string to utf8.
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * To convert path names returned by these functions to the internally used
+ * utf8 format this function has to be used.
+ *
+ * @param str The multibyte encoded string to convert
+ *
+ * @return The converted string or a null QByteArray on error.
+ *
+ * @see c_free_locale_string()
+ * @see c_utf8_to_locale()
+ *
+ */
+ QByteArray c_utf8_from_locale(const mbchar_t *str);
+
+extern "C" {
+
+#endif // __cplusplus
+
+/**
+ * @brief Convert a utf8 encoded string to platform specific locale.
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * To convert strings as input for the cross platform functions from the
+ * internally used utf8 format, this function has to be used.
+ * The returned string has to be freed by c_free_locale_string(). On some
+ * platforms this method allocates memory and on others not but it has never
+ * sto be cared about.
+ *
+ * If the string to convert is a path, consider using c_utf8_path_to_locale().
+ *
+ * @param str The utf8 string to convert.
+ *
+ * @return The malloced converted multibyte string or NULL on error.
+ *
+ * @see c_free_locale_string()
+ * @see c_utf8_from_locale()
+ *
+ */
+mbchar_t* c_utf8_string_to_locale(const char *wstr);
+
+/**
+ * @brief Free buffer malloced by c_utf8_to_locale().
+ *
+ * This function is part of the multi platform abstraction of basic file
+ * operations to handle various platform encoding correctly.
+ *
+ * Instead of using the standard file operations the multi platform aliases
+ * defined in c_private.h have to be used instead.
+ *
+ * This function frees the memory that was allocated by a previous call to
+ * c_utf8_to_locale().
+ *
+ * @param buf The buffer to free.
+ *
+ * @see c_utf8_from_locale(), c_utf8_to_locale()
+ *
+ */
+#define c_free_locale_string(x) SAFE_FREE(x)
+
+
+/**
+ * }@
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _C_UTF8_H */
return rc;
}
-csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
+std::unique_ptr<csync_file_stat_t> csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
switch(ctx->replica) {
case REMOTE_REPLICA:
if( ctx->remote.read_from_db ) {
}
-int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
+int csync_vio_stat(CSYNC *ctx, const char *uri, csync_file_stat_t *buf) {
int rc = -1;
switch(ctx->replica) {
csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name);
int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle);
-csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle);
+std::unique_ptr<csync_file_stat_t> csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle);
-int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf);
+int csync_vio_stat(CSYNC *ctx, const char *uri, csync_file_stat_t *buf);
char *csync_vio_get_status_string(CSYNC *ctx);
+++ /dev/null
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 "c_lib.h"
-#include "csync.h"
-#include "csync_log.h"
-
-csync_vio_file_stat_t *csync_vio_file_stat_new(void) {
- csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t));
- ZERO_STRUCTP(file_stat);
- return file_stat;
-}
-
-csync_vio_file_stat_t* csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat) {
- csync_vio_file_stat_t *file_stat_cpy = csync_vio_file_stat_new();
- memcpy(file_stat_cpy, file_stat, sizeof(csync_vio_file_stat_t));
- if (file_stat_cpy->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
- file_stat_cpy->etag = c_strdup(file_stat_cpy->etag);
- }
- if (file_stat_cpy->directDownloadCookies) {
- file_stat_cpy->directDownloadCookies = c_strdup(file_stat_cpy->directDownloadCookies);
- }
- if (file_stat_cpy->directDownloadUrl) {
- file_stat_cpy->directDownloadUrl = c_strdup(file_stat_cpy->directDownloadUrl);
- }
- if (file_stat_cpy->checksumHeader) {
- file_stat_cpy->checksumHeader = c_strdup(file_stat_cpy->checksumHeader);
- }
- file_stat_cpy->name = c_strdup(file_stat_cpy->name);
- return file_stat_cpy;
-}
-
-void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) {
- /* FIXME: free rest */
- if (file_stat == NULL) {
- return;
- }
-
- if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) {
- SAFE_FREE(file_stat->etag);
- }
- SAFE_FREE(file_stat->directDownloadUrl);
- SAFE_FREE(file_stat->directDownloadCookies);
- SAFE_FREE(file_stat->name);
- SAFE_FREE(file_stat->original_name);
- SAFE_FREE(file_stat->checksumHeader);
- SAFE_FREE(file_stat);
-}
-
-void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* src ) {
-
- csync_vio_set_file_id( dst->file_id, src );
- if( c_streq( dst->file_id, "" )) {
- return;
- }
- dst->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID;
-}
-
-void csync_vio_set_file_id( char* dst, const char *src ) {
- if( src && dst ) {
- if( strlen(src) > FILE_ID_BUF_SIZE ) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Ignoring file_id because it is too long: %s", src);
- strcpy(dst, "");
- } else {
- strcpy(dst, src);
- }
- }
-}
csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const char *name);
int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle);
-csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_local_readdir(csync_vio_handle_t *dhandle);
+std::unique_ptr<csync_file_stat_t> OCSYNC_EXPORT csync_vio_local_readdir(csync_vio_handle_t *dhandle);
-int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf);
+int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_file_stat_t *buf);
#endif /* _CSYNC_VIO_LOCAL_H */
#include "c_private.h"
#include "c_lib.h"
#include "c_string.h"
+#include "c_utf8.h"
#include "csync_util.h"
#include "csync_log.h"
#include "csync_vio.h"
return rc;
}
-csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
+
+std::unique_ptr<csync_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;
struct _tdirent *dirent = NULL;
-
- errno = 0;
- file_stat = csync_vio_file_stat_new();
- if (file_stat == NULL) {
- goto err;
- }
- file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
+ std::unique_ptr<csync_file_stat_t> file_stat;
dirent = _treaddir(handle->dh);
if (dirent == NULL) {
- goto err;
+ return {};
}
- file_stat->name = c_utf8_from_locale(dirent->d_name);
- if (file_stat->name == NULL) {
- //file_stat->original_name = c_strdup(dirent->d_name);
- if (asprintf(&file_stat->original_name, "%s/%s", handle->path, dirent->d_name) < 0) {
- goto err;
- }
+
+ file_stat.reset(new csync_file_stat_t);
+ file_stat->path = c_utf8_from_locale(dirent->d_name);
+ if (file_stat->path.isNull()) {
+ file_stat->original_path = handle->path;
+ file_stat->original_path += '/';
+ file_stat->original_path += dirent->d_name;
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Invalid characters in file/directory name, please rename: \"%s\" (%s)",
dirent->d_name, handle->path);
}
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;
+ file_stat->type = CSYNC_FTW_TYPE_DIR;
} else {
- file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+ file_stat->type = CSYNC_FTW_TYPE_FILE;
}
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:
- csync_vio_file_stat_destroy(file_stat);
-
- return NULL;
}
-int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
+int csync_vio_local_stat(const char *uri, csync_file_stat_t *buf) {
csync_stat_t sb;
mbchar_t *wuri = c_utf8_path_to_locale( uri );
return -1;
}
- buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
+ *buf = csync_file_stat_t();
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;
+ buf->type = CSYNC_FTW_TYPE_DIR;
break;
case S_IFREG:
- buf->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+ buf->type = CSYNC_FTW_TYPE_FILE;
break;
case S_IFLNK:
- buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
- break;
case S_IFSOCK:
- buf->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+ buf->type = CSYNC_FTW_TYPE_SLINK;
break;
default:
- buf->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+ buf->type = CSYNC_FTW_TYPE_SKIP;
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;
+ buf->is_hidden = true;
}
#endif
- buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
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->modtime = sb.st_mtime;
buf->size = sb.st_size;
- buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
c_free_locale_string(wuri);
return 0;
#include "c_private.h"
#include "c_lib.h"
-#include "c_string.h"
+#include "c_utf8.h"
#include "csync_util.h"
#include "csync_log.h"
#include "csync_vio.h"
}
}
-csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
+std::unique_ptr<csync_file_stat_t> csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
dhandle_t *handle = NULL;
- csync_vio_file_stat_t *file_stat = NULL;
+ std::unique_ptr<csync_file_stat_t> file_stat;
DWORD rem;
handle = (dhandle_t *) dhandle;
errno = 0;
- file_stat = csync_vio_file_stat_new();
- if (file_stat == NULL) {
- errno = ENOMEM;
- goto err;
- }
- file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
// 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 (dwError != ERROR_NO_MORE_FILES) {
errno = EACCES; // no more files is fine. Otherwise EACCESS
}
- goto err;
+ return nullptr;
}
}
- file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
+ file_stat.reset(new csync_file_stat_t);
+ file_stat->path = c_utf8_from_locale(handle->ffd.cFileName);
- file_stat->flags = CSYNC_VIO_FILE_FLAGS_NONE;
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
// Detect symlinks, and treat junctions as symlinks too.
if (handle->ffd.dwReserved0 == IO_REPARSE_TAG_SYMLINK
|| handle->ffd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT) {
- file_stat->flags |= CSYNC_VIO_FILE_FLAGS_SYMLINK;
- file_stat->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK;
+ file_stat->type = CSYNC_FTW_TYPE_SLINK;
} else {
// The SIS and DEDUP reparse points should be treated as
// regular files. We don't know about the other ones yet,
// but will also treat them normally for now.
- file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+ file_stat->type = CSYNC_FTW_TYPE_FILE;
}
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE
|| handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
- file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
+ file_stat->type = CSYNC_FTW_TYPE_SKIP;
} else if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+ file_stat->type = CSYNC_FTW_TYPE_DIR;
} else {
- file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+ file_stat->type = CSYNC_FTW_TYPE_FILE;
}
/* Check for the hidden flag */
if( handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) {
- file_stat->flags |= CSYNC_VIO_FILE_FLAGS_HIDDEN;
+ file_stat->is_hidden = true;
}
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FLAGS;
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-
file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow;
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-
- file_stat->atime = FileTimeToUnixTime(&handle->ffd.ftLastAccessTime, &rem);
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
-
- file_stat->mtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
- /* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Local File MTime: %llu", (unsigned long long) buf->mtime ); */
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
-
- file_stat->ctime = FileTimeToUnixTime(&handle->ffd.ftCreationTime, &rem);
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
-
+ file_stat->modtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem);
return file_stat;
-
-err:
- SAFE_FREE(file_stat);
-
- return NULL;
}
-int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
+int csync_vio_local_stat(const char *uri, csync_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)
FileIndex.QuadPart &= 0x0000FFFFFFFFFFFF;
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
buf->inode = FileIndex.QuadPart;
+ buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
- 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;
- }
+ DWORD rem;
+ buf->modtime = FileTimeToUnixTime(&fileInfo.ftLastWriteTime, &rem);
c_free_locale_string(wuri);
CloseHandle(h);
return QByteArray();
}
-static csync_vio_file_stat_t *propertyMapToFileStat(const QMap<QString, QString> &map)
+static std::unique_ptr<csync_file_stat_t> propertyMapToFileStat(const QMap<QString, QString> &map)
{
- csync_vio_file_stat_t *file_stat = csync_vio_file_stat_new();
+ std::unique_ptr<csync_file_stat_t> file_stat(new csync_file_stat_t);
for (auto it = map.constBegin(); it != map.constEnd(); ++it) {
QString property = it.key();
QString value = it.value();
if (property == "resourcetype") {
if (value.contains("collection")) {
- file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
+ file_stat->type = CSYNC_FTW_TYPE_DIR;
} else {
- file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
+ file_stat->type = CSYNC_FTW_TYPE_FILE;
}
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
} else if (property == "getlastmodified") {
- file_stat->mtime = oc_httpdate_parse(value.toUtf8());
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
+ file_stat->modtime = oc_httpdate_parse(value.toUtf8());
} else if (property == "getcontentlength") {
bool ok = false;
qlonglong ll = value.toLongLong(&ok);
if (ok && ll >= 0) {
file_stat->size = ll;
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
}
} else if (property == "getetag") {
- file_stat->etag = csync_normalize_etag(value.toUtf8());
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG;
+ file_stat->etag = Utility::normalizeEtag(value.toUtf8());
} else if (property == "id") {
- csync_vio_file_stat_set_file_id(file_stat, value.toUtf8());
+ file_stat->file_id = value.toUtf8();
} else if (property == "downloadURL") {
- file_stat->directDownloadUrl = strdup(value.toUtf8());
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL;
+ file_stat->directDownloadUrl = value.toUtf8();
} else if (property == "dDC") {
- file_stat->directDownloadCookies = strdup(value.toUtf8());
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES;
+ file_stat->directDownloadCookies = value.toUtf8();
} else if (property == "permissions") {
- auto v = value.toUtf8();
- if (value.isEmpty()) {
- // special meaning for our code: server returned permissions but are empty
- // meaning only reading is allowed for this resource
- file_stat->remotePerm[0] = ' ';
- // see _csync_detect_update()
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERM;
- } else if (v.length() < int(sizeof(file_stat->remotePerm))) {
- strcpy(file_stat->remotePerm, v.constData());
- file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERM;
- } else {
- qCWarning(lcDiscovery) << "permissions too large" << v;
- }
+ file_stat->remotePerm = value.toUtf8();
} else if (property == "checksums") {
- QByteArray checksum = findBestChecksum(value.toUtf8());
- if (!checksum.isEmpty()) {
- file_stat->checksumHeader = strdup(checksum.constData());
- }
+ file_stat->checksumHeader = findBestChecksum(value.toUtf8());
} else if (property == "share-types" && !value.isEmpty()) {
// Since QMap is sorted, "share-types" is always "permissions".
- if (file_stat->remotePerm[0] == '\0' || !(file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM)) {
+ if (file_stat->remotePerm.isEmpty()) {
qWarning() << "Server returned a share type, but no permissions?";
} else {
// S means shared with me.
// But for our purpose, we want to know if the file is shared. It does not matter
// if we are the owner or not.
// Piggy back on the persmission field 'S'
- if (!std::strchr(file_stat->remotePerm, 'S')) {
- if (std::strlen(file_stat->remotePerm) < sizeof(file_stat->remotePerm) - 1) {
- std::strcat(file_stat->remotePerm, "S");
- } else {
- qWarning() << "permissions too large" << file_stat->remotePerm;
- }
- }
+ if (!file_stat->remotePerm.contains('S'))
+ file_stat->remotePerm.append('S');
}
}
}
}
- FileStatPointer file_stat(propertyMapToFileStat(map));
- file_stat->name = strdup(file.toUtf8());
- if (!file_stat->etag || strlen(file_stat->etag) == 0) {
- qCCritical(lcDiscovery) << "etag of" << file_stat->name << "is" << file_stat->etag << " This must not happen.";
+ std::unique_ptr<csync_file_stat_t> file_stat(propertyMapToFileStat(map));
+ file_stat->path = file.toUtf8();
+ if (file_stat->etag.isEmpty()) {
+ qCCritical(lcDiscovery) << "etag of" << file_stat->path << "is" << file_stat->etag << "This must not happen.";
}
if (_isExternalStorage) {
/* All the entries in a external storage have 'M' in their permission. However, for all
purposes in the desktop client, we only need to know about the mount points.
So replace the 'M' by a 'm' for every sub entries in an external storage */
- std::replace(file_stat->remotePerm, file_stat->remotePerm + strlen(file_stat->remotePerm),
- 'M', 'm');
+ file_stat->remotePerm.replace('M', 'm');
}
QStringRef fileRef(&file);
if (slashPos > -1) {
fileRef = file.midRef(slashPos + 1);
}
- _results.append(file_stat);
+ _results.push_back(std::move(file_stat));
}
//This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed.
}
emit etag(_firstEtag);
emit etagConcatenation(_etagConcatenation);
- emit finishedWithResult(_results);
+ emit finishedWithResult();
deleteLater();
}
// Schedule the DiscoverySingleDirectoryJob
_singleDirJob = new DiscoverySingleDirectoryJob(_account, fullPath, this);
- QObject::connect(_singleDirJob, SIGNAL(finishedWithResult(const QList<FileStatPointer> &)),
- this, SLOT(singleDirectoryJobResultSlot(const QList<FileStatPointer> &)));
+ QObject::connect(_singleDirJob, SIGNAL(finishedWithResult()),
+ this, SLOT(singleDirectoryJobResultSlot()));
QObject::connect(_singleDirJob, SIGNAL(finishedWithError(int, QString)),
this, SLOT(singleDirectoryJobFinishedWithErrorSlot(int, QString)));
QObject::connect(_singleDirJob, SIGNAL(firstDirectoryPermissions(QString)),
}
-void DiscoveryMainThread::singleDirectoryJobResultSlot(const QList<FileStatPointer> &result)
+void DiscoveryMainThread::singleDirectoryJobResultSlot()
{
if (!_currentDiscoveryDirectoryResult) {
return; // possibly aborted
}
- qCDebug(lcDiscovery) << "Have" << result.count() << "results for " << _currentDiscoveryDirectoryResult->path;
-
- _currentDiscoveryDirectoryResult->list = result;
+ _currentDiscoveryDirectoryResult->list = _singleDirJob->takeResults();
_currentDiscoveryDirectoryResult->code = 0;
- _currentDiscoveryDirectoryResult->listIndex = 0;
+
+ qCDebug(lcDiscovery) << "Have" << _currentDiscoveryDirectoryResult->list.size() << "results for " << _currentDiscoveryDirectoryResult->path;
+
_currentDiscoveryDirectoryResult = 0; // the sync thread owns it now
if (!_firstFolderProcessed) {
if (_singleDirJob) {
_singleDirJob->disconnect(SIGNAL(finishedWithError(int, QString)), this);
_singleDirJob->disconnect(SIGNAL(firstDirectoryPermissions(QString)), this);
- _singleDirJob->disconnect(SIGNAL(finishedWithResult(const QList<FileStatPointer> &)), this);
+ _singleDirJob->disconnect(SIGNAL(finishedWithResult()), this);
_singleDirJob->abort();
}
if (_currentDiscoveryDirectoryResult) {
}
-csync_vio_file_stat_t *DiscoveryJob::remote_vio_readdir_hook(csync_vio_handle_t *dhandle,
+std::unique_ptr<csync_file_stat_t> DiscoveryJob::remote_vio_readdir_hook(csync_vio_handle_t *dhandle,
void *userdata)
{
DiscoveryJob *discoveryJob = static_cast<DiscoveryJob *>(userdata);
if (discoveryJob) {
DiscoveryDirectoryResult *directoryResult = static_cast<DiscoveryDirectoryResult *>(dhandle);
- if (directoryResult->listIndex < directoryResult->list.size()) {
- csync_vio_file_stat_t *file_stat = directoryResult->list.at(directoryResult->listIndex++).data();
- // Make a copy, csync_update will delete the copy
- return csync_vio_file_stat_copy(file_stat);
+ if (!directoryResult->list.empty()) {
+ auto file_stat = std::move(directoryResult->list.front());
+ directoryResult->list.pop_front();
+ return file_stat;
}
}
return NULL;
#include <QMutex>
#include <QWaitCondition>
#include <QLinkedList>
+#include <deque>
namespace OCC {
};
-/**
- * @brief The FileStatPointer class
- * @ingroup libsync
- */
-class FileStatPointer
-{
-public:
- FileStatPointer(csync_vio_file_stat_t *stat)
- : _stat(stat)
- {
- }
- FileStatPointer(const FileStatPointer &other)
- : _stat(csync_vio_file_stat_copy(other._stat))
- {
- }
- ~FileStatPointer()
- {
- csync_vio_file_stat_destroy(_stat);
- }
- FileStatPointer &operator=(const FileStatPointer &other)
- {
- csync_vio_file_stat_destroy(_stat);
- _stat = csync_vio_file_stat_copy(other._stat);
- return *this;
- }
- inline csync_vio_file_stat_t *data() const { return _stat; }
- inline csync_vio_file_stat_t *operator->() const { return _stat; }
-
-private:
- csync_vio_file_stat_t *_stat;
-};
-
struct DiscoveryDirectoryResult
{
QString path;
QString msg;
int code;
- QList<FileStatPointer> list;
- int listIndex;
+ std::deque<std::unique_ptr<csync_file_stat_t>> list;
DiscoveryDirectoryResult()
: code(EIO)
- , listIndex(0)
{
}
};
void setIsRootPath() { _isRootPath = true; }
void start();
void abort();
+ std::deque<std::unique_ptr<csync_file_stat_t>> &&takeResults() { return std::move(_results); }
+
// This is not actually a network job, it is just a job
signals:
void firstDirectoryPermissions(const QString &);
void etagConcatenation(const QString &);
void etag(const QString &);
- void finishedWithResult(const QList<FileStatPointer> &);
+ void finishedWithResult();
void finishedWithError(int csyncErrnoCode, const QString &msg);
private slots:
void directoryListingIteratedSlot(QString, const QMap<QString, QString> &);
void lsJobFinishedWithErrorSlot(QNetworkReply *);
private:
- QList<FileStatPointer> _results;
+ std::deque<std::unique_ptr<csync_file_stat_t>> _results;
QString _subPath;
QString _etagConcatenation;
QString _firstEtag;
void doGetSizeSlot(const QString &path, qint64 *result);
// From Job:
- void singleDirectoryJobResultSlot(const QList<FileStatPointer> &);
+ void singleDirectoryJobResultSlot();
void singleDirectoryJobFinishedWithErrorSlot(int csyncErrnoCode, const QString &msg);
void singleDirectoryJobFirstDirectoryPermissionsSlot(const QString &);
// For using QNAM to get the directory listings
static csync_vio_handle_t *remote_vio_opendir_hook(const char *url,
void *userdata);
- static csync_vio_file_stat_t *remote_vio_readdir_hook(csync_vio_handle_t *dhandle,
+ static std::unique_ptr<csync_file_stat_t> remote_vio_readdir_hook(csync_vio_handle_t *dhandle,
void *userdata);
static void remote_vio_closedir_hook(csync_vio_handle_t *dhandle,
void *userdata);
#include "vio/csync_vio_local.h"
#include "std/c_path.h"
#include "std/c_string.h"
+#include "std/c_utf8.h"
namespace OCC {
time_t FileSystem::getModTime(const QString &filename)
{
- csync_vio_file_stat_t *stat = csync_vio_file_stat_new();
+ csync_file_stat_t stat;
qint64 result = -1;
- if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
- && (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME)) {
- result = stat->mtime;
+ if (csync_vio_local_stat(filename.toUtf8().data(), &stat) != -1
+ && (stat.modtime != 0)) {
+ result = stat.modtime;
} else {
qCWarning(lcFileSystem) << "Could not get modification time for" << filename
<< "with csync, using QFileInfo";
result = Utility::qDateTimeToTime_t(QFileInfo(filename).lastModified());
}
- csync_vio_file_stat_destroy(stat);
return result;
}
static qint64 getSizeWithCsync(const QString &filename)
{
qint64 result = 0;
- csync_vio_file_stat_t *stat = csync_vio_file_stat_new();
- if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
- && (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_SIZE)) {
- result = stat->size;
+ csync_file_stat_t stat;
+ if (csync_vio_local_stat(filename.toUtf8().data(), &stat) != -1) {
+ result = stat.size;
} else {
qCWarning(lcFileSystem) << "Could not get size for" << filename << "with csync";
}
- csync_vio_file_stat_destroy(stat);
return result;
}
#endif
case CSYNC_STATUS_TREE_ERROR:
errStr = tr("CSync got an error while processing internal trees.");
break;
- case CSYNC_STATUS_MEMORY_ERROR:
- errStr = tr("CSync failed to reserve memory.");
- break;
case CSYNC_STATUS_PARAM_ERROR:
errStr = tr("CSync fatal parameter error.");
break;
add_cmocka_test(check_csync_commit csync_tests/check_csync_commit.cpp ${TEST_TARGET_LIBRARIES})
# vio
-add_cmocka_test(check_vio_file_stat vio_tests/check_vio_file_stat.cpp ${TEST_TARGET_LIBRARIES})
add_cmocka_test(check_vio vio_tests/check_vio.cpp ${TEST_TARGET_LIBRARIES})
add_cmocka_test(check_vio_ext vio_tests/check_vio_ext.cpp ${TEST_TARGET_LIBRARIES})
#include "csync.h"
#include "csync_log.cpp"
#include "c_private.h"
+#include "std/c_utf8.h"
static int setup(void **state) {
CSYNC *csync;
* 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 "csync_misc.h"
+#include "common/utility.h"
#include <stdlib.h>
#include "torture.h"
static void check_csync_normalize_etag(void **state)
{
- char *str;
+ QByteArray str;
(void) state; /* unused */
#define CHECK_NORMALIZE_ETAG(TEST, EXPECT) \
- str = csync_normalize_etag(TEST); \
- assert_string_equal(str, EXPECT); \
- free(str);
+ str = OCC::Utility::normalizeEtag(TEST); \
+ assert_string_equal(str.constData(), EXPECT); \
CHECK_NORMALIZE_ETAG("foo", "foo");
}
/* create a file stat, caller must free memory */
-static csync_vio_file_stat_t* create_fstat(const char *name,
+static std::unique_ptr<csync_file_stat_t> create_fstat(const char *name,
ino_t inode,
time_t mtime)
{
- csync_vio_file_stat_t *fs = NULL;
+ std::unique_ptr<csync_file_stat_t> fs(new csync_file_stat_t);
time_t t;
- fs = csync_vio_file_stat_new();
- if (fs == NULL) {
- return NULL;
- }
-
if (name && *name) {
- fs->name = c_strdup(name);
+ fs->path = name;
} else {
- fs->name = c_strdup("file.txt");
- }
-
- if (fs->name == NULL) {
- csync_vio_file_stat_destroy(fs);
- return NULL;
+ fs->path = "file.txt";
}
- fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
-
- fs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
-
+ fs->type = CSYNC_FTW_TYPE_FILE;
if (inode == 0) {
fs->inode = 619070;
} else {
fs->inode = inode;
}
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE;
-
fs->size = 157459;
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
-
-
if (mtime == 0) {
- fs->atime = fs->ctime = fs->mtime = time(&t);
+ fs->modtime = time(&t);
} else {
- fs->atime = fs->ctime = fs->mtime = mtime;
+ fs->modtime = mtime;
}
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME;
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_CTIME;
- fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
return fs;
}
static int failing_fn(CSYNC *ctx,
const char *file,
- const csync_vio_file_stat_t *fs,
+ const csync_file_stat_t *fs,
int flag)
{
(void) ctx;
{
CSYNC *csync = (CSYNC*)*state;
csync_file_stat_t *st;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc;
fs = create_fstat("file.txt", 0, 1217597845);
- assert_non_null(fs);
rc = _csync_detect_update(csync,
"/tmp/check_csync1/file.txt",
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, 0);
/* create a statedb */
csync_set_status(csync, 0xFFFF);
-
- csync_vio_file_stat_destroy(fs);
}
/* Test behaviour in case no db is there. For that its important that the
{
CSYNC *csync = (CSYNC*)*state;
csync_file_stat_t *st;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc;
fs = create_fstat("file.txt", 0, 1217597845);
- assert_non_null(fs);
rc = _csync_detect_update(csync,
"/tmp/check_csync1/file.txt",
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, 0);
/* create a statedb */
csync_set_status(csync, 0xFFFF);
-
- csync_vio_file_stat_destroy(fs);
}
static void check_csync_detect_update_db_eval(void **state)
{
CSYNC *csync = (CSYNC*)*state;
csync_file_stat_t *st;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc;
fs = create_fstat("file.txt", 0, 42);
- assert_non_null(fs);
rc = _csync_detect_update(csync,
"/tmp/check_csync1/file.txt",
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, 0);
/* create a statedb */
csync_set_status(csync, 0xFFFF);
-
- csync_vio_file_stat_destroy(fs);
}
CSYNC *csync = (CSYNC*)*state;
// csync_file_stat_t *st;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc = 0;
fs = create_fstat("wurst.txt", 0, 42);
- assert_non_null(fs);
csync_set_statedb_exists(csync, 1);
rc = _csync_detect_update(csync,
"/tmp/check_csync1/wurst.txt",
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, 0);
*/
/* create a statedb */
csync_set_status(csync, 0xFFFF);
-
- csync_vio_file_stat_destroy(fs);
}
static void check_csync_detect_update_db_new(void **state)
{
CSYNC *csync = (CSYNC*)*state;
csync_file_stat_t *st;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc;
fs = create_fstat("file.txt", 42000, 0);
- assert_non_null(fs);
rc = _csync_detect_update(csync,
"/tmp/check_csync1/file.txt",
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, 0);
/* create a statedb */
csync_set_status(csync, 0xFFFF);
-
- csync_vio_file_stat_destroy(fs);
}
static void check_csync_detect_update_null(void **state)
{
CSYNC *csync = (CSYNC*)*state;
- csync_vio_file_stat_t *fs;
+ std::unique_ptr<csync_file_stat_t> fs;
int rc;
fs = create_fstat("file.txt", 0, 0);
- assert_non_null(fs);
rc = _csync_detect_update(csync,
NULL,
- fs,
+ fs.get(),
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, -1);
NULL,
CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, -1);
-
- csync_vio_file_stat_destroy(fs);
}
static void check_csync_ftw(void **state)
#include <stdio.h>
#include "c_string.h"
#include "c_path.h"
+#include "c_utf8.h"
#ifdef _WIN32
#include <string.h>
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
#endif
const char *exp_out = "\x48\xc3\xa4"; // UTF-8
- out = c_utf8_from_locale(in);
+ QByteArray out = c_utf8_from_locale(in);
assert_string_equal(out, exp_out);
- c_free_locale_string(out);
- assert_null(out);
-
(void) state; /* unused */
}
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);
+ QByteArray out = c_utf8_from_locale(in);
assert_string_equal(out, exp_out);
- c_free_locale_string(out);
- assert_null(out);
-
(void) state; /* unused */
}
#include "torture.h"
#include "csync_private.h"
+#include "std/c_utf8.h"
#include "vio/csync_vio.h"
#define CSYNC_TEST_DIR "/tmp/csync_test/"
{
CSYNC *csync = (CSYNC*)*state;
csync_vio_handle_t *dh;
- csync_vio_file_stat_t *dirent;
+ std::unique_ptr<csync_file_stat_t> dirent;
int rc;
dh = csync_vio_opendir(csync, CSYNC_TEST_DIR);
assert_non_null(dh);
dirent = csync_vio_readdir(csync, dh);
- assert_non_null(dirent);
+ assert_non_null(dirent.get());
- csync_vio_file_stat_destroy(dirent);
rc = csync_vio_closedir(csync, dh);
assert_int_equal(rc, 0);
}
#include "torture.h"
#include "csync_private.h"
+#include "std/c_utf8.h"
#include "vio/csync_vio.h"
#ifdef _WIN32
static void traverse_dir(void **state, const char *dir, int *cnt)
{
csync_vio_handle_t *dh;
- csync_vio_file_stat_t *dirent;
+ std::unique_ptr<csync_file_stat_t> dirent;
statevar *sv = (statevar*) *state;
CSYNC *csync = sv->csync;
char *subdir;
assert_non_null(dh);
while( (dirent = csync_vio_readdir(csync, dh)) ) {
- assert_non_null(dirent);
- if (dirent->original_name) {
- sv->ignored_dir = c_strdup(dirent->original_name);
+ assert_non_null(dirent.get());
+ if (!dirent->original_path.isEmpty()) {
+ sv->ignored_dir = c_strdup(dirent->original_path);
continue;
}
- assert_non_null(dirent->name);
- assert_int_equal( dirent->fields & CSYNC_VIO_FILE_STAT_FIELDS_TYPE, CSYNC_VIO_FILE_STAT_FIELDS_TYPE );
+ assert_false(dirent->path.isEmpty());
- if( c_streq( dirent->name, "..") || c_streq( dirent->name, "." )) {
+ if( c_streq( dirent->path, "..") || c_streq( dirent->path, "." )) {
continue;
}
- is_dir = (dirent->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) ? 1:0;
+ is_dir = (dirent->type == CSYNC_FTW_TYPE_DIR) ? 1:0;
- assert_int_not_equal( asprintf( &subdir, "%s/%s", dir, dirent->name ), -1 );
+ assert_int_not_equal( asprintf( &subdir, "%s/%s", dir, dirent->path.constData() ), -1 );
assert_int_not_equal( asprintf( &subdir_out, format_str,
is_dir ? "<DIR>":" ",
SAFE_FREE(subdir_out);
}
- csync_vio_file_stat_destroy(dirent);
rc = csync_vio_closedir(csync, dh);
assert_int_equal(rc, 0);
+++ /dev/null
-/*
- * libcsync -- a library to sync a directory with another
- *
- * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
- *
- * 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 "torture.h"
-
-#include "csync.h"
-
-static void check_csync_vio_file_stat_new(void **state)
-{
- csync_vio_file_stat_t *tstat;
-
- (void) state; /* unused */
-
- tstat = csync_vio_file_stat_new();
- assert_non_null(tstat);
-
- csync_vio_file_stat_destroy(tstat);
-}
-
-
-int torture_run_tests(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(check_csync_vio_file_stat_new),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
-