Added silc_file_stat, silc_file_fstat and silc_file_fsize
authorPekka Riikonen <priikone@silcnet.org>
Sun, 3 Feb 2008 15:51:02 +0000 (17:51 +0200)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 3 Feb 2008 15:51:02 +0000 (17:51 +0200)
lib/silcutil/silcfileutil.c
lib/silcutil/silcfileutil.h
lib/silcutil/tests/test_silcdir.c
lib/silcutil/unix/silcunixdir.c

index a4b9739c2075fb040d10a5759e11f0147ff68c0d..e21da72db217e0040b8c34001ca5b5b19c5b7af0 100644 (file)
@@ -165,6 +165,11 @@ char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
   }
 
   buffer = silc_calloc(filelen + 1, sizeof(*buffer));
   }
 
   buffer = silc_calloc(filelen + 1, sizeof(*buffer));
+  if (!buffer) {
+    silc_set_errno_posix(errno);
+    silc_file_close(fd);
+    return NULL;
+  }
 
   if ((silc_file_read(fd, buffer, filelen)) == -1) {
     memset(buffer, 0, sizeof(buffer));
 
   if ((silc_file_read(fd, buffer, filelen)) == -1) {
     memset(buffer, 0, sizeof(buffer));
@@ -183,26 +188,169 @@ char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
   return (char *)buffer;
 }
 
   return (char *)buffer;
 }
 
