diff options
author | Mike Lockwood <lockwood@android.com> | 2010-09-13 17:15:58 -0400 |
---|---|---|
committer | Mike Lockwood <lockwood@android.com> | 2010-09-14 10:37:27 -0400 |
commit | d32114950770a6e9361e0869a41e5a03a7acab42 (patch) | |
tree | dd51c95ed04cc9eb701e5ad8db5b954004f65bd6 /media/mtp | |
parent | c59ad085c9737e8d56328732be6864de302acae9 (diff) | |
download | frameworks_av-d32114950770a6e9361e0869a41e5a03a7acab42.zip frameworks_av-d32114950770a6e9361e0869a41e5a03a7acab42.tar.gz frameworks_av-d32114950770a6e9361e0869a41e5a03a7acab42.tar.bz2 |
MTP: Delete all files and subdirectories when deleting directories.
Children are now recursively deleted from the database and filesystem.
Change-Id: Ifd9b48cbc34b84b8f5073f2493dfe9735fae5492
Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media/mtp')
-rw-r--r-- | media/mtp/MtpServer.cpp | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index 3d3bd62..6332b4e 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -21,6 +21,8 @@ #include <sys/stat.h> #include <fcntl.h> #include <errno.h> +#include <sys/stat.h> +#include <dirent.h> #include <cutils/properties.h> @@ -686,21 +688,77 @@ done: return result; } +static void deleteRecursive(const char* path) { + char pathbuf[PATH_MAX]; + int pathLength = strlen(path); + if (pathLength >= sizeof(pathbuf) - 1) { + LOGE("path too long: %s\n", path); + } + strcpy(pathbuf, path); + if (pathbuf[pathLength - 1] != '/') { + pathbuf[pathLength++] = '/'; + } + char* fileSpot = pathbuf + pathLength; + int pathRemaining = sizeof(pathbuf) - pathLength - 1; + + DIR* dir = opendir(path); + if (!dir) { + LOGE("opendir %s failed: %s", path, strerror(errno)); + return; + } + + struct dirent* entry; + while ((entry = readdir(dir))) { + const char* name = entry->d_name; + + // ignore "." and ".." + if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) { + continue; + } + + int nameLength = strlen(name); + if (nameLength > pathRemaining) { + LOGE("path %s/%s too long\n", path, name); + continue; + } + strcpy(fileSpot, name); + + int type = entry->d_type; + if (entry->d_type == DT_DIR) { + deleteRecursive(pathbuf); + rmdir(pathbuf); + } else { + unlink(pathbuf); + } + } +} + +static void deletePath(const char* path) { + struct stat statbuf; + if (stat(path, &statbuf) == 0) { + if (S_ISDIR(statbuf.st_mode)) { + deleteRecursive(path); + rmdir(path); + } else { + unlink(path); + } + } else { + LOGE("deletePath stat failed for %s: %s", path, strerror(errno)); + } +} + MtpResponseCode MtpServer::doDeleteObject() { MtpObjectHandle handle = mRequest.getParameter(1); - MtpObjectFormat format = mRequest.getParameter(1); + MtpObjectFormat format = mRequest.getParameter(2); // FIXME - support deleting all objects if handle is 0xFFFFFFFF // FIXME - implement deleting objects by format - // FIXME - handle non-empty directories MtpString filePath; int64_t fileLength; int result = mDatabase->getObjectFilePath(handle, filePath, fileLength); if (result == MTP_RESPONSE_OK) { LOGV("deleting %s", (const char *)filePath); - // one of these should work - rmdir((const char *)filePath); - unlink((const char *)filePath); + deletePath((const char *)filePath); return mDatabase->deleteFile(handle); } else { return result; |