00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00038 #include "fat_dentry.h"
00039 #include <ctype.h>
00040 #include <str.h>
00041
00042 static bool is_d_char(const char ch)
00043 {
00044 if (isalnum(ch) || ch == '_' || ch == '-')
00045 return true;
00046 else
00047 return false;
00048 }
00049
00062 int fat_dentry_namecmp(char *name, const char *component)
00063 {
00064 int rc;
00065 size_t size;
00066
00067 if (!(rc = stricmp(name, component)))
00068 return rc;
00069 if (!str_chr(name, '.')) {
00070
00071
00072
00073
00074 size = str_size(name);
00075 name[size] = '.';
00076 name[size + 1] = '\0';
00077 rc = stricmp(name, component);
00078 }
00079 return rc;
00080 }
00081
00082 bool fat_dentry_name_verify(const char *name)
00083 {
00084 unsigned int i;
00085 unsigned int dot = 0;
00086 bool dot_found = false;
00087
00088
00089 for (i = 0; name[i]; i++) {
00090 if (name[i] == '.') {
00091 if (dot_found) {
00092 return false;
00093 } else {
00094 dot_found = true;
00095 dot = i;
00096 }
00097 } else {
00098 if (!is_d_char(name[i]))
00099 return false;
00100 }
00101 }
00102
00103 if (dot_found) {
00104 if (dot > FAT_NAME_LEN)
00105 return false;
00106 if (i - dot > FAT_EXT_LEN + 1)
00107 return false;
00108 } else {
00109 if (i > FAT_NAME_LEN)
00110 return false;
00111 }
00112
00113 return true;
00114 }
00115
00116 void fat_dentry_name_get(const fat_dentry_t *d, char *buf)
00117 {
00118 unsigned int i;
00119
00120 for (i = 0; i < FAT_NAME_LEN; i++) {
00121 if (d->name[i] == FAT_PAD)
00122 break;
00123
00124 if (d->name[i] == FAT_DENTRY_E5_ESC)
00125 *buf++ = 0xe5;
00126 else {
00127 if (d->lcase & FAT_LCASE_LOWER_NAME)
00128 *buf++ = tolower(d->name[i]);
00129 else
00130 *buf++ = d->name[i];
00131 }
00132 }
00133
00134 if (d->ext[0] != FAT_PAD)
00135 *buf++ = '.';
00136
00137 for (i = 0; i < FAT_EXT_LEN; i++) {
00138 if (d->ext[i] == FAT_PAD) {
00139 *buf = '\0';
00140 return;
00141 }
00142
00143 if (d->ext[i] == FAT_DENTRY_E5_ESC)
00144 *buf++ = 0xe5;
00145 else {
00146 if (d->lcase & FAT_LCASE_LOWER_EXT)
00147 *buf++ = tolower(d->ext[i]);
00148 else
00149 *buf++ = d->ext[i];
00150 }
00151 }
00152
00153 *buf = '\0';
00154 }
00155
00156 void fat_dentry_name_set(fat_dentry_t *d, const char *name)
00157 {
00158 unsigned int i;
00159 const char fake_ext[] = " ";
00160 bool lower_name = true;
00161 bool lower_ext = true;
00162
00163 for (i = 0; i < FAT_NAME_LEN; i++) {
00164 switch ((uint8_t) *name) {
00165 case 0xe5:
00166 d->name[i] = FAT_DENTRY_E5_ESC;
00167 name++;
00168 break;
00169 case '\0':
00170 case '.':
00171 d->name[i] = FAT_PAD;
00172 break;
00173 default:
00174 if (isalpha(*name)) {
00175 if (!islower(*name))
00176 lower_name = false;
00177 }
00178
00179 d->name[i] = toupper(*name++);
00180 break;
00181 }
00182 }
00183
00184 if (*name++ != '.')
00185 name = fake_ext;
00186
00187 for (i = 0; i < FAT_EXT_LEN; i++) {
00188 switch ((uint8_t) *name) {
00189 case 0xe5:
00190 d->ext[i] = FAT_DENTRY_E5_ESC;
00191 name++;
00192 break;
00193 case '\0':
00194 d->ext[i] = FAT_PAD;
00195 break;
00196 default:
00197 if (isalpha(*name)) {
00198 if (!islower(*name))
00199 lower_ext = false;
00200 }
00201
00202 d->ext[i] = toupper(*name++);
00203 break;
00204 }
00205 }
00206
00207 if (lower_name)
00208 d->lcase |= FAT_LCASE_LOWER_NAME;
00209 else
00210 d->lcase &= ~FAT_LCASE_LOWER_NAME;
00211
00212 if (lower_ext)
00213 d->lcase |= FAT_LCASE_LOWER_EXT;
00214 else
00215 d->lcase &= ~FAT_LCASE_LOWER_EXT;
00216 }
00217
00218 fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d)
00219 {
00220 if (d->attr & FAT_ATTR_VOLLABEL) {
00221
00222 return FAT_DENTRY_SKIP;
00223 }
00224 if (d->name[0] == FAT_DENTRY_ERASED) {
00225
00226 return FAT_DENTRY_FREE;
00227 }
00228 if (d->name[0] == FAT_DENTRY_UNUSED) {
00229
00230 return FAT_DENTRY_LAST;
00231 }
00232 if (d->name[0] == FAT_DENTRY_DOT) {
00233
00234
00235
00236
00237 return FAT_DENTRY_SKIP;
00238 }
00239 return FAT_DENTRY_VALID;
00240 }
00241