diff options
author | William Wilgus <me.theuser@yahoo.com> | 2017-02-03 17:13:58 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2020-08-20 23:08:57 +0000 |
commit | 5ef28cccf92f5eada6d502fa4b0e16a13e94be5b (patch) | |
tree | 05f9d2f8bdf3c0cc54c5893159a7dcf07c7e3e55 /firmware/common/pathfuncs.c | |
parent | 31fc46ded69be7438cca2ba2c2b93c1f200165a6 (diff) | |
download | rockbox-5ef28cccf92f5eada6d502fa4b0e16a13e94be5b.tar.gz rockbox-5ef28cccf92f5eada6d502fa4b0e16a13e94be5b.zip |
Allow mounting of any directory as the root directory.
Provide definitions for the macros:
* RB_ROOT_VOL_HIDDEN(v) to exclude certain items from the root.
* RB_ROOT_CONTENTS to return a string with the name of the
directory to mount in the root.
Defaults are in export/rbpaths.h
It's a bit much for those that don't need the full functionality.
Some conditional define can cut it back a lot to cut out things only
needed if alternate root mounts are required. I'm just not bothering
yet. The basic concept would be applied to all targets to keep file
code from forking too much.
Change-Id: I90b5c0a1c949283d3102c16734b0b6ac73901a30
Diffstat (limited to 'firmware/common/pathfuncs.c')
-rw-r--r-- | firmware/common/pathfuncs.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c index 0935a9a6e3..078c0b6938 100644 --- a/firmware/common/pathfuncs.c +++ b/firmware/common/pathfuncs.c | |||
@@ -105,7 +105,7 @@ static const unsigned char storage_dec_indexes[STORAGE_NUM_TYPES+1] = | |||
105 | */ | 105 | */ |
106 | int path_strip_volume(const char *name, const char **nameptr, bool greedy) | 106 | int path_strip_volume(const char *name, const char **nameptr, bool greedy) |
107 | { | 107 | { |
108 | int volume = 0; | 108 | int volume = ROOT_VOLUME; |
109 | const char *t = name; | 109 | const char *t = name; |
110 | int c, v = 0; | 110 | int c, v = 0; |
111 | 111 | ||
@@ -114,9 +114,16 @@ int path_strip_volume(const char *name, const char **nameptr, bool greedy) | |||
114 | * digits within the brackets is parsed as the volume number and of | 114 | * digits within the brackets is parsed as the volume number and of |
115 | * those, only the last ones VOL_MUM_MAX allows. | 115 | * those, only the last ones VOL_MUM_MAX allows. |
116 | */ | 116 | */ |
117 | c = *(t = GOBBLE_PATH_SEPCH(t)); /* skip all leading slashes */ | 117 | t = GOBBLE_PATH_SEPCH(t); /* skip all leading slashes */ |
118 | if (t == name) | ||
119 | { | ||
120 | volume = -1; /* relative path; don't know */ | ||
121 | goto psv_out; | ||
122 | } | ||
123 | |||
124 | c = *t; | ||
118 | if (c != VOL_START_TOK) /* missing start token? no volume */ | 125 | if (c != VOL_START_TOK) /* missing start token? no volume */ |
119 | goto volume0; | 126 | goto psv_out; |
120 | 127 | ||
121 | do | 128 | do |
122 | { | 129 | { |
@@ -127,7 +134,7 @@ int path_strip_volume(const char *name, const char **nameptr, bool greedy) | |||
127 | break; | 134 | break; |
128 | case '\0': | 135 | case '\0': |
129 | case PATH_SEPCH: /* no closing bracket; no volume */ | 136 | case PATH_SEPCH: /* no closing bracket; no volume */ |
130 | goto volume0; | 137 | goto psv_out; |
131 | default: /* something else; reset volume */ | 138 | default: /* something else; reset volume */ |
132 | v = 0; | 139 | v = 0; |
133 | } | 140 | } |
@@ -137,7 +144,7 @@ int path_strip_volume(const char *name, const char **nameptr, bool greedy) | |||
137 | if (!(c = *++t)) /* no more path and no '/' is ok */ | 144 | if (!(c = *++t)) /* no more path and no '/' is ok */ |
138 | ; | 145 | ; |
139 | else if (c != PATH_SEPCH) /* more path and no separator after end */ | 146 | else if (c != PATH_SEPCH) /* more path and no separator after end */ |
140 | goto volume0; | 147 | goto psv_out; |
141 | else if (greedy) | 148 | else if (greedy) |
142 | t = GOBBLE_PATH_SEPCH(++t); /* strip remaining separators */ | 149 | t = GOBBLE_PATH_SEPCH(++t); /* strip remaining separators */ |
143 | 150 | ||
@@ -146,7 +153,7 @@ int path_strip_volume(const char *name, const char **nameptr, bool greedy) | |||
146 | 153 | ||
147 | volume = v; | 154 | volume = v; |
148 | name = t; | 155 | name = t; |
149 | volume0: | 156 | psv_out: |
150 | if (nameptr) | 157 | if (nameptr) |
151 | *nameptr = name; | 158 | *nameptr = name; |
152 | return volume; | 159 | return volume; |
@@ -157,10 +164,14 @@ volume0: | |||
157 | */ | 164 | */ |
158 | int get_volume_name(int volume, char *buffer) | 165 | int get_volume_name(int volume, char *buffer) |
159 | { | 166 | { |
160 | if (volume < 0) | 167 | if (volume < 0 || volume == ROOT_VOLUME) |
161 | { | 168 | { |
162 | *buffer = '\0'; | 169 | char *t = buffer; |
163 | return 0; | 170 | if (volume == ROOT_VOLUME) |
171 | *t++ = PATH_ROOTCHR; | ||
172 | |||
173 | *t = '\0'; | ||
174 | return t - buffer; | ||
164 | } | 175 | } |
165 | 176 | ||
166 | volume %= VOL_NUM_MAX; /* as path parser would have it */ | 177 | volume %= VOL_NUM_MAX; /* as path parser would have it */ |
@@ -173,6 +184,20 @@ int get_volume_name(int volume, char *buffer) | |||
173 | return snprintf(buffer, VOL_MAX_LEN + 1, "%c%s%d%c", | 184 | return snprintf(buffer, VOL_MAX_LEN + 1, "%c%s%d%c", |
174 | VOL_START_TOK, voldec, volume, VOL_END_TOK); | 185 | VOL_START_TOK, voldec, volume, VOL_END_TOK); |
175 | } | 186 | } |
187 | |||
188 | /* Returns volume name formatted with the root. Assumes buffer size is at | ||
189 | * least {VOL_MAX_LEN}+2 */ | ||
190 | int make_volume_root(int volume, char *buffer) | ||
191 | { | ||
192 | char *t = buffer; | ||
193 | |||
194 | if (volume >= 0 && volume != ROOT_VOLUME) | ||
195 | *t++ = PATH_ROOTCHR; | ||
196 | |||
197 | t += get_volume_name(volume, t); | ||
198 | |||
199 | return t - buffer; | ||
200 | } | ||
176 | #endif /* HAVE_MULTIVOLUME */ | 201 | #endif /* HAVE_MULTIVOLUME */ |
177 | 202 | ||
178 | /* Just like path_strip_volume() but strips a leading drive specifier and | 203 | /* Just like path_strip_volume() but strips a leading drive specifier and |