am 71ebe154: Add mkdirs() command.
* commit '71ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5':
Add mkdirs() command.
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 6bfb8da..0ac656b 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -200,6 +200,12 @@
(enabled ? "Share enabled" : "Share disabled"), false);
}
return 0;
+ } else if (!strcmp(argv[1], "mkdirs")) {
+ if (argc != 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mkdirs <path>", false);
+ return 0;
+ }
+ rc = vm->mkdirs(argv[2]);
} else {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
}
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 180387c..f606b5b 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -32,6 +32,7 @@
#include <openssl/md5.h>
+#include <cutils/fs.h>
#include <cutils/log.h>
#include <sysutils/NetlinkEvent.h>
@@ -1577,6 +1578,26 @@
}
return rc;
-
}
+int VolumeManager::mkdirs(char* path) {
+ // Require that path lives under a volume we manage
+ const char* emulated_source = getenv("EMULATED_STORAGE_SOURCE");
+ const char* root = NULL;
+ if (!strncmp(path, emulated_source, strlen(emulated_source))) {
+ root = emulated_source;
+ } else {
+ Volume* vol = getVolumeForFile(path);
+ if (vol) {
+ root = vol->getMountpoint();
+ }
+ }
+
+ if (!root) {
+ SLOGE("Failed to find volume for %s", path);
+ return -EINVAL;
+ }
+
+ /* fs_mkdirs() does symlink checking and relative path enforcement */
+ return fs_mkdirs(path, 0700);
+}
diff --git a/VolumeManager.h b/VolumeManager.h
index be78516..9d69d6a 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -140,6 +140,15 @@
int getDirectVolumeList(struct volume_info *vol_list);
int unmountAllAsecsInDir(const char *directory);
+ /*
+ * Ensure that all directories along given path exist, creating parent
+ * directories as needed. Validates that given path is absolute and that
+ * it contains no relative "." or ".." paths or symlinks. Last path segment
+ * is treated as filename and ignored, unless the path ends with "/". Also
+ * ensures that path belongs to a volume managed by vold.
+ */
+ int mkdirs(char* path);
+
private:
VolumeManager();
void readInitialState();