-/* Returns the size of `filename'. Returns 0 on error. */
+/* Returns the size of `filename'. */
 
 SilcUInt64 silc_file_size(const char *filename)
 {
 
 SilcUInt64 silc_file_size(const char *filename)
 {
-  int ret;
-  struct stat stats;
+  SilcFileStatStruct status;
 
 
-#ifdef SILC_WIN32
-  ret = stat(filename, &stats);
-#endif /* SILC_WIN32 */
-#ifdef SILC_UNIX
-  ret = lstat(filename, &stats);
-#endif /* SILC_UNIX */
-#ifdef SILC_SYMBIAN
-  ret = stat(filename, &stats);
-#endif /* SILC_SYMBIAN */
-  if (ret < 0) {
-    silc_set_errno_posix(errno);
+  if (!silc_file_stat(filename, FALSE, &status))
     return 0;
     return 0;
+
+  return status.size;
+}
+
+/* Return file size */
+
+SilcUInt64 silc_file_fsize(int fd)
+{
+  SilcFileStatStruct status;
+
+  if (!silc_file_fstat(fd, &status))
+    return 0;
+
+  return status.size;
+}
+
+/* Fill file status context */
+
+static void silc_file_fill_stat(struct stat *status,
+                               SilcFileStat return_stat)
+{
+  memset(return_stat, 0, sizeof(*return_stat));
+
+  silc_time_value(status->st_atime * 1000, &return_stat->last_access);
+  silc_time_value(status->st_mtime * 1000, &return_stat->last_mod);
+  silc_time_value(status->st_ctime * 1000, &return_stat->last_change);
+
+  return_stat->rdev = status->st_rdev;
+  return_stat->dev = status->st_dev;
+  return_stat->nlink = status->st_nlink;
+  return_stat->gid = status->st_gid;
+  return_stat->uid = status->st_uid;
+  return_stat->size = status->st_size;
+
+#if defined(S_IFSOCK)
+  if (status->st_mode & S_IFSOCK)
+    return_stat->mode |= SILC_FILE_IFSOCK;
+#endif /* S_IFSOCK */
+#if defined(S_IFLNK)
+  if (status->st_mode & S_IFLNK)
+    return_stat->mode |= SILC_FILE_IFLNK;
+#endif /* S_IFLNK */
+#if defined(S_IFREG)
+  if (status->st_mode & S_IFREG)
+    return_stat->mode |= SILC_FILE_IFREG;
+#endif /* S_IFREG */
+#if defined(S_IFBLK)
+  if (status->st_mode & S_IFBLK)
+    return_stat->mode |= SILC_FILE_IFBLK;
+#endif /* S_IFBLK */
+#if defined(S_IFDIR)
+  if (status->st_mode & S_IFDIR)
+    return_stat->mode |= SILC_FILE_IFDIR;
+#endif /* S_IFDIR */
+#if defined(S_IFCHR)
+  if (status->st_mode & S_IFCHR)
+    return_stat->mode |= SILC_FILE_IFCHR;
+#endif /* S_IFCHR */
+#if defined(S_IFIFO)
+  if (status->st_mode & S_IFIFO)
+    return_stat->mode |= SILC_FILE_IFIFO;
+#endif /* S_IFIFO */
+#if defined(S_IRUSR)
+  if (status->st_mode & S_IRUSR)
+    return_stat->mode |= SILC_FILE_IRUSR;
+#endif /* S_IRUSR */
+#if defined(S_IWUSR)
+  if (status->st_mode & S_IWUSR)
+    return_stat->mode |= SILC_FILE_IWUSR;
+#endif /* S_IWUSR */
+#if defined(S_IXUSR)
+  if (status->st_mode & S_IXUSR)
+    return_stat->mode |= SILC_FILE_IXUSR;
+#endif /* S_IXUSR */
+#if defined(S_IRGRP)
+  if (status->st_mode & S_IRGRP)
+    return_stat->mode |= SILC_FILE_IRGRP;
+#endif /* S_IRGRP */
+#if defined(S_IWGRP)
+  if (status->st_mode & S_IWGRP)
+    return_stat->mode |= SILC_FILE_IWGRP;
+#endif /* S_IWGRP */
+#if defined(S_IXGRP)
+  if (status->st_mode & S_IXGRP)
+    return_stat->mode |= SILC_FILE_IXGRP;
+#endif /* S_IXGRP */
+#if defined(S_IROTH)
+  if (status->st_mode & S_IROTH)
+    return_stat->mode |= SILC_FILE_IROTH;
+#endif /* S_IROTH */
+#if defined(S_IWOTH)
+  if (status->st_mode & S_IWOTH)
+    return_stat->mode |= SILC_FILE_IWOTH;
+#endif /* S_IWOTH */
+#if defined(S_IXOTH)
+  if (status->st_mode & S_IXOTH)
+    return_stat->mode |= SILC_FILE_IXOTH;
+#endif /* S_IXOTH */
+}
+
+/* Return file status information */
+
+SilcBool silc_file_stat(const char *filename, SilcBool follow_symlinks,
+                       SilcFileStat return_stat)
+{
+  struct stat status;
+
+  if (silc_unlikely(!filename || !return_stat)) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+    return FALSE;
   }
 
   }
 
-  return (SilcUInt64)stats.st_size;
+  SILC_LOG_DEBUG(("Get status for file '%s'", filename));
+
+  if (!follow_symlinks) {
+    if (silc_unlikely(stat(filename, &status) != 0)) {
+      silc_set_errno_posix(errno);
+      return FALSE;
+    }
+  } else {
+#ifdef HAVE_LSTAT
+    if (silc_unlikely(lstat(filename, &status) != 0)) {
+      silc_set_errno_posix(errno);
+      return FALSE;
+    }
+#else
+    if (silc_unlikely(stat(filename, &status) != 0)) {
+      silc_set_errno_posix(errno);
+      return FALSE;
+    }
+#endif /* HAVE_LSTAT */
+  }
+
+  silc_file_fill_stat(&status, return_stat);
+
+  return TRUE;
+}
+
+/* Return file status information. */
+
+SilcBool silc_file_fstat(int fd, SilcFileStat return_stat)
+{
+  struct stat status;
+
+  if (silc_unlikely(!return_stat)) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+    return FALSE;
+  }
+
+  if (silc_unlikely(fstat(fd, &status) != 0)) {
+    silc_set_errno_posix(errno);
+    return FALSE;
+  }
+
+  silc_file_fill_stat(&status, return_stat);
+
+  return TRUE;
 }
 }
