Switch keystore to binder

Change-Id: I6dacdc43bcc1a56e47655e37e825ee6a205eb56b
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index dcd3bcb..01da2c0 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -18,11 +18,14 @@
 #include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
-#include <sys/socket.h>
 
-#include <cutils/sockets.h>
+#include <keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
-#include "keystore.h"
+#include <keystore/keystore.h>
+
+using namespace android;
 
 static const char* responses[] = {
     NULL,
@@ -41,55 +44,158 @@
     /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
 };
 
+#define NO_ARG_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            int32_t ret = service->cmd(); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define SINGLE_ARG_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            int32_t ret = service->cmd(String16(argv[2])); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define STING_ARG_DATA_STDIN_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            uint8_t* data; \
+            size_t dataSize; \
+            read_input(&data, &dataSize); \
+            int32_t ret = service->cmd(String16(argv[2]), data, dataSize); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define SINGLE_ARG_DATA_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            uint8_t* data; \
+            size_t dataSize; \
+            int32_t ret = service->cmd(String16(argv[2]), &data, &dataSize); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else if (ret != ::NO_ERROR) { \
+                fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
+                return 1; \
+            } else { \
+                fwrite(data, dataSize, 1, stdout); \
+                fflush(stdout); \
+                free(data); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+static int saw(sp<IKeystoreService> service, const String16& name) {
+    Vector<String16> matches;
+    int32_t ret = service->saw(name, &matches);
+    if (ret < 0) {
+        fprintf(stderr, "saw: could not connect: %d\n", ret);
+        return 1;
+    } else if (ret != ::NO_ERROR) {
+        fprintf(stderr, "saw: %s (%d)\n", responses[ret], ret);
+        return 1;
+    } else {
+        Vector<String16>::const_iterator it = matches.begin();
+        for (; it != matches.end(); ++it) {
+            printf("%s\n", String8(*it).string());
+        }
+        return 0;
+    }
+}
+
 int main(int argc, char* argv[])
 {
     if (argc < 2) {
-        printf("Usage: %s action [parameter ...]\n", argv[0]);
-        return 0;
-    }
-
-    int sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                   SOCK_STREAM);
-    if (sock == -1) {
-        puts("Failed to connect");
+        fprintf(stderr, "Usage: %s action [parameter ...]\n", argv[0]);
         return 1;
     }
 
-    send(sock, argv[1], 1, 0);
-    uint8_t bytes[65536];
-    for (int i = 2; i < argc; ++i) {
-        uint16_t length = strlen(argv[i]);
-        bytes[0] = length >> 8;
-        bytes[1] = length;
-        send(sock, &bytes, 2, 0);
-        send(sock, argv[i], length, 0);
-    }
-    shutdown(sock, SHUT_WR);
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
-    uint8_t code;
-    if (recv(sock, &code, 1, 0) != 1) {
-        puts("Failed to receive");
+    if (service == NULL) {
+        fprintf(stderr, "%s: error: could not connect to keystore service\n", argv[0]);
         return 1;
     }
-    printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
-    int i;
-    while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
-        int length;
-        int offset;
-        if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
-            puts("Failed to receive");
-            return 1;
-        }
-        length = bytes[0] << 8 | bytes[1];
-        for (offset = 0; offset < length; offset += i) {
-            i = recv(sock, &bytes[offset], length - offset, 0);
-            if (i <= 0) {
-                puts("Failed to receive");
-                return 1;
-            }
-        }
-        fwrite(bytes, 1, length, stdout);
-        puts("");
+
+    /*
+     * All the commands should return a value
+     */
+
+    NO_ARG_INT_RETURN(test);
+
+    SINGLE_ARG_DATA_RETURN(get);
+
+    // TODO: insert
+
+    SINGLE_ARG_INT_RETURN(del);
+
+    SINGLE_ARG_INT_RETURN(exist);
+
+    if (strcmp(argv[1], "saw") == 0) {
+        return saw(service, argc < 3 ? String16("") : String16(argv[2]));
     }
-    return 0;
+
+    NO_ARG_INT_RETURN(reset);
+
+    SINGLE_ARG_INT_RETURN(password);
+
+    NO_ARG_INT_RETURN(lock);
+
+    SINGLE_ARG_INT_RETURN(unlock);
+
+    NO_ARG_INT_RETURN(zero);
+
+    SINGLE_ARG_INT_RETURN(generate);
+
+    SINGLE_ARG_DATA_RETURN(get_pubkey);
+
+    SINGLE_ARG_INT_RETURN(del_key);
+
+    // TODO: grant
+
+    // TODO: ungrant
+
+    // TODO: getmtime
+
+    fprintf(stderr, "%s: unknown command: %s\n", argv[0], argv[1]);
+    return 1;
 }