X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcsftp%2Fsftp_fs_memory.c;h=afa2d2291c36d259dd55b081445e6649d24b9b26;hb=1ea936cbf1bb3b19bd55839b904ef59ada84b8b5;hp=0f6745856e5d9ad27d9995a480c97fc56f5f20e4;hpb=136c61d20cf0afab840dba155b28c78c03dc5018;p=silc.git diff --git a/lib/silcsftp/sftp_fs_memory.c b/lib/silcsftp/sftp_fs_memory.c index 0f674585..afa2d229 100644 --- a/lib/silcsftp/sftp_fs_memory.c +++ b/lib/silcsftp/sftp_fs_memory.c @@ -1,10 +1,10 @@ /* - sftp_fs_memory.c + sftp_fs_memory.c Author: Pekka Riikonen - Copyright (C) 2001 Pekka Riikonen + Copyright (C) 2001 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ /* $Id$ */ /* XXX TODO Win32 support */ -#include "silcincludes.h" +#include "silc.h" #include "silcsftp.h" #include "silcsftp_fs.h" #include "sftp_util.h" @@ -33,7 +33,7 @@ typedef struct MemFSEntryStruct { 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 */ + SilcUInt32 created; /* Time of creation */ char *name; /* Name of the entry */ char *data; /* Data of the entry */ unsigned int directory : 1; /* Set if this is directory */ @@ -58,7 +58,7 @@ typedef struct { /* Generates absolute path from relative path that may include '.' and '..' in the path. */ -static char *mem_expand_path(MemFSEntry root, const char *path) +static char *memfs_expand_path(MemFSEntry root, const char *path) { if (!strstr(path, "./") && !strstr(path, "../") && !strstr(path, "/..") && !strstr(path, "/.")) @@ -70,14 +70,14 @@ static char *mem_expand_path(MemFSEntry root, const char *path) /* Add `entry' to directory `dir'. */ -static bool mem_add_entry(MemFSEntry dir, MemFSEntry entry, - bool check_perm) +static SilcBool memfs_add_entry(MemFSEntry dir, MemFSEntry entry, + SilcBool check_perm) { int i; /* Must be both write and exec permissions */ - if (check_perm && - !((dir->perm & SILC_SFTP_FS_PERM_WRITE) && + if (check_perm && + !((dir->perm & SILC_SFTP_FS_PERM_WRITE) && (dir->perm & SILC_SFTP_FS_PERM_EXEC))) return FALSE; @@ -115,7 +115,7 @@ static bool mem_add_entry(MemFSEntry dir, MemFSEntry entry, /* Removes entry `entry' and all entries under it recursively. */ -static bool mem_del_entry(MemFSEntry entry, bool check_perm) +static SilcBool memfs_del_entry(MemFSEntry entry, SilcBool check_perm) { int i; @@ -129,7 +129,7 @@ static bool mem_del_entry(MemFSEntry entry, bool check_perm) /* Delete all entries recursively under this entry */ for (i = 0; i < entry->entry_count; i++) { if (entry->entry[i]) { - if (!mem_del_entry(entry->entry[i], FALSE)) + if (!memfs_del_entry(entry->entry[i], FALSE)) return FALSE; } } @@ -150,11 +150,11 @@ static bool mem_del_entry(MemFSEntry entry, bool check_perm) return TRUE; } -/* Finds first occurence of entry named `name' under the directory `dir'. +/* Finds first occurence of entry named `name' under the directory `dir'. This does not check subdirectories recursively. */ -static MemFSEntry mem_find_entry(MemFSEntry dir, const char *name, - SilcUInt32 name_len) +static MemFSEntry memfs_find_entry(MemFSEntry dir, const char *name, + SilcUInt32 name_len) { int i; @@ -172,13 +172,13 @@ static MemFSEntry mem_find_entry(MemFSEntry dir, const char *name, /* Finds the entry by the `path' which may include full path or relative path. */ -static MemFSEntry mem_find_entry_path(MemFSEntry dir, const char *p) +static MemFSEntry memfs_find_entry_path(MemFSEntry dir, const char *p) { MemFSEntry entry = NULL; int len; char *path, *cp; - cp = path = mem_expand_path(dir, p); + cp = path = memfs_expand_path(dir, p); if (strlen(cp) == 1 && cp[0] == '/') return dir; @@ -187,7 +187,7 @@ static MemFSEntry mem_find_entry_path(MemFSEntry dir, const char *p) cp++; len = strcspn(cp, DIR_SEPARATOR); while (cp && len) { - entry = mem_find_entry(dir, cp, len); + entry = memfs_find_entry(dir, cp, len); if (!entry) { silc_free(cp); return NULL; @@ -207,8 +207,8 @@ static MemFSEntry mem_find_entry_path(MemFSEntry dir, const char *p) /* Deletes entry by the name `name' from the directory `dir'. This does not check subdirectories recursively. */ -static bool mem_del_entry_name(MemFSEntry dir, const char *name, - SilcUInt32 name_len, bool check_perm) +static SilcBool memfs_del_entry_name(MemFSEntry dir, const char *name, + SilcUInt32 name_len, SilcBool check_perm) { MemFSEntry entry; @@ -216,17 +216,17 @@ static bool mem_del_entry_name(MemFSEntry dir, const char *name, if (check_perm) return FALSE; - entry = mem_find_entry(dir, name, name_len); + entry = memfs_find_entry(dir, name, name_len); if (entry) - return mem_del_entry(entry, check_perm); + return memfs_del_entry(entry, check_perm); return FALSE; } /* Create new handle and add it to the list of open handles. */ -static MemFSFileHandle mem_create_handle(MemFS fs, int fd, MemFSEntry entry) +static MemFSFileHandle memfs_create_handle(MemFS fs, int fd, MemFSEntry entry) { MemFSFileHandle handle; int i; @@ -275,7 +275,7 @@ static MemFSFileHandle mem_create_handle(MemFS fs, int fd, MemFSEntry entry) /* Deletes the handle and remove it from the open handle list. */ -static bool mem_del_handle(MemFS fs, MemFSFileHandle handle) +static SilcBool memfs_del_handle(MemFS fs, MemFSFileHandle handle) { if (handle->handle > fs->handles_count) return FALSE; @@ -296,7 +296,7 @@ static bool mem_del_handle(MemFS fs, MemFSFileHandle handle) /* Find handle by handle index. */ -static MemFSFileHandle mem_find_handle(MemFS fs, SilcUInt32 handle) +static MemFSFileHandle memfs_find_handle(MemFS fs, SilcUInt32 handle) { if (handle > fs->handles_count) return NULL; @@ -335,9 +335,14 @@ SilcSFTPFilesystem silc_sftp_fs_memory_alloc(SilcSFTPFSMemoryPerm perm) fs->root_perm = perm; fs->root->directory = TRUE; fs->root->name = strdup(DIR_SEPARATOR); + if (!fs->root->name) { + silc_free(fs->root); + silc_free(fs); + } filesystem = silc_calloc(1, sizeof(*filesystem)); if (!filesystem) { + silc_free(fs->root->name); silc_free(fs->root); silc_free(fs); return NULL; @@ -380,12 +385,19 @@ void *silc_sftp_fs_memory_add_dir(SilcSFTPFilesystem fs, void *dir, return NULL; entry->perm = perm; - entry->name = strdup(name); entry->directory = TRUE; entry->parent = dir ? dir : memfs->root; + entry->name = strdup(name); + if (!entry->name) { + silc_free(entry); + return NULL; + } - if (!mem_add_entry(dir ? dir : memfs->root, entry, FALSE)) + if (!memfs_add_entry(dir ? dir : memfs->root, entry, FALSE)) { + silc_free(entry->name); + silc_free(entry); return NULL; + } return entry; } @@ -397,16 +409,16 @@ void *silc_sftp_fs_memory_add_dir(SilcSFTPFilesystem fs, void *dir, 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(SilcSFTPFilesystem fs, void *dir) +SilcBool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir) { MemFS memfs = (MemFS)fs->fs_context; - bool ret; + SilcBool ret; if (dir) - return mem_del_entry(dir, FALSE); + return memfs_del_entry(dir, FALSE); /* Remove from root */ - ret = mem_del_entry(memfs->root, FALSE); + ret = memfs_del_entry(memfs->root, FALSE); memfs->root = silc_calloc(1, sizeof(*memfs->root)); if (!memfs->root) @@ -415,6 +427,11 @@ bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir) memfs->root->perm = memfs->root_perm; memfs->root->directory = TRUE; memfs->root->name = strdup(DIR_SEPARATOR); + if (!memfs->root->name) { + silc_free(memfs->root); + memfs->root = NULL; + return FALSE; + } return ret; } @@ -427,10 +444,10 @@ bool silc_sftp_fs_memory_del_dir(SilcSFTPFilesystem fs, void *dir) file and they work in POSIX style. Returns TRUE if the file was added to the directory. */ -bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, - SilcSFTPFSMemoryPerm perm, - const char *filename, - const char *realpath) +SilcBool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, + SilcSFTPFSMemoryPerm perm, + const char *filename, + const char *realpath) { MemFS memfs = (MemFS)fs->fs_context; MemFSEntry entry; @@ -440,31 +457,37 @@ bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir, return FALSE; entry->perm = perm; + entry->directory = FALSE; entry->name = strdup(filename); entry->data = strdup(realpath); - entry->directory = FALSE; + if (!entry->name || !entry->data) { + silc_free(entry->name); + silc_free(entry->data); + silc_free(entry); + return FALSE; + } - return mem_add_entry(dir ? dir : memfs->root, entry, FALSE); + return memfs_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(SilcSFTPFilesystem fs, void *dir, - const char *filename) +SilcBool silc_sftp_fs_memory_del_file(SilcSFTPFilesystem fs, void *dir, + const char *filename) { MemFS memfs = (MemFS)fs->fs_context; if (!filename) return FALSE; - return mem_del_entry_name(dir ? dir : memfs->root, filename, + return memfs_del_entry_name(dir ? dir : memfs->root, filename, strlen(filename), FALSE); } -SilcSFTPHandle mem_get_handle(void *context, SilcSFTP sftp, - const unsigned char *data, - SilcUInt32 data_len) +SilcSFTPHandle memfs_get_handle(void *context, SilcSFTP sftp, + const unsigned char *data, + SilcUInt32 data_len) { MemFS fs = (MemFS)context; SilcUInt32 handle; @@ -473,12 +496,12 @@ SilcSFTPHandle mem_get_handle(void *context, SilcSFTP sftp, return NULL; SILC_GET32_MSB(handle, data); - return (SilcSFTPHandle)mem_find_handle(fs, handle); + return (SilcSFTPHandle)memfs_find_handle(fs, handle); } -unsigned char *mem_encode_handle(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcUInt32 *handle_len) +unsigned char *memfs_encode_handle(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcUInt32 *handle_len) { unsigned char *data; MemFSFileHandle h = (MemFSFileHandle)handle; @@ -492,12 +515,12 @@ unsigned char *mem_encode_handle(void *context, SilcSFTP sftp, return data; } -void mem_open(void *context, SilcSFTP sftp, - const char *filename, - SilcSFTPFileOperation pflags, - SilcSFTPAttributes attrs, - SilcSFTPHandleCallback callback, - void *callback_context) +void memfs_open(void *context, SilcSFTP sftp, + const char *filename, + SilcSFTPFileOperation pflags, + SilcSFTPAttributes attrs, + SilcSFTPHandleCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; MemFSEntry entry; @@ -511,7 +534,7 @@ void mem_open(void *context, SilcSFTP sftp, } /* Find such file */ - entry = mem_find_entry_path(fs->root, filename); + entry = memfs_find_entry_path(fs->root, filename); if (!entry) { (*callback)(sftp, SILC_SFTP_STATUS_NO_SUCH_FILE, NULL, callback_context); return; @@ -520,20 +543,20 @@ void mem_open(void *context, SilcSFTP sftp, if (entry->directory || !entry->data) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } /* Check for reading */ - if ((pflags & SILC_SFTP_FXF_READ) && + if ((pflags & SILC_SFTP_FXF_READ) && !(entry->perm & SILC_SFTP_FS_PERM_READ)) { - (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, callback_context); return; - } + } /* Check for writing */ - if (((pflags & SILC_SFTP_FXF_WRITE) || (pflags & SILC_SFTP_FXF_APPEND)) && + if (((pflags & SILC_SFTP_FXF_WRITE) || (pflags & SILC_SFTP_FXF_APPEND)) && !(entry->perm & SILC_SFTP_FS_PERM_WRITE)) { - (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, callback_context); return; } @@ -548,28 +571,28 @@ void mem_open(void *context, SilcSFTP sftp, flags |= O_APPEND; /* Attempt to open the file for real. */ - fd = silc_file_open_mode(entry->data + 7, flags, + 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); + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, callback_context); return; } /* File opened, return handle */ - handle = mem_create_handle(fs, fd, entry); + handle = memfs_create_handle(fs, fd, entry); if (handle) - (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle, callback_context); else - (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, callback_context); } -void mem_close(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_close(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPStatusCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; MemFSFileHandle h = (MemFSFileHandle)handle; @@ -578,36 +601,39 @@ void mem_close(void *context, SilcSFTP sftp, if (h->fd != -1) { ret = silc_file_close(h->fd); if (ret == -1) { - (*callback)(sftp, silc_sftp_map_errno(errno), NULL, NULL, + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, NULL, callback_context); return; } } - mem_del_handle(fs, h); + memfs_del_handle(fs, h); (*callback)(sftp, SILC_SFTP_STATUS_OK, NULL, NULL, callback_context); } -void mem_read(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcUInt64 offset, - SilcUInt32 len, - SilcSFTPDataCallback callback, - void *callback_context) +void memfs_read(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcUInt64 offset, + SilcUInt32 len, + SilcSFTPDataCallback callback, + void *callback_context) { MemFSFileHandle h = (MemFSFileHandle)handle; - unsigned char *data; + unsigned char data[63488]; int ret; - if (len > 32768) - len = 32768; + if (len > 63488) + len = 63488; - data = silc_malloc(len); - if (!data) { - (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, 0, callback_context); + ret = lseek(h->fd, (off_t)offset, SEEK_SET); + if (ret < 0) { + if (!ret) + (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, 0, callback_context); + else + (*callback)(sftp, silc_sftp_map_errno(silc_errno), + NULL, 0, callback_context); return; } - lseek(h->fd, (off_t)offset, SEEK_SET); /* Attempt to read */ ret = silc_file_read(h->fd, data, len); @@ -615,25 +641,23 @@ void mem_read(void *context, SilcSFTP sftp, if (!ret) (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, 0, callback_context); else - (*callback)(sftp, silc_sftp_map_errno(errno), NULL, 0, callback_context); - silc_free(data); + (*callback)(sftp, silc_sftp_map_errno(silc_errno), + NULL, 0, callback_context); return; } /* Return data */ - (*callback)(sftp, SILC_SFTP_STATUS_OK, (const unsigned char *)data, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (const unsigned char *)data, ret, callback_context); - - silc_free(data); } -void mem_write(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcUInt64 offset, - const unsigned char *data, - SilcUInt32 data_len, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_write(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcUInt64 offset, + const unsigned char *data, + SilcUInt32 data_len, + SilcSFTPStatusCallback callback, + void *callback_context) { MemFSFileHandle h = (MemFSFileHandle)handle; int ret; @@ -643,7 +667,7 @@ void mem_write(void *context, SilcSFTP sftp, /* Attempt to write */ ret = silc_file_write(h->fd, data, data_len); if (ret <= 0) { - (*callback)(sftp, silc_sftp_map_errno(errno), NULL, NULL, + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, NULL, callback_context); return; } @@ -651,52 +675,52 @@ void mem_write(void *context, SilcSFTP sftp, (*callback)(sftp, SILC_SFTP_STATUS_OK, NULL, NULL, callback_context); } -void mem_remove(void *context, SilcSFTP sftp, - const char *filename, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_remove(void *context, SilcSFTP sftp, + const char *filename, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Remove is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_rename(void *context, SilcSFTP sftp, - const char *oldname, - const char *newname, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_rename(void *context, SilcSFTP sftp, + const char *oldname, + const char *newname, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Rename is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_mkdir(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_mkdir(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Mkdir is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_rmdir(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_rmdir(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Rmdir is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_opendir(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPHandleCallback callback, - void *callback_context) +void memfs_opendir(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPHandleCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; MemFSEntry entry; @@ -706,7 +730,7 @@ void mem_opendir(void *context, SilcSFTP sftp, path = (const char *)DIR_SEPARATOR; /* Find such directory */ - entry = mem_find_entry_path(fs->root, path); + entry = memfs_find_entry_path(fs->root, path); if (!entry) { (*callback)(sftp, SILC_SFTP_STATUS_NO_SUCH_FILE, NULL, callback_context); return; @@ -715,29 +739,29 @@ void mem_opendir(void *context, SilcSFTP sftp, if (!entry->directory) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } /* Must be read permissions to open a directory */ if (!(entry->perm & SILC_SFTP_FS_PERM_READ)) { - (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, callback_context); return; } /* Directory opened, return handle */ - handle = mem_create_handle(fs, 0, entry); + handle = memfs_create_handle(fs, 0, entry); if (handle) - (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle, callback_context); else - (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL, callback_context); } -void mem_readdir(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPNameCallback callback, - void *callback_context) +void memfs_readdir(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPNameCallback callback, + void *callback_context) { MemFSFileHandle h = (MemFSFileHandle)handle; MemFSEntry entry; @@ -747,7 +771,7 @@ void mem_readdir(void *context, SilcSFTP sftp, char long_name[256]; SilcUInt64 filesize = 0; char *date; - struct stat stats; + SilcFileStatStruct stats; if (!h->entry->directory) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); @@ -775,28 +799,32 @@ void mem_readdir(void *context, SilcSFTP sftp, filesize = sizeof(*entry); memset(long_name, 0, sizeof(long_name)); - date = ctime(&entry->created); + date = (char *)silc_time_string(entry->created); if (strrchr(date, ':')) *strrchr(date, ':') = '\0'; if (!entry->directory) { filesize = silc_file_size(entry->data + 7); - memset(&stats, 0, sizeof(stats)); - stat(entry->data + 7, &stats); + silc_file_stat(entry->data + 7, TRUE, &stats); } /* Long name format is: drwx------ 1 324210 Apr 8 08:40 mail/ 1234567890 123 12345678 123456789012 */ - snprintf(long_name, sizeof(long_name) - 1, + silc_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' : '-'), ((entry->perm & SILC_SFTP_FS_PERM_EXEC) ? 'x' : '-'), (entry->directory ? (int)entry->entry_count : 1), - filesize, date, entry->name, - (entry->directory ? "/" : +#ifndef SILC_WIN32 + (unsigned long long)filesize, +#else + (unsigned long)filesize, +#endif + date, entry->name, + (entry->directory ? "/" : ((entry->perm & SILC_SFTP_FS_PERM_EXEC) ? "*" : ""))); /* Add attributes */ @@ -812,8 +840,8 @@ void mem_readdir(void *context, SilcSFTP sftp, attrs->gid = 0; if (!entry->directory) { attrs->flags |= SILC_SFTP_ATTR_ACMODTIME; - attrs->atime = stats.st_atime; - attrs->mtime = stats.st_mtime; + attrs->atime = silc_time_epoch(&stats.last_access); + attrs->mtime = silc_time_epoch(&stats.last_mod); } /* Add the name */ @@ -840,22 +868,21 @@ void mem_readdir(void *context, SilcSFTP sftp, silc_sftp_name_free(name); } -void mem_stat(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttrCallback callback, - void *callback_context) +void memfs_stat(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttrCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; MemFSEntry entry; SilcSFTPAttributes attrs; - int ret; - struct stat stats; + SilcFileStatStruct stats; if (!path || !strlen(path)) path = (const char *)DIR_SEPARATOR; /* Find such directory */ - entry = mem_find_entry_path(fs->root, path); + entry = memfs_find_entry_path(fs->root, path); if (!entry) { (*callback)(sftp, SILC_SFTP_STATUS_NO_SUCH_FILE, NULL, callback_context); return; @@ -864,12 +891,11 @@ void mem_stat(void *context, SilcSFTP sftp, if (entry->directory || !entry->data) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } /* Get real stat */ - ret = stat(entry->data + 7, &stats); - if (ret == -1) { - (*callback)(sftp, silc_sftp_map_errno(errno), NULL, callback_context); + if (!silc_file_stat(entry->data + 7, TRUE, &stats)) { + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, callback_context); return; } @@ -877,39 +903,38 @@ void mem_stat(void *context, SilcSFTP sftp, if (!attrs) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } attrs->flags = (SILC_SFTP_ATTR_SIZE | SILC_SFTP_ATTR_UIDGID | SILC_SFTP_ATTR_ACMODTIME); - attrs->size = stats.st_size; + attrs->size = stats.size; attrs->uid = 0; /* We use always 0 UID and GID */ attrs->gid = 0; - attrs->atime = stats.st_atime; - attrs->mtime = stats.st_mtime; + attrs->atime = silc_time_epoch(&stats.last_access); + attrs->mtime = silc_time_epoch(&stats.last_mod); /* Return attributes */ - (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, callback_context); silc_sftp_attr_free(attrs); } -void mem_lstat(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttrCallback callback, - void *callback_context) +void memfs_lstat(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttrCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; MemFSEntry entry; SilcSFTPAttributes attrs; - int ret; - struct stat stats; + SilcFileStatStruct stats; if (!path || !strlen(path)) path = (const char *)DIR_SEPARATOR; /* Find such directory */ - entry = mem_find_entry_path(fs->root, path); + entry = memfs_find_entry_path(fs->root, path); if (!entry) { (*callback)(sftp, SILC_SFTP_STATUS_NO_SUCH_FILE, NULL, callback_context); return; @@ -918,16 +943,11 @@ void mem_lstat(void *context, SilcSFTP sftp, if (entry->directory || !entry->data) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } /* 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); + if (!silc_file_stat(entry->data + 7, FALSE, &stats)) { + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, callback_context); return; } @@ -935,42 +955,40 @@ void mem_lstat(void *context, SilcSFTP sftp, if (!attrs) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } attrs->flags = (SILC_SFTP_ATTR_SIZE | SILC_SFTP_ATTR_UIDGID | SILC_SFTP_ATTR_ACMODTIME); - attrs->size = stats.st_size; + attrs->size = stats.size; attrs->uid = 0; /* We use always 0 UID and GID */ attrs->gid = 0; - attrs->atime = stats.st_atime; - attrs->mtime = stats.st_mtime; + attrs->atime = silc_time_epoch(&stats.last_access); + attrs->mtime = silc_time_epoch(&stats.last_mod); /* Return attributes */ - (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, callback_context); silc_sftp_attr_free(attrs); } -void mem_fstat(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPAttrCallback callback, - void *callback_context) +void memfs_fstat(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPAttrCallback callback, + void *callback_context) { MemFSFileHandle h = (MemFSFileHandle)handle; SilcSFTPAttributes attrs; - int ret; - struct stat stats; + SilcFileStatStruct stats; if (h->entry->directory || !h->entry->data) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } /* Get real stat */ - ret = fstat(h->fd, &stats); - if (ret == -1) { - (*callback)(sftp, silc_sftp_map_errno(errno), NULL, callback_context); + if (!silc_file_fstat(h->fd, &stats)) { + (*callback)(sftp, silc_sftp_map_errno(silc_errno), NULL, callback_context); return; } @@ -978,70 +996,70 @@ void mem_fstat(void *context, SilcSFTP sftp, if (!attrs) { (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); return; - } + } attrs->flags = (SILC_SFTP_ATTR_SIZE | SILC_SFTP_ATTR_UIDGID | SILC_SFTP_ATTR_ACMODTIME); - attrs->size = stats.st_size; + attrs->size = stats.size; attrs->uid = 0; /* We use always 0 UID and GID */ attrs->gid = 0; - attrs->atime = stats.st_atime; - attrs->mtime = stats.st_mtime; + attrs->atime = silc_time_epoch(&stats.last_access); + attrs->mtime = silc_time_epoch(&stats.last_mod); /* Return attributes */ - (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPAttributes)attrs, callback_context); silc_sftp_attr_free(attrs); } - -void mem_setstat(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context) + +void memfs_setstat(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Setstat is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_fsetstat(void *context, SilcSFTP sftp, - SilcSFTPHandle handle, - SilcSFTPAttributes attrs, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_fsetstat(void *context, SilcSFTP sftp, + SilcSFTPHandle handle, + SilcSFTPAttributes attrs, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Fsetstat is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_readlink(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPNameCallback callback, - void *callback_context) +void memfs_readlink(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPNameCallback callback, + void *callback_context) { /* Readlink is not supported */ (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, callback_context); } -void mem_symlink(void *context, SilcSFTP sftp, - const char *linkpath, - const char *targetpath, - SilcSFTPStatusCallback callback, - void *callback_context) +void memfs_symlink(void *context, SilcSFTP sftp, + const char *linkpath, + const char *targetpath, + SilcSFTPStatusCallback callback, + void *callback_context) { /* Symlink is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, NULL, callback_context); } -void mem_realpath(void *context, SilcSFTP sftp, - const char *path, - SilcSFTPNameCallback callback, - void *callback_context) +void memfs_realpath(void *context, SilcSFTP sftp, + const char *path, + SilcSFTPNameCallback callback, + void *callback_context) { MemFS fs = (MemFS)context; char *realpath; @@ -1050,7 +1068,7 @@ void mem_realpath(void *context, SilcSFTP sftp, if (!path || !strlen(path)) path = (const char *)DIR_SEPARATOR; - realpath = mem_expand_path(fs->root, path); + realpath = memfs_expand_path(fs->root, path); if (!realpath) goto fail; @@ -1074,7 +1092,7 @@ void mem_realpath(void *context, SilcSFTP sftp, goto fail; name->count = 1; - (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, (const SilcSFTPName)name, + (*callback)(sftp, SILC_SFTP_STATUS_OK, (const SilcSFTPName)name, callback_context); silc_sftp_name_free(name); @@ -1084,38 +1102,38 @@ void mem_realpath(void *context, SilcSFTP sftp, (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context); } -void mem_extended(void *context, SilcSFTP sftp, - const char *request, - const unsigned char *data, - SilcUInt32 data_len, - SilcSFTPExtendedCallback callback, - void *callback_context) +void memfs_extended(void *context, SilcSFTP sftp, + const char *request, + const unsigned char *data, + SilcUInt32 data_len, + SilcSFTPExtendedCallback callback, + void *callback_context) { /* Extended is not supported */ - (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, 0, + (*callback)(sftp, SILC_SFTP_STATUS_OP_UNSUPPORTED, NULL, 0, callback_context); } const struct SilcSFTPFilesystemOpsStruct silc_sftp_fs_memory = { - mem_get_handle, - mem_encode_handle, - mem_open, - mem_close, - mem_read, - mem_write, - mem_remove, - mem_rename, - mem_mkdir, - mem_rmdir, - mem_opendir, - mem_readdir, - mem_stat, - mem_lstat, - mem_fstat, - mem_setstat, - mem_fsetstat, - mem_readlink, - mem_symlink, - mem_realpath, - mem_extended + memfs_get_handle, + memfs_encode_handle, + memfs_open, + memfs_close, + memfs_read, + memfs_write, + memfs_remove, + memfs_rename, + memfs_mkdir, + memfs_rmdir, + memfs_opendir, + memfs_readdir, + memfs_stat, + memfs_lstat, + memfs_fstat, + memfs_setstat, + memfs_fsetstat, + memfs_readlink, + memfs_symlink, + memfs_realpath, + memfs_extended };