index a02c49b3a3126a56982f7ea234dacf3c0a33c2ca..0824553804a32a497b216e565b6f3d2aa4fe7f8c 100644 (file)
@@ -17,7 +17,7 @@
 
 */
 
 
 */
 
-/****h* silcutil/SILC File Util Interface
+/****h* silcutil/File Util Interface
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
 #ifndef SILCFILEUTIL_H
 #define SILCFILEUTIL_H
 
 #ifndef SILCFILEUTIL_H
 #define SILCFILEUTIL_H
 
+/****d* silcutil/SilcFileMode
+ *
+ * NAME
+ *
+ *    typedef enum { ... } SilcFileMode;
+ *
+ * DESCRIPTION
+ *
+ *    A file mode bits that specify the file's mode, type and protection
+ *    in the SilcFileStat context.
+ *
+ * SOURCE
+ */
+typedef enum {
+  /* Type */
+  SILC_FILE_IFDIR     = 0x00000001,  /* Entry is directory */
+  SILC_FILE_IFCHR     = 0x00000002,  /* Entry is character device */
+  SILC_FILE_IFBLK     = 0x00000004,  /* Entry is block device */
+  SILC_FILE_IFREG     = 0x00000008,  /* Entry is regular file */
+  SILC_FILE_IFIFO     = 0x00000010,  /* Entry is FIFO */
+  SILC_FILE_IFLNK     = 0x00000020,  /* Entry is symbolic link */
+  SILC_FILE_IFSOCK    = 0x00000040,  /* Entry is socket */
+
+  /* Protection */
+  SILC_FILE_IRUSR     = 0x00000080,  /* Owner has read permission */
+  SILC_FILE_IWUSR     = 0x00000100,  /* Owner has write permission */
+  SILC_FILE_IXUSR     = 0x00000200,  /* Owner has execute permission */
+  SILC_FILE_IRGRP     = 0x00000400,  /* Group has read permission */
+  SILC_FILE_IWGRP     = 0x00000800,  /* Group has write permission */
+  SILC_FILE_IXGRP     = 0x00001000,  /* Group has execute permission */
+  SILC_FILE_IROTH     = 0x00002000,  /* Others have read permission */
+  SILC_FILE_IWOTH     = 0x00004000,  /* Others have write permission */
+  SILC_FILE_IXOTH     = 0x00008000,  /* Others have execute permission */
+} SilcFileMode;
+/***/
+
+/****s* silcutil/SilcFileStat
+ *
+ * NAME
+ *
+ *    typedef struct SilcFileStatObject { ... } *SilcFileStat,
+ *                                               SilcFileStatStruct;
+ *
+ * DESCRIPTION
+ *
+ *    The file entry status information structure.  The structure contains
+ *    various information about a file.  The structure is filled by calling
+ *    the silc_file_stat or silc_file_fstat functions.
+ *
+ * SOURCE
+ */
+typedef struct SilcFileStatObject {
+  SilcTimeStruct last_access;          /* Time of last access */
+  SilcTimeStruct last_mod;             /* Time of last modification */
+  SilcTimeStruct last_change;          /* Time of last status change */
+  SilcUInt64 size;                     /* Entry size in bytes */
+  SilcUInt32 uid;                      /* Owner ID of the entry */
+  SilcUInt32 gid;                      /* Group owner ID of the entry */
+  SilcUInt32 dev;                      /* Entry device number */
+  SilcUInt32 rdev;                     /* Device number if special file */
+  SilcUInt32 nlink;                    /* Number of hard links */
+  SilcFileMode mode;                   /* Entry mode */
+} *SilcFileStat, SilcFileStatStruct;
+/***/
+
 /* Prototypes */
 
 /* Prototypes */
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_open
+/****f* silcutil/silc_file_open
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
  ***/
 int silc_file_open(const char *filename, int flags);
 
  ***/
 int silc_file_open(const char *filename, int flags);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_open_mode
