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