CommandListener.cpp revision 8b8f71b1d760411279f3b07a5c97709f052c689e
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdlib.h> 18#include <sys/socket.h> 19#include <sys/types.h> 20#include <netinet/in.h> 21#include <arpa/inet.h> 22#include <dirent.h> 23#include <errno.h> 24 25#define LOG_TAG "CommandListener" 26#include <cutils/log.h> 27 28#include <sysutils/SocketClient.h> 29 30#include "CommandListener.h" 31#include "VolumeManager.h" 32#include "ResponseCode.h" 33 34CommandListener::CommandListener() : 35 FrameworkListener("vold") { 36 registerCmd(new ListVolumesCmd()); 37 registerCmd(new MountCmd()); 38 registerCmd(new UnmountCmd()); 39 registerCmd(new ShareCmd()); 40 registerCmd(new UnshareCmd()); 41 registerCmd(new ShareAvailableCmd()); 42 registerCmd(new SimulateCmd()); 43 registerCmd(new FormatCmd()); 44 registerCmd(new CreateAsecCmd()); 45 registerCmd(new FinalizeAsecCmd()); 46 registerCmd(new DestroyAsecCmd()); 47 registerCmd(new MountAsecCmd()); 48 registerCmd(new ListAsecCmd()); 49 registerCmd(new AsecPathCmd()); 50} 51 52CommandListener::ListVolumesCmd::ListVolumesCmd() : 53 VoldCommand("list_volumes") { 54} 55 56int CommandListener::ListVolumesCmd::runCommand(SocketClient *cli, 57 int argc, char **argv) { 58 return VolumeManager::Instance()->listVolumes(cli); 59} 60 61CommandListener::MountCmd::MountCmd() : 62 VoldCommand("mount") { 63} 64 65int CommandListener::MountCmd::runCommand(SocketClient *cli, 66 int argc, char **argv) { 67 /* Synchronously mount a volume */ 68 if (VolumeManager::Instance()->mountVolume(argv[1])) { 69 cli->sendMsg(ResponseCode::OperationFailed, "Failed to mount volume.", true); 70 } else { 71 cli->sendMsg(ResponseCode::CommandOkay, "Volume mounted.", false); 72 } 73 74 return 0; 75} 76 77CommandListener::UnmountCmd::UnmountCmd() : 78 VoldCommand("unmount") { 79} 80 81int CommandListener::UnmountCmd::runCommand(SocketClient *cli, 82 int argc, char **argv) { 83 /* Synchronously unmount a volume */ 84 if (VolumeManager::Instance()->unmountVolume(argv[1])) { 85 cli->sendMsg(ResponseCode::OperationFailed, "Failed to unmount volume.", true); 86 } else { 87 cli->sendMsg(ResponseCode::CommandOkay, "Volume unmounted.", false); 88 } 89 90 return 0; 91} 92 93CommandListener::ShareCmd::ShareCmd() : 94 VoldCommand("share") { 95} 96 97int CommandListener::ShareCmd::runCommand(SocketClient *cli, 98 int argc, char **argv) { 99 if (VolumeManager::Instance()->shareVolume(argv[1], argv[2])) { 100 cli->sendMsg(ResponseCode::OperationFailed, "Failed to share volume.", true); 101 } else { 102 cli->sendMsg(ResponseCode::CommandOkay, "Volume shared.", false); 103 } 104 105 return 0; 106} 107 108CommandListener::UnshareCmd::UnshareCmd() : 109 VoldCommand("unshare") { 110} 111 112int CommandListener::UnshareCmd::runCommand(SocketClient *cli, 113 int argc, char **argv) { 114 if (VolumeManager::Instance()->unshareVolume(argv[1], argv[2])) { 115 cli->sendMsg(ResponseCode::OperationFailed, "Failed to unshare volume.", true); 116 } else { 117 cli->sendMsg(ResponseCode::CommandOkay, "Volume unshared.", false); 118 } 119 120 return 0; 121} 122 123CommandListener::ShareAvailableCmd::ShareAvailableCmd() : 124 VoldCommand("share_available") { 125} 126 127int CommandListener::ShareAvailableCmd::runCommand(SocketClient *cli, 128 int argc, char **argv) { 129 bool avail = false; 130 131 if (VolumeManager::Instance()->shareAvailable(argv[1], &avail)) { 132 cli->sendMsg(ResponseCode::OperationFailed, 133 "Failed to determine share availability", true); 134 } else { 135 cli->sendMsg(ResponseCode::ShareAvailabilityResult, 136 (avail ? "Share available" : "Share unavailable"), 137 false); 138 } 139 return 0; 140} 141 142CommandListener::SimulateCmd::SimulateCmd() : 143 VoldCommand("simulate") { 144} 145 146int CommandListener::SimulateCmd::runCommand(SocketClient *cli, 147 int argc, char **argv) { 148 if (VolumeManager::Instance()->simulate(argv[1], argv[2])) { 149 cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute.", true); 150 } else { 151 cli->sendMsg(ResponseCode::CommandOkay, "Simulation executed.", false); 152 } 153 154 return 0; 155} 156 157CommandListener::FormatCmd::FormatCmd() : 158 VoldCommand("format") { 159} 160 161int CommandListener::FormatCmd::runCommand(SocketClient *cli, 162 int argc, char **argv) { 163 if (VolumeManager::Instance()->formatVolume(argv[1])) { 164 cli->sendMsg(ResponseCode::OperationFailed, "Failed to format", true); 165 } else { 166 cli->sendMsg(ResponseCode::CommandOkay, "Volume formatted.", false); 167 } 168 169 return 0; 170} 171 172CommandListener::CreateAsecCmd::CreateAsecCmd() : 173 VoldCommand("create_asec") { 174} 175 176int CommandListener::CreateAsecCmd::runCommand(SocketClient *cli, 177 int argc, char **argv) { 178 if (argc != 6) { 179 cli->sendMsg(ResponseCode::CommandSyntaxError, 180 "Usage: create_asec <namespace-id> <size_mb> <fstype> <key> <ownerUid>", 181 false); 182 return 0; 183 } 184 185 unsigned int numSectors = (atoi(argv[2]) * (1024 * 1024)) / 512; 186 if (VolumeManager::Instance()->createAsec(argv[1], atoi(argv[2]), 187 argv[3], argv[4], 188 atoi(argv[5]))) { 189 cli->sendMsg(ResponseCode::OperationFailed, "Cache creation failed", true); 190 } else { 191 cli->sendMsg(ResponseCode::CommandOkay, "Cache created", false); 192 } 193 194 return 0; 195} 196 197CommandListener::FinalizeAsecCmd::FinalizeAsecCmd() : 198 VoldCommand("finalize_asec") { 199} 200 201int CommandListener::FinalizeAsecCmd::runCommand(SocketClient *cli, 202 int argc, char **argv) { 203 if (argc != 2) { 204 cli->sendMsg(ResponseCode::CommandSyntaxError, 205 "Usage: finalize_asec <namespace-id>", false); 206 return 0; 207 } 208 209 if (VolumeManager::Instance()->finalizeAsec(argv[1])) { 210 cli->sendMsg(ResponseCode::OperationFailed, "Cache finalize failed", true); 211 } else { 212 cli->sendMsg(ResponseCode::CommandOkay, "Cache finalized", false); 213 } 214 return 0; 215} 216 217CommandListener::DestroyAsecCmd::DestroyAsecCmd() : 218 VoldCommand("destroy_asec") { 219} 220 221int CommandListener::DestroyAsecCmd::runCommand(SocketClient *cli, 222 int argc, char **argv) { 223 if (argc != 2) { 224 cli->sendMsg(ResponseCode::CommandSyntaxError, 225 "Usage: destroy_asec <namespace-id>", false); 226 return 0; 227 } 228 229 if (VolumeManager::Instance()->destroyAsec(argv[1])) { 230 cli->sendMsg(ResponseCode::OperationFailed, "Destroy failed", true); 231 } else { 232 cli->sendMsg(ResponseCode::CommandOkay, "Cache Destroyed", false); 233 } 234 return 0; 235} 236 237CommandListener::MountAsecCmd::MountAsecCmd() : 238 VoldCommand("mount_asec") { 239} 240 241int CommandListener::MountAsecCmd::runCommand(SocketClient *cli, 242 int argc, char **argv) { 243 if (argc != 4) { 244 cli->sendMsg(ResponseCode::CommandSyntaxError, 245 "Usage: mount_asec <namespace-id> <key> <ownerUid>", false); 246 return 0; 247 } 248 249 if (VolumeManager::Instance()->mountAsec(argv[1], argv[2], atoi(argv[3]))) { 250 cli->sendMsg(ResponseCode::OperationFailed, "Mount failed", true); 251 } else { 252 cli->sendMsg(ResponseCode::CommandOkay, "Mount succeeded", false); 253 } 254 return 0; 255} 256 257CommandListener::ListAsecCmd::ListAsecCmd() : 258 VoldCommand("list_asec") { 259 260} 261 262int CommandListener::ListAsecCmd::runCommand(SocketClient *cli, 263 int argc, char **argv) { 264 DIR *d = opendir("/sdcard/android_secure"); 265 266 if (!d) { 267 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true); 268 return 0; 269 } 270 271 struct dirent *dent; 272 while ((dent = readdir(d))) { 273 if (dent->d_name[0] == '.') 274 continue; 275 if (!strcmp(&dent->d_name[strlen(dent->d_name)-5], ".asec")) { 276 char id[255]; 277 memset(id, 0, sizeof(id)); 278 strncpy(id, dent->d_name, strlen(dent->d_name) -5); 279 cli->sendMsg(ResponseCode::AsecListResult, id, false); 280 } 281 } 282 closedir(d); 283 cli->sendMsg(ResponseCode::CommandOkay, "ASEC listing complete", false); 284 285 return 0; 286} 287 288CommandListener::AsecPathCmd::AsecPathCmd() : 289 VoldCommand("asec_path") { 290} 291 292int CommandListener::AsecPathCmd::runCommand(SocketClient *cli, 293 int argc, char **argv) { 294 if (argc != 2) { 295 cli->sendMsg(ResponseCode::CommandSyntaxError, 296 "Usage: asec_path <namespace-id>", false); 297 return 0; 298 } 299 300 char mountPath[255]; 301 302 if (VolumeManager::Instance()->getAsecMountPath(argv[1], mountPath, 303 sizeof(mountPath))) { 304 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get mount path", true); 305 } else { 306 cli->sendMsg(ResponseCode::AsecPathResult, mountPath, false); 307 } 308 309 return 0; 310} 311