+/****f* silcutil/silc_file_open_mode
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -63,7 +128,7 @@ int silc_file_open(const char *filename, int flags);
  ***/
 int silc_file_open_mode(const char *filename, int flags, int mode);
 
  ***/
 int silc_file_open_mode(const char *filename, int flags, int mode);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_read
+/****f* silcutil/silc_file_read
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -77,7 +142,7 @@ int silc_file_open_mode(const char *filename, int flags, int mode);
  ***/
 int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len);
 
  ***/
 int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_write
+/****f* silcutil/silc_file_write
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -91,7 +156,7 @@ int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len);
  ***/
 int silc_file_write(int fd, const char *buffer, SilcUInt32 len);
 
  ***/
 int silc_file_write(int fd, const char *buffer, SilcUInt32 len);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_close
+/****f* silcutil/silc_file_close
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -105,7 +170,7 @@ int silc_file_write(int fd, const char *buffer, SilcUInt32 len);
  ***/
 int silc_file_close(int fd);
 
  ***/
 int silc_file_close(int fd);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_set_nonblock
+/****f* silcutil/silc_file_set_nonblock
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -118,7 +183,7 @@ int silc_file_close(int fd);
  ***/
 int silc_file_set_nonblock(int fd);
 
  ***/
 int silc_file_set_nonblock(int fd);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_readfile
+/****f* silcutil/silc_file_readfile
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -133,7 +198,7 @@ int silc_file_set_nonblock(int fd);
  *    NULL terminated.
  *
  *    If the `return_len' pointer is not NULL, it's filled with the length of
  *    NULL terminated.
  *
  *    If the `return_len' pointer is not NULL, it's filled with the length of
- *    the file.
+ *    the file.  The returned length does not include the terminator.
  *
  *    If `stack' is non-NULL the returned buffer is allocated from `stack'.
  *    The allocation consumes `stack' so caller should push the stack before
  *
  *    If `stack' is non-NULL the returned buffer is allocated from `stack'.
  *    The allocation consumes `stack' so caller should push the stack before
@@ -143,7 +208,7 @@ int silc_file_set_nonblock(int fd);
 char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
                         SilcStack stack);
 
 char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
                         SilcStack stack);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_writefile
+/****f* silcutil/silc_file_writefile
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -159,7 +224,7 @@ char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
 int silc_file_writefile(const char *filename, const char *buffer,
                        SilcUInt32 len);
 
 int silc_file_writefile(const char *filename, const char *buffer,
                        SilcUInt32 len);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_writefile_mode
+/****f* silcutil/silc_file_writefile_mode
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -175,7 +240,7 @@ int silc_file_writefile(const char *filename, const char *buffer,
 int silc_file_writefile_mode(const char *filename, const char *buffer,
                             SilcUInt32 len, int mode);
 
 int silc_file_writefile_mode(const char *filename, const char *buffer,
                             SilcUInt32 len, int mode);
 
-/****f* silcutil/SilcFileUtilAPI/silc_file_size
+/****f* silcutil/silc_file_size
  *
  * SYNOPSIS
  *
  *
  * SYNOPSIS
  *
@@ -183,9 +248,63 @@ int silc_file_writefile_mode(const char *filename, const char *buffer,
  *
  * DESCRIPTION
  *
  *
  * DESCRIPTION
  *
- *    Returns the size of `filename'. Returns 0 on error.
+ *    Returns the size of `filename'.  Returns 0 on error and sets silc_errno.
+ *    If silc_errno is not set the file size is 0 bytes if this returns 0.
  *
  ***/
 SilcUInt64 silc_file_size(const char *filename);
 
  *
  ***/
 SilcUInt64 silc_file_size(const char *filename);
 
