mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
568 lines
16 KiB
C
568 lines
16 KiB
C
/*
|
|
* libcsync -- a library to sync a directory with another
|
|
*
|
|
* 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 csync.h
|
|
*
|
|
* @brief Application developer interface for csync.
|
|
*
|
|
* @defgroup csyncPublicAPI csync public API
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
#ifndef _CSYNC_H
|
|
#define _CSYNC_H
|
|
|
|
#include "std/c_private.h"
|
|
#include <sys/stat.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <config_csync.h>
|
|
|
|
#include "csync_version.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct csync_client_certs_s {
|
|
char *certificatePath;
|
|
char *certificatePasswd;
|
|
};
|
|
|
|
/**
|
|
* Instruction enum. In the file traversal structure, it describes
|
|
* the csync state of a file.
|
|
*/
|
|
enum csync_status_codes_e {
|
|
CSYNC_STATUS_OK = 0,
|
|
|
|
CSYNC_STATUS_ERROR = 1024, /* don't use this code,
|
|
*/
|
|
CSYNC_STATUS_UNSUCCESSFUL,
|
|
CSYNC_STATUS_NO_LOCK, /* OBSOLETE does not happen anymore */
|
|
CSYNC_STATUS_STATEDB_LOAD_ERROR,
|
|
CSYNC_STATUS_STATEDB_CORRUPTED,
|
|
CSYNC_STATUS_NO_MODULE,
|
|
CSYNC_STATUS_TIMESKEW, /* OBSOLETE */
|
|
CSYNC_STATUS_FILESYSTEM_UNKNOWN, /* UNUSED */
|
|
CSYNC_STATUS_TREE_ERROR,
|
|
CSYNC_STATUS_MEMORY_ERROR,
|
|
CSYNC_STATUS_PARAM_ERROR,
|
|
CSYNC_STATUS_UPDATE_ERROR,
|
|
CSYNC_STATUS_RECONCILE_ERROR,
|
|
CSYNC_STATUS_PROPAGATE_ERROR, /* OBSOLETE */
|
|
CSYNC_STATUS_REMOTE_ACCESS_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_REMOTE_CREATE_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_REMOTE_STAT_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_LOCAL_CREATE_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_LOCAL_STAT_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_PROXY_ERROR, /* UNUSED */
|
|
CSYNC_STATUS_LOOKUP_ERROR,
|
|
CSYNC_STATUS_SERVER_AUTH_ERROR,
|
|
CSYNC_STATUS_PROXY_AUTH_ERROR,
|
|
CSYNC_STATUS_CONNECT_ERROR,
|
|
CSYNC_STATUS_TIMEOUT,
|
|
CSYNC_STATUS_HTTP_ERROR,
|
|
CSYNC_STATUS_PERMISSION_DENIED,
|
|
CSYNC_STATUS_NOT_FOUND,
|
|
CSYNC_STATUS_FILE_EXISTS,
|
|
CSYNC_STATUS_OUT_OF_SPACE,
|
|
CSYNC_STATUS_QUOTA_EXCEEDED, /* UNUSED */
|
|
CSYNC_STATUS_SERVICE_UNAVAILABLE,
|
|
CSYNC_STATUS_FILE_SIZE_ERROR,
|
|
CSYNC_STATUS_CONTEXT_LOST,
|
|
CSYNC_STATUS_MERGE_FILETREE_ERROR,
|
|
CSYNC_STATUS_CSYNC_STATUS_ERROR,
|
|
CSYNC_STATUS_OPENDIR_ERROR,
|
|
CSYNC_STATUS_READDIR_ERROR,
|
|
CSYNC_STATUS_OPEN_ERROR,
|
|
CSYNC_STATUS_ABORTED,
|
|
/* Codes for file individual status: */
|
|
CSYNC_STATUS_INDIVIDUAL_IS_SYMLINK,
|
|
CSYNC_STATUS_INDIVIDUAL_IS_HARDLINK,
|
|
CSYNC_STATUS_INDIVIDUAL_IGNORE_LIST,
|
|
CSYNC_STATUS_INDIVIDUAL_IS_INVALID_CHARS,
|
|
CYSNC_STATUS_FILE_LOCKED_OR_OPEN
|
|
};
|
|
|
|
typedef enum csync_status_codes_e CSYNC_STATUS;
|
|
|
|
#ifndef likely
|
|
# define likely(x) (x)
|
|
#endif
|
|
#ifndef unlikely
|
|
# define unlikely(x) (x)
|
|
#endif
|
|
|
|
#define CSYNC_STATUS_IS_OK(x) (likely((x) == CSYNC_STATUS_OK))
|
|
#define CSYNC_STATUS_IS_ERR(x) (unlikely((x) >= CSYNC_STATUS_ERROR))
|
|
#define CSYNC_STATUS_IS_EQUAL(x, y) ((x) == (y))
|
|
|
|
|
|
enum csync_instructions_e {
|
|
CSYNC_INSTRUCTION_NONE = 0x00000000, /* Nothing to do (UPDATE|RECONCILE) */
|
|
CSYNC_INSTRUCTION_EVAL = 0x00000001, /* There was changed compared to the DB (UPDATE) */
|
|
CSYNC_INSTRUCTION_REMOVE = 0x00000002, /* The file need to be removed (RECONCILE) */
|
|
CSYNC_INSTRUCTION_RENAME = 0x00000004, /* The file need to be renamed (RECONCILE) */
|
|
CSYNC_INSTRUCTION_EVAL_RENAME= 0x00000800, /* The file is new, it is the destination of a rename (UPDATE) */
|
|
CSYNC_INSTRUCTION_NEW = 0x00000008, /* The file is new compared to the db (UPDATE) */
|
|
CSYNC_INSTRUCTION_CONFLICT = 0x00000010, /* The file need to be downloaded because it is a conflict (RECONCILE) */
|
|
CSYNC_INSTRUCTION_IGNORE = 0x00000020, /* The file is ignored (UPDATE|RECONCILE) */
|
|
CSYNC_INSTRUCTION_SYNC = 0x00000040, /* The file need to be pushed to the other remote (RECONCILE) */
|
|
CSYNC_INSTRUCTION_STAT_ERROR = 0x00000080,
|
|
CSYNC_INSTRUCTION_ERROR = 0x00000100
|
|
};
|
|
|
|
enum csync_ftw_type_e {
|
|
CSYNC_FTW_TYPE_FILE,
|
|
CSYNC_FTW_TYPE_SLINK,
|
|
CSYNC_FTW_TYPE_DIR,
|
|
CSYNC_FTW_TYPE_SKIP
|
|
};
|
|
|
|
|
|
#define FILE_ID_BUF_SIZE 21
|
|
|
|
// 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;
|
|
|
|
dev_t device;
|
|
uint64_t inode;
|
|
nlink_t nlink;
|
|
|
|
int fields; // actually enum csync_vio_file_stat_fields_e fields;
|
|
enum csync_vio_file_type_e type;
|
|
|
|
enum csync_vio_file_flags_e flags;
|
|
};
|
|
|
|
csync_vio_file_stat_t *csync_vio_file_stat_new(void);
|
|
csync_vio_file_stat_t *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
|
|
|
|
void csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat);
|
|
|
|
void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src );
|
|
|
|
void csync_vio_set_file_id(char* dst, const char *src );
|
|
|
|
|
|
/**
|
|
* CSync File Traversal structure.
|
|
*
|
|
* This structure is passed to the visitor function for every file
|
|
* which is seen.
|
|
*
|
|
*/
|
|
|
|
struct csync_tree_walk_file_s {
|
|
const char *path;
|
|
int64_t size;
|
|
int64_t inode;
|
|
time_t modtime;
|
|
mode_t mode;
|
|
enum csync_ftw_type_e type;
|
|
enum csync_instructions_e instruction;
|
|
|
|
/* For directories: If the etag has been updated and need to be writen on the db */
|
|
int should_update_etag;
|
|
|
|
const char *rename_path;
|
|
const char *etag;
|
|
const char *file_id;
|
|
const char *remotePerm;
|
|
char *directDownloadUrl;
|
|
char *directDownloadCookies;
|
|
struct {
|
|
int64_t size;
|
|
time_t modtime;
|
|
const char *etag;
|
|
const char *file_id;
|
|
enum csync_instructions_e instruction;
|
|
} other;
|
|
|
|
CSYNC_STATUS error_status;
|
|
};
|
|
typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
|
|
|
|
/**
|
|
* csync handle
|
|
*/
|
|
typedef struct csync_s CSYNC;
|
|
|
|
typedef int (*csync_auth_callback) (const char *prompt, char *buf, size_t len,
|
|
int echo, int verify, void *userdata);
|
|
|
|
typedef void (*csync_log_callback) (int verbosity,
|
|
const char *function,
|
|
const char *buffer,
|
|
void *userdata);
|
|
|
|
typedef void (*csync_update_callback) (bool local,
|
|
const char *dirUrl,
|
|
void *userdata);
|
|
|
|
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,
|
|
void *userdata);
|
|
typedef void (*csync_vio_closedir_hook) (csync_vio_handle_t *dhhandle,
|
|
void *userdata);
|
|
typedef int (*csync_vio_stat_hook) (csync_vio_handle_t *dhhandle,
|
|
void *userdata);
|
|
|
|
/**
|
|
* @brief Allocate a csync context.
|
|
*
|
|
* @param csync The context variable to allocate.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_create(CSYNC **csync, const char *local, const char *remote);
|
|
|
|
/**
|
|
* @brief Initialize the file synchronizer.
|
|
*
|
|
* This function loads the configuration
|
|
*
|
|
* @param ctx The context to initialize.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_init(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Update detection
|
|
*
|
|
* @param ctx The context to run the update detection on.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_update(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Reconciliation
|
|
*
|
|
* @param ctx The context to run the reconciliation on.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_reconcile(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Commit the sync results to journal
|
|
*
|
|
* @param ctx The context to commit.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_commit(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Destroy the csync context
|
|
*
|
|
* frees the memory.
|
|
*
|
|
* @param ctx The context to destroy.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_destroy(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Add an additional exclude list.
|
|
*
|
|
* @param ctx The context to add the exclude list.
|
|
*
|
|
* @param path The path pointing to the file.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_add_exclude_list(CSYNC *ctx, const char *path);
|
|
|
|
/**
|
|
* @brief Removes all items imported from exclude lists.
|
|
*
|
|
* @param ctx The context to add the exclude list.
|
|
*/
|
|
void csync_clear_exclude_list(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Get the userdata saved in the context.
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @return The userdata saved in the context, NULL if an error
|
|
* occured.
|
|
*/
|
|
void *csync_get_userdata(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Save userdata to the context which is passed to the auth
|
|
* callback function.
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @param userdata The userdata to be stored in the context.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_set_userdata(CSYNC *ctx, void *userdata);
|
|
|
|
/**
|
|
* @brief Get the authentication callback set.
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @return The authentication callback set or NULL if an error
|
|
* occured.
|
|
*/
|
|
csync_auth_callback csync_get_auth_callback(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Set the authentication callback.
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @param cb The authentication callback.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_set_auth_callback(CSYNC *ctx, csync_auth_callback cb);
|
|
|
|
/**
|
|
* @brief Set the log level.
|
|
*
|
|
* @param[in] level The log verbosity.
|
|
*
|
|
* @return 0 on success, < 0 if an error occured.
|
|
*/
|
|
int csync_set_log_level(int level);
|
|
|
|
/**
|
|
* @brief Get the log verbosity
|
|
*
|
|
* @return The log verbosity, -1 on error.
|
|
*/
|
|
int csync_get_log_level(void);
|
|
|
|
/**
|
|
* @brief Get the logging callback set.
|
|
*
|
|
* @return The logging callback set or NULL if an error
|
|
* occured.
|
|
*/
|
|
csync_log_callback csync_get_log_callback(void);
|
|
|
|
/**
|
|
* @brief Set the logging callback.
|
|
*
|
|
* @param cb The logging callback.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_set_log_callback(csync_log_callback cb);
|
|
|
|
/**
|
|
* @brief get the userdata set for the logging callback.
|
|
*
|
|
* @return The userdata or NULL.
|
|
*/
|
|
void *csync_get_log_userdata(void);
|
|
|
|
/**
|
|
* @brief Set the userdata passed to the logging callback.
|
|
*
|
|
* @param[in] data The userdata to set.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_set_log_userdata(void *data);
|
|
|
|
/* Used for special modes or debugging */
|
|
CSYNC_STATUS csync_get_status(CSYNC *ctx);
|
|
|
|
/* Used for special modes or debugging */
|
|
int csync_set_status(CSYNC *ctx, int status);
|
|
|
|
typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
|
|
|
|
/**
|
|
* @brief Walk the local file tree and call a visitor function for each file.
|
|
*
|
|
* @param ctx The csync context.
|
|
* @param visitor A callback function to handle the file info.
|
|
* @param filter A filter, built from or'ed csync_instructions_e
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_walk_local_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
|
|
|
/**
|
|
* @brief Walk the remote file tree and call a visitor function for each file.
|
|
*
|
|
* @param ctx The csync context.
|
|
* @param visitor A callback function to handle the file info.
|
|
* @param filter A filter, built from and'ed csync_instructions_e
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *visitor, int filter);
|
|
|
|
/**
|
|
* @brief Get the csync status string.
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @return A const pointer to a string with more precise status info.
|
|
*/
|
|
const char *csync_get_status_string(CSYNC *ctx);
|
|
|
|
#ifdef WITH_ICONV
|
|
/**
|
|
* @brief Set iconv source codec for filenames.
|
|
*
|
|
* @param from Source codec.
|
|
*
|
|
* @return 0 on success, or an iconv error number.
|
|
*/
|
|
int csync_set_iconv_codec(const char *from);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Set a property to module
|
|
*
|
|
* @param ctx The csync context.
|
|
*
|
|
* @param key The property key
|
|
*
|
|
* @param value An opaque pointer to the data.
|
|
*
|
|
* @return 0 on success, less than 0 if an error occured.
|
|
*/
|
|
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
|
|
|
|
/**
|
|
* @brief Aborts the current sync run as soon as possible. Can be called from another thread.
|
|
*
|
|
* @param ctx The csync context.
|
|
*/
|
|
void csync_request_abort(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Clears the abort flag. Can be called from another thread.
|
|
*
|
|
* @param ctx The csync context.
|
|
*/
|
|
void csync_resume(CSYNC *ctx);
|
|
|
|
/**
|
|
* @brief Checks for the abort flag, to be used from the modules.
|
|
*
|
|
* @param ctx The csync context.
|
|
*/
|
|
int csync_abort_requested(CSYNC *ctx);
|
|
|
|
/**
|
|
* Specify if it is allowed to read the remote tree from the DB (default to enabled)
|
|
*/
|
|
int csync_set_read_from_db(CSYNC* ctx, int enabled);
|
|
|
|
char *csync_normalize_etag(const char *);
|
|
time_t oc_httpdate_parse( const char *date );
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* }@
|
|
*/
|
|
#endif /* _CSYNC_H */
|
|
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|