}
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));
return (char *)buffer;
}
-/* Returns the size of `filename'. Returns 0 on error. */
+/* Returns the size of `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 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;
}
*/
-/****h* silcutil/SILC File Util Interface
+/****h* silcutil/File Util Interface
*
* DESCRIPTION
*
#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 */
-/****f* silcutil/SilcFileUtilAPI/silc_file_open
+/****f* silcutil/silc_file_open
*
* SYNOPSIS
*
***/
int silc_file_open(const char *filename, int flags);
-/****f* silcutil/SilcFileUtilAPI/silc_file_open_mode
+/****f* silcutil/silc_file_open_mode
*
* SYNOPSIS
*
***/
int silc_file_open_mode(const char *filename, int flags, int mode);
-/****f* silcutil/SilcFileUtilAPI/silc_file_read
+/****f* silcutil/silc_file_read
*
* SYNOPSIS
*
***/
int silc_file_read(int fd, unsigned char *buf, SilcUInt32 buf_len);
-/****f* silcutil/SilcFileUtilAPI/silc_file_write
+/****f* silcutil/silc_file_write
*
* SYNOPSIS
*
***/
int silc_file_write(int fd, const char *buffer, SilcUInt32 len);
-/****f* silcutil/SilcFileUtilAPI/silc_file_close
+/****f* silcutil/silc_file_close
*
* SYNOPSIS
*
***/
int silc_file_close(int fd);
-/****f* silcutil/SilcFileUtilAPI/silc_file_set_nonblock
+/****f* silcutil/silc_file_set_nonblock
*
* SYNOPSIS
*
***/
int silc_file_set_nonblock(int fd);
-/****f* silcutil/SilcFileUtilAPI/silc_file_readfile
+/****f* silcutil/silc_file_readfile
*
* SYNOPSIS
*
* 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
char *silc_file_readfile(const char *filename, SilcUInt32 *return_len,
SilcStack stack);
-/****f* silcutil/SilcFileUtilAPI/silc_file_writefile
+/****f* silcutil/silc_file_writefile
*
* SYNOPSIS
*
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
*
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
*
*
* 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);
+/****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 */
SilcBool success = FALSE;
SilcDir dir;
SilcDirEntry entry;
- SilcDirEntryStat status;
+ SilcFileStatStruct status;
if (argc > 1 && !strcmp(argv[1], "-d")) {
silc_log_debug(TRUE);
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);
/* Directory entry context */
struct SilcDirEntryStruct {
struct dirent *entry; /* Entry */
- SilcDirEntryStatStruct status; /* Status */
+ SilcFileStatStruct status; /* Status */
};
/* The directory context */
/* 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);
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 (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;
-}