+/****f* silcutil/silc_file_fsize
+ *
+ * SYNOPSIS
+ *
+ *    SilcUInt64 silc_file_fsize(int fd);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the size of the file indicated by open file descriptor `fd'.
+ *    Returns 0 on error and sets silc_errno.  If silc_errno is not set the
+ *    file size is 0 bytes if this returns 0.
+ *
+ ***/
+SilcUInt64 silc_file_fsize(int fd);
+
+/****f* silcutil/silc_file_stat
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_file_stat(const char *filename, SilcBool follow_symlinks,
+ *                            SilcFileStat return_stat);
+ *
+ * DESCRIPTION
+ *
+ *    Returns status information of a file named `filename'.  The status
+ *    information is returned to `return_stat' structure.  If the
+ *    `follow_symlinks' is TRUE this will return the status of the file the
+ *    symlink referts to.  If it is FALSE, returns the status of the link
+ *    itself.
+ *
+ *    Returns FALSE on error and sets the silc_errno.  Returns TRUE otherwise.
+ *
+ ***/
+SilcBool silc_file_stat(const char *filename, SilcBool follow_symlinks,
+                       SilcFileStat return_stat);
+
+/****f* silcutil/silc_file_fstat
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_file_fstat(int fd, SilcFileStat return_stat);
+ *
+ * DESCRIPTION
+ *
+ *    Returns status information of a opened file indicated by the file
+ *    descriptor `fd'.  The status information is returned to the
+ *    `return_stat' structure.
+ *
+ *    Returns FALSE on error and sets the silc_errno.  Returns TRUE otherwise.
+ *
+ ***/
+SilcBool silc_file_fstat(int fd, SilcFileStat return_stat);
+
 #endif /* !SILCFILEUTIL_H */
 #endif /* !SILCFILEUTIL_H */
index 151aad67862aaf4626da4551f54e8f94f2eac2a9..3f8bff74ca08c95b81531c91a7dff94b516ba4cd 100644 (file)
@@ -7,7 +7,7 @@ int main(int argc, char **argv)
   SilcBool success = FALSE;
   SilcDir dir;
   SilcDirEntry entry;
   SilcBool success = FALSE;
   SilcDir dir;
   SilcDirEntry entry;
