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