diff options
Diffstat (limited to 'firmware/common/dir_uncached.c')
| -rw-r--r-- | firmware/common/dir_uncached.c | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c deleted file mode 100644 index b850a51..0000000 --- a/firmware/common/dir_uncached.c +++ /dev/null @@ -1,312 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id: dir.c 13741 2007-06-30 02:08:27Z jethead71 $ - * - * Copyright (C) 2002 by Björn Stenberg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdbool.h> -#include <stdlib.h> -#include "fat.h" -#include "dir.h" -#include "debug.h" -#include "filefuncs.h" - -#if (MEMORYSIZE > 8) -#define MAX_OPEN_DIRS 12 -#else -#define MAX_OPEN_DIRS 8 -#endif - -static DIR_UNCACHED opendirs[MAX_OPEN_DIRS]; - -// release all dir handles on a given volume "by force", to avoid leaks -int release_dirs(int volume) -{ - DIR_UNCACHED* pdir = opendirs; - int dd; - int closed = 0; - for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++) - { -#ifdef HAVE_MULTIVOLUME - if (pdir->fatdir.file.volume == volume) -#else - (void)volume; -#endif - { - pdir->busy = false; /* mark as available, no further action */ - closed++; - } - } - return closed; /* return how many we did */ -} - -DIR_UNCACHED* opendir_uncached(const char* name) -{ - char namecopy[MAX_PATH]; - char* part; - char* end; - struct fat_direntry entry; - int dd; - DIR_UNCACHED* pdir = opendirs; -#ifdef HAVE_MULTIVOLUME - int volume; -#endif - - if ( name[0] != '/' ) { - DEBUGF("Only absolute paths supported right now\n"); - return NULL; - } - - /* find a free dir descriptor */ - for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++) - if ( !pdir->busy ) - break; - - if ( dd == MAX_OPEN_DIRS ) { - DEBUGF("Too many dirs open\n"); - errno = EMFILE; - return NULL; - } - - pdir->busy = true; - -#ifdef HAVE_MULTIVOLUME - /* try to extract a heading volume name, if present */ - volume = strip_volume(name, namecopy); - pdir->volumecounter = 0; -#else - strlcpy(namecopy, name, sizeof(namecopy)); /* just copy */ -#endif - - if ( fat_opendir(IF_MV(volume,) &pdir->fatdir, 0, NULL) < 0 ) { - DEBUGF("Failed opening root dir\n"); - pdir->busy = false; - return NULL; - } - - for ( part = strtok_r(namecopy, "/", &end); part; - part = strtok_r(NULL, "/", &end)) { - /* scan dir for name */ - while (1) { - if ((fat_getnext(&pdir->fatdir,&entry) < 0) || - (!entry.name[0])) { - pdir->busy = false; - return NULL; - } - if ( (entry.attr & FAT_ATTR_DIRECTORY) && - (!strcasecmp(part, entry.name)) ) { - /* In reality, the parent_dir parameter of fat_opendir seems - * useless because it's sole purpose it to have a way to - * update the file metadata, but here we are only reading - * a directory so there's no need for that kind of stuff. - * However, the rmdir_uncached function uses a ugly hack to - * avoid opening a directory twice when deleting it and thus - * needs those information. That's why we pass pdir->fatdir both - * as the parent directory and the resulting one (this is safe, - * in doubt, check fat_open(dir) code) which will allow this kind of - * (ugly) things */ - if ( fat_opendir(IF_MV(volume,) - &pdir->fatdir, - entry.firstcluster, - &pdir->fatdir) < 0 ) { - DEBUGF("Failed opening dir '%s' (%ld)\n", - part, entry.firstcluster); - pdir->busy = false; - return NULL; - } -#ifdef HAVE_MULTIVOLUME - pdir->volumecounter = -1; /* n.a. to subdirs */ -#endif - break; - } - } - } - - return pdir; -} - -int closedir_uncached(DIR_UNCACHED* dir) -{ - dir->busy=false; - return 0; -} - -struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir) -{ - struct fat_direntry entry; - struct dirent_uncached* theent = &(dir->theent); - - if (!dir->busy) - return NULL; - -#ifdef HAVE_MULTIVOLUME - /* Volumes (secondary file systems) get inserted into the root directory - of the first volume, since we have no separate top level. */ - if (dir->volumecounter >= 0 /* on a root dir */ - && dir->volumecounter < NUM_VOLUMES /* in range */ - && dir->fatdir.file.volume == 0) /* at volume 0 */ - { /* fake special directories, which don't really exist, but - will get redirected upon opendir_uncached() */ - while (++dir->volumecounter < NUM_VOLUMES) - { - if (fat_ismounted(dir->volumecounter)) - { - memset(theent, 0, sizeof(*theent)); - theent->info.attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; - snprintf(theent->d_name, sizeof(theent->d_name), - VOL_NAMES, dir->volumecounter); - return theent; - } - } - } -#endif - /* normal directory entry fetching follows here */ - if (fat_getnext(&(dir->fatdir),&entry) < 0) - return NULL; - - if ( !entry.name[0] ) - return NULL; - - strlcpy(theent->d_name, entry.name, sizeof(theent->d_name)); - theent->info.attribute = entry.attr; - theent->info.wrtdate = entry.wrtdate; - theent->info.wrttime = entry.wrttime; - theent->info.size = entry.filesize; - theent->startcluster = entry.firstcluster; - - return theent; -} - -int mkdir_uncached(const char *name) -{ - DIR_UNCACHED *dir; - char namecopy[MAX_PATH]; - char* end; - char *basename; - char *parent; - struct dirent_uncached *entry; - int dd; - DIR_UNCACHED* pdir = opendirs; - struct fat_dir *newdir; - int rc; - - if ( name[0] != '/' ) { - DEBUGF("mkdir: Only absolute paths supported right now\n"); - return -1; - } - /* find a free dir descriptor */ - for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++) - if ( !pdir->busy ) - break; - - if ( dd == MAX_OPEN_DIRS ) { - DEBUGF("Too many dirs open\n"); - errno = EMFILE; - return -5; - } - - pdir->busy = true; - newdir = &pdir->fatdir; - - strlcpy(namecopy, name, sizeof(namecopy)); - - /* Split the base name and the path */ - end = strrchr(namecopy, '/'); - *end = 0; - basename = end+1; - - if(namecopy == end) /* Root dir? */ - parent = "/"; - else - parent = namecopy; - - DEBUGF("mkdir: parent: %s, name: %s\n", parent, basename); - - dir = opendir_uncached(parent); - - if(!dir) { - DEBUGF("mkdir: can't open parent dir\n"); - pdir->busy = false; - return -2; - } - - if(basename[0] == 0) { - DEBUGF("mkdir: Empty dir name\n"); - pdir->busy = false; - errno = EINVAL; - return -3; - } - - /* Now check if the name already exists */ - while ((entry = readdir_uncached(dir))) { - if ( !strcasecmp(basename, entry->d_name) ) { - DEBUGF("mkdir error: file exists\n"); - errno = EEXIST; - closedir_uncached(dir); - pdir->busy = false; - return - 4; - } - } - - memset(newdir, 0, sizeof(struct fat_dir)); - - rc = fat_create_dir(basename, newdir, &(dir->fatdir)); - closedir_uncached(dir); - pdir->busy = false; - - return rc; -} - -int rmdir_uncached(const char* name) -{ - int rc; - DIR_UNCACHED* dir; - struct dirent_uncached* entry; - - dir = opendir_uncached(name); - if (!dir) - { - errno = ENOENT; /* open error */ - return -1; - } - - /* check if the directory is empty */ - while ((entry = readdir_uncached(dir))) - { - if (strcmp(entry->d_name, ".") && - strcmp(entry->d_name, "..")) - { - DEBUGF("rmdir error: not empty\n"); - errno = ENOTEMPTY; - closedir_uncached(dir); - return -2; - } - } - - rc = fat_remove(&(dir->fatdir.file)); - if ( rc < 0 ) { - DEBUGF("Failed removing dir: %d\n", rc); - errno = EIO; - rc = rc * 10 - 3; - } - - closedir_uncached(dir); - return rc; -} |