Typo fix.
[silc.git] / lib / silcsftp / sftp_fs_memory.c
index 0f6745856e5d9ad27d9995a480c97fc56f5f20e4..7e7c24f43716438b9fa0b1c097b5d46408af9fef 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  sftp_fs_memory.c 
+  sftp_fs_memory.c
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  Copyright (C) 2001 - 2007 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 */
@@ -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 mem_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 mem_del_entry(MemFSEntry entry, SilcBool check_perm)
 {
   int i;
 
@@ -150,7 +150,7 @@ 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,
@@ -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 mem_del_entry_name(MemFSEntry dir, const char *name,
+                                  SilcUInt32 name_len, SilcBool check_perm)
 {
   MemFSEntry entry;
 
@@ -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 mem_del_handle(MemFS fs, MemFSFileHandle handle)
 {
   if (handle->handle > fs->handles_count)
     return FALSE;
@@ -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 (!mem_add_entry(dir ? dir : memfs->root, entry, FALSE)) {
+    silc_free(entry->name);
+    silc_free(entry);
     return NULL;
+  }
 
   return entry;
 }
@@ -397,10 +409,10 @@ 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);
@@ -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,9 +457,15 @@ 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);
 }
@@ -450,15 +473,15 @@ bool silc_sftp_fs_memory_add_file(SilcSFTPFilesystem fs, void *dir,
 /* 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 mem_del_entry_name(dir ? dir : memfs->root, filename,
                            strlen(filename), FALSE);
 }
 
@@ -492,7 +515,7 @@ unsigned char *mem_encode_handle(void *context, SilcSFTP sftp,
   return data;
 }
 
-void mem_open(void *context, SilcSFTP sftp, 
+void mem_open(void *context, SilcSFTP sftp,
              const char *filename,
              SilcSFTPFileOperation pflags,
              SilcSFTPAttributes attrs,
@@ -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,7 +571,7 @@ 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) {
@@ -559,10 +582,10 @@ void mem_open(void *context, SilcSFTP sftp,
   /* File opened, return handle */
   handle = mem_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);
 }
 
@@ -578,7 +601,7 @@ 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(errno), NULL, NULL,
                  callback_context);
       return;
     }
@@ -590,24 +613,26 @@ void mem_close(void *context, SilcSFTP sftp,
 
 void mem_read(void *context, SilcSFTP sftp,
              SilcSFTPHandle handle,
-             SilcUInt64 offset, 
+             SilcUInt64 offset,
              SilcUInt32 len,
              SilcSFTPDataCallback callback,
              void *callback_context)
 {
   MemFSFileHandle h = (MemFSFileHandle)handle;
-  unsigned char *data;
+  unsigned char data[32768];
   int ret;
 
   if (len > 32768)
     len = 32768;
 
-  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(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);
@@ -616,15 +641,12 @@ void mem_read(void *context, SilcSFTP sftp,
       (*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);
     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,
@@ -643,7 +665,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(errno), NULL, NULL,
                callback_context);
     return;
   }
@@ -657,7 +679,7 @@ void mem_remove(void *context, SilcSFTP sftp,
                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);
 }
 
@@ -668,7 +690,7 @@ void mem_rename(void *context, SilcSFTP sftp,
                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);
 }
 
@@ -679,7 +701,7 @@ void mem_mkdir(void *context, SilcSFTP sftp,
               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);
 }
 
@@ -689,7 +711,7 @@ void mem_rmdir(void *context, SilcSFTP sftp,
               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);
 }
 
@@ -715,11 +737,11 @@ 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;
   }
@@ -727,10 +749,10 @@ void mem_opendir(void *context, SilcSFTP sftp,
   /* Directory opened, return handle */
   handle = mem_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);
 }
 
@@ -775,7 +797,7 @@ 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';
 
@@ -788,15 +810,20 @@ void mem_readdir(void *context, SilcSFTP sftp,
     /* 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 */
@@ -864,7 +891,7 @@ 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);
@@ -877,7 +904,7 @@ 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);
@@ -888,7 +915,7 @@ void mem_stat(void *context, SilcSFTP sftp,
   attrs->mtime = stats.st_mtime;
 
   /* 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);
@@ -918,7 +945,7 @@ 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
@@ -935,7 +962,7 @@ 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);
@@ -946,7 +973,7 @@ void mem_lstat(void *context, SilcSFTP sftp,
   attrs->mtime = stats.st_mtime;
 
   /* 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);
@@ -965,7 +992,7 @@ void mem_fstat(void *context, SilcSFTP sftp,
   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);
@@ -978,7 +1005,7 @@ 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);
@@ -989,12 +1016,12 @@ void mem_fstat(void *context, SilcSFTP sftp,
   attrs->mtime = stats.st_mtime;
 
   /* 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,
@@ -1002,7 +1029,7 @@ void mem_setstat(void *context, SilcSFTP sftp,
                 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);
 }
 
@@ -1013,7 +1040,7 @@ void mem_fsetstat(void *context, SilcSFTP sftp,
                  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);
 }
 
@@ -1034,7 +1061,7 @@ void mem_symlink(void *context, SilcSFTP sftp,
                 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);
 }
 
@@ -1074,7 +1101,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);
@@ -1092,7 +1119,7 @@ void mem_extended(void *context, SilcSFTP sftp,
                  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);
 }