Add comments for line coverage
[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 <unistd.h>
19 #include <sys/types.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <tzplatform_config.h>
25
26 #include "common.h"
27 #include "list.h"
28 #include "log.h"
29 #include "storage-internal.h"
30 #include "storage-external-dbus.h"
31
32 #define FORMAT_TIMEOUT  (120*1000)
33
34 /*
35         Get compat path from origin Multi-user path
36         from TZ_USER_CONTENT/.. to /opt/usr/media/..
37         Input should be normalized path like /opt/usr/home/owner/media (TODO: internal normalization)
38
39         Why this API should be provided?
40         In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
41         However, although system daemon operates real path,
42                 system daemon needs to provide compat path to App if the real path is converted.
43
44         Usage:
45                 #include <storage-internal.h>
46
47                 char dest[100];
48                 if(storage_get_compat_internal_path(src, sizeof(dest), dest) < 0)
49                         // cannot convert. use src path
50                 else
51                         // can convert. use dest path
52  */
53 //LCOV_EXCL_START Untested function
54 API int storage_get_compat_internal_path(const char* origin, int len, char* compat)
55 {
56         int r = -1;
57         int str_len;
58         const char* str;
59
60         if (!compat || !origin) {
61                 _E("Invalid parameter");
62                 return -1;
63         }
64
65         if (getuid() <= USER_UID_START) {
66                 //LCOV_EXCL_START System Error
67                 _E("Only apps and user session daemons are allowed "
68                                 "to use storage_get_compat_internal_path()");
69                 return -1;
70                 //LCOV_EXCL_STOP
71         }
72
73         // this API works on place where compat path is bind-mounted
74         if (!is_compat_bind_mount()) {
75                 //LCOV_EXCL_START System Error
76                 _E("No compat bind mount");
77                 return -1;
78                 //LCOV_EXCL_STOP
79         }
80
81         str = tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT);
82         str_len = strlen(str);
83         if (strncmp(origin, str, str_len) != 0) {
84                 _E("Failed to match TZ_USER_CONTENT");
85                 return -1;
86         }
87
88         r = snprintf(compat, len, "%s%s", COMPAT_DIR, origin + str_len);
89         if (r < 0) {
90                 //LCOV_EXCL_START System Error
91                 _E("Failed to create new path");
92                 return -1;
93                 //LCOV_EXCL_STOP
94         }
95
96         return 0;
97 }
98 //LCOV_EXCL_STOP
99
100 /*
101         Get Multi-user path from compat path
102         from /opt/usr/media/.. to TZ_USER_CONTENT/..
103         Input should be normalized path like /opt/usr/media (TODO: internal normalization)
104
105         Why this API should be provided?
106         In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
107         However, although some APIs send the compat path to system daemon,
108                 system daemon should access real path.
109
110         Usage:
111                 #include <storage-internal.h>
112
113                 char dest[100];
114                 if(storage_get_origin_internal_path(src, sizeof(dest), dest) < 0)
115                         // cannot convert. use src path
116                 else
117                         // can convert. use dest path
118 */
119 API int storage_get_origin_internal_path(const char* compat, int len, char* origin)
120 {
121         int r;
122         int compat_len;
123
124         if (!compat || !origin) {
125                 _E("Invalid parameter");
126                 return -1;
127         }
128
129         if (getuid() <= USER_UID_START) {
130                 //LCOV_EXCL_START System Error
131                 _E("Only apps and user session daemons are allowed "
132                                 "to use storage_get_origin_internal_path()");
133                 return -1;
134                 //LCOV_EXCL_STOP
135         }
136
137         // this API works on place where compat path is bind-mounted
138         if (!is_compat_bind_mount()) {
139                 //LCOV_EXCL_START System Error
140                 _E("no compat bind mount");
141                 return -1;
142                 //LCOV_EXCL_STOP
143         }
144
145         compat_len = strlen(COMPAT_DIR);
146         if (strncmp(compat, COMPAT_DIR, compat_len) != 0) {
147                 _E("failed to match COMPAT_DIR");
148                 return -1;
149         }
150
151         r = snprintf(origin, len, "%s%s", tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT), compat + compat_len);
152         if (r < 0) {
153                 //LCOV_EXCL_START System Error
154                 _E("failed to create new path");
155                 return -1;
156                 //LCOV_EXCL_STOP
157         }
158
159         return 0;
160 }
161
162 API int storage_get_primary_sdcard(int *storage_id, char **path)
163 {
164         GVariant *result;
165         storage_ext_device info;
166
167         if (!storage_id || !path)
168                 return STORAGE_ERROR_INVALID_PARAMETER;
169
170         if (!storage_ext_is_supported())
171                 return STORAGE_ERROR_NO_DEVICE;
172
173         result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
174                         STORAGE_EXT_PATH_MANAGER,
175                         STORAGE_EXT_IFACE_MANAGER,
176                         "GetMmcPrimary",
177                         NULL);
178         if (!result) {
179                 //LCOV_EXCL_START System Error
180                 _E("Failed to get primary sdcard partition"); //LCOV_EXCL_LINE
181                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
182                 //LCOV_EXCL_STOP
183         }
184
185         g_variant_get(result, "(issssssisibii)",
186                         &info.type, &info.devnode, &info.syspath,
187                         &info.fs_usage, &info.fs_type,
188                         &info.fs_version, &info.fs_uuid,
189                         &info.readonly, &info.mount_point,
190                         &info.state, &info.primary,
191                         &info.flags, &info.storage_id);
192
193         g_variant_unref(result);
194
195         if (info.storage_id < 0)
196                 return STORAGE_ERROR_NO_DEVICE;
197
198         *path = strdup(info.mount_point);
199         if (*path == NULL)
200                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
201
202         *storage_id = info.storage_id;
203
204         return STORAGE_ERROR_NONE;
205 }
206
207 API int storage_get_storage_level(const char *path, char **level)
208 {
209         int ret;
210
211         if (!level || !path)
212                 return STORAGE_ERROR_INVALID_PARAMETER;
213
214         ret = storage_ext_get_storage_level(path, level);
215         if (ret == -ENOMEM)
216                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
217         else if (ret == -EINVAL)
218                 return STORAGE_ERROR_INVALID_PARAMETER;
219         else if (ret < 0)
220                 return STORAGE_ERROR_OPERATION_FAILED;
221
222         return STORAGE_ERROR_NONE;
223 }
224
225 //LCOV_EXCL_START Not called callback
226 static void mount_mmc_cb(GVariant *var, void *user_data, GError *err)
227 {
228         struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
229         int mmc_ret = -1;
230
231         _D("mount_mmc_cb called");
232
233         if (!var) {
234                 _E("no message [%s]", err->message);
235                 mmc_ret = -EBADMSG;
236                 goto exit;
237         }
238
239         g_variant_get(var, "(i)", &mmc_ret);
240
241         _I("Mount State : %d", mmc_ret);
242
243 exit:
244         if (var)
245                 g_variant_unref(var);
246         (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
247 }
248 //LCOV_EXCL_STOP
249
250 API int storage_request_mount_mmc(struct mmc_contents *mmc_data)
251 {
252         void (*mount_cb)(GVariant *, void *, GError *) = NULL;
253         void *data = NULL;
254         char *path;
255         int ret;
256         int id;
257
258         if (mmc_data && mmc_data->mmc_cb) {
259                 _I("Mount callback exists");
260                 mount_cb = mount_mmc_cb;
261                 data = mmc_data;
262         }
263
264         ret = storage_get_primary_sdcard(&id, &path);
265         if (ret != STORAGE_ERROR_NONE)
266                 return ret;
267
268         ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
269                         STORAGE_EXT_PATH_MANAGER,
270                         STORAGE_EXT_IFACE_MANAGER,
271                         "Mount",
272                         g_variant_new("(is)", id, ""),
273                         mount_cb,
274                         -1,
275                         data);
276
277         _I("Mount Request %s", ret == 0 ? "Success" : "Failed");
278
279         if (ret == -ENOMEM)
280                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
281         if (ret < 0)
282                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
283
284         return STORAGE_ERROR_NONE;
285 }
286
287 //LCOV_EXCL_START Not called callback
288 static void unmount_mmc_cb(GVariant *var, void *user_data, GError *err)
289 {
290         struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
291         int mmc_ret;
292
293         _D("unmount_mmc_cb called");
294
295         if (!var) {
296                 _E("no message [%s]", err->message);
297                 mmc_ret = -EBADMSG;
298                 goto exit;
299         }
300
301         g_variant_get(var, "(i)", &mmc_ret);
302
303         _I("Unmount State : %d", mmc_ret);
304
305 exit:
306         if (var)
307                 g_variant_unref(var);
308         (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
309 }
310 //LCOV_EXCL_STOP
311
312 API int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
313 {
314         void (*unmount_cb)(GVariant *, void *, GError *) = NULL;
315         void *data = NULL;
316         char *path;
317         int ret;
318         int id;
319
320         if (option < 0 || option > 1)
321                 return STORAGE_ERROR_INVALID_PARAMETER;
322
323         if (mmc_data && mmc_data->mmc_cb) {
324                 _I("Unmount callback exists");
325                 unmount_cb = unmount_mmc_cb;
326                 data = mmc_data;
327         }
328
329         ret = storage_get_primary_sdcard(&id, &path);
330         if (ret != STORAGE_ERROR_NONE)
331                 return ret;
332
333         ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
334                         STORAGE_EXT_PATH_MANAGER,
335                         STORAGE_EXT_IFACE_MANAGER,
336                         "Unmount",
337                         g_variant_new("(ii)", id, option),
338                         unmount_cb,
339                         -1,
340                         data);
341
342         _I("Unmount Request %s", ret == 0 ? "Success" : "Failed");
343
344         if (ret == -ENOMEM)
345                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
346         if (ret < 0)
347                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
348
349         return STORAGE_ERROR_NONE;
350 }
351
352 //LCOV_EXCL_START Not called callback
353 static void format_mmc_cb(GVariant *var, void *user_data, GError *err)
354 {
355         struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
356         int mmc_ret;
357
358         _D("format_mmc_cb called");
359
360         if (!var) {
361                 _E("no message [%s]", err->message);
362                 mmc_ret = -EBADMSG;
363                 goto exit;
364         }
365
366         g_variant_get(var, "(i)", &mmc_ret);
367
368         _I("Format State : %d", mmc_ret);
369
370 exit:
371         if (var)
372                 g_variant_unref(var);
373         (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
374 }
375 //LCOV_EXCL_STOP
376
377 API int storage_request_format_mmc(struct mmc_contents *mmc_data)
378 {
379         return storage_format_mmc(mmc_data, 1);
380 }
381
382 API int storage_format_mmc(struct mmc_contents *mmc_data, int option)
383 {
384         void (*format_cb)(GVariant *, void *, GError *) = NULL;
385         void *data = NULL;
386         char *path;
387         int ret;
388         int id;
389
390         if (option < 0 || option > 1)
391                 return STORAGE_ERROR_INVALID_PARAMETER;
392
393         if (mmc_data && mmc_data->mmc_cb) {
394                 _I("Format callback exists");
395                 format_cb = format_mmc_cb;
396                 data = mmc_data;
397         }
398
399         ret = storage_get_primary_sdcard(&id, &path);
400         if (ret != STORAGE_ERROR_NONE)
401                 return ret;
402
403         ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
404                         STORAGE_EXT_PATH_MANAGER,
405                         STORAGE_EXT_IFACE_MANAGER,
406                         "Format",
407                         g_variant_new("(ii)", id, option),
408                         format_cb,
409                         FORMAT_TIMEOUT,
410                         data);
411
412         _I("Format Request %s", ret == 0 ? "Success" : "Failed");
413
414         if (ret == -ENOMEM)
415                 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
416         if (ret < 0)
417                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
418
419         return STORAGE_ERROR_NONE;
420 }