vdc.c revision d4b3661cae1664ca07025b7f0dacc621de0ed93f
12352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/* 22352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Copyright (C) 2008 The Android Open Source Project 32352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 42352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 52352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * you may not use this file except in compliance with the License. 62352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * You may obtain a copy of the License at 72352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 82352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 92352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Unless required by applicable law or agreed to in writing, software 112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * See the License for the specific language governing permissions and 142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * limitations under the License. 152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <stdio.h> 182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <stdlib.h> 192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <unistd.h> 202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <string.h> 212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <signal.h> 222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <errno.h> 232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <fcntl.h> 242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <stdlib.h> 252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <sys/socket.h> 272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <sys/select.h> 282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <sys/time.h> 292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <sys/types.h> 302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <sys/un.h> 312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <cutils/sockets.h> 332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <private/android_filesystem_config.h> 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic void usage(char *progname); 362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic int do_monitor(int sock, int stop_after_cmd); 372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic int do_cmd(int sock, int argc, char **argv); 382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint main(int argc, char **argv) { 402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int sock; 412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (argc < 2) 432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown usage(argv[0]); 442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if ((sock = socket_local_client("vold", 462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown ANDROID_SOCKET_NAMESPACE_RESERVED, 472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown SOCK_STREAM)) < 0) { 482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown fprintf(stderr, "Error connecting (%s)\n", strerror(errno)); 492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown exit(4); 502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!strcmp(argv[1], "monitor")) 532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown exit(do_monitor(sock, 0)); 542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown exit(do_cmd(sock, argc, argv)); 552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic int do_cmd(int sock, int argc, char **argv) { 582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown char final_cmd[255] = "0 "; /* 0 is a (now required) sequence number */ 592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int i; 602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int ret; 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown for (i = 1; i < argc; i++) { 632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown char *cmp; 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!index(argv[i], ' ')) 662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " "); 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown else 682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " "); 692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown ret = strlcat(final_cmd, cmp, sizeof(final_cmd)); 712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (ret >= sizeof(final_cmd)) 722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown abort(); 732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown free(cmp); 742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) { 772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown perror("write"); 782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return errno; 792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 81 return do_monitor(sock, 1); 82} 83 84static int do_monitor(int sock, int stop_after_cmd) { 85 char *buffer = malloc(4096); 86 87 if (!stop_after_cmd) 88 printf("[Connected to Vold]\n"); 89 90 while(1) { 91 fd_set read_fds; 92 struct timeval to; 93 int rc = 0; 94 95 to.tv_sec = 10; 96 to.tv_usec = 0; 97 98 FD_ZERO(&read_fds); 99 FD_SET(sock, &read_fds); 100 101 if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) { 102 fprintf(stderr, "Error in select (%s)\n", strerror(errno)); 103 free(buffer); 104 return errno; 105 } else if (!rc) { 106 continue; 107 fprintf(stderr, "[TIMEOUT]\n"); 108 return ETIMEDOUT; 109 } else if (FD_ISSET(sock, &read_fds)) { 110 memset(buffer, 0, 4096); 111 if ((rc = read(sock, buffer, 4096)) <= 0) { 112 if (rc == 0) 113 fprintf(stderr, "Lost connection to Vold - did it crash?\n"); 114 else 115 fprintf(stderr, "Error reading data (%s)\n", strerror(errno)); 116 free(buffer); 117 if (rc == 0) 118 return ECONNRESET; 119 return errno; 120 } 121 122 int offset = 0; 123 int i = 0; 124 125 for (i = 0; i < rc; i++) { 126 if (buffer[i] == '\0') { 127 int code; 128 char tmp[4]; 129 130 strncpy(tmp, buffer + offset, 3); 131 tmp[3] = '\0'; 132 code = atoi(tmp); 133 134 printf("%s\n", buffer + offset); 135 if (stop_after_cmd) { 136 if (code >= 200 && code < 600) 137 return 0; 138 } 139 offset = i + 1; 140 } 141 } 142 } 143 } 144 free(buffer); 145 return 0; 146} 147 148static void usage(char *progname) { 149 fprintf(stderr, "Usage: %s <monitor>|<cmd> [arg1] [arg2...]\n", progname); 150 exit(1); 151} 152 153