summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/gensquashfs.18
-rw-r--r--lib/fstree/fstree_from_file.c36
-rw-r--r--mkfs/options.c8
-rw-r--r--tests/fstree_from_file.c16
4 files changed, 56 insertions, 12 deletions
diff --git a/doc/gensquashfs.1 b/doc/gensquashfs.1
index 8050dc6..c52ce70 100644
--- a/doc/gensquashfs.1
+++ b/doc/gensquashfs.1
@@ -100,7 +100,10 @@ l l
l l
l l
rd.
-<path>;Absolute path of the entry in the image.
+<path>;T{
+Absolute path of the entry in the image. Can be put in quotes
+if some components contain spaces.
+T}
<location>;T{
Optional location of the input file. Can be specified relative to either the
description file or the pack directory. If omitted, the image path is used
@@ -132,6 +135,9 @@ file /sbin/init 0755 0 0 ../init/sbin/init
# Read from ./bin/bash relative to pack dir or listing path
# /bin is created implicitly with default attributes.
file /bin/bash 0755 0 0
+
+# file name with a space in it and a "special" name
+file "/opt/my app/\\"special\\"/data" 0600 0 0
.fi
.in
.SH AUTHOR
diff --git a/lib/fstree/fstree_from_file.c b/lib/fstree/fstree_from_file.c
index 13328d5..901e431 100644
--- a/lib/fstree/fstree_from_file.c
+++ b/lib/fstree/fstree_from_file.c
@@ -113,7 +113,7 @@ static int handle_line(fstree_t *fs, const char *filename,
size_t line_num, char *line)
{
const char *extra = NULL, *msg = NULL;
- char keyword[16], *path;
+ char keyword[16], *path, *ptr;
unsigned int x;
struct stat sb;
size_t i;
@@ -136,17 +136,35 @@ static int handle_line(fstree_t *fs, const char *filename,
/* isolate path */
path = line + i;
- for (; line[i] != '\0'; ++i) {
- /* TODO: escape sequences to support spaces in path */
+ if (*path == '"') {
+ ptr = path;
+ ++i;
- if (isspace(line[i]))
- break;
- }
+ while (line[i] != '\0' && line[i] != '"') {
+ if (line[i] == '\\' &&
+ (line[i + 1] == '"' || line[i + 1] == '\\')) {
+ *(ptr++) = line[i + 1];
+ i += 2;
+ } else {
+ *(ptr++) = line[i++];
+ }
+ }
- if (!isspace(line[i]))
- goto fail_ent;
+ if (line[i] != '"' || !isspace(line[i + 1]))
+ goto fail_ent;
+
+ *ptr = '\0';
+ ++i;
+ } else {
+ while (line[i] != '\0' && !isspace(line[i]))
+ ++i;
+
+ if (!isspace(line[i]))
+ goto fail_ent;
+
+ line[i++] = '\0';
+ }
- line[i++] = '\0';
while (isspace(line[i]))
++i;
diff --git a/mkfs/options.c b/mkfs/options.c
index 25f7453..2dab6b8 100644
--- a/mkfs/options.c
+++ b/mkfs/options.c
@@ -83,7 +83,8 @@ static const char *help_string =
"pipe <path> <mode> <uid> <gid>\n"
"sock <path> <mode> <uid> <gid>\n"
"\n"
-"<path> Absolute path of the entry in the image.\n"
+"<path> Absolute path of the entry in the image. Can be put in quotes\n"
+" if some components contain spaces.\n"
"<location> If given, location of the input file. Either absolute or relative\n"
" to the description file. If omitted, the image path is used,\n"
" relative to the description file.\n"
@@ -107,7 +108,10 @@ static const char *help_string =
" \n"
" # Read bin/bash, relative to listing or pack dir.\n"
" # Implicitly create /bin.\n"
-" file /bin/bash 0755 0 0"
+" file /bin/bash 0755 0 0\n"
+" \n"
+" # file name with a space in it.\n"
+" file \"/opt/my app/\\\"special\\\"/data\" 0600 0 0\n"
"\n\n";
void process_command_line(options_t *opt, int argc, char **argv)
diff --git a/tests/fstree_from_file.c b/tests/fstree_from_file.c
index c5b9b5b..f4fc345 100644
--- a/tests/fstree_from_file.c
+++ b/tests/fstree_from_file.c
@@ -14,6 +14,8 @@ static const char *testdesc =
"nod /chardev 0600 6 7 c 13 37\n"
"nod /blkdev 0600 8 9 b 42 21\n"
"pipe /pipe 0644 10 11\n"
+"dir \"/foo bar\" 0755 0 0\n"
+"dir \"/foo bar/ test \\\"/\" 0755 0 0\n"
" sock /sock 0555 12 13 ";
int main(void)
@@ -56,6 +58,20 @@ int main(void)
assert(n->data.dir->children == NULL);
n = n->next;
+ assert(n->mode == (S_IFDIR | 0755));
+ assert(n->uid == 0);
+ assert(n->gid == 0);
+ assert(strcmp(n->name, "foo bar") == 0);
+ assert(n->data.dir->children != NULL);
+
+ assert(n->data.dir->children->next == NULL);
+ assert(n->data.dir->children->mode == (S_IFDIR | 0755));
+ assert(n->data.dir->children->uid == 0);
+ assert(n->data.dir->children->gid == 0);
+ assert(strcmp(n->data.dir->children->name, " test \"") == 0);
+ assert(n->data.dir->children->data.dir->children == NULL);
+
+ n = n->next;
assert(n->mode == (S_IFIFO | 0644));
assert(n->uid == 10);
assert(n->gid == 11);