CommandListener.cpp revision d9a4e358614a0c5f60cc76c0636ee4bb02004a32
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/*
2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project
3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License.
6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at
7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *      http://www.apache.org/licenses/LICENSE-2.0
9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software
11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and
14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License.
15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */
16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdlib.h>
18f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sys/socket.h>
19a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <sys/types.h>
20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <netinet/in.h>
21f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <arpa/inet.h>
22a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <dirent.h>
23f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <errno.h>
242350c44ff39b4cb2940893964a05f778fc80a436San Mehat#include <fcntl.h>
25f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
26d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#define LOG_TAG "VoldCmdListener"
27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h>
28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sysutils/SocketClient.h>
30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "CommandListener.h"
32f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "VolumeManager.h"
33a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "ResponseCode.h"
34586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat#include "Process.h"
352350c44ff39b4cb2940893964a05f778fc80a436San Mehat#include "Xwarp.h"
36d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Loop.h"
37d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Devmapper.h"
38f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
39f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatCommandListener::CommandListener() :
40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat                 FrameworkListener("vold") {
41d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    registerCmd(new DumpCmd());
42eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new VolumeCmd());
43eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new AsecCmd());
44a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    registerCmd(new ShareCmd());
45586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    registerCmd(new StorageCmd());
462350c44ff39b4cb2940893964a05f778fc80a436San Mehat    registerCmd(new XwarpCmd());
47f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
49d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatvoid CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
50d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char buffer[4096];
51d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char *p = buffer;
52d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
53d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    memset(buffer, 0, sizeof(buffer));
54d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    int i;
55d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    for (i = 0; i < argc; i++) {
56d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        int len = strlen(argv[i]) + 1; // Account for space
57d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (i == argObscure) {
58d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            len += 2; // Account for {}
59d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
60d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
61d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i == argObscure) {
62d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '{';
63d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '}';
64d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
65d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                continue;
66d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
67d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            strcpy(p, argv[i]);
68d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            p+= strlen(argv[i]);
69d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i != (argc -1)) {
70d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
71d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
72d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
73d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
74d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    LOGD("%s", buffer);
75d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
76d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
77d9a4e358614a0c5f60cc76c0636ee4bb02004a32San MehatCommandListener::DumpCmd::DumpCmd() :
78d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                 VoldCommand("dump") {
79d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
80d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
81d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatint CommandListener::DumpCmd::runCommand(SocketClient *cli,
82d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                                         int argc, char **argv) {
83d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping loop status", false);
84d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Loop::dumpState(cli)) {
85d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
86d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
87d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping DM status", false);
88d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Devmapper::dumpState(cli)) {
89d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
90d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
91d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
92d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
93d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    return 0;
94d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
95d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
96d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
97eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::VolumeCmd::VolumeCmd() :
98eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("volume") {
99f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
100f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
101eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::VolumeCmd::runCommand(SocketClient *cli,
102f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat                                                      int argc, char **argv) {
103d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
104d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
105eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
106eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
107eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        return 0;
108eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    }
109f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
110eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
111eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
112eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat
113eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "list")) {
114eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        return vm->listVolumes(cli);
115d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    } else if (!strcmp(argv[1], "debug")) {
116d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        vm->setDebug(true);
117eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "mount")) {
118eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        rc = vm->mountVolume(argv[2]);
119eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unmount")) {
1204ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
1214ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc >= 4 && !strcmp(argv[3], "force")) {
1224ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
1234ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
1244ba8948dc16463053e21cda5744f519a555080d0San Mehat        rc = vm->unmountVolume(argv[2], force);
125eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "format")) {
126eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        rc = vm->formatVolume(argv[2]);
127eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "share")) {
128b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        rc = vm->shareVolume(argv[2], argv[3]);
129eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unshare")) {
130b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        rc = vm->unshareVolume(argv[2], argv[3]);
131eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "shared")) {
132eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        bool enabled = false;
133eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat
1342b22552f9a3b077f9d0a3624ac6f9b8b332f8a7aSan Mehat        if (vm->shareEnabled(argv[2], argv[3], &enabled)) {
135eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(
136eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    ResponseCode::OperationFailed, "Failed to determine share enable state", true);
137eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        } else {
138eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::ShareEnabledResult,
139eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    (enabled ? "Share enabled" : "Share disabled"), false);
140eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
141b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        return 0;
14249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    } else {
143eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
14449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    }
14549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
146eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!rc) {
147eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);
148a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    } else {
1498f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        int erno = errno;
1508f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = ResponseCode::convertFromErrno();
151eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(rc, "volume operation failed", true);
152a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
153a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
154a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    return 0;
155a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
157a2677e4ad01f250b0765f04adf0acfa6627efc98San MehatCommandListener::ShareCmd::ShareCmd() :
158a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                 VoldCommand("share") {
159a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
160a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
161a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint CommandListener::ShareCmd::runCommand(SocketClient *cli,
162a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                                                      int argc, char **argv) {
163d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
164d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
165eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
166eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
167a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        return 0;
168a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
169a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
170eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
171eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
172a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
173eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "status")) {
174eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        bool avail = false;
175a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
176eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (vm->shareAvailable(argv[2], &avail)) {
177eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(
178eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    ResponseCode::OperationFailed, "Failed to determine share availability", true);
179eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        } else {
180eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::ShareStatusResult,
181eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    (avail ? "Share available" : "Share unavailable"), false);
182eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
183a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    } else {
184eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown share cmd", false);
185a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
1865817821cf10b5f7d13eb693ffbc3f80f13bc681bSan Mehat
1875817821cf10b5f7d13eb693ffbc3f80f13bc681bSan Mehat    return 0;
1885817821cf10b5f7d13eb693ffbc3f80f13bc681bSan Mehat}
1895817821cf10b5f7d13eb693ffbc3f80f13bc681bSan Mehat
190586536c60b773e3517531ad8a6cb0de6722c67fcSan MehatCommandListener::StorageCmd::StorageCmd() :
191586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                 VoldCommand("storage") {
192586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
193586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
194586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehatint CommandListener::StorageCmd::runCommand(SocketClient *cli,
195586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                                                      int argc, char **argv) {
196d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
197d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
198586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (argc < 2) {
199586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
200586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        return 0;
201586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
202586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
203586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (!strcmp(argv[1], "users")) {
204586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        DIR *dir;
205586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        struct dirent *de;
206586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
207586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        if (!(dir = opendir("/proc"))) {
208586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open /proc", true);
209586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            return 0;
210586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
211586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
212586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        while ((de = readdir(dir))) {
213586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            int pid = Process::getPid(de->d_name);
214586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
215586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (pid < 0) {
216586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                continue;
217586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
218586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
219586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            char processName[255];
220586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            Process::getProcessName(pid, processName, sizeof(processName));
221586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
222586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (Process::checkFileDescriptorSymLinks(pid, argv[2]) ||
223586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkFileMaps(pid, argv[2]) ||
224586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "cwd") ||
225586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "root") ||
226586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "exe")) {
227586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
228586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                char msg[1024];
229586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                snprintf(msg, sizeof(msg), "%d %s", pid, processName);
230586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                cli->sendMsg(ResponseCode::StorageUsersListResult, msg, false);
231586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
232586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
233586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        closedir(dir);
234586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Storage user list complete", false);
235586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    } else {
236586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
237586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
238586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    return 0;
239586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
240586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
241eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::AsecCmd::AsecCmd() :
242eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("asec") {
243048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat}
244048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
245eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::AsecCmd::runCommand(SocketClient *cli,
246eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                                                      int argc, char **argv) {
247eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
248eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
249048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat        return 0;
250048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat    }
251048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
252eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
253eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
254a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
255eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "list")) {
256d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
2573bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat        DIR *d = opendir(Volume::SEC_ASECDIR);
258a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
259eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (!d) {
260eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true);
261eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
262eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
263a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
264eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        struct dirent *dent;
265eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        while ((dent = readdir(d))) {
266eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            if (dent->d_name[0] == '.')
267eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                continue;
268eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            if (!strcmp(&dent->d_name[strlen(dent->d_name)-5], ".asec")) {
269eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                char id[255];
270eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                memset(id, 0, sizeof(id));
271eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                strncpy(id, dent->d_name, strlen(dent->d_name) -5);
272eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                cli->sendMsg(ResponseCode::AsecListResult, id, false);
273eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            }
274eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
275eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        closedir(d);
276eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "create")) {
277d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 5);
278eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 7) {
279eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
280eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid>", false);
281eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
282a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        }
283a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
284eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
2858f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]));
286eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "finalize")) {
287d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
288eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
289eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
290eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
291eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
2928f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->finalizeAsec(argv[2]);
293eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "destroy")) {
294d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
2954ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
2964ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
297eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
298eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
2994ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
3004ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
3014ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
3024ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
3038f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->destroyAsec(argv[2], force);
304eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "mount")) {
305d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 3);
306eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 5) {
307eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
308eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec mount <namespace-id> <key> <ownerUid>", false);
309eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
310eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3118f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]));
312eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unmount")) {
313d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
3144ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
3154ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
316eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
317eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3184ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
3194ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
3204ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
3214ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
3228f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->unmountAsec(argv[2], force);
323eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "rename")) {
324d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
325eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 4) {
326eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
327eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec rename <old_id> <new_id>", false);
328eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
329eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3308f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->renameAsec(argv[2], argv[3]);
331eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "path")) {
332d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
333eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
334eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
335eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
336eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
337eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        char path[255];
338a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
339eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (vm->getAsecMountPath(argv[2], path, sizeof(path))) {
340eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to get path", true);
341eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        } else {
342eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
343eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3448f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        return 0;
345a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    } else {
346d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
347eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
348a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
349a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
3508f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    if (!rc) {
3518f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "asec operation succeeded", false);
3528f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    } else {
3538f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = ResponseCode::convertFromErrno();
3548f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(rc, "asec operation failed", true);
3558f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    }
3568f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat
357a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return 0;
358a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
3592350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3602350c44ff39b4cb2940893964a05f778fc80a436San MehatCommandListener::XwarpCmd::XwarpCmd() :
3612350c44ff39b4cb2940893964a05f778fc80a436San Mehat                 VoldCommand("xwarp") {
3622350c44ff39b4cb2940893964a05f778fc80a436San Mehat}
3632350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3642350c44ff39b4cb2940893964a05f778fc80a436San Mehatint CommandListener::XwarpCmd::runCommand(SocketClient *cli,
3652350c44ff39b4cb2940893964a05f778fc80a436San Mehat                                                      int argc, char **argv) {
3662350c44ff39b4cb2940893964a05f778fc80a436San Mehat    if (argc < 2) {
3672350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
3682350c44ff39b4cb2940893964a05f778fc80a436San Mehat        return 0;
3692350c44ff39b4cb2940893964a05f778fc80a436San Mehat    }
3702350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3712350c44ff39b4cb2940893964a05f778fc80a436San Mehat    if (!strcmp(argv[1], "enable")) {
3722350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::enable()) {
3732350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to enable xwarp", true);
3742350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
3752350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
3762350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3772350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Xwarp mirroring started", false);
3782350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else if (!strcmp(argv[1], "disable")) {
3792350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::disable()) {
3802350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to disable xwarp", true);
3812350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
3822350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
3832350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3842350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Xwarp disabled", false);
3852350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else if (!strcmp(argv[1], "status")) {
3862350c44ff39b4cb2940893964a05f778fc80a436San Mehat        char msg[255];
3872350c44ff39b4cb2940893964a05f778fc80a436San Mehat        bool r;
3882350c44ff39b4cb2940893964a05f778fc80a436San Mehat        unsigned mirrorPos, maxSize;
3892350c44ff39b4cb2940893964a05f778fc80a436San Mehat
3902350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::status(&r, &mirrorPos, &maxSize)) {
3912350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to get xwarp status", true);
3922350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
3932350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
3942350c44ff39b4cb2940893964a05f778fc80a436San Mehat        snprintf(msg, sizeof(msg), "%s %u %u", (r ? "ready" : "not-ready"), mirrorPos, maxSize);
3952350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::XwarpStatusResult, msg, false);
3962350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else {
3972350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
3982350c44ff39b4cb2940893964a05f778fc80a436San Mehat    }
3992350c44ff39b4cb2940893964a05f778fc80a436San Mehat
4002350c44ff39b4cb2940893964a05f778fc80a436San Mehat    return 0;
4012350c44ff39b4cb2940893964a05f778fc80a436San Mehat}
4022350c44ff39b4cb2940893964a05f778fc80a436San Mehat
403