CommandListener.cpp revision 5817821cf10b5f7d13eb693ffbc3f80f13bc681b
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 UnmountAsecCmd()); 49 registerCmd(new ListAsecCmd()); 50 registerCmd(new AsecPathCmd()); 51} 52 53CommandListener::ListVolumesCmd::ListVolumesCmd() : 54 VoldCommand("list_volumes") { 55} 56 57int CommandListener::ListVolumesCmd::runCommand(SocketClient *cli, 58 int argc, char **argv) { 59 return VolumeManager::Instance()->listVolumes(cli); 60} 61 62CommandListener::MountCmd::MountCmd() : 63 VoldCommand("mount") { 64} 65 66int CommandListener::MountCmd::runCommand(SocketClient *cli, 67 int argc, char **argv) { 68 /* Synchronously mount a volume */ 69 if (VolumeManager::Instance()->mountVolume(argv[1])) { 70 cli->sendMsg(ResponseCode::OperationFailed, "Failed to mount volume.", true); 71 } else { 72 cli->sendMsg(ResponseCode::CommandOkay, "Volume mounted.", false); 73 } 74 75 return 0; 76} 77 78CommandListener::UnmountCmd::UnmountCmd() : 79 VoldCommand("unmount") { 80} 81 82int CommandListener::UnmountCmd::runCommand(SocketClient *cli, 83 int argc, char **argv) { 84 /* Synchronously unmount a volume */ 85 if (VolumeManager::Instance()->unmountVolume(argv[1])) { 86 cli->sendMsg(ResponseCode::OperationFailed, "Failed to unmount volume.", true); 87 } else { 88 cli->sendMsg(ResponseCode::CommandOkay, "Volume unmounted.", false); 89 } 90 91 return 0; 92} 93 94CommandListener::ShareCmd::ShareCmd() : 95 VoldCommand("share") { 96} 97 98int CommandListener::ShareCmd::runCommand(SocketClient *cli, 99 int argc, char **argv) { 100 if (VolumeManager::Instance()->shareVolume(argv[1], argv[2])) { 101 cli->sendMsg(ResponseCode::OperationFailed, "Failed to share volume.", true); 102 } else { 103 cli->sendMsg(ResponseCode::CommandOkay, "Volume shared.", false); 104 } 105 106 return 0; 107} 108 109CommandListener::UnshareCmd::UnshareCmd() : 110 VoldCommand("unshare") { 111} 112 113int CommandListener::UnshareCmd::runCommand(SocketClient *cli, 114 int argc, char **argv) { 115 if (VolumeManager::Instance()->unshareVolume(argv[1], argv[2])) { 116 cli->sendMsg(ResponseCode::OperationFailed, "Failed to unshare volume.", true); 117 } else { 118 cli->sendMsg(ResponseCode::CommandOkay, "Volume unshared.", false); 119 } 120 121 return 0; 122} 123 124CommandListener::ShareAvailableCmd::ShareAvailableCmd() : 125 VoldCommand("share_available") { 126} 127 128int CommandListener::ShareAvailableCmd::runCommand(SocketClient *cli, 129 int argc, char **argv) { 130 bool avail = false; 131 132 if (VolumeManager::Instance()->shareAvailable(argv[1], &avail)) { 133 cli->sendMsg(ResponseCode::OperationFailed, 134 "Failed to determine share availability", true); 135 } else { 136 cli->sendMsg(ResponseCode::ShareAvailabilityResult, 137 (avail ? "Share available" : "Share unavailable"), 138 false); 139 } 140 return 0; 141} 142 143CommandListener::SimulateCmd::SimulateCmd() : 144 VoldCommand("simulate") { 145} 146 147int CommandListener::SimulateCmd::runCommand(SocketClient *cli, 148 int argc, char **argv) { 149 if (VolumeManager::Instance()->simulate(argv[1], argv[2])) { 150 cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute.", true); 151 } else { 152 cli->sendMsg(ResponseCode::CommandOkay, "Simulation executed.", false); 153 } 154 155 return 0; 156} 157 158CommandListener::FormatCmd::FormatCmd() : 159 VoldCommand("format") { 160} 161 162int CommandListener::FormatCmd::runCommand(SocketClient *cli, 163 int argc, char **argv) { 164 if (VolumeManager::Instance()->formatVolume(argv[1])) { 165 cli->sendMsg(ResponseCode::OperationFailed, "Failed to format", true); 166 } else { 167 cli->sendMsg(ResponseCode::CommandOkay, "Volume formatted.", false); 168 } 169 170 return 0; 171} 172 173CommandListener::CreateAsecCmd::CreateAsecCmd() : 174 VoldCommand("create_asec") { 175} 176 177int CommandListener::CreateAsecCmd::runCommand(SocketClient *cli, 178 int argc, char **argv) { 179 if (argc != 6) { 180 cli->sendMsg(ResponseCode::CommandSyntaxError, 181 "Usage: create_asec <namespace-id> <size_mb> <fstype> <key> <ownerUid>", 182 false); 183 return 0; 184 } 185 186 unsigned int numSectors = (atoi(argv[2]) * (1024 * 1024)) / 512; 187 if (VolumeManager::Instance()->createAsec(argv[1], numSectors, 188 argv[3], argv[4], 189 atoi(argv[5]))) { 190 cli->sendMsg(ResponseCode::OperationFailed, "Container creation failed", true); 191 } else { 192 cli->sendMsg(ResponseCode::CommandOkay, "Container created", false); 193 } 194 195 return 0; 196} 197 198CommandListener::FinalizeAsecCmd::FinalizeAsecCmd() : 199 VoldCommand("finalize_asec") { 200} 201 202int CommandListener::FinalizeAsecCmd::runCommand(SocketClient *cli, 203 int argc, char **argv) { 204 if (argc != 2) { 205 cli->sendMsg(ResponseCode::CommandSyntaxError, 206 "Usage: finalize_asec <namespace-id>", false); 207 return 0; 208 } 209 210 if (VolumeManager::Instance()->finalizeAsec(argv[1])) { 211 cli->sendMsg(ResponseCode::OperationFailed, "Container finalize failed", true); 212 } else { 213 cli->sendMsg(ResponseCode::CommandOkay, "Container finalized", false); 214 } 215 return 0; 216} 217 218CommandListener::DestroyAsecCmd::DestroyAsecCmd() : 219 VoldCommand("destroy_asec") { 220} 221 222int CommandListener::DestroyAsecCmd::runCommand(SocketClient *cli, 223 int argc, char **argv) { 224 if (argc != 2) { 225 cli->sendMsg(ResponseCode::CommandSyntaxError, 226 "Usage: destroy_asec <namespace-id>", false); 227 return 0; 228 } 229 230 if (VolumeManager::Instance()->destroyAsec(argv[1])) { 231 cli->sendMsg(ResponseCode::OperationFailed, "Destroy failed", true); 232 } else { 233 cli->sendMsg(ResponseCode::CommandOkay, "Container Destroyed", false); 234 } 235 return 0; 236} 237 238CommandListener::MountAsecCmd::MountAsecCmd() : 239 VoldCommand("mount_asec") { 240} 241 242int CommandListener::MountAsecCmd::runCommand(SocketClient *cli, 243 int argc, char **argv) { 244 if (argc != 4) { 245 cli->sendMsg(ResponseCode::CommandSyntaxError, 246 "Usage: mount_asec <namespace-id> <key> <ownerUid>", false); 247 return 0; 248 } 249 250 if (VolumeManager::Instance()->mountAsec(argv[1], argv[2], atoi(argv[3]))) { 251 cli->sendMsg(ResponseCode::OperationFailed, "Mount failed", true); 252 } else { 253 cli->sendMsg(ResponseCode::CommandOkay, "Mount succeeded", false); 254 } 255 return 0; 256} 257 258CommandListener::UnmountAsecCmd::UnmountAsecCmd() : 259 VoldCommand("unmount_asec") { 260} 261 262int CommandListener::UnmountAsecCmd::runCommand(SocketClient *cli, 263 int argc, char **argv) { 264 if (argc != 2) { 265 cli->sendMsg(ResponseCode::CommandSyntaxError, 266 "Usage: unmount_asec <namespace-id>", false); 267 return 0; 268 } 269 270 if (VolumeManager::Instance()->unmountAsec(argv[1])) { 271 cli->sendMsg(ResponseCode::OperationFailed, "Unmount failed", true); 272 } else { 273 cli->sendMsg(ResponseCode::CommandOkay, "Unmount succeeded", false); 274 } 275 return 0; 276} 277 278CommandListener::ListAsecCmd::ListAsecCmd() : 279 VoldCommand("list_asec") { 280 281} 282 283int CommandListener::ListAsecCmd::runCommand(SocketClient *cli, 284 int argc, char **argv) { 285 DIR *d = opendir("/sdcard/android_secure"); 286 287 if (!d) { 288 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true); 289 return 0; 290 } 291 292 struct dirent *dent; 293 while ((dent = readdir(d))) { 294 if (dent->d_name[0] == '.') 295 continue; 296 if (!strcmp(&dent->d_name[strlen(dent->d_name)-5], ".asec")) { 297 char id[255]; 298 memset(id, 0, sizeof(id)); 299 strncpy(id, dent->d_name, strlen(dent->d_name) -5); 300 cli->sendMsg(ResponseCode::AsecListResult, id, false); 301 } 302 } 303 closedir(d); 304 cli->sendMsg(ResponseCode::CommandOkay, "ASEC listing complete", false); 305 306 return 0; 307} 308 309CommandListener::AsecPathCmd::AsecPathCmd() : 310 VoldCommand("asec_path") { 311} 312 313int CommandListener::AsecPathCmd::runCommand(SocketClient *cli, 314 int argc, char **argv) { 315 if (argc != 2) { 316 cli->sendMsg(ResponseCode::CommandSyntaxError, 317 "Usage: asec_path <namespace-id>", false); 318 return 0; 319 } 320 321 char mountPath[255]; 322 323 if (VolumeManager::Instance()->getAsecMountPath(argv[1], mountPath, 324 sizeof(mountPath))) { 325 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get mount path", true); 326 } else { 327 cli->sendMsg(ResponseCode::AsecPathResult, mountPath, false); 328 } 329 330 return 0; 331} 332