1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdio.h> 18f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdlib.h> 19f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <unistd.h> 20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <string.h> 21f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <signal.h> 22f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <errno.h> 23f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <fcntl.h> 24092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm#include <stdlib.h> 25f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 26f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/socket.h> 27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/select.h> 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/time.h> 29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/types.h> 30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/un.h> 31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 32f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/sockets.h> 33f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <private/android_filesystem_config.h> 34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 35f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic void usage(char *progname); 36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int do_monitor(int sock, int stop_after_cmd); 37f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int do_cmd(int sock, int argc, char **argv); 38f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 39f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint main(int argc, char **argv) { 40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int sock; 41f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence int wait_for_socket; 425e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash char *progname; 43f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 445e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash progname = argv[0]; 45f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 465e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash wait_for_socket = argc > 1 && strcmp(argv[1], "--wait") == 0; 47f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if(wait_for_socket) { 48f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence argv++; 49f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence argc--; 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 51f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 525e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash if(argc < 2) { 535e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash usage(progname); 54f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence exit(5); 555e900ac898bd9d96d6fded95c0b9c080dda54e8fMohamad Ayyash } 56f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 57d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence const char* sockname = "vold"; 58d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence if (!strcmp(argv[1], "cryptfs")) { 59d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence sockname = "cryptd"; 60d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence } 61d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence 62d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence while ((sock = socket_local_client(sockname, 63f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence ANDROID_SOCKET_NAMESPACE_RESERVED, 64f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence SOCK_STREAM)) < 0) { 65f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if(!wait_for_socket) { 66f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence fprintf(stderr, "Error connecting (%s)\n", strerror(errno)); 67f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence exit(4); 68f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } else { 690628fa25141261e549f06d1c6f9e9f3d29e2b8f0Paul Lawrence usleep(10000); 70f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 71f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 72f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 73f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence if (!strcmp(argv[1], "monitor")) { 74f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(do_monitor(sock, 0)); 75f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } else { 76f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence exit(do_cmd(sock, argc, argv)); 77f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 78f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 79f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 80f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int do_cmd(int sock, int argc, char **argv) { 81d4b3661cae1664ca07025b7f0dacc621de0ed93fKen Sumrall char final_cmd[255] = "0 "; /* 0 is a (now required) sequence number */ 82d0b4295ccc07d0cd715ade415c8c0d7d6945880ePaul Lawrence 83f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int i; 847929deb206d8c04801deb4a26232f83a55e6fd32Chih-Wei Huang size_t ret; 85f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 86f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (i = 1; i < argc; i++) { 87f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat char *cmp; 88f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 89dd58c430b38aebae70f3b26707894ee52b792126Dan Albert if (!strchr(argv[i], ' ')) 90f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " "); 91f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat else 92f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " "); 93f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 94092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ret = strlcat(final_cmd, cmp, sizeof(final_cmd)); 95092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm if (ret >= sizeof(final_cmd)) 96092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm abort(); 97f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(cmp); 98f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 99f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 100f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) { 101f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat perror("write"); 102f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return errno; 103f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 104f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 105f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return do_monitor(sock, 1); 106f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 107f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 108f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int do_monitor(int sock, int stop_after_cmd) { 109f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat char *buffer = malloc(4096); 110f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 111f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!stop_after_cmd) 112f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat printf("[Connected to Vold]\n"); 113f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 114f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat while(1) { 115f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat fd_set read_fds; 116f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat struct timeval to; 117f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int rc = 0; 118f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 119f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat to.tv_sec = 10; 120f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat to.tv_usec = 0; 121f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 122f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat FD_ZERO(&read_fds); 123f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat FD_SET(sock, &read_fds); 124f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 125f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) { 126f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat fprintf(stderr, "Error in select (%s)\n", strerror(errno)); 127f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(buffer); 128f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return errno; 129f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } else if (!rc) { 130f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat continue; 131f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat fprintf(stderr, "[TIMEOUT]\n"); 132f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return ETIMEDOUT; 133f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } else if (FD_ISSET(sock, &read_fds)) { 134f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat memset(buffer, 0, 4096); 135f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if ((rc = read(sock, buffer, 4096)) <= 0) { 136f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (rc == 0) 137f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat fprintf(stderr, "Lost connection to Vold - did it crash?\n"); 138f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat else 139f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat fprintf(stderr, "Error reading data (%s)\n", strerror(errno)); 140f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(buffer); 141f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (rc == 0) 142f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return ECONNRESET; 143f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return errno; 144f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 145f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence 146f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int offset = 0; 147f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int i = 0; 148f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 149f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (i = 0; i < rc; i++) { 150f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (buffer[i] == '\0') { 151f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat int code; 152f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat char tmp[4]; 153f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 1542152266deb82f96ef5a22d3a56a76bf6177e1e04Henrik Baard strlcpy(tmp, buffer + offset, sizeof(tmp)); 155f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat code = atoi(tmp); 156f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 157f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat printf("%s\n", buffer + offset); 158f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (stop_after_cmd) { 159f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (code >= 200 && code < 600) 160f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 161f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 162f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat offset = i + 1; 163f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 164f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 165f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 166f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 167f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(buffer); 168f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 169f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 170f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 171f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic void usage(char *progname) { 172f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence fprintf(stderr, 173f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence "Usage: %s [--wait] <monitor>|<cmd> [arg1] [arg2...]\n", progname); 174f4faa575c9fc20a8a8e133d6098865b5ce3a7ed2Paul Lawrence } 175