-  SilcDirEntryStat status;
+  SilcFileStatStruct status;
 
   if (argc > 1 && !strcmp(argv[1], "-d")) {
     silc_log_debug(TRUE);
 
   if (argc > 1 && !strcmp(argv[1], "-d")) {
     silc_log_debug(TRUE);
@@ -24,19 +24,19 @@ int main(int argc, char **argv)
   while ((entry = silc_dir_read(dir, &status)))
     printf(
      "%c%c%c%c%c%c%c%c%c%c %3d %4d %4d %8lu %04d-%02d-%02d %02d:%02d %s\n",
   while ((entry = silc_dir_read(dir, &status)))
     printf(
      "%c%c%c%c%c%c%c%c%c%c %3d %4d %4d %8lu %04d-%02d-%02d %02d:%02d %s\n",
-       status->mode & SILC_DIR_ENTRY_IFDIR ? 'd' : '-',
-       status->mode & SILC_DIR_ENTRY_IRUSR ? 'r' : '-',
-       status->mode & SILC_DIR_ENTRY_IWUSR ? 'w' : '-',
-       status->mode & SILC_DIR_ENTRY_IXUSR ? 'x' : '-',
-       status->mode & SILC_DIR_ENTRY_IRGRP ? 'r' : '-',
-       status->mode & SILC_DIR_ENTRY_IWGRP ? 'w' : '-',
-       status->mode & SILC_DIR_ENTRY_IXGRP ? 'x' : '-',
-       status->mode & SILC_DIR_ENTRY_IROTH ? 'r' : '-',
-       status->mode & SILC_DIR_ENTRY_IWOTH ? 'w' : '-',
-       status->mode & SILC_DIR_ENTRY_IXOTH ? 'x' : '-',
-       status->nlink, status->uid, status->gid, status->size,
-       status->last_mod.year, status->last_mod.month, status->last_mod.day,
-       status->last_mod.hour, status->last_mod.minute,
+       status.mode & SILC_FILE_IFDIR ? 'd' : '-',
+       status.mode & SILC_FILE_IRUSR ? 'r' : '-',
+       status.mode & SILC_FILE_IWUSR ? 'w' : '-',
+       status.mode & SILC_FILE_IXUSR ? 'x' : '-',
+       status.mode & SILC_FILE_IRGRP ? 'r' : '-',
+       status.mode & SILC_FILE_IWGRP ? 'w' : '-',
+       status.mode & SILC_FILE_IXGRP ? 'x' : '-',
+       status.mode & SILC_FILE_IROTH ? 'r' : '-',
+       status.mode & SILC_FILE_IWOTH ? 'w' : '-',
+       status.mode & SILC_FILE_IXOTH ? 'x' : '-',
+       status.nlink, status.uid, status.gid, status.size,
+       status.last_mod.year, status.last_mod.month, status.last_mod.day,
+       status.last_mod.hour, status.last_mod.minute,
        silc_dir_entry_name(entry));
 
   fflush(stdout);
        silc_dir_entry_name(entry));
 
   fflush(stdout);
index 49de3079fd59ffa4d33cb2486524a6e55af9c38b..ffd3535cd1fe980de19a2827a98dc4b73146c13c 100644 (file)
@@ -24,7 +24,7 @@
 /* Directory entry context */
 struct SilcDirEntryStruct {
   struct dirent *entry;                          /* Entry */
 /* Directory entry context */
 struct SilcDirEntryStruct {
   struct dirent *entry;                          /* Entry */
-  SilcDirEntryStatStruct status;         /* Status */
+  SilcFileStatStruct status;             /* Status */
 };
 
 /* The directory context */
 };
 
 /* The directory context */
@@ -89,7 +89,7 @@ void silc_dir_close(SilcDir dir)
 
 /* Read next entry in the directory */
 
 
 /* Read next entry in the directory */
 
-SilcDirEntry silc_dir_read(SilcDir dir, SilcDirEntryStat *status)
+SilcDirEntry silc_dir_read(SilcDir dir, SilcFileStat status)
 {
   if (!dir) {
     silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
 {
   if (!dir) {
     silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
@@ -105,8 +105,13 @@ SilcDirEntry silc_dir_read(SilcDir dir, SilcDirEntryStat *status)
     return NULL;
   }
 
     return NULL;
   }
 
-  if (status)
-    *status = silc_dir_entry_stat(dir, &dir->entry);
+  if (status) {
+    char *name = NULL;
+    silc_asprintf(&name, "%s/%s", dir->name, dir->entry.entry->d_name);
+    if (name)
+      silc_file_stat(name, TRUE, status);
+    silc_free(name);
+  }
 
   return (SilcDirEntry)&dir->entry;
 }
 
   return (SilcDirEntry)&dir->entry;
 }
@@ -146,109 +151,3 @@ const char *silc_dir_entry_name(SilcDirEntry entry)
 
   return (const char *)entry->entry->d_name;
 }
 
   return (const char *)entry->entry->d_name;
 }
