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