#define DIR_SEPARATOR "/"
+struct SilcSFTPFilesystemOpsStruct silc_sftp_fs_memory;
+
/* Memory filesystem entry */
typedef struct MemFSEntryStruct {
char *name; /* Name of the entry */
bool directory; /* TRUE if this is directory */
SilcSFTPFSMemoryPerm perm; /* Permissions */
struct MemFSEntryStruct **entry; /* Files and sub-directories */
- uint32 entry_count; /* Number of files and sub-directories */
+ SilcUInt32 entry_count; /* Number of files and sub-directories */
struct MemFSEntryStruct *parent; /* non-NULL if `directory' is TRUE,
includes parent directory. */
unsigned long created; /* Time of creation */
/* File handle. */
typedef struct {
- uint32 handle; /* Handle index */
+ SilcUInt32 handle; /* Handle index */
int fd; /* Real file handle */
MemFSEntry entry; /* Filesystem entry */
} *MemFSFileHandle;
MemFSEntry root; /* Root of the filesystem hierarchy */
SilcSFTPFSMemoryPerm root_perm;
MemFSFileHandle *handles; /* Open file handles */
- uint32 handles_count;
+ SilcUInt32 handles_count;
} *MemFS;
/* Generates absolute path from relative path that may include '.' and '..'
This does not check subdirectories recursively. */
static MemFSEntry mem_find_entry(MemFSEntry dir, const char *name,
- uint32 name_len)
+ SilcUInt32 name_len)
{
int i;
not check subdirectories recursively. */
static bool mem_del_entry_name(MemFSEntry dir, const char *name,
- uint32 name_len, bool check_perm)
+ SilcUInt32 name_len, bool check_perm)
{
MemFSEntry entry;
if (fs->handles[handle->handle] == handle) {
fs->handles[handle->handle] = NULL;
if (handle->fd != -1)
- close(handle->fd);
+ silc_file_close(handle->fd);
silc_free(handle);
return TRUE;
}
/* Find handle by handle index. */
-static MemFSFileHandle mem_find_handle(MemFS fs, uint32 handle)
+static MemFSFileHandle mem_find_handle(MemFS fs, SilcUInt32 handle)
{
if (handle > fs->handles_count)
return NULL;
silc_sftp_fs_memory_free. The `perm' is the permissions for the root
directory of the filesystem (/ dir). */
-void *silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm)
+SilcSFTPFilesystem silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm)
{
+ SilcSFTPFilesystem filesystem;
MemFS fs;
fs = silc_calloc(1, sizeof(*fs));
fs->root->directory = TRUE;
fs->root->name = strdup(DIR_SEPARATOR);
- return (void *)fs;
+ filesystem = silc_calloc(1, sizeof(*filesystem));
+ filesystem->fs = &silc_sftp_fs_memory;
+ filesystem->fs_context = (void *)fs;
+
+ return filesystem;
}
/* Frees the memory filesystem context. */
-void silc_sftp_fs_memory_free(void *context)
+void silc_sftp_fs_memory_free(SilcSFTPFilesystem fs)
{
- MemFS fs = (MemFS)context;
+ MemFS memfs = (MemFS)fs->fs_context;
- silc_free(fs->root);
- silc_free(fs);
+ silc_free(memfs->root);
+ silc_free(memfs);
}
/* Adds a new directory to the memory filesystem. Returns the directory
not free the returned context. The `perm' will indicate the permissions
for the directory and they work in POSIX style. */
-void *silc_sftp_fs_memory_add_dir(void *context, void *dir,
+void *silc_sftp_fs_memory_add_dir(SilcSFTPFilesystem fs, void *dir,
SilcSFTPFSMemoryPerm perm,
const char *name)
{
- MemFS fs = (MemFS)context;
+ MemFS memfs = (MemFS)fs->fs_context;
MemFSEntry entry;
entry = silc_calloc(1, sizeof(*entry));
entry->perm = perm;
entry->name = strdup(name);
entry->directory = TRUE;
- entry->parent = dir ? dir : fs->root;
+ entry->parent = dir ? dir : memfs->root;
- if (!mem_add_entry(dir ? dir : fs->root, entry, FALSE))
+ if (!mem_add_entry(dir ? dir : memfs->root, entry, FALSE))
return NULL;
return entry;
in memory file system. The filesystem does not allow removing directories
with remote access using the filesystem access function sftp_rmdir. */
-bool silc_sftp_fs_memory_del_dir(void *context, void *dir)
+bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir)
{
- MemFS fs = (MemFS)context;
+ MemFS memfs = (MemFS)fs->fs_context;
bool ret;
if (dir)
return mem_del_entry(dir, FALSE);
/* Remove from root */
- ret = mem_del_entry(fs->root, FALSE);
+ ret = mem_del_entry(memfs->root, FALSE);
- fs->root = silc_calloc(1, sizeof(*fs->root));
- fs->root->perm = fs->root_perm;
- fs->root->directory = TRUE;
- fs->root->name = strdup(DIR_SEPARATOR);
+ memfs->root = silc_calloc(1, sizeof(*memfs->root));
+ memfs->root->perm = memfs->root_perm;
+ memfs->root->directory = TRUE;
+ memfs->root->name = strdup(DIR_SEPARATOR);
return ret;
}
file and they work in POSIX style. Returns TRUE if the file was
added to the directory. */
-bool silc_sftp_fs_memory_add_file(void *context,
- void *dir,
+bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir,
SilcSFTPFSMemoryPerm perm,
const char *filename,
const char *realpath)
{
- MemFS fs = (MemFS)context;
+ MemFS memfs = (MemFS)fs->fs_context;
MemFSEntry entry;
entry = silc_calloc(1, sizeof(*entry));
entry->data = strdup(realpath);
entry->directory = FALSE;
- return mem_add_entry(dir ? dir : fs->root, entry, FALSE);
+ return mem_add_entry(dir ? dir : memfs->root, entry, FALSE);
}
/* Removes a file indicated by the `filename' from the directory
indicated by the `dir'. Returns TRUE if the removing was success. */
-bool silc_sftp_fs_memory_del_file(void *context, void *dir,
+bool silc_sftp_fs_memory_del_file(SilcSFTPFilesystem fs, void *dir,
const char *filename)
{
- MemFS fs = (MemFS)context;
+ MemFS memfs = (MemFS)fs->fs_context;
if (!filename)
return FALSE;
- return mem_del_entry_name(dir ? dir : fs->root, filename,
+ return mem_del_entry_name(dir ? dir : memfs->root, filename,
strlen(filename), FALSE);
}
SilcSFTPHandle mem_get_handle(void *context, SilcSFTP sftp,
const unsigned char *data,
- uint32 data_len)
+ SilcUInt32 data_len)
{
MemFS fs = (MemFS)context;
- uint32 handle;
+ SilcUInt32 handle;
if (data_len < 4)
return NULL;
unsigned char *mem_encode_handle(void *context, SilcSFTP sftp,
SilcSFTPHandle handle,
- uint32 *handle_len)
+ SilcUInt32 *handle_len)
{
unsigned char *data;
MemFSFileHandle h = (MemFSFileHandle)handle;
flags |= O_APPEND;
/* Attempt to open the file for real. */
- fd = open(entry->data + 7, flags,
- (attrs->flags & SILC_SFTP_ATTR_PERMISSIONS ?
- attrs->permissions : 0600));
+ fd = silc_file_open_mode(entry->data + 7, flags,
+ (attrs->flags & SILC_SFTP_ATTR_PERMISSIONS ?
+ attrs->permissions : 0600));
if (fd == -1) {
(*callback)(sftp, silc_sftp_map_errno(errno), NULL, callback_context);
return;
int ret;
if (h->fd != -1) {
- ret = close(h->fd);
+ ret = silc_file_close(h->fd);
if (ret == -1) {
(*callback)(sftp, silc_sftp_map_errno(errno), NULL, NULL,
callback_context);
void mem_read(void *context, SilcSFTP sftp,
SilcSFTPHandle handle,
- uint64 offset,
- uint32 len,
+ SilcUInt64 offset,
+ SilcUInt32 len,
SilcSFTPDataCallback callback,
void *callback_context)
{
lseek(h->fd, (off_t)offset, SEEK_SET);
/* Attempt to read */
- ret = read(h->fd, data, len);
+ ret = silc_file_read(h->fd, data, len);
if (ret <= 0) {
if (!ret)
(*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, 0, callback_context);
void mem_write(void *context, SilcSFTP sftp,
SilcSFTPHandle handle,
- uint64 offset,
+ SilcUInt64 offset,
const unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
SilcSFTPStatusCallback callback,
void *callback_context)
{
lseek(h->fd, (off_t)offset, SEEK_SET);
/* Attempt to write */
- ret = write(h->fd, data, data_len);
+ ret = silc_file_write(h->fd, data, data_len);
if (ret <= 0) {
(*callback)(sftp, silc_sftp_map_errno(errno), NULL, NULL,
callback_context);
MemFSFileHandle handle;
if (!path || !strlen(path))
- path = (const char *)strdup("/");
+ path = (const char *)DIR_SEPARATOR;
/* Find such directory */
entry = mem_find_entry_path(fs->root, path);
SilcSFTPAttributes attrs;
int i;
char long_name[256];
- unsigned long filesize = 0;
+ SilcUInt64 filesize = 0;
char *date;
struct stat stats;
*strrchr(date, ':') = '\0';
if (!entry->directory)
- if (!lstat(entry->data + 7, &stats))
- filesize = stats.st_size;
+ filesize = silc_file_size(entry->data + 7);
/* Long name format is:
drwx------ 1 324210 Apr 8 08:40 mail/
1234567890 123 12345678 123456789012 */
- snprintf(long_name, sizeof(long_name),
- "%c%c%c%c------ %3d %8lu %12s %s%s",
+ snprintf(long_name, sizeof(long_name) - 1,
+ "%c%c%c%c------ %3d %8llu %12s %s%s",
(entry->directory ? 'd' : '-'),
((entry->perm & SILC_SFTP_FS_PERM_READ) ? 'r' : '-'),
((entry->perm & SILC_SFTP_FS_PERM_WRITE) ? 'w' : '-'),
struct stat stats;
if (!path || !strlen(path))
- path = (const char *)strdup("/");
+ path = (const char *)DIR_SEPARATOR;
/* Find such directory */
entry = mem_find_entry_path(fs->root, path);
struct stat stats;
if (!path || !strlen(path))
- path = (const char *)strdup("/");
+ path = (const char *)DIR_SEPARATOR;
/* Find such directory */
entry = mem_find_entry_path(fs->root, path);
}
/* Get real stat */
+#ifndef SILC_WIN32
ret = lstat(entry->data + 7, &stats);
+#else
+ ret = stat(entry->data + 7, &stats);
+#endif
if (ret == -1) {
(*callback)(sftp, silc_sftp_map_errno(errno), NULL, callback_context);
return;
SilcSFTPName name;
if (!path || !strlen(path))
- path = (const char *)strdup("/");
+ path = (const char *)DIR_SEPARATOR;
realpath = mem_expand_path(fs->root, path);
if (!realpath) {
void mem_extended(void *context, SilcSFTP sftp,
const char *request,
const unsigned char *data,
- uint32 data_len,
+ SilcUInt32 data_len,
SilcSFTPExtendedCallback callback,
void *callback_context)
{
callback_context);
}
-struct SilcSFTPFilesystemStruct silc_sftp_fs_memory = {
+struct SilcSFTPFilesystemOpsStruct silc_sftp_fs_memory = {
mem_get_handle,
mem_encode_handle,
mem_open,