Changeset a2aa1dec in mainline for uspace/srv/fs/fat/fat_ops.c
- Timestamp:
- 2008-04-02T19:46:57Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0f718ab
- Parents:
- 94b0b63
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
r94b0b63 ra2aa1dec 1 1 /* 2 * Copyright (c) 200 7Jakub Jermar2 * Copyright (c) 2008 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 38 38 #include "fat.h" 39 39 #include "../../vfs/vfs.h" 40 #include <libfs.h> 40 41 #include <ipc/ipc.h> 41 42 #include <async.h> 42 43 #include <errno.h> 43 44 #define PLB_GET_CHAR(i) (fat_reg.plb_ro[(i) % PLB_SIZE]) 44 #include <string.h> 45 45 46 46 #define FAT_NAME_LEN 8 … … 54 54 #define FAT_DENTRY_ERASED 0xe5 55 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) 56 static void dentry_name_canonify(fat_dentry_t *d, char *buf) 67 57 { 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; 58 int i; 73 59 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 } 60 for (i = 0; i < FAT_NAME_LEN; i++) { 61 if (d->name[i] == FAT_PAD) { 62 buf++; 63 break; 99 64 } 100 if (!dot_processed) { 101 dot_processed = true; 102 pos = -1; 103 if (PLB_GET_CHAR(cur) != '.') 104 return 0; 65 if (d->name[i] == FAT_DENTRY_E5_ESC) 66 *buf++ = 0xe5; 67 else 68 *buf++ = d->name[i]; 69 } 70 if (d->ext[0] != FAT_PAD) 71 *buf++ = '.'; 72 for (i = 0; i < FAT_EXT_LEN; i++) { 73 if (d->ext[i] == FAT_PAD) { 74 *buf = '\0'; 75 return; 76 } 77 if (d->ext[i] == FAT_DENTRY_E5_ESC) 78 *buf++ = 0xe5; 79 else 80 *buf++ = d->ext[i]; 81 } 82 } 83 84 static fat_dentry_t *fat_dentry_get(fat_node_t *dirnode, unsigned idx) 85 { 86 return NULL; /* TODO */ 87 } 88 89 static void fat_dentry_put(fat_dentry_t *dentry) 90 { 91 /* TODO */ 92 } 93 94 static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index) 95 { 96 return NULL; /* TODO */ 97 } 98 99 static void *fat_match(void *prnt, const char *component) 100 { 101 fat_node_t *parentp = (fat_node_t *)prnt; 102 char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; 103 unsigned i; 104 unsigned dentries; 105 fat_dentry_t *d; 106 107 dentries = parentp->size / sizeof(fat_dentry_t); 108 for (i = 0; i < dentries; i++) { 109 d = fat_dentry_get(parentp, i); 110 if (d->attr & FAT_ATTR_VOLLABEL) { 111 /* volume label entry */ 112 fat_dentry_put(d); 105 113 continue; 106 114 } 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 } 115 if (d->name[0] == FAT_DENTRY_ERASED) { 116 /* not-currently-used entry */ 117 fat_dentry_put(d); 118 continue; 122 119 } 123 return 0; /* extra characters in the component */ 120 if (d->name[0] == FAT_DENTRY_UNUSED) { 121 /* never used entry */ 122 fat_dentry_put(d); 123 break; 124 } 125 if (d->name[0] == FAT_DENTRY_DOT) { 126 /* 127 * Most likely '.' or '..'. 128 * It cannot occur in a regular file name. 129 */ 130 fat_dentry_put(d); 131 continue; 132 } 133 134 dentry_name_canonify(d, name); 135 if (strcmp(name, component) == 0) { 136 /* hit */ 137 void *node = fat_node_get(parentp->dev_handle, 138 (fs_index_t)d->firstc); 139 fat_dentry_put(d); 140 return node; 141 142 } else { 143 /* miss */ 144 fat_dentry_put(d); 145 } 124 146 } 125 if (ext_processed || (name_processed && dentry->ext[0] == FAT_PAD)) 126 return cur - start; 127 else 128 return 0; 147 148 return NULL; 129 149 } 150 151 /** libfs operations */ 152 libfs_ops_t fat_libfs_ops = { 153 .match = fat_match, 154 .node_get = fat_node_get, 155 .create = NULL, 156 .destroy = NULL, 157 .link = NULL, 158 .unlink = NULL, 159 .index_get = NULL, 160 .size_get = NULL, 161 .lnkcnt_get = NULL, 162 .has_children = NULL, 163 .root_get = NULL, 164 .plb_get_char = NULL, 165 .is_directory = NULL, 166 .is_file = NULL 167 }; 130 168 131 169 void fat_lookup(ipc_callid_t rid, ipc_call_t *request) 132 170 { 133 int first = IPC_GET_ARG1(*request); 134 int second = IPC_GET_ARG2(*request); 135 int dev_handle = IPC_GET_ARG3(*request); 136 137 171 libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 138 172 } 139 173
Note:
See TracChangeset
for help on using the changeset viewer.