#endif
/*
- * Convert a string to lowercase.
+ * Convert a string to lowercase. Converts at most 'len' characters,
+ * 'len' may be larger than the length of 'str' if 'str' is NULL
+ * terminated.
*/
-static void downcase(char *str)
+static void downcase(char *str, size_t len)
{
- while (*str != '\0') {
+ while (*str != '\0' && len--) {
*str = tolower(*str);
str++;
}
ptr = s_name;
while (*ptr && *ptr != ' ')
ptr++;
+ if (dirent->lcase & CASE_LOWER_BASE)
+ downcase(s_name, (unsigned)(ptr - s_name));
if (dirent->ext[0] && dirent->ext[0] != ' ') {
- *ptr = '.';
- ptr++;
+ *ptr++ = '.';
memcpy(ptr, dirent->ext, 3);
+ if (dirent->lcase & CASE_LOWER_EXT)
+ downcase(ptr, 3);
ptr[3] = '\0';
while (*ptr && *ptr != ' ')
ptr++;
*s_name = '\0';
else if (*s_name == aRING)
*s_name = DELETED_FLAG;
- downcase(s_name);
}
static int flush_dirty_fat_buffer(fsdata *mydata);
int ret;
if (clustnum > 0) {
- startsect = mydata->data_begin +
- clustnum * mydata->clust_size;
+ startsect = clust_to_sect(mydata, clustnum);
} else {
startsect = mydata->rootdir_sect;
}
return -1;
}
- block = memalign(ARCH_DMA_MINALIGN, cur_dev->blksz);
+ block = malloc_cache_aligned(cur_dev->blksz);
if (block == NULL) {
debug("Error: allocating block\n");
return -1;
mydata->data_begin = mydata->rootdir_sect +
mydata->rootdir_size -
(mydata->clust_size * 2);
- mydata->root_cluster = (mydata->rootdir_sect -
- mydata->data_begin) /
- mydata->clust_size;
+ mydata->root_cluster =
+ sect_to_clust(mydata, mydata->rootdir_sect);
}
mydata->fatbufnum = -1;
mydata->fat_dirty = 0;
- mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
+ mydata->fatbuf = malloc_cache_aligned(FATBUFSIZE);
if (mydata->fatbuf == NULL) {
debug("Error: allocating memory\n");
return -1;
itr->fsdata = parent->fsdata;
if (clustnum > 0) {
itr->clust = clustnum;
+ itr->is_root = 0;
} else {
itr->clust = parent->fsdata->root_cluster;
+ itr->is_root = 1;
}
itr->dent = NULL;
itr->remaining = 0;
itr->last_cluster = 0;
- itr->is_root = 0;
}
static void *next_cluster(fat_itr *itr)
int fat_exists(const char *filename)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc_cache_aligned(sizeof(fat_itr));
+ if (!itr)
+ return 0;
ret = fat_itr_root(itr, &fsdata);
if (ret)
- return 0;
+ goto out;
ret = fat_itr_resolve(itr, filename, TYPE_ANY);
+ free(fsdata.fatbuf);
+out:
+ free(itr);
return ret == 0;
}
int fat_size(const char *filename, loff_t *size)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc_cache_aligned(sizeof(fat_itr));
+ if (!itr)
+ return -ENOMEM;
ret = fat_itr_root(itr, &fsdata);
if (ret)
- return ret;
+ goto out_free_itr;
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
if (ret) {
* Directories don't have size, but fs_size() is not
* expected to fail if passed a directory path:
*/
+ free(fsdata.fatbuf);
fat_itr_root(itr, &fsdata);
if (!fat_itr_resolve(itr, filename, TYPE_DIR)) {
*size = 0;
- return 0;
+ ret = 0;
}
- return ret;
+ goto out_free_both;
}
*size = FAT2CPU32(itr->dent->size);
-
- return 0;
+out_free_both:
+ free(fsdata.fatbuf);
+out_free_itr:
+ free(itr);
+ return ret;
}
int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
loff_t maxsize, loff_t *actread)
{
fsdata fsdata;
- fat_itr itrblock, *itr = &itrblock;
+ fat_itr *itr;
int ret;
+ itr = malloc_cache_aligned(sizeof(fat_itr));
+ if (!itr)
+ return -ENOMEM;
ret = fat_itr_root(itr, &fsdata);
if (ret)
- return ret;
+ goto out_free_itr;
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
if (ret)
- return ret;
+ goto out_free_both;
printf("reading %s\n", filename);
- return get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
+ ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
+
+out_free_both:
+ free(fsdata.fatbuf);
+out_free_itr:
+ free(itr);
+ return ret;
}
int file_fat_read(const char *filename, void *buffer, int maxsize)
int fat_opendir(const char *filename, struct fs_dir_stream **dirsp)
{
- fat_dir *dir = malloc(sizeof(*dir));
+ fat_dir *dir = calloc(1, sizeof(*dir));
int ret;
if (!dir)
ret = fat_itr_root(&dir->itr, &dir->fsdata);
if (ret)
- goto fail;
+ goto fail_free_dir;
ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR);
if (ret)
- goto fail;
+ goto fail_free_both;
*dirsp = (struct fs_dir_stream *)dir;
return 0;
-fail:
+fail_free_both:
+ free(dir->fsdata.fatbuf);
+fail_free_dir:
free(dir);
return ret;
}
void fat_closedir(struct fs_dir_stream *dirs)
{
fat_dir *dir = (fat_dir *)dirs;
+ free(dir->fsdata.fatbuf);
free(dir);
}