Subversion Repositories HelenOS

Rev

Rev 2643 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup fs
  30.  * @{
  31.  */
  32.  
  33. /**
  34.  * @file    fat_ops.c
  35.  * @brief   Implementation of VFS operations for the FAT file system server.
  36.  */
  37.  
  38. #include "fat.h"
  39. #include "../../vfs/vfs.h"
  40. #include <ipc/ipc.h>
  41. #include <async.h>
  42. #include <errno.h>
  43.  
  44. #define PLB_GET_CHAR(i)     (fat_reg.plb_ro[(i) % PLB_SIZE])
  45.  
  46. #define FAT_NAME_LEN        8
  47. #define FAT_EXT_LEN     3
  48.  
  49. #define FAT_PAD         ' '
  50.  
  51. #define FAT_DENTRY_UNUSED   0x00
  52. #define FAT_DENTRY_E5_ESC   0x05
  53. #define FAT_DENTRY_DOT      0x2e
  54. #define FAT_DENTRY_ERASED   0xe5
  55.  
  56. /** Compare one component of path to a directory entry.
  57.  *
  58.  * @param dentry    Directory entry to compare the path component with.
  59.  * @param start     Index into PLB where the path component starts.
  60.  * @param last      Index of the last character of the path in PLB.
  61.  *
  62.  * @return      Zero on failure or delta such that (index + delta) %
  63.  *          PLB_SIZE points to a new path component in PLB.
  64.  */
  65. static unsigned match_path_component(fat_dentry_t *dentry, unsigned start,
  66.     unsigned last)
  67. {
  68.     unsigned cur;   /* current position in PLB */
  69.     int pos;    /* current position in dentry->name or dentry->ext */
  70.     bool name_processed = false;
  71.     bool dot_processed = false;
  72.     bool ext_processed = false;
  73.  
  74.     if (last < start)
  75.         last += PLB_SIZE;
  76.     for (pos = 0, cur = start; (cur <= last) && (PLB_GET_CHAR(cur) != '/');
  77.         pos++, cur++) {
  78.         if (!name_processed) {
  79.             if ((pos == FAT_NAME_LEN - 1) ||
  80.                 (dentry->name[pos + 1] == FAT_PAD)) {
  81.                     /* this is the last character in name */
  82.                 name_processed = true;
  83.             }
  84.             if (dentry->name[0] == FAT_PAD) {
  85.                 /* name is empty */
  86.                 name_processed = true;
  87.             } else if ((pos == 0) && (dentry->name[pos] ==
  88.                 FAT_DENTRY_E5_ESC)) {
  89.                 if (PLB_GET_CHAR(cur) == 0xe5)
  90.                     continue;
  91.                 else
  92.                     return 0;   /* character mismatch */
  93.             } else {
  94.                 if (PLB_GET_CHAR(cur) == dentry->name[pos])
  95.                     continue;
  96.                 else
  97.                     return 0;   /* character mismatch */
  98.             }
  99.         }
  100.         if (!dot_processed) {
  101.             dot_processed = true;
  102.             pos = -1;
  103.             if (PLB_GET_CHAR(cur) != '.')
  104.                 return 0;
  105.             continue;
  106.         }
  107.         if (!ext_processed) {
  108.             if ((pos == FAT_EXT_LEN - 1) ||
  109.                 (dentry->ext[pos + 1] == FAT_PAD)) {
  110.                 /* this is the last character in ext */
  111.                 ext_processed = true;
  112.             }
  113.             if (dentry->ext[0] == FAT_PAD) {
  114.                 /* ext is empty; the match will fail */
  115.                 ext_processed = true;
  116.             } else if (PLB_GET_CHAR(cur) == dentry->ext[pos]) {
  117.                 continue;
  118.             } else {
  119.                 /* character mismatch */
  120.                 return 0;
  121.             }
  122.         }
  123.         return 0;   /* extra characters in the component */
  124.     }
  125.     if (ext_processed || (name_processed && dentry->ext[0] == FAT_PAD))
  126.         return cur - start;
  127.     else
  128.         return 0;
  129. }
  130.  
  131. void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
  132. {
  133.     int first = IPC_GET_ARG1(*request);
  134.     int second = IPC_GET_ARG2(*request);
  135.     int dev_handle = IPC_GET_ARG3(*request);
  136.  
  137.    
  138. }
  139.  
  140. /**
  141.  * @}
  142.  */
  143.