CommandListener.cpp revision a19b250bd273455933ca3502cf2c2e0a803aff77
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 if (VolumeManager::Instance()->createAsec(argv[1], atoi(argv[2]), 186 argv[3], argv[4], 187 atoi(argv[5]))) { 188 cli->sendMsg(ResponseCode::OperationFailed, "Cache creation failed", true); 189 } else { 190 cli->sendMsg(ResponseCode::CommandOkay, "Cache created", false); 191 } 192 193 return 0; 194} 195 196CommandListener::FinalizeAsecCmd::FinalizeAsecCmd() : 197 VoldCommand("finalize_asec") { 198} 199 200int CommandListener::FinalizeAsecCmd::runCommand(SocketClient *cli, 201 int argc, char **argv) { 202 if (argc != 2) { 203 cli->sendMsg(ResponseCode::CommandSyntaxError, 204 "Usage: finalize_asec <namespace-id>", false); 205 return 0; 206 } 207 208 if (VolumeManager::Instance()->finalizeAsec(argv[1])) { 209 cli->sendMsg(ResponseCode::OperationFailed, "Cache finalize failed", true); 210 } else { 211 cli->sendMsg(ResponseCode::CommandOkay, "Cache finalized", false); 212 } 213 return 0; 214} 215 216CommandListener::DestroyAsecCmd::DestroyAsecCmd() : 217 VoldCommand("destroy_asec") { 218} 219 220int CommandListener::DestroyAsecCmd::runCommand(SocketClient *cli, 221 int argc, char **argv) { 222 if (argc != 2) { 223 cli->sendMsg(ResponseCode::CommandSyntaxError, 224 "Usage: destroy_asec <namespace-id>", false); 225 return 0; 226 } 227 228 if (VolumeManager::Instance()->destroyAsec(argv[1])) { 229 cli->sendMsg(ResponseCode::OperationFailed, "Destroy failed", true); 230 } else { 231 cli->sendMsg(ResponseCode::CommandOkay, "Cache Destroyed", false); 232 } 233 return 0; 234} 235 236CommandListener::MountAsecCmd::MountAsecCmd() : 237 VoldCommand("mount_asec") { 238} 239 240int CommandListener::MountAsecCmd::runCommand(SocketClient *cli, 241 int argc, char **argv) { 242 if (argc != 4) { 243 cli->sendMsg(ResponseCode::CommandSyntaxError, 244 "Usage: mount_asec <namespace-id> <key> <ownerUid>", false); 245 return 0; 246 } 247 248 if (VolumeManager::Instance()->mountAsec(argv[1], argv[2], atoi(argv[3]))) { 249 cli->sendMsg(ResponseCode::OperationFailed, "Mount failed", true); 250 } else { 251 cli->sendMsg(ResponseCode::CommandOkay, "Mount succeeded", false); 252 } 253 return 0; 254} 255 256CommandListener::ListAsecCmd::ListAsecCmd() : 257 VoldCommand("list_asec") { 258 259} 260 261int CommandListener::ListAsecCmd::runCommand(SocketClient *cli, 262 int argc, char **argv) { 263 DIR *d = opendir("/sdcard/android_secure"); 264 265 if (!d) { 266 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true); 267 return 0; 268 } 269 270 struct dirent *dent; 271 while ((dent = readdir(d))) { 272 if (dent->d_name[0] == '.') 273 continue; 274 if (!strcmp(&dent->d_name[strlen(dent->d_name)-5], ".asec")) { 275 char id[255]; 276 memset(id, 0, sizeof(id)); 277 strncpy(id, dent->d_name, strlen(dent->d_name) -5); 278 cli->sendMsg(ResponseCode::AsecListResult, id, false); 279 } 280 } 281 closedir(d); 282 cli->sendMsg(ResponseCode::CommandOkay, "ASEC listing complete", false); 283 284 return 0; 285} 286 287CommandListener::AsecPathCmd::AsecPathCmd() : 288 VoldCommand("asec_path") { 289} 290 291int CommandListener::AsecPathCmd::runCommand(SocketClient *cli, 292 int argc, char **argv) { 293 if (argc != 2) { 294 cli->sendMsg(ResponseCode::CommandSyntaxError, 295 "Usage: asec_path <namespace-id>", false); 296 return 0; 297 } 298 299 char mountPath[255]; 300 301 if (VolumeManager::Instance()->getAsecMountPath(argv[1], mountPath, 302 sizeof(mountPath))) { 303 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get mount path", true); 304 } else { 305 cli->sendMsg(ResponseCode::AsecPathResult, mountPath, false); 306 } 307 308 return 0; 309} 310