-
-/* Return entry status information */
-
-SilcDirEntryStat silc_dir_entry_stat(SilcDir dir, SilcDirEntry entry)
-{
-  struct stat status;
-  char *name = NULL;
-
-  if (!dir || !entry) {
-    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
-    return NULL;
-  }
-
-  silc_asprintf(&name, "%s/%s", dir->name, entry->entry->d_name);
-  if (!name)
-    return NULL;
-
-  SILC_LOG_DEBUG(("Get status for entry '%s'", name));
-
-  if (lstat(name, &status) != 0) {
-    silc_set_errno_posix(errno);
-    silc_free(name);
-    return NULL;
-  }
-
-  silc_free(name);
-
-  memset(&entry->status, 0, sizeof(entry->status));
-
-  silc_time_value(status.st_atime * 1000, &entry->status.last_access);
-  silc_time_value(status.st_mtime * 1000, &entry->status.last_mod);
-  silc_time_value(status.st_ctime * 1000, &entry->status.last_change);
-
-  entry->status.dev = status.st_dev;
-  entry->status.nlink = status.st_nlink;
-  entry->status.gid = status.st_gid;
-  entry->status.uid = status.st_uid;
-  entry->status.size = status.st_size;
-
-#if defined(S_IFSOCK)
-  if (status.st_mode & S_IFSOCK)
-    entry->status.mode |= SILC_DIR_ENTRY_IFSOCK;
-#endif /* S_IFSOCK */
-#if defined(S_IFLNK)
-  if (status.st_mode & S_IFLNK)
-    entry->status.mode |= SILC_DIR_ENTRY_IFLNK;
-#endif /* S_IFLNK */
-#if defined(S_IFREG)
-  if (status.st_mode & S_IFREG)
-    entry->status.mode |= SILC_DIR_ENTRY_IFREG;
-#endif /* S_IFREG */
-#if defined(S_IFBLK)
-  if (status.st_mode & S_IFBLK)
-    entry->status.mode |= SILC_DIR_ENTRY_IFBLK;
-#endif /* S_IFBLK */
-#if defined(S_IFDIR)
-  if (status.st_mode & S_IFDIR)
-    entry->status.mode |= SILC_DIR_ENTRY_IFDIR;
-#endif /* S_IFDIR */
-#if defined(S_IFCHR)
-  if (status.st_mode & S_IFCHR)
-    entry->status.mode |= SILC_DIR_ENTRY_IFCHR;
-#endif /* S_IFCHR */
-#if defined(S_IFIFO)
-  if (status.st_mode & S_IFIFO)
-    entry->status.mode |= SILC_DIR_ENTRY_IFIFO;
-#endif /* S_IFIFO */
-#if defined(S_IRUSR)
-  if (status.st_mode & S_IRUSR)
-    entry->status.mode |= SILC_DIR_ENTRY_IRUSR;
-#endif /* S_IRUSR */
-#if defined(S_IWUSR)
-  if (status.st_mode & S_IWUSR)
-    entry->status.mode |= SILC_DIR_ENTRY_IWUSR;
-#endif /* S_IWUSR */
-#if defined(S_IXUSR)
-  if (status.st_mode & S_IXUSR)
-    entry->status.mode |= SILC_DIR_ENTRY_IXUSR;
-#endif /* S_IXUSR */
-#if defined(S_IRGRP)
-  if (status.st_mode & S_IRGRP)
-    entry->status.mode |= SILC_DIR_ENTRY_IRGRP;
-#endif /* S_IRGRP */
-#if defined(S_IWGRP)
-  if (status.st_mode & S_IWGRP)
-    entry->status.mode |= SILC_DIR_ENTRY_IWGRP;
-#endif /* S_IWGRP */
-#if defined(S_IXGRP)
-  if (status.st_mode & S_IXGRP)
-    entry->status.mode |= SILC_DIR_ENTRY_IXGRP;
-#endif /* S_IXGRP */
-#if defined(S_IROTH)
-  if (status.st_mode & S_IROTH)
-    entry->status.mode |= SILC_DIR_ENTRY_IROTH;
-#endif /* S_IROTH */
-#if defined(S_IWOTH)
-  if (status.st_mode & S_IWOTH)
-    entry->status.mode |= SILC_DIR_ENTRY_IWOTH;
-#endif /* S_IWOTH */
-#if defined(S_IXOTH)
-  if (status.st_mode & S_IXOTH)
-    entry->status.mode |= SILC_DIR_ENTRY_IXOTH;
-#endif /* S_IXOTH */
-
-  return (SilcDirEntryStat)&entry->status;
-}