From 71ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 17 Sep 2013 17:24:38 -0700 Subject: [PATCH] Add mkdirs() command. Apps without sdcard_r or sdcard_rw need to have someone create package-specific directories on their behalf. If apps have trouble creating on their own, they now delegate through system to have vold create the paths. Requires that the requested path is actually managed by vold. Bug: 10577808 Change-Id: I6835fc8f52240f9de07f89742a426a153e3ca32a --- CommandListener.cpp | 6 ++++++ VolumeManager.cpp | 23 ++++++++++++++++++++++- VolumeManager.h | 9 +++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CommandListener.cpp b/CommandListener.cpp index 5de920f..049d42c 100644 --- a/CommandListener.cpp +++ b/CommandListener.cpp @@ -202,6 +202,12 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli, (enabled ? "Share enabled" : "Share disabled"), false); } return 0; + } else if (!strcmp(argv[1], "mkdirs")) { + if (argc != 3) { + cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mkdirs ", 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 +#include #include #include @@ -1577,6 +1578,26 @@ int VolumeManager::cleanupAsec(Volume *v, bool force) { } 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 @@ public: 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();