vold: Add support for renaming secure containers

Signed-off-by: San Mehat <san@google.com>
diff --git a/CommandListener.cpp b/CommandListener.cpp
index f15d44a..e5ebb46 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -46,6 +46,7 @@
     registerCmd(new DestroyAsecCmd());
     registerCmd(new MountAsecCmd());
     registerCmd(new UnmountAsecCmd());
+    registerCmd(new RenameAsecCmd());
     registerCmd(new ListAsecCmd());
     registerCmd(new AsecPathCmd());
 }
@@ -275,6 +276,26 @@
     return 0;
 }
 
+CommandListener::RenameAsecCmd::RenameAsecCmd() :
+                 VoldCommand("rename_asec") {
+}
+
+int CommandListener::RenameAsecCmd::runCommand(SocketClient *cli,
+                                            int argc, char **argv) {
+    if (argc != 3) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError,
+                     "Usage: rename_asec <id1> <id2>", false);
+        return 0;
+    }
+
+    if (VolumeManager::Instance()->renameAsec(argv[1], argv[2])) {
+        cli->sendMsg(ResponseCode::OperationFailed, "Rename failed", true);
+    } else {
+        cli->sendMsg(ResponseCode::CommandOkay, "Rename succeeded", false);
+    }
+    return 0;
+}
+
 CommandListener::ListAsecCmd::ListAsecCmd() :
                  VoldCommand("list_asec") {
 
diff --git a/CommandListener.h b/CommandListener.h
index 64ff31f..571b81b 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -118,6 +118,13 @@
         int runCommand(SocketClient *c, int argc, char ** argv);
     };
 
+    class RenameAsecCmd : public VoldCommand {
+    public:
+        RenameAsecCmd();
+        virtual ~RenameAsecCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    };
+
     class ListAsecCmd : public VoldCommand {
     public:
         ListAsecCmd();
@@ -132,7 +139,6 @@
         int runCommand(SocketClient *c, int argc, char ** argv);
     };
 
-
 };
 
 #endif
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index c8b4505..0b63c9f 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -284,6 +284,42 @@
     return 0;
 }
 
+int VolumeManager::renameAsec(const char *id1, const char *id2) {
+    char *asecFilename1;
+    char *asecFilename2;
+    char mountPoint[255];
+
+    asprintf(&asecFilename1, "/sdcard/android_secure/%s.asec", id1);
+    asprintf(&asecFilename2, "/sdcard/android_secure/%s.asec", id2);
+
+    snprintf(mountPoint, sizeof(mountPoint), "/asec/%s", id1);
+    if (isMountpointMounted(mountPoint)) {
+        LOGW("Rename attempt when src mounted");
+        errno = EBUSY;
+        goto out_err;
+    }
+
+    if (!access(asecFilename2, F_OK)) {
+        LOGE("Rename attempt when dst exists");
+        errno = EADDRINUSE;
+        goto out_err;
+    }
+
+    if (rename(asecFilename1, asecFilename2)) {
+        LOGE("Rename of '%s' to '%s' failed (%s)", asecFilename1, asecFilename2, strerror(errno));
+        goto out_err;
+    }
+
+    free(asecFilename1);
+    free(asecFilename2);
+    return 0;
+
+out_err:
+    free(asecFilename1);
+    free(asecFilename2);
+    return -1;
+}
+
 int VolumeManager::unmountAsec(const char *id) {
     char asecFileName[255];
     char mountPoint[255];
diff --git a/VolumeManager.h b/VolumeManager.h
index a0761b4..07861d4 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -64,6 +64,7 @@
     int destroyAsec(const char *id);
     int mountAsec(const char *id, const char *key, int ownerUid);
     int unmountAsec(const char *id);
+    int renameAsec(const char *id1, const char *id2);
     int getAsecMountPath(const char *id, char *buffer, int maxlen);
 
     // XXX: This should be moved private once switch uevents are working