Check block module enabled before sending GetMmcPrimary dbus method
[platform/core/system/libstorage.git] / src / storage-inhouse.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <tzplatform_config.h>
23
24 #include "common.h"
25 #include "list.h"
26 #include "log.h"
27 #include "storage-internal.h"
28 #include "storage-external-dbus.h"
29 #include "storage-experimental.h"
30
31 /*
32         Get compat path from origin Multi-user path
33         from TZ_USER_CONTENT/.. to /opt/usr/media/..
34         Input should be normalized path like /opt/usr/home/owner/media (TODO: internal normalization)
35
36         Why this API should be provided?
37         In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
38         However, although system daemon operates real path,
39                 system daemon needs to provide compat path to App if the real path is converted.
40
41         Usage:
42                 #include <storage-internal.h>
43
44                 char dest[100];
45                 if(storage_get_compat_internal_path(src, sizeof(dest), dest) < 0)
46                         // cannot convert. use src path
47                 else
48                         // can convert. use dest path
49  */
50 //LCOV_EXCL_START Untested function
51 API int storage_get_compat_internal_path(const char* origin, int len, char* compat)
52 {
53         int r = -1;
54         int str_len;
55         const char* str;
56
57         if (!compat || !origin) {
58                 _E("Invalid parameter");
59                 return -1;
60         }
61
62         // this API works on place where compat path is bind-mounted
63         if (!is_compat_bind_mount()) {
64                 //LCOV_EXCL_START System Error
65                 _E("No compat bind mount");
66                 return -1;
67                 //LCOV_EXCL_STOP
68         }
69
70         str = tzplatform_getenv(TZ_USER_CONTENT);
71         str_len = strlen(str);
72         if (strncmp(origin, str, str_len) != 0) {
73                 _E("Failed to match TZ_USER_CONTENT");
74                 return -1;
75         }
76
77         r = snprintf(compat, len, "%s%s", COMPAT_DIR, origin + str_len);
78         if (r < 0) {
79                 //LCOV_EXCL_START System Error
80                 _E("Failed to create new path");
81                 return -1;
82                 //LCOV_EXCL_STOP
83         }
84
85         return 0;
86 }
87 //LCOV_EXCL_STOP
88
89 /*
90         Get Multi-user path from compat path
91         from /opt/usr/media/.. to TZ_USER_CONTENT/..
92         Input should be normalized path like /opt/usr/media (TODO: internal normalization)
93
94         Why this API should be provided?
95         In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
96         However, although some APIs send the compat path to system daemon,
97                 system daemon should access real path.
98
99         Usage:
100                 #include <storage-internal.h>
101
102                 char dest[100];
103                 if(storage_get_origin_internal_path(src, sizeof(dest), dest) < 0)
104                         // cannot convert. use src path
105                 else
106                         // can convert. use dest path
107 */
108 API int storage_get_origin_internal_path(const char* compat, int len, char* origin)
109 {
110         int r;
111         int compat_len;
112
113         if (!compat || !origin) {
114                 _E("Invalid parameter");
115                 return -1;
116         }
117
118         // this API works on place where compat path is bind-mounted
119         if (!is_compat_bind_mount()) {
120                 //LCOV_EXCL_START System Error
121                 _E("no compat bind mount");
122                 return -1;
123                 //LCOV_EXCL_STOP
124         }
125
126         compat_len = strlen(COMPAT_DIR);
127         if (strncmp(compat, COMPAT_DIR, compat_len) != 0) {
128                 _E("failed to match COMPAT_DIR");
129                 return -1;
130         }
131
132         r = snprintf(origin, len, "%s%s", tzplatform_getenv(TZ_USER_CONTENT), compat + compat_len);
133         if (r < 0) {
134                 //LCOV_EXCL_START System Error
135                 _E("failed to create new path");
136                 return -1;
137                 //LCOV_EXCL_STOP
138         }
139
140         return 0;
141 }
142
143 API int storage_get_primary_sdcard(int *storage_id, char **path)
144 {
145         GVariant *result;
146         storage_ext_device info;
147
148         if (!storage_id || !path)
149                 return STORAGE_ERROR_INVALID_PARAMETER;
150
151         if (!storage_ext_is_supported())
152                 return STORAGE_ERROR_NO_DEVICE;
153
154         result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
155                         STORAGE_EXT_PATH_MANAGER,
156                         STORAGE_EXT_IFACE_MANAGER,
157                         "GetMmcPrimary",
158                         NULL);
159         if (!result) {
160                 //LCOV_EXCL_START System Error
161                 _E("Failed to get primary sdcard partition"); //LCOV_EXCL_LINE
162                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
163                 //LCOV_EXCL_STOP
164         }
165
166         g_variant_get(result, "(issssssisibii)",
167                         &info.type, &info.devnode, &info.syspath,
168                         &info.fs_usage, &info.fs_type,
169                         &info.fs_version, &info.fs_uuid,
170                         &info.readonly, &info.mount_point,
171                         &info.state, &info.primary,
172                         &info.flags, &info.storage_id);
173
174         g_variant_unref(result);
175
176         if (info.storage_id < 0)
177                 return STORAGE_ERROR_NO_DEVICE;
178
179         *path = strdup(info.mount_point);
180         if (*path == NULL)
181                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
182
183         *storage_id = info.storage_id;
184
185         return STORAGE_ERROR_NONE;
186 }
187
188 API int storage_get_type_dev(int storage_id, storage_type_e *type, storage_dev_e *dev)
189 {
190         storage_ext_device *ext_dev;
191         int ret;
192
193         if (storage_id < 0) {
194                 _E("Invalid parameger");
195                 return STORAGE_ERROR_NO_DEVICE;
196         }
197
198         if (!type) {
199                 _E("Invalid parameger");
200                 return STORAGE_ERROR_INVALID_PARAMETER;
201         }
202
203         if (!dev) {
204                 _E("Invalid parameger");
205                 return STORAGE_ERROR_INVALID_PARAMETER;
206         }
207
208         ret = storage_get_type(storage_id, type);
209         if (ret != STORAGE_ERROR_NONE) {
210                 _E("Failed to get storage type: %d", ret);
211                 return ret;
212         }
213         if (*type == STORAGE_TYPE_INTERNAL)
214                 return STORAGE_ERROR_NONE;
215
216         ext_dev = calloc(1, sizeof(storage_ext_device));
217         if (!ext_dev) {
218                 //LCOV_EXCL_START System Error
219                 _E("calloc failed");
220                 return STORAGE_ERROR_OUT_OF_MEMORY;
221                 //LCOV_EXCL_STOP
222         }
223
224         ret = storage_ext_get_device_info(storage_id, ext_dev);
225         if (ret < 0) {
226                 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
227                 ret = STORAGE_ERROR_NO_DEVICE;
228                 goto out;
229         }
230
231         if (ext_dev->type == STORAGE_EXT_SCSI)
232                 *dev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
233         else if (ext_dev->type == STORAGE_EXT_MMC)
234                 *dev = STORAGE_DEV_EXT_SDCARD;
235         ret = STORAGE_ERROR_NONE;
236         _I("type: %d(internal:0, external:1) dev: %d(sdcard: 1001, usb: 1002)", *type, *dev);
237
238 out:
239         storage_ext_release_device(&ext_dev);
240         return ret;
241 }