mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
This is a start for a sftp module.
This commit is contained in:
parent
05253be461
commit
ecf1027a54
76
cmake/Modules/FindLIBSSH.cmake
Normal file
76
cmake/Modules/FindLIBSSH.cmake
Normal file
@ -0,0 +1,76 @@
|
||||
# - Try to find LIBSSH
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBSSH_FOUND - system has LIBSSH
|
||||
# LIBSSH_INCLUDE_DIRS - the LIBSSH include directory
|
||||
# LIBSSH_LIBRARIES - Link these to use LIBSSH
|
||||
# LIBSSH_DEFINITIONS - Compiler switches required for using LIBSSH
|
||||
#
|
||||
# Copyright (c) 2008 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBSSH_FOUND TRUE)
|
||||
else (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
find_path(LIBSSH_INCLUDE_DIR
|
||||
NAMES
|
||||
libssh/libssh.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIR)
|
||||
|
||||
find_library(SSH_LIBRARY
|
||||
NAMES
|
||||
ssh
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(SSH_LIBRARY)
|
||||
|
||||
if (SSH_LIBRARY)
|
||||
set(SSH_FOUND TRUE)
|
||||
endif (SSH_LIBRARY)
|
||||
|
||||
set(LIBSSH_INCLUDE_DIRS
|
||||
${LIBSSH_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if (SSH_FOUND)
|
||||
set(LIBSSH_LIBRARIES
|
||||
${LIBSSH_LIBRARIES}
|
||||
${SSH_LIBRARY}
|
||||
)
|
||||
endif (SSH_FOUND)
|
||||
|
||||
if (LIBSSH_INCLUDE_DIRS AND LIBSSH_LIBRARIES)
|
||||
set(LIBSSH_FOUND TRUE)
|
||||
endif (LIBSSH_INCLUDE_DIRS AND LIBSSH_LIBRARIES)
|
||||
|
||||
if (LIBSSH_FOUND)
|
||||
if (NOT LIBSSH_FIND_QUIETLY)
|
||||
message(STATUS "Found LIBSSH: ${LIBSSH_LIBRARIES}")
|
||||
endif (NOT LIBSSH_FIND_QUIETLY)
|
||||
else (LIBSSH_FOUND)
|
||||
if (LIBSSH_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find LIBSSH")
|
||||
endif (LIBSSH_FIND_REQUIRED)
|
||||
endif (LIBSSH_FOUND)
|
||||
|
||||
# show the LIBSSH_INCLUDE_DIRS and LIBSSH_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES)
|
||||
|
||||
endif (LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
project(modules)
|
||||
|
||||
find_package(Libsmbclient REQUIRED)
|
||||
find_package(LIBSSH REQUIRED)
|
||||
|
||||
set(MODULES_PUBLIC_INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
@ -17,6 +18,10 @@ set(SMB_PLUGIN
|
||||
csync_smb
|
||||
)
|
||||
|
||||
set(SFTP_PLUGIN
|
||||
csync_sftp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${MODULES_PUBLIC_INCLUDE_DIRS}
|
||||
${MODULES_PRIVATE_INCLUDE_DIRS}
|
||||
@ -27,10 +32,19 @@ target_link_libraries(${SMB_PLUGIN} ${LIBSMBCLIENT_LIBRARIES} ${CSTDLIB_LIBRARY}
|
||||
|
||||
macro_add_plugin(csync_dummy csync_dummy.c)
|
||||
|
||||
macro_add_plugin(${SFTP_PLUGIN} csync_sftp.c)
|
||||
target_link_libraries(${SFTP_PLUGIN} ${LIBSSH_LIBRARIES} ${CSTDLIB_LIBRARY})
|
||||
|
||||
INSTALL(
|
||||
TARGETS
|
||||
${SMB_PLUGIN}
|
||||
${SFTP_PLUGIN}
|
||||
DESTINATION
|
||||
${PLUGIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
# create test file as bad plugin for the vio testcase
|
||||
file(WRITE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/csync_bad.so
|
||||
"bad plugin"
|
||||
)
|
||||
|
||||
603
modules/csync_sftp.c
Normal file
603
modules/csync_sftp.c
Normal file
@ -0,0 +1,603 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* This program is free software = NULL, you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation = NULL, either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY = NULL, without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program = NULL, if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* vim: ts=2 sw=2 et cindent
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include "c_lib.h"
|
||||
#include "vio/csync_vio_module.h"
|
||||
#include "vio/csync_vio_file_stat.h"
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DEBUG_SFTP(x)
|
||||
#else
|
||||
#define DEBUG_SFTP(x) printf x
|
||||
#endif
|
||||
|
||||
int connected;
|
||||
SSH_SESSION *ssh_session;
|
||||
SFTP_SESSION *sftp_session;
|
||||
|
||||
/* parse_uri */
|
||||
static const char *uri_prefix = "sftp:";
|
||||
static int parse_uri(const char *uri, char **user, char **passwd,
|
||||
char **hostname, char **port, char **path) {
|
||||
const char *p = NULL;
|
||||
const char *r = NULL;
|
||||
const char *q = NULL;
|
||||
char *s = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
/* Ensure these returns are at least valid pointers. */
|
||||
*hostname = c_strdup("");
|
||||
*port = c_strdup("");
|
||||
*path = c_strdup("");
|
||||
*user = c_strdup("");
|
||||
*passwd = c_strdup("");
|
||||
|
||||
if (*hostname == NULL || *port == NULL || *path == NULL ||
|
||||
*user == NULL || *passwd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = c_strdup(uri);
|
||||
if (s == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(uri_prefix);
|
||||
/* check if we have the right prefix */
|
||||
if (strncmp(s, uri_prefix, len) || (s[len] != '/' && s[len] != '\0')) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
p = s + len;
|
||||
|
||||
if (strncmp(p, "//", 2) == 2) {
|
||||
DEBUG_SFTP(("Invalid path (does not begin with sftp://\n"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Skip the double slash */
|
||||
p += 2;
|
||||
|
||||
if (*p == '\0') {
|
||||
goto decoding;
|
||||
}
|
||||
|
||||
/* check that '@' occurs before '/', if '/' exists at all */
|
||||
q = strchr(p, '@');
|
||||
r = strchr(p, '/');
|
||||
if (q && (!r || q < r)) {
|
||||
char *userinfo = NULL;
|
||||
const char *u;
|
||||
userinfo = c_strndup(p, q - p);
|
||||
if (userinfo == NULL) {
|
||||
goto err;
|
||||
}
|
||||
u = strchr(userinfo, ':');
|
||||
if (u) {
|
||||
SAFE_FREE(*user);
|
||||
*user = c_strndup(userinfo, u - userinfo);
|
||||
if (*user == NULL) {
|
||||
SAFE_FREE(userinfo);
|
||||
goto err;
|
||||
}
|
||||
SAFE_FREE(*passwd);
|
||||
*passwd = c_strdup(u + 1);
|
||||
if (*passwd == NULL) {
|
||||
SAFE_FREE(userinfo);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
SAFE_FREE(*user);
|
||||
*user = c_strdup(userinfo);
|
||||
if (*user == NULL) {
|
||||
SAFE_FREE(userinfo);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(userinfo) + 1;
|
||||
SAFE_FREE(userinfo);
|
||||
p += len;
|
||||
}
|
||||
DEBUG_SFTP(("user: %s\n", *user));
|
||||
DEBUG_SFTP(("passwd: %s\n", *passwd));
|
||||
|
||||
if (*p == '\0') {
|
||||
goto decoding;
|
||||
}
|
||||
|
||||
/* check if we have a path */
|
||||
r = strchr(p, '/');
|
||||
if (r) {
|
||||
char *h = NULL;
|
||||
h = c_strndup(p, r - p);
|
||||
if (h == NULL) {
|
||||
goto err;
|
||||
}
|
||||
/* look for port */
|
||||
q = strchr(h, ':');
|
||||
if (q) {
|
||||
SAFE_FREE(*port);
|
||||
*port = c_strdup(q + 1);
|
||||
if (*port == NULL) {
|
||||
SAFE_FREE(h);
|
||||
goto err;
|
||||
}
|
||||
SAFE_FREE(*hostname);
|
||||
*hostname = c_strndup(h, q - h);
|
||||
if (*hostname == NULL) {
|
||||
SAFE_FREE(h);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
SAFE_FREE(*hostname);
|
||||
*hostname = c_strdup(h);
|
||||
if (*hostname == NULL) {
|
||||
SAFE_FREE(h);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
len = strlen(h) + 1;
|
||||
SAFE_FREE(h);
|
||||
} else {
|
||||
SAFE_FREE(*hostname);
|
||||
*hostname = c_strdup(p);
|
||||
if (*hostname == NULL) {
|
||||
goto err;
|
||||
}
|
||||
len = strlen(p);
|
||||
}
|
||||
DEBUG_SFTP(("hostname: %s\n", *hostname));
|
||||
DEBUG_SFTP(("port: %s\n", *port));
|
||||
|
||||
p += len;
|
||||
if (*p == '\0') {
|
||||
goto decoding;
|
||||
}
|
||||
|
||||
SAFE_FREE(*path);
|
||||
*path = c_strdup(p);
|
||||
if (*path == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (**path) {
|
||||
char *d = NULL;
|
||||
if (asprintf(&d, "/%s", *path) < 0) {
|
||||
return -1;
|
||||
}
|
||||
SAFE_FREE(*path);
|
||||
*path = d;
|
||||
DEBUG_SFTP(("path: %s\n", *path));
|
||||
}
|
||||
|
||||
goto decoding;
|
||||
err:
|
||||
SAFE_FREE(s);
|
||||
return -1;
|
||||
decoding:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _sftp_connect(const char *uri) {
|
||||
SSH_OPTIONS *options = NULL;
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
char *host = NULL;
|
||||
char *port = NULL;
|
||||
char *path = NULL;
|
||||
unsigned char hash[MD5_DIGEST_LEN];
|
||||
int rc = -1;
|
||||
int auth = SSH_AUTH_ERROR;
|
||||
int state = SSH_SERVER_ERROR;
|
||||
|
||||
if (connected) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = parse_uri(uri, &user, &passwd, &host, &port, &path);
|
||||
if (rc < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
options = ssh_options_new();
|
||||
if (options == NULL) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* set the option to connect to the server */
|
||||
ssh_options_set_host(options, host);
|
||||
if (*port) {
|
||||
ssh_options_set_port(options, atoi(port));
|
||||
}
|
||||
|
||||
if (*user) {
|
||||
ssh_options_set_username(options, user);
|
||||
}
|
||||
|
||||
/* connect to the server */
|
||||
ssh_session = ssh_new();
|
||||
ssh_set_options(ssh_session, options);
|
||||
rc = ssh_connect(ssh_session);
|
||||
if (rc < 0) {
|
||||
ssh_disconnect(ssh_session);
|
||||
ssh_session = NULL;
|
||||
ssh_finalize();
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check the server public key hash */
|
||||
state = ssh_is_server_known(ssh_session);
|
||||
switch (state) {
|
||||
case SSH_SERVER_KNOWN_OK:
|
||||
break;
|
||||
case SSH_SERVER_KNOWN_CHANGED:
|
||||
fprintf(stderr, "Host key for server changed : server's one is now :\n");
|
||||
ssh_get_pubkey_hash(ssh_session, hash);
|
||||
ssh_print_hexa("Public key hash", hash, MD5_DIGEST_LEN);
|
||||
fprintf(stderr,"For security reason, connection will be stopped\n");
|
||||
ssh_disconnect(ssh_session);
|
||||
ssh_finalize();
|
||||
rc = -1;
|
||||
goto out;
|
||||
break;
|
||||
case SSH_SERVER_FOUND_OTHER:
|
||||
fprintf(stderr, "The host key for this server was not found but an other "
|
||||
"type of key exists.\n");
|
||||
fprintf(stderr, "An attacker might change the default server key to "
|
||||
"confuse your client into thinking the key does not exist\n");
|
||||
ssh_disconnect(ssh_session);
|
||||
ssh_finalize();
|
||||
rc = -1;
|
||||
goto out;
|
||||
break;
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
fprintf(stderr,"The server is unknown. Connect manually to the host "
|
||||
"first to retrieve the public key hash\n");
|
||||
ssh_disconnect(ssh_session);
|
||||
ssh_finalize();
|
||||
rc = -1;
|
||||
goto out;
|
||||
break;
|
||||
case SSH_SERVER_ERROR:
|
||||
fprintf(stderr, "%s", ssh_get_error(ssh_session));
|
||||
ssh_disconnect(ssh_session);
|
||||
ssh_finalize();
|
||||
rc = -1;
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* authenticate with the server */
|
||||
if (*passwd) {
|
||||
auth = ssh_userauth_password(ssh_session, user, passwd);
|
||||
/*
|
||||
char username[256] = {0};
|
||||
char password[256] = {0};
|
||||
*/
|
||||
} else {
|
||||
auth = ssh_userauth_autopubkey(ssh_session);
|
||||
if (auth == SSH_AUTH_ERROR) {
|
||||
fprintf(stderr, "Authenticating with pubkey: %s\n", ssh_get_error(ssh_session));
|
||||
ssh_finalize();
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: call callback */
|
||||
|
||||
/* start the sftp session */
|
||||
sftp_session = sftp_new(ssh_session);
|
||||
if (sftp_session == NULL) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = sftp_init(sftp_session);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
connected = 1;
|
||||
rc = 0;
|
||||
out:
|
||||
SAFE_FREE(user);
|
||||
SAFE_FREE(passwd);
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(port);
|
||||
SAFE_FREE(path);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
csync_vio_file_stat_t fs;
|
||||
|
||||
/*
|
||||
* file functions
|
||||
*/
|
||||
|
||||
static csync_vio_method_handle_t *_open(const char *durl, int flags, mode_t mode) {
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
char *host = NULL;
|
||||
char *port = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
/* FIXME: implement mode with SFTP_ATTRIBUTES */
|
||||
(void) mode;
|
||||
|
||||
if (_sftp_connect(durl) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parse_uri(durl, &user, &passwd, &host, &port, &path) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mh = (csync_vio_method_handle_t *) sftp_open(sftp_session, path, flags, NULL);
|
||||
|
||||
SAFE_FREE(user);
|
||||
SAFE_FREE(passwd);
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(port);
|
||||
SAFE_FREE(path);
|
||||
|
||||
return mh;
|
||||
}
|
||||
|
||||
static csync_vio_method_handle_t *_creat(const char *durl, mode_t mode) {
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
char *host = NULL;
|
||||
char *port = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
(void) mode;
|
||||
|
||||
if (_sftp_connect(durl) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parse_uri(durl, &user, &passwd, &host, &port, &path) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mh = (csync_vio_method_handle_t *) sftp_open(sftp_session, path, O_CREAT|O_WRONLY|O_TRUNC, NULL);
|
||||
|
||||
SAFE_FREE(user);
|
||||
SAFE_FREE(passwd);
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(port);
|
||||
SAFE_FREE(path);
|
||||
|
||||
return mh;
|
||||
}
|
||||
|
||||
static int _close(csync_vio_method_handle_t *fhandle) {
|
||||
return sftp_file_close(fhandle);
|
||||
}
|
||||
|
||||
static ssize_t _read(csync_vio_method_handle_t *fhandle, void *buf, size_t count) {
|
||||
return sftp_read(fhandle, buf, count);
|
||||
}
|
||||
|
||||
static ssize_t _write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count) {
|
||||
return sftp_write(fhandle, buf, count);
|
||||
}
|
||||
|
||||
static off_t _lseek(csync_vio_method_handle_t *fhandle, off_t offset, int whence) {
|
||||
/* FIXME: really implement seek for lseek? */
|
||||
(void) whence;
|
||||
sftp_seek(fhandle, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* directory functions
|
||||
*/
|
||||
|
||||
static csync_vio_method_handle_t *_opendir(const char *durl) {
|
||||
csync_vio_method_handle_t *mh = NULL;
|
||||
char *user = NULL;
|
||||
char *passwd = NULL;
|
||||
char *host = NULL;
|
||||
char *port = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
if (_sftp_connect(durl) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parse_uri(durl, &user, &passwd, &host, &port, &path) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mh = (csync_vio_method_handle_t *) sftp_opendir(sftp_session, path);
|
||||
|
||||
SAFE_FREE(user);
|
||||
SAFE_FREE(passwd);
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(port);
|
||||
SAFE_FREE(path);
|
||||
|
||||
return mh;
|
||||
}
|
||||
|
||||
static int _closedir(csync_vio_method_handle_t *dhandle) {
|
||||
return sftp_dir_close(dhandle);
|
||||
}
|
||||
|
||||
static csync_vio_file_stat_t *_readdir(csync_vio_method_handle_t *dhandle) {
|
||||
SFTP_ATTRIBUTES *dirent = NULL;
|
||||
csync_vio_file_stat_t *fs = NULL;
|
||||
|
||||
/* TODO: consider adding the _sftp_connect function */
|
||||
dirent = sftp_readdir(sftp_session, dhandle);
|
||||
if (dirent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs = c_malloc(sizeof(csync_vio_file_stat_t));
|
||||
if (fs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->name = c_strdup(dirent->name);
|
||||
fs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
switch (dirent->type) {
|
||||
case SSH_FILEXFER_TYPE_REGULAR:
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
break;
|
||||
case SSH_FILEXFER_TYPE_DIRECTORY:
|
||||
fs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
fs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
break;
|
||||
case SSH_FILEXFER_TYPE_SYMLINK:
|
||||
case SSH_FILEXFER_TYPE_SPECIAL:
|
||||
case SSH_FILEXFER_TYPE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
static int _mkdir(const char *uri, mode_t mode) {
|
||||
(void) uri;
|
||||
(void) mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _rmdir(const char *uri) {
|
||||
(void) uri;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _stat(const char *uri, csync_vio_file_stat_t *buf) {
|
||||
time_t now;
|
||||
|
||||
buf->name = c_basename(uri);
|
||||
if (buf->name == NULL) {
|
||||
csync_vio_file_stat_destroy(buf);
|
||||
}
|
||||
buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
time(&now);
|
||||
buf->mtime = now;
|
||||
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _rename(const char *olduri, const char *newuri) {
|
||||
(void) olduri;
|
||||
(void) newuri;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _unlink(const char *uri) {
|
||||
(void) uri;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _chmod(const char *uri, mode_t mode) {
|
||||
(void) uri;
|
||||
(void) mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _chown(const char *uri, uid_t owner, gid_t group) {
|
||||
(void) uri;
|
||||
(void) owner;
|
||||
(void) group;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _utimes(const char *uri, const struct timeval *times) {
|
||||
(void) uri;
|
||||
(void) times;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
csync_vio_method_t _method = {
|
||||
.method_table_size = sizeof(csync_vio_method_t),
|
||||
.open = _open,
|
||||
.creat = _creat,
|
||||
.close = _close,
|
||||
.read = _read,
|
||||
.write = _write,
|
||||
.lseek = _lseek,
|
||||
.opendir = _opendir,
|
||||
.closedir = _closedir,
|
||||
.readdir = _readdir,
|
||||
.mkdir = _mkdir,
|
||||
.rmdir = _rmdir,
|
||||
.stat = _stat,
|
||||
.rename = _rename,
|
||||
.unlink = _unlink,
|
||||
.chmod = _chmod,
|
||||
.chown = _chown,
|
||||
.utimes = _utimes
|
||||
};
|
||||
|
||||
csync_vio_method_t *vio_module_init(const char *method_name, const char *args, csync_auth_callback cb) {
|
||||
DEBUG_SFTP(("csync_sftp - method_name: %s\n", method_name));
|
||||
DEBUG_SFTP(("csync_sftp - args: %s\n", args));
|
||||
|
||||
(void) method_name;
|
||||
(void) args;
|
||||
|
||||
return &_method;
|
||||
}
|
||||
|
||||
void vio_module_shutdown(csync_vio_method_t *method) {
|
||||
(void) method;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user