• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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_legacy/IMountService.h>
18 #include <binder/BpBinder.h>
19 #include <binder/IServiceManager.h>
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26 
27 namespace android {
28 
29 static sp<IMountService> gMountService;
30 
init()31 static 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 
isMounted(const char * mountPoint)41 static 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 
millisecondSleep(int milliseconds)79 static 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 
mount(const char * path)87 static int mount(const char* path) {
88     String16 string(path);
89     gMountService->mountMedia(string);
90 
91     for (int i = 0; i < 60; 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 
unmount(const char * path)102 static int unmount(const char* path) {
103     String16 string(path);
104     gMountService->unmountMedia(string);
105 
106     for (int i = 0; i < 20; 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 
format(const char * path)117 static int format(const char* path) {
118     String16 string(path);
119 
120     if (isMounted(path))
121         return -EBUSY;
122     gMountService->formatMedia(string);
123 
124     return 0;
125 }
126 
umsEnable(bool enable)127 static int umsEnable(bool enable) {
128     gMountService->setMassStorageEnabled(enable);
129     return 0;
130 }
131 
132 };
133 
main(int argc,char ** argv)134 int main(int argc, char **argv)
135 {
136     const char* command = (argc > 1 ? argv[1] : "");
137     const char* argument = (argc > 2 ? argv[2] : "");
138 
139     if (strcmp(command, "mount") == 0) {
140         android::init();
141         return android::mount(argument);
142     } else if (strcmp(command, "format") == 0) {
143         android::init();
144         return android::format(argument);
145     } else if (strcmp(command, "unmount") == 0) {
146         android::init();
147         return android::unmount(argument);
148     } else if (strcmp(command, "ums") == 0) {
149         if (strcmp(argument, "enable") == 0) {
150             android::init();
151             return android::umsEnable(true);
152         } else if (strcmp(argument, "disable") == 0) {
153             android::init();
154             return android::umsEnable(false);
155         }
156     }
157 
158     fprintf(stderr, "usage:\n"
159                     "    sdutil mount <mount path>          - mounts the SD card at the given mount point\n"
160                     "    sdutil unmount <mount path>        - unmounts the SD card at the given mount point\n"
161                     "    sdutil format <mount path>         - formats the SD card at the given mount point\n"
162                     "    sdutil ums enable                  - enables USB mass storage\n"
163                     "    sdutil ums disable                 - disnables USB mass storage\n"
164                     );
165     return -1;
166 }
167