blob: ac14c151e9f565f54702d6f3717f051d3abe14ce [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <hardware/IMountService.h>
18#include <utils/BpBinder.h>
19#include <utils/IServiceManager.h>
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <time.h>
26
27namespace android {
28
29static sp<IMountService> gMountService;
30
31static void init() {
32 sp<IServiceManager> sm = defaultServiceManager();
33 sp<IBinder> binder = sm->getService(String16("mount"));
34 gMountService = interface_cast<IMountService>(binder);
35 if (gMountService == 0) {
36 fprintf(stderr, "could not get MountService\n");
37 exit(1);
38 }
39}
40
41static bool isMounted(const char* mountPoint) {
42 char s[2000];
43 FILE *f = fopen("/proc/mounts", "r");
44 bool mounted = false;
45
46 while (fgets(s, sizeof(s), f))
47 {
48 char *c, *path = NULL;
49
50 for (c = s; *c; c++)
51 {
52 if (*c == ' ')
53 {
54 *c = 0;
55 path = c + 1;
56 break;
57 }
58 }
59
60 for (c = path; *c; c++)
61 {
62 if (*c == ' ')
63 {
64 *c = '\0';
65 break;
66 }
67 }
68
69 if (strcmp(mountPoint, path) == 0) {
70 mounted = true;
71 break;
72 }
73 }
74
75 fclose(f);
76 return mounted;
77}
78
79static void millisecondSleep(int milliseconds) {
80 struct timespec reqt, remt;
81 reqt.tv_sec = milliseconds / 1000;
82 reqt.tv_nsec = 1000000 * (milliseconds % 1000);
83 nanosleep(&reqt, &remt) ;
84
85}
86
87static int mount(const char* path) {
88 String16 string(path);
89 gMountService->mountMedia(string);
90
91 for (int i = 0; i < 10; i++) {
92 if (isMounted(path)) {
93 return 0;
94 }
95 millisecondSleep(500);
96 }
97
98 fprintf(stderr, "failed to mount %s\n", path);
99 return -1;
100}
101
102static int unmount(const char* path) {
103 String16 string(path);
104 gMountService->unmountMedia(string);
105
106 for (int i = 0; i < 10; i++) {
107 if (!isMounted(path)) {
108 return 0;
109 }
110 millisecondSleep(500);
111 }
112
113 fprintf(stderr, "failed to unmount %s\n", path);
114 return -1;
115}
116
117static int umsEnable(bool enable) {
118 gMountService->setMassStorageEnabled(enable);
119 return 0;
120}
121
122};
123
124int main(int argc, char **argv)
125{
126 const char* command = (argc > 1 ? argv[1] : "");
127 const char* argument = (argc > 2 ? argv[2] : "");
128
129 if (strcmp(command, "mount") == 0) {
130 android::init();
131 return android::mount(argument);
132 } else if (strcmp(command, "unmount") == 0) {
133 android::init();
134 return android::unmount(argument);
135 } else if (strcmp(command, "ums") == 0) {
136 if (strcmp(argument, "enable") == 0) {
137 android::init();
138 return android::umsEnable(true);
139 } else if (strcmp(argument, "disable") == 0) {
140 android::init();
141 return android::umsEnable(false);
142 }
143 }
144
145 fprintf(stderr, "usage:\n"
146 " sdutil mount <mount path> - mounts the SD card at the given mount point\n"
147 " sdutil unmount <mount path> - unmounts the SD card at the given mount point\n"
148 " sdutil ums enable - enables USB mass storage\n"
149 " sdutil ums disable - disnables USB mass storage\n"
150 );
151 return -1;
152}