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>
2537dcda68d334f70e1f7f69a9817def65fe3ee717Olivier Bailly#include <string.h>
26f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
27d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#define LOG_TAG "VoldCmdListener"
28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h>
29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <sysutils/SocketClient.h>
313ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall#include <private/android_filesystem_config.h>
32f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
33f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "CommandListener.h"
34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "VolumeManager.h"
35a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "ResponseCode.h"
36586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat#include "Process.h"
372350c44ff39b4cb2940893964a05f778fc80a436San Mehat#include "Xwarp.h"
38d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Loop.h"
39d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include "Devmapper.h"
408f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall#include "cryptfs.h"
41b87937cdea689594a293979b30b13054e7455deeKen Sumrall#include "fstrim.h"
42f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
433fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn#define DUMP_ARGS 0
443fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn
45f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatCommandListener::CommandListener() :
46149aa3eb65a8cb878781206b1476aae110e0e1fdRobert Greenwalt                 FrameworkListener("vold", true) {
47d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    registerCmd(new DumpCmd());
48eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new VolumeCmd());
49eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    registerCmd(new AsecCmd());
50508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    registerCmd(new ObbCmd());
51586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    registerCmd(new StorageCmd());
522350c44ff39b4cb2940893964a05f778fc80a436San Mehat    registerCmd(new XwarpCmd());
538f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    registerCmd(new CryptfsCmd());
54b87937cdea689594a293979b30b13054e7455deeKen Sumrall    registerCmd(new FstrimCmd());
55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
57d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatvoid CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
583fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn#if DUMP_ARGS
59d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char buffer[4096];
60d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    char *p = buffer;
61d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
62d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    memset(buffer, 0, sizeof(buffer));
63d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    int i;
64d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    for (i = 0; i < argc; i++) {
658f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        unsigned int len = strlen(argv[i]) + 1; // Account for space
66d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (i == argObscure) {
67d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            len += 2; // Account for {}
68d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
69d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
70d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i == argObscure) {
71d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '{';
72d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = '}';
73d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
74d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                continue;
75d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
76d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            strcpy(p, argv[i]);
77d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            p+= strlen(argv[i]);
78d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            if (i != (argc -1)) {
79d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                *p++ = ' ';
80d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat            }
81d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        }
82d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
8397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    SLOGD("%s", buffer);
843fd60b428202a0f5f324fccc67c0c0402b9131baDianne Hackborn#endif
85d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
86d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
87d9a4e358614a0c5f60cc76c0636ee4bb02004a32San MehatCommandListener::DumpCmd::DumpCmd() :
88d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                 VoldCommand("dump") {
89d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
90d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
91d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatint CommandListener::DumpCmd::runCommand(SocketClient *cli,
92d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat                                         int argc, char **argv) {
93d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping loop status", false);
94d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Loop::dumpState(cli)) {
95d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
96d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
97d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(0, "Dumping DM status", false);
98d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    if (Devmapper::dumpState(cli)) {
99d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
100d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    }
10196597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    cli->sendMsg(0, "Dumping mounted filesystems", false);
10296597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    FILE *fp = fopen("/proc/mounts", "r");
10396597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    if (fp) {
10496597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        char line[1024];
10596597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        while (fgets(line, sizeof(line), fp)) {
10696597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat            line[strlen(line)-1] = '\0';
10796597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat            cli->sendMsg(0, line, false);;
10896597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        }
10996597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat        fclose(fp);
11096597e8b840ef671fe5279f8bd64fb09a8b38d4cSan Mehat    }
111d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
112d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
113d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    return 0;
114d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat}
115d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
116d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
117eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::VolumeCmd::VolumeCmd() :
118eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("volume") {
119f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
120f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
121eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::VolumeCmd::runCommand(SocketClient *cli,
122f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat                                                      int argc, char **argv) {
123d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
124d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
125eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
126eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
127eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        return 0;
128eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    }
129f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
130eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
131eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
132eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat
133eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "list")) {
134eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        return vm->listVolumes(cli);
135d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    } else if (!strcmp(argv[1], "debug")) {
13657df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        if (argc != 3 || (argc == 3 && (strcmp(argv[2], "off") && strcmp(argv[2], "on")))) {
13757df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume debug <off/on>", false);
13857df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
13957df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
14057df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        vm->setDebug(!strcmp(argv[2], "on") ? true : false);
141eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "mount")) {
14257df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        if (argc != 3) {
14357df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mount <path>", false);
14457df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
14557df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
146eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        rc = vm->mountVolume(argv[2]);
147eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unmount")) {
1480b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall        if (argc < 3 || argc > 4 ||
1490b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall           ((argc == 4 && strcmp(argv[3], "force")) &&
1500b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall            (argc == 4 && strcmp(argv[3], "force_and_revert")))) {
1510b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume unmount <path> [force|force_and_revert]", false);
15257df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
15357df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
15457df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat
1554ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
1560b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall        bool revert = false;
1574ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc >= 4 && !strcmp(argv[3], "force")) {
1584ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
1590b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall        } else if (argc >= 4 && !strcmp(argv[3], "force_and_revert")) {
1600b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall            force = true;
1610b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall            revert = true;
1624ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
1630b8b59719357fb80c330442787f7d5b1e332263bKen Sumrall        rc = vm->unmountVolume(argv[2], force, revert);
164eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "format")) {
1659caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        if (argc < 3 || argc > 4 ||
1669caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall            (argc == 4 && strcmp(argv[3], "wipe"))) {
1679caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume format <path> [wipe]", false);
16857df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
16957df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
1709caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        bool wipe = false;
1719caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        if (argc >= 4 && !strcmp(argv[3], "wipe")) {
1729caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall            wipe = true;
1739caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        }
1749caab76c6b5aefdeeb1715a3695491ca793b8c18Ken Sumrall        rc = vm->formatVolume(argv[2], wipe);
175eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "share")) {
17657df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        if (argc != 4) {
17757df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
17857df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat                    "Usage: volume share <path> <method>", false);
17957df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
18057df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
181b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        rc = vm->shareVolume(argv[2], argv[3]);
182eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unshare")) {
18357df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        if (argc != 4) {
18457df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
18557df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat                    "Usage: volume unshare <path> <method>", false);
18657df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
18757df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
188b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        rc = vm->unshareVolume(argv[2], argv[3]);
189eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "shared")) {
190eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        bool enabled = false;
19157df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        if (argc != 4) {
19257df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
19357df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat                    "Usage: volume shared <path> <method>", false);
19457df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat            return 0;
19557df7bf33968d65c23f3d0dc9f30a8ce2625b1d0San Mehat        }
196eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat
1972b22552f9a3b077f9d0a3624ac6f9b8b332f8a7aSan Mehat        if (vm->shareEnabled(argv[2], argv[3], &enabled)) {
198eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(
199eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    ResponseCode::OperationFailed, "Failed to determine share enable state", true);
200eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        } else {
201eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::ShareEnabledResult,
202eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    (enabled ? "Share enabled" : "Share disabled"), false);
203eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
204b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat        return 0;
20571ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey    } else if (!strcmp(argv[1], "mkdirs")) {
20671ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey        if (argc != 3) {
20771ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volume mkdirs <path>", false);
20871ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey            return 0;
20971ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey        }
21071ebe154a5fbbb4b394a439ff0b6b9c84fbd04f5Jeff Sharkey        rc = vm->mkdirs(argv[2]);
21149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    } else {
212eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume cmd", false);
21349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    }
21449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
215eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!rc) {
216eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);
217a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    } else {
2188f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        int erno = errno;
2198f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = ResponseCode::convertFromErrno();
220eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(rc, "volume operation failed", true);
221a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
222a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
223a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    return 0;
224a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
225a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
226586536c60b773e3517531ad8a6cb0de6722c67fcSan MehatCommandListener::StorageCmd::StorageCmd() :
227586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                 VoldCommand("storage") {
228586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
229586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
230586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehatint CommandListener::StorageCmd::runCommand(SocketClient *cli,
231586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                                                      int argc, char **argv) {
232d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat    dumpArgs(argc, argv, -1);
233d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat
234586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (argc < 2) {
235586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
236586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        return 0;
237586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
238586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
239586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    if (!strcmp(argv[1], "users")) {
240586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        DIR *dir;
241586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        struct dirent *de;
242586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
243586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        if (!(dir = opendir("/proc"))) {
244586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open /proc", true);
245586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            return 0;
246586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
247586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
248586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        while ((de = readdir(dir))) {
249586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            int pid = Process::getPid(de->d_name);
250586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
251586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (pid < 0) {
252586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                continue;
253586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
254586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
255586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            char processName[255];
256586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            Process::getProcessName(pid, processName, sizeof(processName));
257586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
258586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            if (Process::checkFileDescriptorSymLinks(pid, argv[2]) ||
259586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkFileMaps(pid, argv[2]) ||
260586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "cwd") ||
261586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "root") ||
262586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                Process::checkSymLink(pid, argv[2], "exe")) {
263586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
264586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                char msg[1024];
265586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                snprintf(msg, sizeof(msg), "%d %s", pid, processName);
266586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat                cli->sendMsg(ResponseCode::StorageUsersListResult, msg, false);
267586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat            }
268586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        }
269586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        closedir(dir);
270586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Storage user list complete", false);
271586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    } else {
272586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
273586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    }
274586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat    return 0;
275586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat}
276586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat
277eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan MehatCommandListener::AsecCmd::AsecCmd() :
278eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                 VoldCommand("asec") {
279048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat}
280048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
281344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Rootvoid CommandListener::AsecCmd::listAsecsInDirectory(SocketClient *cli, const char *directory) {
282344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    DIR *d = opendir(directory);
283344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
284344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    if (!d) {
285344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true);
286344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return;
287344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
288344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
289344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    size_t dirent_len = offsetof(struct dirent, d_name) +
2908c480f73eed963eeca9b7df3e4c4543c6e43b0d7Elliott Hughes            fpathconf(dirfd(d), _PC_NAME_MAX) + 1;
291344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
292344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    struct dirent *dent = (struct dirent *) malloc(dirent_len);
293344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    if (dent == NULL) {
294344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        cli->sendMsg(ResponseCode::OperationFailed, "Failed to allocate memory", true);
295344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        return;
296344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
297344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
298344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    struct dirent *result;
299344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
300344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    while (!readdir_r(d, dent, &result) && result != NULL) {
301344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (dent->d_name[0] == '.')
302344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            continue;
303344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (dent->d_type != DT_REG)
304344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            continue;
305344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        size_t name_len = strlen(dent->d_name);
306344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (name_len > 5 && name_len < 260 &&
307344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                !strcmp(&dent->d_name[name_len - 5], ".asec")) {
308344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            char id[255];
309344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            memset(id, 0, sizeof(id));
3107b0bc8571465666d6cba79bda60b72a97f852c05Kenny Root            strlcpy(id, dent->d_name, name_len - 4);
311344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::AsecListResult, id, false);
312344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
313344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    }
314344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    closedir(d);
315344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
316344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    free(dent);
317344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root}
318344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
319eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint CommandListener::AsecCmd::runCommand(SocketClient *cli,
320eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                                                      int argc, char **argv) {
321eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (argc < 2) {
322eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
323048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat        return 0;
324048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat    }
325048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat
326eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    VolumeManager *vm = VolumeManager::Instance();
327eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    int rc = 0;
328a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
329eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    if (!strcmp(argv[1], "list")) {
330d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
331a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
332344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_EXT);
333344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        listAsecsInDirectory(cli, Volume::SEC_ASECDIR_INT);
334eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "create")) {
335d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 5);
336344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (argc != 8) {
337eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
338344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                    "Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid> "
339344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root                    "<isExternal>", false);
340eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
341a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        }
342a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
343eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
344344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        const bool isExternal = (atoi(argv[7]) == 1);
345344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]), isExternal);
346eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "finalize")) {
347d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
348eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
349eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
350eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
351eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3528f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->finalizeAsec(argv[2]);
353344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root    } else if (!strcmp(argv[1], "fixperms")) {
354344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        dumpArgs(argc, argv, -1);
355344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if  (argc != 5) {
356344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
357344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            return 0;
358344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
359344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
360344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        char *endptr;
361344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        gid_t gid = (gid_t) strtoul(argv[3], &endptr, 10);
362344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        if (*endptr != '\0') {
363344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
364344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root            return 0;
365344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        }
366344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root
367344ca10856f3d3087a3288ce8f91ad83665d93fbKenny Root        rc = vm->fixupAsecPermissions(argv[2], gid, argv[4]);
368eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "destroy")) {
369d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
3704ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
3714ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
372eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
373eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3744ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
3754ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
3764ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
3774ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
3788f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->destroyAsec(argv[2], force);
379eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "mount")) {
380d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, 3);
381eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 5) {
382eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
383eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec mount <namespace-id> <key> <ownerUid>", false);
384eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
385eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3868f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]));
387eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "unmount")) {
388d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
3894ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc < 3) {
3904ba8948dc16463053e21cda5744f519a555080d0San Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
391eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
392eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
3934ba8948dc16463053e21cda5744f519a555080d0San Mehat        bool force = false;
3944ba8948dc16463053e21cda5744f519a555080d0San Mehat        if (argc > 3 && !strcmp(argv[3], "force")) {
3954ba8948dc16463053e21cda5744f519a555080d0San Mehat            force = true;
3964ba8948dc16463053e21cda5744f519a555080d0San Mehat        }
3978f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->unmountAsec(argv[2], force);
398eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "rename")) {
399d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
400eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 4) {
401eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError,
402eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat                    "Usage: asec rename <old_id> <new_id>", false);
403eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
404eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
4058f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = vm->renameAsec(argv[2], argv[3]);
406eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat    } else if (!strcmp(argv[1], "path")) {
407d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
408eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        if (argc != 3) {
409eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
410eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            return 0;
411eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
412eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        char path[255];
413a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
41488ac2c06539485942bf414efda2d39647fa1a415San Mehat        if (!(rc = vm->getAsecMountPath(argv[2], path, sizeof(path)))) {
415eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
41688ac2c06539485942bf414efda2d39647fa1a415San Mehat            return 0;
417eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        }
418736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn    } else if (!strcmp(argv[1], "fspath")) {
419736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        dumpArgs(argc, argv, -1);
420736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        if (argc != 3) {
421736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fspath <container-id>", false);
422736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            return 0;
423736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        }
424736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        char path[255];
425736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn
426736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        if (!(rc = vm->getAsecFilesystemPath(argv[2], path, sizeof(path)))) {
427736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
428736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn            return 0;
429736910ca99a40b9add4353bf619e778c40938948Dianne Hackborn        }
430a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    } else {
431d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat        dumpArgs(argc, argv, -1);
432eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
433a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
434a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
4358f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    if (!rc) {
4368f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "asec operation succeeded", false);
4378f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    } else {
4388f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        rc = ResponseCode::convertFromErrno();
4398f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat        cli->sendMsg(rc, "asec operation failed", true);
4408f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat    }
4418f2875b29780312f4edda3d831cc8a99e1648dd5San Mehat
442a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return 0;
443a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
4442350c44ff39b4cb2940893964a05f778fc80a436San Mehat
445508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny RootCommandListener::ObbCmd::ObbCmd() :
446508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root                 VoldCommand("obb") {
447fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root}
448fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
449508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Rootint CommandListener::ObbCmd::runCommand(SocketClient *cli,
450fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                                                      int argc, char **argv) {
451fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    if (argc < 2) {
452fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
453fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        return 0;
454fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
455fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
456fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    VolumeManager *vm = VolumeManager::Instance();
457fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    int rc = 0;
458fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
459508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    if (!strcmp(argv[1], "list")) {
460508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        dumpArgs(argc, argv, -1);
461508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root
462508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        rc = vm->listMountedObbs(cli);
463508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    } else if (!strcmp(argv[1], "mount")) {
464fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            dumpArgs(argc, argv, 3);
465fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            if (argc != 5) {
466fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                cli->sendMsg(ResponseCode::CommandSyntaxError,
4676947904a76b69a1db20a3ddd30c0bcd281922fdeJeff Sharkey                        "Usage: obb mount <filename> <key> <ownerGid>", false);
468fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root                return 0;
469fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            }
470508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            rc = vm->mountObb(argv[2], argv[3], atoi(argv[4]));
471fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else if (!strcmp(argv[1], "unmount")) {
472fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        dumpArgs(argc, argv, -1);
473fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        if (argc < 3) {
474508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb unmount <source file> [force]", false);
475fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            return 0;
476fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        }
477fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        bool force = false;
478fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        if (argc > 3 && !strcmp(argv[3], "force")) {
479fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root            force = true;
480fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        }
481508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        rc = vm->unmountObb(argv[2], force);
482508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root    } else if (!strcmp(argv[1], "path")) {
483508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        dumpArgs(argc, argv, -1);
484508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        if (argc != 3) {
485508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb path <source file>", false);
486508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            return 0;
487508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        }
488508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        char path[255];
489508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root
490508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        if (!(rc = vm->getObbMountPath(argv[2], path, sizeof(path)))) {
491508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
492508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root            return 0;
493508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        }
494fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else {
495fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        dumpArgs(argc, argv, -1);
496508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown obb cmd", false);
497fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
498fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
499fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    if (!rc) {
500508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(ResponseCode::CommandOkay, "obb operation succeeded", false);
501fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    } else {
502fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root        rc = ResponseCode::convertFromErrno();
503508c0e1605b795bbb51cb47d955b89f3df26ca94Kenny Root        cli->sendMsg(rc, "obb operation failed", true);
504fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    }
505fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
506fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root    return 0;
507fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root}
508fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root
5092350c44ff39b4cb2940893964a05f778fc80a436San MehatCommandListener::XwarpCmd::XwarpCmd() :
5102350c44ff39b4cb2940893964a05f778fc80a436San Mehat                 VoldCommand("xwarp") {
5112350c44ff39b4cb2940893964a05f778fc80a436San Mehat}
5122350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5132350c44ff39b4cb2940893964a05f778fc80a436San Mehatint CommandListener::XwarpCmd::runCommand(SocketClient *cli,
5142350c44ff39b4cb2940893964a05f778fc80a436San Mehat                                                      int argc, char **argv) {
5152350c44ff39b4cb2940893964a05f778fc80a436San Mehat    if (argc < 2) {
5162350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
5172350c44ff39b4cb2940893964a05f778fc80a436San Mehat        return 0;
5182350c44ff39b4cb2940893964a05f778fc80a436San Mehat    }
5192350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5202350c44ff39b4cb2940893964a05f778fc80a436San Mehat    if (!strcmp(argv[1], "enable")) {
5212350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::enable()) {
5222350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to enable xwarp", true);
5232350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
5242350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
5252350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5262350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Xwarp mirroring started", false);
5272350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else if (!strcmp(argv[1], "disable")) {
5282350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::disable()) {
5292350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to disable xwarp", true);
5302350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
5312350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
5322350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5332350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandOkay, "Xwarp disabled", false);
5342350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else if (!strcmp(argv[1], "status")) {
5352350c44ff39b4cb2940893964a05f778fc80a436San Mehat        char msg[255];
5362350c44ff39b4cb2940893964a05f778fc80a436San Mehat        bool r;
5372350c44ff39b4cb2940893964a05f778fc80a436San Mehat        unsigned mirrorPos, maxSize;
5382350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5392350c44ff39b4cb2940893964a05f778fc80a436San Mehat        if (Xwarp::status(&r, &mirrorPos, &maxSize)) {
5402350c44ff39b4cb2940893964a05f778fc80a436San Mehat            cli->sendMsg(ResponseCode::OperationFailed, "Failed to get xwarp status", true);
5412350c44ff39b4cb2940893964a05f778fc80a436San Mehat            return 0;
5422350c44ff39b4cb2940893964a05f778fc80a436San Mehat        }
5432350c44ff39b4cb2940893964a05f778fc80a436San Mehat        snprintf(msg, sizeof(msg), "%s %u %u", (r ? "ready" : "not-ready"), mirrorPos, maxSize);
5442350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::XwarpStatusResult, msg, false);
5452350c44ff39b4cb2940893964a05f778fc80a436San Mehat    } else {
5462350c44ff39b4cb2940893964a05f778fc80a436San Mehat        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
5472350c44ff39b4cb2940893964a05f778fc80a436San Mehat    }
5482350c44ff39b4cb2940893964a05f778fc80a436San Mehat
5492350c44ff39b4cb2940893964a05f778fc80a436San Mehat    return 0;
5502350c44ff39b4cb2940893964a05f778fc80a436San Mehat}
5518f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
5528f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken SumrallCommandListener::CryptfsCmd::CryptfsCmd() :
5538f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall                 VoldCommand("cryptfs") {
5548f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall}
5558f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
5568f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrallint CommandListener::CryptfsCmd::runCommand(SocketClient *cli,
5578f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall                                                      int argc, char **argv) {
5583ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
5593ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run cryptfs commands", false);
5603ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        return 0;
5613ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall    }
5623ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall
5638f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    if (argc < 2) {
5648f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
5658f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        return 0;
5668f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    }
5678f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
5688f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    int rc = 0;
5698f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
5708f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    if (!strcmp(argv[1], "checkpw")) {
5718f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        if (argc != 3) {
5728f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs checkpw <passwd>", false);
5738f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall            return 0;
5748f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        }
5758ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall        dumpArgs(argc, argv, 2);
5768f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        rc = cryptfs_check_passwd(argv[2]);
5776864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall    } else if (!strcmp(argv[1], "restart")) {
5786864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall        if (argc != 2) {
5796864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs restart", false);
5806864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall            return 0;
5816864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall        }
5828ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall        dumpArgs(argc, argv, -1);
5836864b7ec94a57b73c300457955d86dc604aeddf5Ken Sumrall        rc = cryptfs_restart();
5847f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall    } else if (!strcmp(argv[1], "cryptocomplete")) {
5857f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall        if (argc != 2) {
5867f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs cryptocomplete", false);
5877f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall            return 0;
5887f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall        }
5897f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall        dumpArgs(argc, argv, -1);
5907f7dbaa2784c10fd2989fb303e5edfb8136d53dcKen Sumrall        rc = cryptfs_crypto_complete();
5918f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    } else if (!strcmp(argv[1], "enablecrypto")) {
5928f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        if ( (argc != 4) || (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace")) ) {
5938f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs enablecrypto <wipe|inplace> <passwd>", false);
5948f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall            return 0;
5958f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        }
5968ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall        dumpArgs(argc, argv, 3);
5978f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        rc = cryptfs_enable(argv[2], argv[3]);
5988ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall    } else if (!strcmp(argv[1], "changepw")) {
59970a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks        if (argc != 3) {
60070a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs changepw <newpasswd>", false);
6018ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall            return 0;
6028ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall        }
60370a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks        SLOGD("cryptfs changepw {}");
60470a4b3fd7a84a84bbe6e9d6d4ca3ee2098259fd9Jason parks        rc = cryptfs_changepw(argv[2]);
6053ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall    } else if (!strcmp(argv[1], "verifypw")) {
6063ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        if (argc != 3) {
6073ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs verifypw <passwd>", false);
6083ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall            return 0;
6093ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        }
6103ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        SLOGD("cryptfs verifypw {}");
6113ad9072a5d6f6bda32123b367545649364e3c11dKen Sumrall        rc = cryptfs_verify_passwd(argv[2]);
612160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall    } else if (!strcmp(argv[1], "getfield")) {
613160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        char valbuf[PROPERTY_VALUE_MAX];
614160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall
615160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        if (argc != 3) {
616160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs getfield <fieldname>", false);
617160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall            return 0;
618160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        }
619160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        dumpArgs(argc, argv, -1);
620160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        rc = cryptfs_getfield(argv[2], valbuf, sizeof(valbuf));
621160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        if (rc == 0) {
622160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall            cli->sendMsg(ResponseCode::CryptfsGetfieldResult, valbuf, false);
623160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        }
624160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall    } else if (!strcmp(argv[1], "setfield")) {
625160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        if (argc != 4) {
626160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs setfield <fieldname> <value>", false);
627160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall            return 0;
628160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        }
629160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        dumpArgs(argc, argv, -1);
630160b4d68ece15947057e31edde4e5608a010c695Ken Sumrall        rc = cryptfs_setfield(argv[2], argv[3]);
6318f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    } else {
6328ddbe40a8a8708dac7c472fa8c098c8f7b24534cKen Sumrall        dumpArgs(argc, argv, -1);
6338f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs cmd", false);
6348f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    }
6358f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
6360167cb15935592deea9abbd6a8bbe904e27bd101Jason parks    // Always report that the command succeeded and return the error code.
6370167cb15935592deea9abbd6a8bbe904e27bd101Jason parks    // The caller will check the return value to see what the error was.
6380167cb15935592deea9abbd6a8bbe904e27bd101Jason parks    char msg[255];
6390167cb15935592deea9abbd6a8bbe904e27bd101Jason parks    snprintf(msg, sizeof(msg), "%d", rc);
6400167cb15935592deea9abbd6a8bbe904e27bd101Jason parks    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
6418f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall
6428f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall    return 0;
6438f869aa1bc685b505c58e97b4e11a9c7491a16f9Ken Sumrall}
644b87937cdea689594a293979b30b13054e7455deeKen Sumrall
645b87937cdea689594a293979b30b13054e7455deeKen SumrallCommandListener::FstrimCmd::FstrimCmd() :
646b87937cdea689594a293979b30b13054e7455deeKen Sumrall                 VoldCommand("fstrim") {
647b87937cdea689594a293979b30b13054e7455deeKen Sumrall}
648b87937cdea689594a293979b30b13054e7455deeKen Sumrallint CommandListener::FstrimCmd::runCommand(SocketClient *cli,
649b87937cdea689594a293979b30b13054e7455deeKen Sumrall                                                      int argc, char **argv) {
650b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
651b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run fstrim commands", false);
652b87937cdea689594a293979b30b13054e7455deeKen Sumrall        return 0;
653b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
654b87937cdea689594a293979b30b13054e7455deeKen Sumrall
655b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if (argc < 2) {
656b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
657b87937cdea689594a293979b30b13054e7455deeKen Sumrall        return 0;
658b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
659b87937cdea689594a293979b30b13054e7455deeKen Sumrall
660b87937cdea689594a293979b30b13054e7455deeKen Sumrall    int rc = 0;
661b87937cdea689594a293979b30b13054e7455deeKen Sumrall
662b87937cdea689594a293979b30b13054e7455deeKen Sumrall    if (!strcmp(argv[1], "dotrim")) {
663b87937cdea689594a293979b30b13054e7455deeKen Sumrall        if (argc != 2) {
664b87937cdea689594a293979b30b13054e7455deeKen Sumrall            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: fstrim dotrim", false);
665b87937cdea689594a293979b30b13054e7455deeKen Sumrall            return 0;
666b87937cdea689594a293979b30b13054e7455deeKen Sumrall        }
667b87937cdea689594a293979b30b13054e7455deeKen Sumrall        dumpArgs(argc, argv, -1);
668b87937cdea689594a293979b30b13054e7455deeKen Sumrall        rc = fstrim_filesystems();
669b87937cdea689594a293979b30b13054e7455deeKen Sumrall    } else {
670b87937cdea689594a293979b30b13054e7455deeKen Sumrall        dumpArgs(argc, argv, -1);
671b87937cdea689594a293979b30b13054e7455deeKen Sumrall        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown fstrim cmd", false);
672b87937cdea689594a293979b30b13054e7455deeKen Sumrall    }
673b87937cdea689594a293979b30b13054e7455deeKen Sumrall
674b87937cdea689594a293979b30b13054e7455deeKen Sumrall    // Always report that the command succeeded and return the error code.
675b87937cdea689594a293979b30b13054e7455deeKen Sumrall    // The caller will check the return value to see what the error was.
676b87937cdea689594a293979b30b13054e7455deeKen Sumrall    char msg[255];
677b87937cdea689594a293979b30b13054e7455deeKen Sumrall    snprintf(msg, sizeof(msg), "%d", rc);
678b87937cdea689594a293979b30b13054e7455deeKen Sumrall    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
679b87937cdea689594a293979b30b13054e7455deeKen Sumrall
680b87937cdea689594a293979b30b13054e7455deeKen Sumrall    return 0;
681b87937cdea689594a293979b30b13054e7455deeKen Sumrall}
682