⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msdos_eval.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  MSDOS evaluation routines * *  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.rtems.com/license/LICENSE. * *  @(#) $Id: msdos_eval.c,v 1.1.2.2 2005/08/17 19:17:37 joel Exp $ */#if HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <assert.h>#include <rtems/libio_.h>#include "fat.h"#include "fat_fat_operations.h"#include "fat_file.h"#include "msdos.h"/* msdos_set_handlers -- *     Set handlers for the node with specified type(i.e. handlers for file  *     or directory). * * PARAMETERS: *     loc - node description * * RETURNS: *     None */static void msdos_set_handlers(rtems_filesystem_location_info_t *loc){    msdos_fs_info_t *fs_info = loc->mt_entry->fs_info;     fat_file_fd_t   *fat_fd = loc->node_access;    if (fat_fd->fat_file_type == FAT_DIRECTORY)        loc->handlers = fs_info->directory_handlers;    else        loc->handlers = fs_info->file_handlers;}/* msdos_eval_path -- * *     The following routine evaluate path for a node that wishes to be *     accessed.  Structure 'pathloc' is returned with a pointer to the *     node to be accessed. * * PARAMETERS: *     pathname - path for evaluation *     flags    - flags *     pathloc  - node description (IN/OUT) * * RETURNS: *     RC_OK and filled pathloc on success, or -1 if error occured *     (errno set appropriately) *        */int msdos_eval_path(    const char                        *pathname,    int                                flags,    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 = NULL;    rtems_filesystem_location_info_t  newloc;    int                               i = 0;    int                               len = 0;    msdos_token_types_t               type = MSDOS_CURRENT_DIR;    char                              token[MSDOS_NAME_MAX + 1];    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);      if (!pathloc->node_access)    {        errno = ENOENT;        rc = -1;        goto err;    }      fat_fd = pathloc->node_access;     rc = fat_file_reopen(fat_fd);    if (rc != RC_OK)        goto err;        while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN))     {        type = msdos_get_token(&pathname[i], token, &len);        i += len;          fat_fd = pathloc->node_access;           switch (type)         {            case MSDOS_UP_DIR:                /*                 *  Only a directory can be decended into.                 */                if (fat_fd->fat_file_type != FAT_DIRECTORY)                {                    errno = ENOTSUP;                    rc = -1;                    goto error;                }                  /*                 *  Am I at the root of this mounted filesystem?                 */                if (pathloc->node_access ==                     pathloc->mt_entry->mt_fs_root.node_access)                 {                    /*                     *  Am I at the root of all filesystems?                     *  XXX: MSDOS is not supposed to be base fs.                     */                    if (pathloc->node_access ==                         rtems_filesystem_root.node_access)                     {                            break;       /* Throw out the .. in this case */                    }                         else                     {                        newloc = pathloc->mt_entry->mt_point_node;                        *pathloc = newloc;                        rc = fat_file_close(pathloc->mt_entry, fat_fd);                        if (rc != RC_OK)                            goto err;                                                    rtems_semaphore_release(fs_info->vol_sema);                        return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),                                                           flags, pathloc);                    }                }                 else                 {                    rc = msdos_find_name(pathloc, token);                    if (rc != RC_OK)                    {                        if (rc == MSDOS_NAME_NOT_FOUND_ERR)                        {                            errno = ENOENT;                            rc = -1;                        }                            goto error;                     }                  }                break;            case MSDOS_NAME:                /*                 *  Only a directory can be decended into.                 */                if (fat_fd->fat_file_type != FAT_DIRECTORY)                {                    errno = ENOTSUP;                    rc = -1;                    goto error;                }                  /*                 *  Otherwise find the token name in the present location and                  * set the node access to the point we have found.                 */                rc = msdos_find_name(pathloc, token);                if (rc != RC_OK)                {                    if (rc == MSDOS_NAME_NOT_FOUND_ERR)                    {                        errno = ENOENT;                        rc = -1;                    }                        goto error;                 }                  break;            case MSDOS_NO_MORE_PATH:            case MSDOS_CURRENT_DIR:                       break;            case MSDOS_INVALID_TOKEN:                errno = ENAMETOOLONG;                rc = -1;                goto error;                break;         }    }    /*     *  Always return the root node.     *     *  If we are at a node that is a mount point. Set loc to the     *  new fs root node and let let the mounted filesystem set the handlers.     *     *  NOTE: The behavior of stat() on a mount point appears to be      *        questionable.     *  NOTE: MSDOS filesystem currently doesn't support mount functionality ->     *        action not implemented     */    fat_fd = pathloc->node_access;       msdos_set_handlers(pathloc);       rtems_semaphore_release(fs_info->vol_sema);    return RC_OK;error:    fat_file_close(pathloc->mt_entry, fat_fd);err:    rtems_semaphore_release(fs_info->vol_sema);    return rc; }/* msdos_eval4make -- *     The following routine evaluate path for a new node to be created. *     'pathloc' is returned with a pointer to the parent of the new node. *     'name' is returned with a pointer to the first character in the *     new node name.  The parent node is verified to be a directory. * * PARAMETERS: *     path    - path for evaluation *     pathloc - IN/OUT (start point for evaluation/parent directory for  *               creation) *     name    - new node name * * RETURNS: *     RC_OK, filled pathloc for parent directory and name of new node on  *     success, or -1 if error occured (errno set appropriately) */int msdos_eval4make(    const char                         *path,     rtems_filesystem_location_info_t   *pathloc,      const char                        **name    )   {    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 = NULL;    rtems_filesystem_location_info_t  newloc;    msdos_token_types_t               type;    int                               i = 0;    int                               len;    char                              token[ MSDOS_NAME_MAX + 1 ];    rtems_boolean                     done = 0;    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);      if (!pathloc->node_access)    {        errno = ENOENT;        rc = -1;        goto err;    }      fat_fd = pathloc->node_access;     rc = fat_file_reopen(fat_fd);    if (rc != RC_OK)        goto err;    while (!done)     {        type = msdos_get_token(&path[i], token, &len);        i += len;        fat_fd = pathloc->node_access;         switch (type)         {            case MSDOS_UP_DIR:                /*                 *  Only a directory can be decended into.                 */                if (fat_fd->fat_file_type != FAT_DIRECTORY)                {                    errno = ENOTDIR;                    rc = -1;                    goto error;                }                  /*                 *  Am I at the root of this mounted filesystem?                 */                if (pathloc->node_access ==                     pathloc->mt_entry->mt_fs_root.node_access)                 {                    /*                     *  Am I at the root of all filesystems?                     *  XXX: MSDOS is not supposed to be base fs.                     */                    if (pathloc->node_access ==                         rtems_filesystem_root.node_access)                     {                            break;       /* Throw out the .. in this case */                    }                        else                     {                        newloc = pathloc->mt_entry->mt_point_node;                        *pathloc = newloc;                        rc = fat_file_close(pathloc->mt_entry, fat_fd);                        if (rc != RC_OK)                            goto err;                        rtems_semaphore_release(fs_info->vol_sema);                        return (*pathloc->ops->evalformake_h)(&path[i-len],                                                               pathloc, name);                    }                }                 else                 {                    rc = msdos_find_name(pathloc, token);                    if (rc != RC_OK)                    {                        if (rc == MSDOS_NAME_NOT_FOUND_ERR)                        {                            errno = ENOENT;                            rc = -1;                        }                            goto error;                     }                  }                break;            case MSDOS_NAME:                /*                 *  Only a directory can be decended into.                 */                if (fat_fd->fat_file_type != FAT_DIRECTORY)                {                    errno = ENOTDIR;                    rc = -1;                    goto error;                }                  /*                 *  Otherwise find the token name in the present location and                  * set the node access to the point we have found.                 */                rc = msdos_find_name(pathloc, token);                if (rc)                {                    if (rc != MSDOS_NAME_NOT_FOUND_ERR)                    {                        errno = ENOENT;                        rc = -1;                        goto error;                    }                    else                        done = TRUE;                }                     break;            case MSDOS_NO_MORE_PATH:                errno = EEXIST;                rc = -1;                goto error;                break;                    case MSDOS_CURRENT_DIR:                break;            case MSDOS_INVALID_TOKEN:                errno = ENAMETOOLONG;                rc = -1;                goto error;                break;        }    }    *name = &path[i - len];    /*     * We have evaluated the path as far as we can.     * Verify there is not any invalid stuff at the end of the name.     */    for( ; path[i] != '\0'; i++)     {        if (!msdos_is_separator(path[i]))        {            errno = ENOENT;            rc = -1;            goto error;        }      }    fat_fd = pathloc->node_access;    if (fat_fd->fat_file_type != FAT_DIRECTORY)    {        errno = ENOTDIR;        rc = -1;        goto error;    }          msdos_set_handlers(pathloc);     rtems_semaphore_release(fs_info->vol_sema);    return RC_OK;error:    fat_file_close(pathloc->mt_entry, fat_fd);err:    rtems_semaphore_release(fs_info->vol_sema);    return rc; }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -