am 10939ac7: Merge "Extract UUID and label from inserted volumes." into klp-dev

* commit '10939ac7e8c9fd141f45f1d6d82c78d5f5f5319c':
  Extract UUID and label from inserted volumes.
diff --git a/Android.mk b/Android.mk
index 8d0b249..cecab1e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,10 +23,13 @@
 	$(KERNEL_HEADERS) \
 	system/extras/ext4_utils \
 	external/openssl/include \
+	external/stlport/stlport \
+	bionic \
 	external/scrypt/lib/crypto
 
 common_shared_libraries := \
 	libsysutils \
+	libstlport \
 	libcutils \
 	liblog \
 	libdiskconfig \
diff --git a/ResponseCode.h b/ResponseCode.h
index dccacb8..5e4c6fa 100644
--- a/ResponseCode.h
+++ b/ResponseCode.h
@@ -57,6 +57,8 @@
     static const int VolumeMountFailedBlank         = 610;
     static const int VolumeMountFailedDamaged       = 611;
     static const int VolumeMountFailedNoMedia       = 612;
+    static const int VolumeUuidChange               = 613;
+    static const int VolumeUserLabelChange          = 614;
 
     static const int ShareAvailabilityChange        = 620;
 
diff --git a/Volume.cpp b/Volume.cpp
index 7d33919..cbec5d4 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -40,6 +40,8 @@
 #include <cutils/fs.h>
 #include <cutils/log.h>
 
+#include <string>
+
 #include "Volume.h"
 #include "VolumeManager.h"
 #include "ResponseCode.h"
@@ -80,6 +82,8 @@
  */
 const char *Volume::LOOPDIR           = "/mnt/obb";
 
+const char *Volume::BLKID_PATH = "/system/bin/blkid";
+
 static const char *stateToStr(int state) {
     if (state == Volume::State_Init)
         return "Initializing";
@@ -109,6 +113,8 @@
     mVm = vm;
     mDebug = false;
     mLabel = strdup(rec->label);
+    mUuid = NULL;
+    mUserLabel = NULL;
     mState = Volume::State_Init;
     mFlags = flags;
     mCurrentlyMountedKdev = -1;
@@ -118,25 +124,8 @@
 
 Volume::~Volume() {
     free(mLabel);
-}
-
-void Volume::protectFromAutorunStupidity() {
-    char filename[255];
-
-    snprintf(filename, sizeof(filename), "%s/autorun.inf", getMountpoint());
-    if (!access(filename, F_OK)) {
-        SLOGW("Volume contains an autorun.inf! - removing");
-        /*
-         * Ensure the filename is all lower-case so
-         * the process killer can find the inode.
-         * Probably being paranoid here but meh.
-         */
-        rename(filename, filename);
-        Process::killProcessesWithOpenFiles(filename, 2);
-        if (unlink(filename)) {
-            SLOGE("Failed to remove %s (%s)", filename, strerror(errno));
-        }
-    }
+    free(mUuid);
+    free(mUserLabel);
 }
 
 void Volume::setDebug(bool enable) {
@@ -162,6 +151,46 @@
     return -1;
 }
 
+void Volume::setUuid(const char* uuid) {
+    char msg[256];
+
+    if (mUuid) {
+        free(mUuid);
+    }
+
+    if (uuid) {
+        mUuid = strdup(uuid);
+        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
+                getFuseMountpoint(), mUuid);
+    } else {
+        mUuid = NULL;
+        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
+    }
+
+    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUuidChange, msg,
+            false);
+}
+
+void Volume::setUserLabel(const char* userLabel) {
+    char msg[256];
+
+    if (mUserLabel) {
+        free(mUserLabel);
+    }
+
+    if (userLabel) {
+        mUserLabel = strdup(userLabel);
+        snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
+                getFuseMountpoint(), mUserLabel);
+    } else {
+        mUserLabel = NULL;
+        snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
+    }
+
+    mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUserLabelChange,
+            msg, false);
+}
+
 void Volume::setState(int state) {
     char msg[255];
     int oldState = mState;
@@ -274,7 +303,6 @@
             fclose(fp);
             return true;
         }
