blob: b0fc5512878a0a2b8820b789c84ef4bc44a7fe73 [file] [log] [blame]
San Mehatf1b736b2009-10-10 17:22:08 -07001/*
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>
San Mehata19b2502010-01-06 10:33:53 -080019#include <sys/types.h>
San Mehatf1b736b2009-10-10 17:22:08 -070020#include <netinet/in.h>
21#include <arpa/inet.h>
San Mehata19b2502010-01-06 10:33:53 -080022#include <dirent.h>
San Mehatf1b736b2009-10-10 17:22:08 -070023#include <errno.h>
San Mehat2350c442010-03-02 13:16:50 -080024#include <fcntl.h>
San Mehatf1b736b2009-10-10 17:22:08 -070025
San Mehatd9a4e352010-03-12 13:32:47 -080026#define LOG_TAG "VoldCmdListener"
San Mehatf1b736b2009-10-10 17:22:08 -070027#include <cutils/log.h>
28
29#include <sysutils/SocketClient.h>
30
31#include "CommandListener.h"
32#include "VolumeManager.h"
San Mehata2677e42009-12-13 10:40:18 -080033#include "ResponseCode.h"
San Mehat586536c2010-02-16 17:12:00 -080034#include "Process.h"
San Mehat2350c442010-03-02 13:16:50 -080035#include "Xwarp.h"
San Mehatd9a4e352010-03-12 13:32:47 -080036#include "Loop.h"
37#include "Devmapper.h"
San Mehatf1b736b2009-10-10 17:22:08 -070038
39CommandListener::CommandListener() :
40 FrameworkListener("vold") {
San Mehatd9a4e352010-03-12 13:32:47 -080041 registerCmd(new DumpCmd());
San Mehateba65e92010-01-29 05:15:16 -080042 registerCmd(new VolumeCmd());
43 registerCmd(new AsecCmd());
Kenny Root508c0e12010-07-12 09:59:49 -070044 registerCmd(new ObbCmd());
San Mehata2677e42009-12-13 10:40:18 -080045 registerCmd(new ShareCmd());
San Mehat586536c2010-02-16 17:12:00 -080046 registerCmd(new StorageCmd());
San Mehat2350c442010-03-02 13:16:50 -080047 registerCmd(new XwarpCmd());
San Mehatf1b736b2009-10-10 17:22:08 -070048}
49
San Mehatd9a4e352010-03-12 13:32:47 -080050void CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
51 char buffer[4096];
52 char *p = buffer;
53
54 memset(buffer, 0, sizeof(buffer));
55 int i;
56 for (i = 0; i < argc; i++) {
57 int len = strlen(argv[i]) + 1; // Account for space
58 if (i == argObscure) {
59 len += 2; // Account for {}
60 }
61 if (((p - buffer) + len) < (sizeof(buffer)-1)) {
62 if (i == argObscure) {
63 *p++ = '{';
64 *p++ = '}';
65 *p++ = ' ';
66 continue;
67 }
68 strcpy(p, argv[i]);
69 p+= strlen(argv[i]);
70 if (i != (argc -1)) {
71 *p++ = ' ';
72 }
73 }
74 }
San Mehat97ac40e2010-03-24 10:24:19 -070075 SLOGD("%s", buffer);
San Mehatd9a4e352010-03-12 13:32:47 -080076}
77
78CommandListener::DumpCmd::DumpCmd() :
79 VoldCommand("dump") {
80}
81
82int CommandListener::DumpCmd::runCommand(SocketClient *cli,
83 int argc, char **argv) {
84 cli->sendMsg(0, "Dumping loop status", false);
85 if (Loop::dumpState(cli)) {
86 cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
87 }
88 cli->sendMsg(0, "Dumping DM status", false);
89 if (Devmapper::dumpState(cli)) {
90 cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
91 }
San Mehat96597e82010-03-17 09:50:54 -070092 cli->sendMsg(0, "Dumping mounted filesystems", false);
93 FILE *fp = fopen("/proc/mounts", "r");
94 if (fp) {
95 char line[1024];
96 while (fgets(line, sizeof(line), fp)) {
97 line[strlen(line)-1] = '\0';
98 cli->sendMsg(0, line, false);;
99 }
100 fclose(fp);
101 }
San Mehatd9a4e352010-03-12 13:32:47 -0800102
103 cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
104 return 0;
105}
106
107
San Mehateba65e92010-01-29 05:15:16 -0800108CommandListener::VolumeCmd::VolumeCmd() :
109 VoldCommand("volume") {
San Mehatf1b736b2009-10-10 17:22:08 -0700110}
111
San Mehateba65e92010-01-29 05:15:16 -0800112int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
San Mehatf1b736b2009-10-10 17:22:08 -0700113 int argc, char **argv) {
San Mehatd9a4e352010-03-12 13:32:47 -0800114 dumpArgs(argc, argv, -1);
115
San Mehateba65e92010-01-29 05:15:16 -0800116 if (argc < 2) {
117 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
118 return 0;
San Mehat49e2bce2009-10-12 16:29:01 -0700119 }
120
San Mehateba65e92010-01-29 05:15:16 -0800121 VolumeManager *vm = VolumeManager::Instance();
122 int rc = 0;
San Mehatf1b736b2009-10-10 17:22:08 -0700123
San Mehateba65e92010-01-29 05:15:16 -0800124 if (!strcmp(argv[1], "list")) {
125 return vm->listVolumes(cli);
San Mehatd9a4e352010-03-12 13:32:47 -0800126 } else if (!strcmp(argv[1], "debug")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700127 if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {
128 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug <off/on>", false);
129 return 0;
130 }
131 vm->setDebug(!strcmp(argv[2], "on") ? true : false);
San Mehateba65e92010-01-29 05:15:16 -0800132 } else if (!strcmp(argv[1], "mount")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700133 if (argc != 3) {
134 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount <path>", false);
135 return 0;
136 }
San Mehateba65e92010-01-29 05:15:16 -0800137 rc = vm->mountVolume(argv[2]);
138 } else if (!strcmp(argv[1], "unmount")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700139 if (argc < 3 || argc > 4 || (argc == 4 && strcmp(argv[3], "force"))) {
140 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount <path> [force]", false);
141 return 0;
142 }
143
San Mehat4ba89482010-02-18 09:00:18 -0800144 bool force = false;
145 if (argc >= 4 && !strcmp(argv[3], "force")) {
146 force = true;
147 }
148 rc = vm->unmountVolume(argv[2], force);
San Mehateba65e92010-01-29 05:15:16 -0800149 } else if (!strcmp(argv[1], "format")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700150 if (argc != 3) {
151 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path>", false);
152 return 0;
153 }
San Mehateba65e92010-01-29 05:15:16 -0800154 rc = vm->formatVolume(argv[2]);
155 } else if (!strcmp(argv[1], "share")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700156 if (argc != 4) {
157 cli->sendMsg(ResponseCode::CommandSyntaxError,
158 "Usage: volume share <path> <method>", false);
159 return 0;
160 }
San Mehatb9aed742010-02-04 15:07:01 -0800161 rc = vm->shareVolume(argv[2], argv[3]);
San Mehateba65e92010-01-29 05:15:16 -0800162 } else if (!strcmp(argv[1], "unshare")) {
San Mehat57df7bf2010-03-14 13:41:27 -0700163 if (argc != 4) {
164 cli->sendMsg(ResponseCode::CommandSyntaxError,
165 "Usage: volume unshare <path> <method>", false);
166 return 0;
167 }
San Mehatb9aed742010-02-04 15:07:01 -0800168 rc = vm->unshareVolume(argv[2], argv[3]);
San Mehateba65e92010-01-29 05:15:16 -0800169 } else if (!strcmp(argv[1], "shared")) {
170 bool enabled = false;
San Mehat57df7bf2010-03-14 13:41:27 -0700171 if (argc != 4) {
172 cli->sendMsg(ResponseCode::CommandSyntaxError,
173 "Usage: volume shared <path> <method>", false);
174 return 0;
175 }
San Mehatf1b736b2009-10-10 17:22:08 -0700176
San Mehat2b225522010-02-03 10:26:40 -0800177 if (vm->shareEnabled(argv[2], argv[3], &enabled)) {
San Mehateba65e92010-01-29 05:15:16 -0800178 cli->sendMsg(
179 ResponseCode::OperationFailed, "Failed to determine share enable state", true);
180 } else {
181 cli->sendMsg(ResponseCode::ShareEnabledResult,
182 (enabled ? "Share enabled" : "Share disabled"), false);
183 }
San Mehatb9aed742010-02-04 15:07:01 -0800184 return 0;
San Mehat49e2bce2009-10-12 16:29:01 -0700185 } else {
San Mehateba65e92010-01-29 05:15:16 -0800186 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
187 }
188
189 if (!rc) {
190 cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);
191 } else {
San Mehat8f2875b2010-02-18 11:40:49 -0800192 int erno = errno;
193 rc = ResponseCode::convertFromErrno();
San Mehateba65e92010-01-29 05:15:16 -0800194 cli->sendMsg(rc, "volume operation failed", true);
San Mehat49e2bce2009-10-12 16:29:01 -0700195 }
196
San Mehatf1b736b2009-10-10 17:22:08 -0700197 return 0;
198}
199
San Mehata2677e42009-12-13 10:40:18 -0800200CommandListener::ShareCmd::ShareCmd() :
201 VoldCommand("share") {
San Mehatf1b736b2009-10-10 17:22:08 -0700202}
203
San Mehata2677e42009-12-13 10:40:18 -0800204int CommandListener::ShareCmd::runCommand(SocketClient *cli,
San Mehatf1b736b2009-10-10 17:22:08 -0700205 int argc, char **argv) {
San Mehatd9a4e352010-03-12 13:32:47 -0800206 dumpArgs(argc, argv, -1);
207
San Mehateba65e92010-01-29 05:15:16 -0800208 if (argc < 2) {
209 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
San Mehata19b2502010-01-06 10:33:53 -0800210 return 0;
211 }
212
San Mehateba65e92010-01-29 05:15:16 -0800213 VolumeManager *vm = VolumeManager::Instance();
214 int rc = 0;
San Mehata19b2502010-01-06 10:33:53 -0800215
San Mehateba65e92010-01-29 05:15:16 -0800216 if (!strcmp(argv[1], "status")) {
217 bool avail = false;
San Mehata19b2502010-01-06 10:33:53 -0800218
San Mehateba65e92010-01-29 05:15:16 -0800219 if (vm->shareAvailable(argv[2], &avail)) {
220 cli->sendMsg(
221 ResponseCode::OperationFailed, "Failed to determine share availability", true);
222 } else {
223 cli->sendMsg(ResponseCode::ShareStatusResult,
224 (avail ? "Share available" : "Share unavailable"), false);
San Mehata19b2502010-01-06 10:33:53 -0800225 }
San Mehateba65e92010-01-29 05:15:16 -0800226 } else {
227 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown share cmd", false);
San Mehata19b2502010-01-06 10:33:53 -0800228 }
San Mehata19b2502010-01-06 10:33:53 -0800229
230 return 0;
231}
232
San Mehat586536c2010-02-16 17:12:00 -0800233CommandListener::StorageCmd::StorageCmd() :
234 VoldCommand("storage") {
235}
236
237int CommandListener::StorageCmd::runCommand(SocketClient *cli,
238 int argc, char **argv) {
San Mehatd9a4e352010-03-12 13:32:47 -0800239 dumpArgs(argc, argv, -1);
240
San Mehat586536c2010-02-16 17:12:00 -0800241 if (argc < 2) {
242 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
243 return 0;
244 }
245
246 if (!strcmp(argv[1], "users")) {
247 DIR *dir;
248 struct dirent *de;
249
250 if (!(dir = opendir("/proc"))) {
251 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open /proc", true);
252 return 0;
253 }
254
255 while ((de = readdir(dir))) {
256 int pid = Process::getPid(de->d_name);
257
258 if (pid < 0) {
259 continue;
260 }
261
262 char processName[255];
263 Process::getProcessName(pid, processName, sizeof(processName));
264
265 if (Process::checkFileDescriptorSymLinks(pid, argv[2]) ||
266 Process::checkFileMaps(pid, argv[2]) ||
267 Process::checkSymLink(pid, argv[2], "cwd") ||
268 Process::checkSymLink(pid, argv[2], "root") ||
269 Process::checkSymLink(pid, argv[2], "exe")) {
270
271 char msg[1024];
272 snprintf(msg, sizeof(msg), "%d %s", pid, processName);
273 cli->sendMsg(ResponseCode::StorageUsersListResult, msg, false);
274 }
275 }
276 closedir(dir);
277 cli->sendMsg(ResponseCode::CommandOkay, "Storage user list complete", false);
278 } else {
279 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
280 }
281 return 0;
282}
283
San Mehateba65e92010-01-29 05:15:16 -0800284CommandListener::AsecCmd::AsecCmd() :
285 VoldCommand("asec") {
San Mehata19b2502010-01-06 10:33:53 -0800286}
287
San Mehateba65e92010-01-29 05:15:16 -0800288int CommandListener::AsecCmd::runCommand(SocketClient *cli,
289 int argc, char **argv) {
290 if (argc < 2) {
291 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
San Mehata19b2502010-01-06 10:33:53 -0800292 return 0;
293 }
294
San Mehateba65e92010-01-29 05:15:16 -0800295 VolumeManager *vm = VolumeManager::Instance();
296 int rc = 0;
San Mehata19b2502010-01-06 10:33:53 -0800297
San Mehateba65e92010-01-29 05:15:16 -0800298 if (!strcmp(argv[1], "list")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800299 dumpArgs(argc, argv, -1);
San Mehat3bb60202010-02-19 18:14:36 -0800300 DIR *d = opendir(Volume::SEC_ASECDIR);
San Mehateba65e92010-01-29 05:15:16 -0800301
302 if (!d) {
303 cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true);
304 return 0;
305 }
306
307 struct dirent *dent;
308 while ((dent = readdir(d))) {
309 if (dent->d_name[0] == '.')
310 continue;
311 if (!strcmp(&dent->d_name[strlen(dent->d_name)-5], ".asec")) {
312 char id[255];
313 memset(id, 0, sizeof(id));
314 strncpy(id, dent->d_name, strlen(dent->d_name) -5);
315 cli->sendMsg(ResponseCode::AsecListResult, id, false);
316 }
317 }
318 closedir(d);
San Mehateba65e92010-01-29 05:15:16 -0800319 } else if (!strcmp(argv[1], "create")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800320 dumpArgs(argc, argv, 5);
San Mehateba65e92010-01-29 05:15:16 -0800321 if (argc != 7) {
322 cli->sendMsg(ResponseCode::CommandSyntaxError,
323 "Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid>", false);
324 return 0;
325 }
326
327 unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
San Mehat8f2875b2010-02-18 11:40:49 -0800328 rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]));
San Mehateba65e92010-01-29 05:15:16 -0800329 } else if (!strcmp(argv[1], "finalize")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800330 dumpArgs(argc, argv, -1);
San Mehateba65e92010-01-29 05:15:16 -0800331 if (argc != 3) {
332 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
333 return 0;
334 }
San Mehat8f2875b2010-02-18 11:40:49 -0800335 rc = vm->finalizeAsec(argv[2]);
San Mehateba65e92010-01-29 05:15:16 -0800336 } else if (!strcmp(argv[1], "destroy")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800337 dumpArgs(argc, argv, -1);
San Mehat4ba89482010-02-18 09:00:18 -0800338 if (argc < 3) {
339 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
San Mehateba65e92010-01-29 05:15:16 -0800340 return 0;
341 }
San Mehat4ba89482010-02-18 09:00:18 -0800342 bool force = false;
343 if (argc > 3 && !strcmp(argv[3], "force")) {
344 force = true;
345 }
San Mehat8f2875b2010-02-18 11:40:49 -0800346 rc = vm->destroyAsec(argv[2], force);
San Mehateba65e92010-01-29 05:15:16 -0800347 } else if (!strcmp(argv[1], "mount")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800348 dumpArgs(argc, argv, 3);
San Mehateba65e92010-01-29 05:15:16 -0800349 if (argc != 5) {
350 cli->sendMsg(ResponseCode::CommandSyntaxError,
351 "Usage: asec mount <namespace-id> <key> <ownerUid>", false);
352 return 0;
353 }
San Mehat8f2875b2010-02-18 11:40:49 -0800354 rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]));
San Mehateba65e92010-01-29 05:15:16 -0800355 } else if (!strcmp(argv[1], "unmount")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800356 dumpArgs(argc, argv, -1);
San Mehat4ba89482010-02-18 09:00:18 -0800357 if (argc < 3) {
358 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
San Mehateba65e92010-01-29 05:15:16 -0800359 return 0;
360 }
San Mehat4ba89482010-02-18 09:00:18 -0800361 bool force = false;
362 if (argc > 3 && !strcmp(argv[3], "force")) {
363 force = true;
364 }
San Mehat8f2875b2010-02-18 11:40:49 -0800365 rc = vm->unmountAsec(argv[2], force);
San Mehateba65e92010-01-29 05:15:16 -0800366 } else if (!strcmp(argv[1], "rename")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800367 dumpArgs(argc, argv, -1);
San Mehateba65e92010-01-29 05:15:16 -0800368 if (argc != 4) {
369 cli->sendMsg(ResponseCode::CommandSyntaxError,
370 "Usage: asec rename <old_id> <new_id>", false);
371 return 0;
372 }
San Mehat8f2875b2010-02-18 11:40:49 -0800373 rc = vm->renameAsec(argv[2], argv[3]);
San Mehateba65e92010-01-29 05:15:16 -0800374 } else if (!strcmp(argv[1], "path")) {
San Mehatd9a4e352010-03-12 13:32:47 -0800375 dumpArgs(argc, argv, -1);
San Mehateba65e92010-01-29 05:15:16 -0800376 if (argc != 3) {
377 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
378 return 0;
379 }
380 char path[255];
381
San Mehat88ac2c02010-03-23 11:15:58 -0700382 if (!(rc = vm->getAsecMountPath(argv[2], path, sizeof(path)))) {
San Mehateba65e92010-01-29 05:15:16 -0800383 cli->sendMsg(ResponseCode::AsecPathResult, path, false);
San Mehat88ac2c02010-03-23 11:15:58 -0700384 return 0;
San Mehateba65e92010-01-29 05:15:16 -0800385 }
San Mehata19b2502010-01-06 10:33:53 -0800386 } else {
San Mehatd9a4e352010-03-12 13:32:47 -0800387 dumpArgs(argc, argv, -1);
San Mehateba65e92010-01-29 05:15:16 -0800388 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
San Mehata19b2502010-01-06 10:33:53 -0800389 }
390
San Mehat8f2875b2010-02-18 11:40:49 -0800391 if (!rc) {
392 cli->sendMsg(ResponseCode::CommandOkay, "asec operation succeeded", false);
393 } else {
394 rc = ResponseCode::convertFromErrno();
395 cli->sendMsg(rc, "asec operation failed", true);
396 }
397
San Mehata19b2502010-01-06 10:33:53 -0800398 return 0;
399}
San Mehat2350c442010-03-02 13:16:50 -0800400
Kenny Root508c0e12010-07-12 09:59:49 -0700401CommandListener::ObbCmd::ObbCmd() :
402 VoldCommand("obb") {
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700403}
404
Kenny Root508c0e12010-07-12 09:59:49 -0700405int CommandListener::ObbCmd::runCommand(SocketClient *cli,
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700406 int argc, char **argv) {
407 if (argc < 2) {
408 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
409 return 0;
410 }
411
412 VolumeManager *vm = VolumeManager::Instance();
413 int rc = 0;
414
Kenny Root508c0e12010-07-12 09:59:49 -0700415 if (!strcmp(argv[1], "list")) {
416 dumpArgs(argc, argv, -1);
417
418 rc = vm->listMountedObbs(cli);
419 } else if (!strcmp(argv[1], "mount")) {
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700420 dumpArgs(argc, argv, 3);
421 if (argc != 5) {
422 cli->sendMsg(ResponseCode::CommandSyntaxError,
Kenny Root508c0e12010-07-12 09:59:49 -0700423 "Usage: obb mount <filename> <key> <ownerUid>", false);
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700424 return 0;
425 }
Kenny Root508c0e12010-07-12 09:59:49 -0700426 rc = vm->mountObb(argv[2], argv[3], atoi(argv[4]));
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700427 } else if (!strcmp(argv[1], "unmount")) {
428 dumpArgs(argc, argv, -1);
429 if (argc < 3) {
Kenny Root508c0e12010-07-12 09:59:49 -0700430 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb unmount <source file> [force]", false);
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700431 return 0;
432 }
433 bool force = false;
434 if (argc > 3 && !strcmp(argv[3], "force")) {
435 force = true;
436 }
Kenny Root508c0e12010-07-12 09:59:49 -0700437 rc = vm->unmountObb(argv[2], force);
438 } else if (!strcmp(argv[1], "path")) {
439 dumpArgs(argc, argv, -1);
440 if (argc != 3) {
441 cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb path <source file>", false);
442 return 0;
443 }
444 char path[255];
445
446 if (!(rc = vm->getObbMountPath(argv[2], path, sizeof(path)))) {
447 cli->sendMsg(ResponseCode::AsecPathResult, path, false);
448 return 0;
449 }
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700450 } else {
451 dumpArgs(argc, argv, -1);
Kenny Root508c0e12010-07-12 09:59:49 -0700452 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown obb cmd", false);
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700453 }
454
455 if (!rc) {
Kenny Root508c0e12010-07-12 09:59:49 -0700456 cli->sendMsg(ResponseCode::CommandOkay, "obb operation succeeded", false);
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700457 } else {
458 rc = ResponseCode::convertFromErrno();
Kenny Root508c0e12010-07-12 09:59:49 -0700459 cli->sendMsg(rc, "obb operation failed", true);
Kenny Rootfb7c4d52010-06-30 18:48:41 -0700460 }
461
462 return 0;
463}
464
San Mehat2350c442010-03-02 13:16:50 -0800465CommandListener::XwarpCmd::XwarpCmd() :
466 VoldCommand("xwarp") {
467}
468
469int CommandListener::XwarpCmd::runCommand(SocketClient *cli,
470 int argc, char **argv) {
471 if (argc < 2) {
472 cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
473 return 0;
474 }
475
476 if (!strcmp(argv[1], "enable")) {
477 if (Xwarp::enable()) {
478 cli->sendMsg(ResponseCode::OperationFailed, "Failed to enable xwarp", true);
479 return 0;
480 }
481
482 cli->sendMsg(ResponseCode::CommandOkay, "Xwarp mirroring started", false);
483 } else if (!strcmp(argv[1], "disable")) {
484 if (Xwarp::disable()) {
485 cli->sendMsg(ResponseCode::OperationFailed, "Failed to disable xwarp", true);
486 return 0;
487 }
488
489 cli->sendMsg(ResponseCode::CommandOkay, "Xwarp disabled", false);
490 } else if (!strcmp(argv[1], "status")) {
491 char msg[255];
492 bool r;
493 unsigned mirrorPos, maxSize;
494
495 if (Xwarp::status(&r, &mirrorPos, &maxSize)) {
496 cli->sendMsg(ResponseCode::OperationFailed, "Failed to get xwarp status", true);
497 return 0;
498 }
499 snprintf(msg, sizeof(msg), "%s %u %u", (r ? "ready" : "not-ready"), mirrorPos, maxSize);
500 cli->sendMsg(ResponseCode::XwarpStatusResult, msg, false);
501 } else {
502 cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
503 }
504
505 return 0;
506}
507