+++ /dev/null
-/*
-
- silcunixdir.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 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
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
-*/
-
-#include "silc.h"
-
-/************************** Types and definitions ***************************/
-
-/* Directory entry context */
-struct SilcDirEntryStruct {
- struct dirent *entry; /* Entry */
- SilcDirEntryStatStruct status; /* Status */
-};
-
-/* The directory context */
-struct SilcDirStruct {
- DIR *dir; /* Directory */
- char *name; /* Directory name */
- struct SilcDirEntryStruct entry; /* Current entry */
-};
-
-/****************************** SILC Dir API ********************************/
-
-/* Open directory */
-
-SilcDir silc_dir_open(const char *name)
-{
- SilcDir dir;
-
- if (!name || !strlen(!name)) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- return NULL;
- }
-
- SILC_LOG_DEBUG(("Open directory '%s'", name));
-
- dir = silc_calloc(1, sizeof(*dir));
- if (!dir)
- return NULL;
-
- dir->name = silc_strdup(name);
- if (!dir->name) {
- silc_free(dir);
- return NULL;
- }
-
- if (dir->name[strlen(dir->name) - 1] == '/')
- dir->name[strlen(dir->name) - 1] = '\0';
-
- dir->dir = opendir(name);
- if (!dir->dir) {
- silc_set_errno_posix(errno);
- silc_free(dir->name);
- silc_free(dir);
- return NULL;
- }
-
- return dir;
-}
-
-/* Close directory */
-
-void silc_dir_close(SilcDir dir)
-{
- if (!dir)
- return;
-
- SILC_LOG_DEBUG(("Close directory '%s'", dir->name));
-
- closedir(dir->dir);
- silc_free(dir->name);
- silc_free(dir);
-}
-
-/* Read next entry in the directory */
-
-SilcDirEntry silc_dir_read(SilcDir dir, SilcDirEntryStat *status)
-{
- if (!dir) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- return NULL;
- }
-
- SILC_LOG_DEBUG(("Read directory '%s'", dir->name));
-
- dir->entry.entry = readdir(dir->dir);
- if (!dir->entry.entry) {
- if (errno)
- silc_set_errno_posix(errno);
- return NULL;
- }
-
- if (status)
- *status = silc_dir_entry_stat(dir, &dir->entry);
-
- return (SilcDirEntry)&dir->entry;
-}
-
-/* Rewind directory */
-
-void silc_dir_rewind(SilcDir dir)
-{
- if (!dir)
- return;
-
- SILC_LOG_DEBUG(("Rewind directory '%s'", dir->name));
-
- rewinddir(dir->dir);
-}
-
-/* Return directory name */
-
-const char *silc_dir_name(SilcDir dir)
-{
- if (!dir) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- return NULL;
- }
-
- return dir->name;
-}
-
-/* Return entry name */
-
-const char *silc_dir_entry_name(SilcDirEntry entry)
-{
- if (!entry) {
- silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
- return NULL;
- }
-
- 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;
-}