-
     }
 
     fclose(fp);
@@ -413,7 +441,7 @@
             continue;
         }
 
-        protectFromAutorunStupidity();
+        extractMetadata(devicePath);
 
         if (providesAsec && mountAsecExternal() != 0) {
             SLOGE("Failed to mount secure area (%s)", strerror(errno));
@@ -550,6 +578,8 @@
         SLOGI("Encrypted volume %s reverted successfully", getMountpoint());
     }
 
+    setUuid(NULL);
+    setUserLabel(NULL);
     setState(Volume::State_Idle);
     mCurrentlyMountedKdev = -1;
     return 0;
@@ -608,3 +638,55 @@
 
     return rc;
 }
+
+/*
+ * Use blkid to extract UUID and label from device, since it handles many
+ * obscure edge cases around partition types and formats. Always broadcasts
+ * updated metadata values.
+ */
+int Volume::extractMetadata(const char* devicePath) {
+    int res = 0;
+
+    std::string cmd;
+    cmd = BLKID_PATH;
+    cmd += " -c /dev/null ";
+    cmd += devicePath;
+
+    FILE* fp = popen(cmd.c_str(), "r");
+    if (!fp) {
+        ALOGE("Failed to run %s: %s", cmd.c_str(), strerror(errno));
+        res = -1;
+        goto done;
+    }
+
+    char line[1024];
+    char value[128];
+    if (fgets(line, sizeof(line), fp) != NULL) {
+        ALOGD("blkid reported: %s", line);
+
+        char* start = strstr(line, "UUID=") + 5;
+        if (sscanf(start, "\"%127[^\"]\"", value) == 1) {
+            setUuid(value);
+        } else {
+            setUuid(NULL);
+        }
+
+        start = strstr(line, "LABEL=") + 6;
+        if (sscanf(start, "\"%127[^\"]\"", value) == 1) {
+            setUserLabel(value);
+        } else {
+            setUserLabel(NULL);
+        }
+    } else {
+        res = -1;
+    }
+
+    pclose(fp);
+
+done:
+    if (res == -1) {
+        setUuid(NULL);
+        setUserLabel(NULL);
+    }
+    return res;
+}
diff --git a/Volume.h b/Volume.h
index 194004c..1444ed3 100644
--- a/Volume.h
+++ b/Volume.h
@@ -45,11 +45,13 @@
     static const char *SEC_ASECDIR_EXT;
     static const char *SEC_ASECDIR_INT;
     static const char *ASECDIR;
-
     static const char *LOOPDIR;
+    static const char *BLKID_PATH;
 
 protected:
-    char *mLabel;
+    char* mLabel;
+    char* mUuid;
+    char* mUserLabel;
     VolumeManager *mVm;
     bool mDebug;
     int mPartIdx;
@@ -69,7 +71,9 @@
     int unmountVol(bool force, bool revert);
     int formatVol(bool wipe);
 
-    const char *getLabel() { return mLabel; }
+    const char* getLabel() { return mLabel; }
+    const char* getUuid() { return mUuid; }
+    const char* getUserLabel() { return mUserLabel; }
     int getState() { return mState; }
     int getFlags() { return mFlags; };
 
@@ -87,6 +91,8 @@
     virtual int getVolInfo(struct volume_info *v) = 0;
 
 protected:
+    void setUuid(const char* uuid);
+    void setUserLabel(const char* userLabel);
     void setState(int state);
 
     virtual int getDeviceNodes(dev_t *devs, int max) = 0;
@@ -101,7 +107,7 @@
     bool isMountpointMounted(const char *path);
     int mountAsecExternal();
     int doUnmount(const char *path, bool force);
-    void protectFromAutorunStupidity();
+    int extractMetadata(const char* devicePath);
 };
 
 typedef android::List<Volume *> VolumeCollection;