diff options
author | Kevin Ferrare <kevin@rockbox.org> | 2007-07-20 17:06:55 +0000 |
---|---|---|
committer | Kevin Ferrare <kevin@rockbox.org> | 2007-07-20 17:06:55 +0000 |
commit | 011a325e32c05f6e4817dcdc555615e6b7b6c102 (patch) | |
tree | ab22ab91b99524dba823cda861b17520db030911 /firmware/common/dir.c | |
parent | 930278bcc0fd944ec50f30074b53b4c7cf0e3ccf (diff) |
Makes apps and plugins interract with directories using a posix-like api instead of calling dircache / simulator functions (no additionnal layer added, only a cosmetic change)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13943 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dir.c')
-rw-r--r-- | firmware/common/dir.c | 334 |
1 files changed, 0 insertions, 334 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c deleted file mode 100644 index 0f46652b3c..0000000000 --- a/firmware/common/dir.c +++ /dev/null @@ -1,334 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2002 by Björn Stenberg - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * 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 "fat.h" -#include "dir.h" -#include "debug.h" -#include "atoi.h" -#include "dircache.h" - -#define MAX_OPEN_DIRS 8 - -static DIR opendirs[MAX_OPEN_DIRS]; - -#ifdef HAVE_MULTIVOLUME - -/* how to name volumes, first char must be outside of legal file names, - a number gets appended to enumerate, if applicable */ -#ifdef HAVE_MMC -static const char* vol_names = "<MMC%d>"; -#define VOL_ENUM_POS 4 /* position of %d, to avoid runtime calculation */ -#elif defined(HAVE_HOTSWAP) -static const char* vol_names = "<microSD%d>"; -#define VOL_ENUM_POS 8 /* position of %d, to avoid runtime calculation */ -#else -static const char* vol_names = "<HD%d>"; -#define VOL_ENUM_POS 3 -#endif - -/* returns on which volume this is, and copies the reduced name - (sortof a preprocessor for volume-decorated pathnames) */ -static int strip_volume(const char* name, char* namecopy) -{ - int volume = 0; - const char *temp = name; - - while (*temp == '/') /* skip all leading slashes */ - ++temp; - - if (*temp && !strncmp(temp, vol_names, VOL_ENUM_POS)) - { - temp += VOL_ENUM_POS; /* behind special name */ - volume = atoi(temp); /* number is following */ - temp = strchr(temp, '/'); /* search for slash behind */ - if (temp != NULL) - name = temp; /* use the part behind the volume */ - else - name = "/"; /* else this must be the root dir */ - } - - strncpy(namecopy, name, MAX_PATH); - namecopy[MAX_PATH-1] = '\0'; - - return volume; -} -#endif /* #ifdef HAVE_MULTIVOLUME */ - - -#ifdef HAVE_HOTSWAP -// release all dir handles on a given volume "by force", to avoid leaks -int release_dirs(int volume) -{ - DIR* pdir = opendirs; - int dd; - int closed = 0; - for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++) - { - if (pdir->fatdir.file.volume == volume) - { - pdir->busy = false; /* mark as available, no further action */ - closed++; - } - } - return closed; /* return how many we did */ -} -#endif /* #ifdef HAVE_HOTSWAP */ - -DIR* opendir(const char* name) -{ - char namecopy[MAX_PATH]; - char* part; - char* end; - struct fat_direntry entry; - int dd; - DIR* 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 - strncpy(namecopy,name,sizeof(namecopy)); /* just copy */ - namecopy[sizeof(namecopy)-1] = '\0'; -#endif - - if ( fat_opendir(IF_MV2(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)) ) { - pdir->parent_dir = pdir->fatdir; - if ( fat_opendir(IF_MV2(volume,) - &pdir->fatdir, - entry.firstcluster, - &pdir->parent_dir) < 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(DIR* dir) -{ - dir->busy=false; - return 0; -} - -struct dirent* readdir(DIR* dir) -{ - struct fat_direntry entry; - struct dirent* 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() */ - while (++dir->volumecounter < NUM_VOLUMES) - { - if (fat_ismounted(dir->volumecounter)) - { - memset(theent, 0, sizeof(*theent)); - theent->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; - - strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); - theent->attribute = entry.attr; - theent->size = entry.filesize; - theent->startcluster = entry.firstcluster; - theent->wrtdate = entry.wrtdate; - theent->wrttime = entry.wrttime; - - return theent; -} - -int mkdir(const char *name) -{ - DIR *dir; - char namecopy[MAX_PATH]; - char* end; - char *basename; - char *parent; - struct dirent *entry; - struct fat_dir newdir; - int rc; - - if ( name[0] != '/' ) { - DEBUGF("mkdir: Only absolute paths supported right now\n"); - return -1; - } - - strncpy(namecopy,name,sizeof(namecopy)); - namecopy[sizeof(namecopy)-1] = 0; - - /* 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(parent); - - if(!dir) { - DEBUGF("mkdir: can't open parent dir\n"); - return -2; - } - - if(basename[0] == 0) { - DEBUGF("mkdir: Empty dir name\n"); - errno = EINVAL; - return -3; - } - - /* Now check if the name already exists */ - while ((entry = readdir(dir))) { - if ( !strcasecmp(basename, entry->d_name) ) { - DEBUGF("mkdir error: file exists\n"); - errno = EEXIST; - closedir(dir); - return - 4; - } - } - - memset(&newdir, sizeof(struct fat_dir), 0); - - rc = fat_create_dir(basename, &newdir, &(dir->fatdir)); -#ifdef HAVE_DIRCACHE - if (rc >= 0) - dircache_mkdir(name); -#endif - - closedir(dir); - - return rc; -} - -int rmdir(const char* name) -{ - int rc; - DIR* dir; - struct dirent* entry; - - dir = opendir(name); - if (!dir) - { - errno = ENOENT; /* open error */ - return -1; - } - - /* check if the directory is empty */ - while ((entry = readdir(dir))) - { - if (strcmp(entry->d_name, ".") && - strcmp(entry->d_name, "..")) - { - DEBUGF("rmdir error: not empty\n"); - errno = ENOTEMPTY; - closedir(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; - } -#ifdef HAVE_DIRCACHE - else - { - dircache_rmdir(name); - } -#endif - - closedir(dir); - - return rc; -} |