summaryrefslogtreecommitdiffstats
path: root/c/src/libfs/src/dosfs/msdos_dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/libfs/src/dosfs/msdos_dir.c')
-rw-r--r--c/src/libfs/src/dosfs/msdos_dir.c483
1 files changed, 0 insertions, 483 deletions
diff --git a/c/src/libfs/src/dosfs/msdos_dir.c b/c/src/libfs/src/dosfs/msdos_dir.c
deleted file mode 100644
index 93449cd2fb..0000000000
--- a/c/src/libfs/src/dosfs/msdos_dir.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * MSDOS directory handlers implementation
- *
- * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
- * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
- *
- * @(#) $Id$
- */
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <rtems/libio_.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <dirent.h>
-
-#include "fat.h"
-#include "fat_fat_operations.h"
-#include "fat_file.h"
-
-#include "msdos.h"
-
-/* msdos_dir_open --
- * Open fat-file which correspondes to the directory being opened and
- * set offset field of file control block to zero.
- *
- * PARAMETERS:
- * iop - file control block
- * pathname - name
- * flag - flags
- * mode - mode
- *
- * RETURNS:
- * RC_OK, if directory opened successfully, or -1 if error occured (errno
- * set apropriately)
- */
-int
-msdos_dir_open(rtems_libio_t *iop, const char *pathname, unsigned32 flag,
- unsigned32 mode)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->file_info;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one( EIO );
-
- rc = fat_file_reopen(fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- iop->offset = 0;
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
-/* msdos_dir_close --
- * Close fat-file which correspondes to the directory being closed
- *
- * PARAMETERS:
- * iop - file control block
- *
- * RETURNS:
- * RC_OK, if directory closed successfully, or -1 if error occured (errno
- * set apropriately.
- */
-int
-msdos_dir_close(rtems_libio_t *iop)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->file_info;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one( EIO );
-
- rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
-/* msdos_dir_read --
- * This routine will read the next directory entry based on the directory
- * offset. The offset should be equal to -n- time the size of an
- * individual dirent structure. If n is not an integer multiple of the
- * sizeof a dirent structure, an integer division will be performed to
- * determine directory entry that will be returned in the buffer. Count
- * should reflect -m- times the sizeof dirent bytes to be placed in the
- * buffer.
- * If there are not -m- dirent elements from the current directory
- * position to the end of the exisiting file, the remaining entries will
- * be placed in the buffer and the returned value will be equal to
- * -m actual- times the size of a directory entry.
- *
- * PARAMETERS:
- * iop - file control block
- * buffer - buffer provided by user
- * count - count of bytes to read
- *
- * RETURNS:
- * the number of bytes read on success, or -1 if error occured (errno
- * set apropriately).
- */
-ssize_t
-msdos_dir_read(rtems_libio_t *iop, void *buffer, unsigned32 count)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
- fat_file_fd_t *fat_fd = iop->file_info;
- fat_file_fd_t *tmp_fat_fd = NULL;
- struct dirent tmp_dirent;
- unsigned32 start = 0;
- ssize_t ret = 0;
- unsigned32 cmpltd = 0;
- unsigned32 j = 0, i = 0;
- unsigned32 bts2rd = 0;
- unsigned32 cur_cln = 0;
-
- /*
- * cast start and count - protect against using sizes that are not exact
- * multiples of the -dirent- size. These could result in unexpected
- * results
- */
- start = iop->offset / sizeof(struct dirent);
- count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
-
- /*
- * optimization: we know that root directory for FAT12/16 volumes is
- * sequential set of sectors and any cluster is sequential set of sectors
- * too, so read such set of sectors is quick operation for low-level IO
- * layer.
- */
- bts2rd = (FAT_FD_OF_ROOT_DIR(fat_fd) &&
- (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16))) ?
- fat_fd->fat_file_size :
- fs_info->fat.vol.bpc;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one(EIO);
-
- while (count > 0)
- {
- /*
- * fat-file is already opened by open call, so read it
- * Always read directory fat-file from the beggining because of MSDOS
- * directories feature :( - we should count elements currently
- * present in the directory because there may be holes :)
- */
- ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, (j * bts2rd),
- bts2rd, fs_info->cl_buf);
- if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- set_errno_and_return_minus_one(EIO);
- }
-
- for (i = 0; i < ret; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
- {
- if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
- MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return cmpltd;
- }
-
- if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
- MSDOS_THIS_DIR_ENTRY_EMPTY)
- continue;
-
- /*
- * skip active entries until get the entry to start from
- */
- if (start)
- {
- start--;
- continue;
- }
-
- /*
- * Move the entry to the return buffer
- *
- * unfortunately there is no method to extract ino except to
- * open fat-file descriptor :( ... so, open it
- */
-
- /* get number of cluster we are working with */
- rc = fat_file_ioctl(iop->pathinfo.mt_entry, fat_fd, F_CLU_NUM,
- j * bts2rd, &cur_cln);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- rc = fat_file_open(iop->pathinfo.mt_entry, cur_cln, i,
- &tmp_fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- tmp_fat_fd->info_cln = cur_cln;
- tmp_fat_fd->info_ofs = i;
-
- /* fill in dirent structure */
- /* XXX: from what and in what d_off should be computed ?! */
- tmp_dirent.d_off = start + cmpltd;
- tmp_dirent.d_reclen = sizeof(struct dirent);
- tmp_dirent.d_ino = tmp_fat_fd->ino;
- tmp_dirent.d_namlen = MSDOS_SHORT_NAME_LEN;
- memcpy(tmp_dirent.d_name, MSDOS_DIR_NAME((fs_info->cl_buf + i)),
- MSDOS_SHORT_NAME_LEN);
-
- /* d_name is null-terminated */
- tmp_dirent.d_name[MSDOS_SHORT_NAME_LEN] = 0;
- memcpy(buffer + cmpltd, &tmp_dirent, sizeof(struct dirent));
-
- iop->offset = iop->offset + sizeof(struct dirent);
- cmpltd += (sizeof(struct dirent));
- count -= (sizeof(struct dirent));
-
- /* inode number extracted, close fat-file */
- rc = fat_file_close(iop->pathinfo.mt_entry, tmp_fat_fd);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- if (count <= 0)
- break;
- }
- j++;
- }
-
- rtems_semaphore_release(fs_info->vol_sema);
- return cmpltd;
-}
-
-/* msdos_dir_write --
- * no write for directory
- */
-
-/* msdos_dir_lseek --
- *
- * This routine will behave in one of three ways based on the state of
- * argument whence. Based on the state of its value the offset argument will
- * be interpreted using one of the following methods:
- *
- * SEEK_SET - offset is the absolute byte offset from the start of the
- * logical start of the dirent sequence that represents the
- * directory
- * SEEK_CUR - offset is used as the relative byte offset from the current
- * directory position index held in the iop structure
- * SEEK_END - N/A --> This will cause an assert.
- *
- * PARAMETERS:
- * iop - file control block
- * offset - offset
- * whence - predefine directive
- *
- * RETURNS:
- * RC_OK on success, or -1 if error occured (errno
- * set apropriately).
- */
-int
-msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence)
-{
- switch (whence)
- {
- case SEEK_SET:
- case SEEK_CUR:
- break;
- /*
- * Movement past the end of the directory via lseek is not a
- * permitted operation
- */
- case SEEK_END:
- default:
- set_errno_and_return_minus_one( EINVAL );
- break;
- }
- return RC_OK;
-}
-
-/* msdos_dir_stat --
- *
- * This routine will obtain the following information concerning the current
- * directory:
- * st_dev device id
- * st_ino node serial number :)
- * st_mode mode extracted from the node
- * st_size total size in bytes
- * st_blksize blocksize for filesystem I/O
- * st_blocks number of blocks allocated
- * stat_mtime time of last modification
- *
- * PARAMETERS:
- * loc - this directory
- * buf - stat buffer provided by user
- *
- * RETURNS:
- * RC_OK and filled stat buffer on success, or -1 if error occured (errno
- * set apropriately).
- */
-int
-msdos_dir_stat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
- )
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;
- fat_file_fd_t *fat_fd = loc->node_access;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one(EIO);
-
- buf->st_dev = fs_info->fat.vol.dev;
- buf->st_ino = fat_fd->ino;
- buf->st_mode = S_IFDIR;
- buf->st_rdev = 0ll;
- buf->st_size = fat_fd->fat_file_size;
- buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
- buf->st_blksize = fs_info->fat.vol.bps;
- buf->st_mtime = fat_fd->mtime;
-
- rtems_semaphore_release(fs_info->vol_sema);
- return RC_OK;
-}
-
-/* msdos_dir_truncate --
- * No truncate for directory.
- *
- * PARAMETERS:
- *
- * RETURNS:
- *
- */
-
-/* msdos_dir_sync --
- * The following routine does a syncronization on a MSDOS directory node.
- * DIR_WrtTime, DIR_WrtDate and DIR_fileSize fields of 32 Bytes Directory
- * Entry Structure(see M$ White Paper) should not be updated for
- * directories, so only call to corresponding fat-file routine.
- *
- * PARAMETERS:
- * iop - file control block
- *
- * RETURNS:
- * RC_OK on success, or -1 if error occured (errno set apropriately).
- */
-int
-msdos_dir_sync(rtems_libio_t *iop)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- fat_file_fd_t *fat_fd = iop->file_info;
- msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one(EIO);
-
- rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
-
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
-}
-
-/* msdos_dir_rmnod --
- * Remove directory node.
- *
- * Check that this directory node is not opened as fat-file, is empty and
- * not filesystem root node. If all this conditions met then delete.
- *
- * PARAMETERS:
- * pathloc - node description
- *
- * RETURNS:
- * RC_OK on success, or -1 if error occured (errno set apropriately).
- */
-int
-msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
-{
- int rc = RC_OK;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info;
- fat_file_fd_t *fat_fd = pathloc->node_access;
- rtems_boolean is_empty = FALSE;
-
- sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
- MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one(EIO);
-
- /*
- * We deny attemp to delete open directory (if directory is current
- * directory we assume it is open one)
- */
- if (fat_fd->links_num > 1)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- set_errno_and_return_minus_one(EBUSY);
- }
-
- /*
- * You cannot remove a node that still has children
- */
- rc = msdos_dir_is_empty(pathloc->mt_entry, fat_fd, &is_empty);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- if (!is_empty)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- set_errno_and_return_minus_one(ENOTEMPTY);
- }
-
- /*
- * You cannot remove the file system root node.
- */
- if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- set_errno_and_return_minus_one(EBUSY);
- }
-
- /*
- * You cannot remove a mountpoint.
- * not used - mount() not implemenetd yet.
- */
-
- /* mark file removed */
- rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
- fat_fd->info_ofs,
- MSDOS_THIS_DIR_ENTRY_EMPTY);
- if (rc != RC_OK)
- {
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
- }
-
- fat_file_mark_removed(pathloc->mt_entry, fat_fd);
-
- rtems_semaphore_release(fs_info->vol_sema);
- return rc;
-}