Index: apps/misc.h =================================================================== --- apps/misc.h (revision 26622) +++ apps/misc.h (working copy) @@ -87,6 +87,11 @@ bool file_exists(const char *file); bool dir_exists(const char *path); +#ifdef HAVE_VOLUMELABEL +/* check, if the file belongs to a mounted volume */ +bool mounted_volume(const char *file); +#endif + /* * removes the extension of filename (if it doesn't start with a .) * puts the result in buffer Index: apps/playlist.c =================================================================== --- apps/playlist.c (revision 26622) +++ apps/playlist.c (working copy) @@ -2823,6 +2823,10 @@ { int result; +#ifdef HAVE_VOLUMELABEL + if (!file_exists(filename)) + return 0; +#endif if (!playlist) playlist = ¤t_playlist; Index: apps/tagcache.c =================================================================== --- apps/tagcache.c (revision 26622) +++ apps/tagcache.c (working copy) @@ -857,6 +857,13 @@ return false; } +#ifdef HAVE_VOLUMELABEL +inline static bool str_mounted(const char *str, const char *unused) +{ + return mounted(str); +} +#endif + static bool check_against_clause(long numeric, const char *str, const struct tagcache_search_clause *clause) { @@ -910,7 +917,10 @@ return !str_ends_with(str, clause->str); case clause_oneof: return str_oneof(str, clause->str); - +#ifdef HAVE_VOLUMELABEL + case clause_mounted: + return str_mounted(str, clause->str); +#endif default: logf("Incorrect tag: %d", clause->type); } @@ -3994,7 +4004,11 @@ if (dircache_is_enabled()) { dc = dircache_get_entry_ptr(buf); - if (dc == NULL) + if (dc == NULL +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s", buf); @@ -4015,7 +4029,11 @@ /* Check if entry has been removed. */ if (global_settings.tagcache_autoupdate) { - if (!file_exists(buf)) + if (!file_exists(buf) +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s", buf); @@ -4105,7 +4123,11 @@ continue; /* Now check if the file exists. */ - if (!file_exists(buf)) + if (!file_exists(buf) +#ifdef HAVE_VOLUMELABEL + && mounted(buf) +#endif + ) { logf("Entry no longer valid."); logf("-> %s / %ld", buf, tfe.tag_length); Index: apps/tagcache.h =================================================================== --- apps/tagcache.h (revision 26622) +++ apps/tagcache.h (working copy) @@ -119,7 +119,11 @@ enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq, clause_lt, clause_lteq, clause_contains, clause_not_contains, clause_begins_with, clause_not_begins_with, clause_ends_with, - clause_not_ends_with, clause_oneof }; + clause_not_ends_with, clause_oneof +#ifdef HAVE_VOLUMELABEL + , clause_mounted +#endif + }; struct tagcache_stat { bool initialized; /* Is tagcache currently busy? */ Index: apps/misc.c =================================================================== --- apps/misc.c (revision 26622) +++ apps/misc.c (working copy) @@ -771,6 +771,25 @@ return true; } +#ifdef HAVE_VOLUMELABEL +bool mounted_volume(const char *file) +{ + if (file[1] != '<') + return true; + else + { + char dir[15]; + char* pos; + strlcpy(dir,file,sizeof(dir)); + pos = strchr(dir, '>'); + if ( pos == NULL ) + return false; + *(pos+1) = 0; + return file_exists(dir); + } +} +#endif + /* * removes the extension of filename (if it doesn't start with a .) * puts the result in buffer Index: apps/tagtree.c =================================================================== --- apps/tagtree.c (revision 26622) +++ apps/tagtree.c (working copy) @@ -100,6 +100,14 @@ static bool sort_inverse; +#ifdef HAVE_VOLUMELABEL +static struct tagcache_search_clause mounted_clause = +{ + tag_filename, clause_mounted, false, source_constant, 0, NULL +}; +#endif + + /* * "%3d. %s" autoscore title %sort = "inverse" %limit = "100" * @@ -294,7 +302,6 @@ MATCH(condition, buf, "$", clause_ends_with); MATCH(condition, buf, "!$", clause_not_ends_with); MATCH(condition, buf, "@", clause_oneof); - return 0; } @@ -1116,6 +1123,9 @@ for (j = 0; j < csi->clause_count[i]; j++) tagcache_search_add_clause(&tcs, csi->clause[i][j]); } +#ifdef HAVE_VOLUMELABEL + tagcache_search_add_clause(&tcs, &mounted_clause); +#endif current_offset = offset; current_entry_count = 0; @@ -1140,6 +1150,10 @@ sort_inverse = false; sort_limit = 0; strip = 0; +#ifdef HAVE_VOLUMELABEL + /* force sorting in any case */ + sort = true; +#endif } if (tag != tag_title && tag != tag_filename) Index: firmware/export/config.h =================================================================== --- firmware/export/config.h (revision 26622) +++ firmware/export/config.h (working copy) @@ -632,7 +632,7 @@ #ifndef NUM_DRIVES #define NUM_DRIVES 1 #endif - +#define HAVE_VOLUMELABEL #define NUM_VOLUMES (NUM_DRIVES * NUM_VOLUMES_PER_DRIVE) #if defined(BOOTLOADER) && defined(HAVE_ADJUSTABLE_CPU_FREQ) Index: firmware/export/config/sansaclipplus.h =================================================================== --- firmware/export/config/sansaclipplus.h (revision 26622) +++ firmware/export/config/sansaclipplus.h (working copy) @@ -14,6 +14,7 @@ #define HAVE_MULTIDRIVE #define NUM_DRIVES 2 #define HAVE_HOTSWAP +#define HAVE_VOLUMELABEL #endif #define HW_SAMPR_CAPS SAMPR_CAP_ALL Index: firmware/export/fat.h =================================================================== --- firmware/export/fat.h (revision 26622) +++ firmware/export/fat.h (working copy) @@ -133,4 +133,9 @@ extern unsigned int fat_get_cluster_size(IF_MV_NONVOID(int volume)); /* public for debug info screen */ extern bool fat_ismounted(int volume); +#ifdef HAVE_VOLUMELABEL +extern char* fat_vol_name(int volume); +extern int fat_vol_name_sz(int volume); #endif + +#endif Index: firmware/include/dir.h =================================================================== --- firmware/include/dir.h (revision 26622) +++ firmware/include/dir.h (working copy) @@ -39,7 +39,10 @@ #define VOL_ENUM_POS 3 #endif +#ifdef HAVE_VOLUMELABEL +int mounted(const char *file); #endif +#endif #ifdef HAVE_DIRCACHE # include "dircache.h" Index: firmware/common/dircache.c =================================================================== --- firmware/common/dircache.c (revision 26622) +++ firmware/common/dircache.c (working copy) @@ -282,8 +282,14 @@ if (volume > 0) { ce->d_name = ((char *)dircache_root+dircache_size); +#ifdef HAVE_VOLUMELABEL + strlcpy(ce->d_name, fat_vol_name(volume), + sizeof(ce->d_name)); + ce->name_len = fat_vol_name_sz(volume); +#else snprintf(ce->d_name, VOL_ENUM_POS + 3, VOL_NAMES, volume); ce->name_len = VOL_ENUM_POS + 3; +#endif dircache_size += ce->name_len; ce->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; ce->size = 0; Index: firmware/common/dir_uncached.c =================================================================== --- firmware/common/dir_uncached.c (revision 26622) +++ firmware/common/dir_uncached.c (working copy) @@ -172,8 +172,13 @@ { memset(theent, 0, sizeof(*theent)); theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; +#ifdef HAVE_VOLUMELABEL + strlcpy(theent->d_name, fat_vol_name(dir->volumecounter), + sizeof(theent->d_name)); +#else snprintf(theent->d_name, sizeof(theent->d_name), VOL_NAMES, dir->volumecounter); +#endif return theent; } } Index: firmware/common/filefuncs.c =================================================================== --- firmware/common/filefuncs.c (revision 26622) +++ firmware/common/filefuncs.c (working copy) @@ -24,6 +24,31 @@ #include "string.h" #ifdef HAVE_MULTIVOLUME + +#ifdef HAVE_VOLUMELABEL +/* returns true, if the filename is on a mounted volume */ +int mounted(const char *file) +{ + const char *temp = file; + while (*temp == '/') /* skip all leading slashes */ + ++temp; + + if ( *temp != '<') + return true; + + int i; + for ( i=1; i #include #include "fat.h" +#include "dir.h" #include "storage.h" #include "debug.h" #include "panic.h" @@ -180,7 +181,11 @@ int drive; /* on which physical device is this located */ #endif bool mounted; /* flag if this volume is mounted */ +#ifdef HAVE_VOLUMELABEL + char mountpt[14]; /* mount point */ + int mountpt_sz; /* length of mount point name */ #endif +#endif }; static struct bpb fat_bpbs[NUM_VOLUMES]; /* mounted partition info */ @@ -292,6 +297,10 @@ for (i=0; ibpb_rootclus = 0 - dirclusters; /* backwards, before the data*/ fat_bpb->rootdiroffset = dirclusters * fat_bpb->bpb_secperclus - rootdirsectors; +#ifdef HAVE_VOLUMELABEL + snprintf(fat_bpb->mountpt, sizeof(fat_bpb->mountpt)-2, + "%s", buf + BS_VOLLAB); +#endif } else #endif /* #ifdef HAVE_FAT16SUPPORT */ @@ -414,6 +427,10 @@ fat_bpb->bpb_fsinfo = secmult * BYTES2INT16(buf,BPB_FSINFO); fat_bpb->rootdirsector = cluster2sec(IF_MV2(fat_bpb,) fat_bpb->bpb_rootclus); +#ifdef HAVE_VOLUMELABEL + snprintf(fat_bpb->mountpt, sizeof(fat_bpb->mountpt)-2, + "%s", buf + BS_32_VOLLAB); +#endif } rc = bpb_is_sane(IF_MV(fat_bpb)); @@ -458,7 +475,32 @@ #ifdef HAVE_MULTIVOLUME fat_bpb->mounted = true; +#ifdef HAVE_VOLUMELABEL +/* default if no volume label is found */ +/* should be refined, when there are several equal labels, + and/or we have a flag for using volume labels as mount points */ + if ( fat_bpb->mountpt[0] == 0 ) + { + snprintf(fat_bpb->mountpt,sizeof(fat_bpb->mountpt),VOL_NAMES,volume); + fat_bpb->mountpt_sz = strlen(fat_bpb->mountpt); + } + else + { + /* trim trailing blanks and add '<' and '>'*/ + char* c = fat_bpb->mountpt + strlen(fat_bpb->mountpt); + while ( (*c == 0 || *c == ' ') && c > fat_bpb->mountpt) + { + *c = 0; + c--; + } + memmove(fat_bpb->mountpt+1, fat_bpb->mountpt, + strlen(fat_bpb->mountpt)); + fat_bpb->mountpt[0] = '<'; + fat_bpb->mountpt[strlen(fat_bpb->mountpt)] = '>'; + fat_bpb->mountpt_sz = strlen(fat_bpb->mountpt); + } #endif +#endif return 0; } @@ -497,8 +539,10 @@ mutex_unlock(&cache_mutex); rc = 0; } -#ifdef HAVE_MULTIVOLUME +#ifdef HAVE_VOLUMELABEL fat_bpb->mounted = false; + memset(fat_bpb->mountpt,0,sizeof(fat_bpb->mountpt)); + fat_bpb->mountpt_sz = 0; #endif return rc; } @@ -2520,4 +2564,16 @@ { return (volume