summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/pathfuncs.c39
-rw-r--r--firmware/export/pathfuncs.h1
2 files changed, 38 insertions, 2 deletions
diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c
index 5242ec2d32..b942fdf022 100644
--- a/firmware/common/pathfuncs.c
+++ b/firmware/common/pathfuncs.c
@@ -109,8 +109,8 @@ static const unsigned char storage_dec_indexes[STORAGE_NUM_TYPES+1] =
109/* Returns on which volume this is and sets *nameptr to the portion of the 109/* Returns on which volume this is and sets *nameptr to the portion of the
110 * path after the volume specifier, which could be the null if the path is 110 * path after the volume specifier, which could be the null if the path is
111 * just a volume root. If *nameptr > name, then a volume specifier was 111 * just a volume root. If *nameptr > name, then a volume specifier was
112 * found. If 'greedy' is 'true', then it all separators after the volume 112 * found. If 'greedy' is 'true', then all separators after the volume
113 * specifier are consumed, if one was found. 113 * specifier are consumed.
114 */ 114 */
115int path_strip_volume(const char *name, const char **nameptr, bool greedy) 115int path_strip_volume(const char *name, const char **nameptr, bool greedy)
116{ 116{
@@ -167,6 +167,41 @@ psv_out:
167 return volume; 167 return volume;
168} 168}
169 169
170/* Strip the last volume component in the path and return the remainder of
171 * the path in *nameptr. If 'greedy' is 'true', then all separators after
172 * the volume specifier are consumed.
173 */
174int path_strip_last_volume(const char *name, const char **nameptr, bool greedy)
175{
176 const char *p = name + strlen(name);
177
178 while (p > name)
179 {
180 /* skip the component */
181 while (p > name && p[-1] != PATH_SEPCH)
182 --p;
183
184 /* bail if we reached the beginning */
185 if (p <= name+1)
186 break;
187
188 /* point at the seprator */
189 --p;
190
191 /* try to strip the volume and return it if found */
192 int volume = path_strip_volume(p, nameptr, greedy);
193 if (volume != ROOT_VOLUME)
194 return volume;
195
196 /* skip any extra separators */
197 while (p > name && p[-1] == PATH_SEPCH)
198 --p;
199 }
200
201 /* return whatever is at the beginning of the path */
202 return path_strip_volume(name, nameptr, greedy);
203}
204
170/* Returns the volume specifier decorated with the storage type name. 205/* Returns the volume specifier decorated with the storage type name.
171 * Assumes the supplied buffer size is at least {VOL_MAX_LEN}+1. 206 * Assumes the supplied buffer size is at least {VOL_MAX_LEN}+1.
172 */ 207 */
diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h
index 385d534714..d4fa4eb460 100644
--- a/firmware/export/pathfuncs.h
+++ b/firmware/export/pathfuncs.h
@@ -79,6 +79,7 @@ static inline bool name_is_dot_dot(const char *name)
79 79
80#ifdef HAVE_MULTIVOLUME 80#ifdef HAVE_MULTIVOLUME
81int path_strip_volume(const char *name, const char **nameptr, bool greedy); 81int path_strip_volume(const char *name, const char **nameptr, bool greedy);
82int path_strip_last_volume(const char *name, const char **nameptr, bool greedy);
82int get_volume_name(int volume, char *name); 83int get_volume_name(int volume, char *name);
83int make_volume_root(int volume, char *dst); 84int make_volume_root(int volume, char *dst);
84#endif 85#endif