Remove _strncpy_safe()
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc-storage.c
1 /*
2  * libmedia-service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyunjun Ko <zzoon.ko@samsung.com>, Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include "media-util-err.h"
23 #include "media-svc-debug.h"
24 #include "media-svc-env.h"
25 #include "media-svc-db-utils.h"
26 #include "media-svc-util.h"
27 #include "media-svc-storage.h"
28
29 int _media_svc_init_storage(sqlite3 *handle, uid_t uid)
30 {
31         int ret = MS_MEDIA_ERR_NONE;
32         char *sql = NULL;
33         sqlite3_stmt *sql_stmt = NULL;
34         int storage_cnt = 0;
35
36         /*Add Internal storage*/
37         sql = sqlite3_mprintf("SELECT COUNT(*) FROM '%s' WHERE storage_uuid='%s' AND storage_name='%s'", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA);
38         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
39         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
40
41         storage_cnt = sqlite3_column_int(sql_stmt, 0);
42         SQLITE3_FINALIZE(sql_stmt);
43
44         if (storage_cnt == 0) {
45                 char *internal_path = NULL;
46                 ret = ms_user_get_internal_root_path(uid, &internal_path);
47                 media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Fail to get root path");
48
49                 sql = sqlite3_mprintf("INSERT INTO %s (storage_uuid, storage_name, storage_path, storage_type) VALUES ('%s', '%s', '%s', 0);",
50                                                 MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_TABLE_MEDIA, internal_path);
51
52                 ret = _media_svc_sql_query(sql, uid);
53                 SQLITE3_SAFE_FREE(sql);
54                 SAFE_FREE(internal_path);
55                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
56         }
57
58         return ret;
59 }
60
61 int _media_svc_get_mmc_info(MediaSvcHandle *handle, char **storage_name, char **storage_path, int *validity, bool *info_exist)
62 {
63         int ret = MS_MEDIA_ERR_NONE;
64         sqlite3_stmt *sql_stmt = NULL;
65         char *sql = NULL;
66
67         sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_TABLE_MEDIA);
68
69         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
70         if (ret != MS_MEDIA_ERR_NONE) {
71                 *storage_name = NULL;
72                 *storage_path = NULL;
73                 *validity = 0;
74                 *info_exist = FALSE;
75
76                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD)
77                         *info_exist = FALSE;
78
79                 return ret;
80         }
81
82         *storage_name = g_strdup((const char *)sqlite3_column_text(sql_stmt, 1));
83         *storage_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 2));
84         *validity = sqlite3_column_int(sql_stmt, 6);
85
86         *info_exist = TRUE;
87
88         SQLITE3_FINALIZE(sql_stmt);
89
90         return MS_MEDIA_ERR_NONE;
91 }
92
93 int _media_svc_check_storage(sqlite3 *handle, const char *storage_id, const char *storage_name, char **storage_path, int *validity, uid_t uid)
94 {
95         int ret = MS_MEDIA_ERR_NONE;
96         sqlite3_stmt *sql_stmt = NULL;
97         char *sql = NULL;
98
99         *storage_path = NULL;
100         *validity = 0;
101
102         if (storage_name != NULL)
103                 sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q AND storage_name=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name);
104         else
105                 sql = sqlite3_mprintf("SELECT * FROM '%s' WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
106
107         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
108
109         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
110
111         *storage_path = g_strdup((const char *)sqlite3_column_text(sql_stmt, 2));
112         *validity = sqlite3_column_int(sql_stmt, 6);
113
114         SQLITE3_FINALIZE(sql_stmt);
115
116         /*check storage media table*/
117         if (STRING_VALID(storage_id)) {
118                 int table_cnt = 0;
119
120                 /*Select list of storage*/
121                 sql = sqlite3_mprintf("SELECT COUNT(*) FROM SQLITE_MASTER WHERE type='table' and name='%q'", storage_id);
122                 ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
123                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
124
125                 table_cnt = sqlite3_column_int(sql_stmt, 0);
126                 SQLITE3_FINALIZE(sql_stmt);
127
128                 if (table_cnt > 0) {
129                         /*DO NOT THING*/
130                 } else {
131                         media_svc_error("media table not exist for storage [%s]", storage_id);
132                         /*make storage media table*/
133                         ret = _media_svc_create_media_table_with_id(storage_id, uid);
134                         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "create media table failed : %d", ret);
135                 }
136         }
137
138         return MS_MEDIA_ERR_NONE;
139 }
140
141 int _media_svc_append_storage(const char *storage_id, const char *storage_name, const char *storage_path, media_svc_storage_type_e storage_type, uid_t uid)
142 {
143         int ret = MS_MEDIA_ERR_NONE;
144         char *sql = sqlite3_mprintf("INSERT INTO %s (storage_uuid, storage_name, storage_path, storage_type) values (%Q, %Q, %Q, %d); ",
145                                                 MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name, storage_path, storage_type);
146
147         ret = _media_svc_sql_query(sql, uid);
148         SQLITE3_SAFE_FREE(sql);
149
150         return ret;
151 }
152
153 int _media_svc_update_storage_path(sqlite3 *handle, const char *storage_id, const char *path, uid_t uid)
154 {
155         int ret = MS_MEDIA_ERR_NONE;
156         char *sql = NULL;
157         char *old_storage_path = NULL;
158         int validity = 0;
159
160         /*Get old path*/
161         ret = _media_svc_check_storage(handle, storage_id, NULL, &old_storage_path, &validity, uid);
162         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
163
164         /*Storage table update*/
165         sql = sqlite3_mprintf("UPDATE '%s' SET storage_path=%Q WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, path, storage_id);
166         ret = _media_svc_sql_query(sql, uid);
167         SQLITE3_SAFE_FREE(sql);
168         if (ret != MS_MEDIA_ERR_NONE) {
169                 G_SAFE_FREE(old_storage_path);
170                 return ret;
171         }
172
173         /*Folder table update*/
174         sql = sqlite3_mprintf("UPDATE '%s' SET path=REPLACE(path, %Q, %Q) WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_FOLDER, old_storage_path, path, storage_id);
175         ret = _media_svc_sql_query(sql, uid);
176         SQLITE3_SAFE_FREE(sql);
177         if (ret != MS_MEDIA_ERR_NONE) {
178                 G_SAFE_FREE(old_storage_path);
179                 return ret;
180         }
181
182         /*Media table update*/
183         sql = sqlite3_mprintf("UPDATE '%s' SET path=REPLACE(path, %Q, %Q);", storage_id, old_storage_path, path);
184         ret = _media_svc_sql_query(sql, uid);
185         SQLITE3_SAFE_FREE(sql);
186         G_SAFE_FREE(old_storage_path);
187         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
188
189         return ret;
190 }
191
192 int _media_svc_delete_storage(const char *storage_id, const char *storage_name, uid_t uid)
193 {
194         int ret = MS_MEDIA_ERR_NONE;
195         char *sql = NULL;
196
197         if (storage_name != NULL)
198                         sql = sqlite3_mprintf("DELETE FROM '%s' WHERE storage_uuid=%Q AND storage_name=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, storage_id, storage_name);
199         else if (storage_id != NULL)
200                 sql = sqlite3_mprintf("DELETE FROM '%s' WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
201
202         ret = _media_svc_sql_query(sql, uid);
203         SQLITE3_SAFE_FREE(sql);
204
205         return ret;
206 }
207
208 int _media_svc_update_storage_validity(const char *storage_id, int validity, uid_t uid)
209 {
210         int ret = MS_MEDIA_ERR_NONE;
211         char *sql = NULL;
212
213         if (storage_id == NULL)
214                 sql = sqlite3_mprintf("UPDATE '%s' SET validity=%d WHERE storage_uuid != 'media';", MEDIA_SVC_DB_TABLE_STORAGE, validity);
215         else
216                 sql = sqlite3_mprintf("UPDATE '%s' SET validity=%d WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, validity, storage_id);
217
218         ret = _media_svc_sql_query(sql, uid);
219         SQLITE3_SAFE_FREE(sql);
220
221         return ret;
222 }
223
224 int _media_svc_get_storage_uuid(sqlite3 *handle, const char *path, char *storage_id, uid_t uid)
225 {
226         int ret = MS_MEDIA_ERR_NONE;
227         sqlite3_stmt *sql_stmt = NULL;
228         char *sql = NULL;
229         char *storage_path = NULL;
230         char *remain_path = NULL;
231         int remain_len = 0;
232         char *internal_path = NULL;
233
234         ret = ms_user_get_internal_root_path(uid, &internal_path);
235         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Fail to get root path");
236
237         if (STRING_VALID(internal_path) && strncmp(path, internal_path, strlen(internal_path)) == 0) {
238                 SAFE_STRLCPY(storage_id, MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_UUID_SIZE+1);
239                 SAFE_FREE(internal_path);
240                 return MS_MEDIA_ERR_NONE;
241         }
242
243         SAFE_FREE(internal_path);
244
245         remain_path = strstr(path + (STRING_VALID(MEDIA_ROOT_PATH_USB) ? strlen(MEDIA_ROOT_PATH_USB) : 0) + 1, "/");
246         if (remain_path != NULL)
247                 remain_len = strlen(remain_path);
248
249         storage_path = strndup(path, strlen(path) - remain_len);
250
251         sql = sqlite3_mprintf("SELECT storage_uuid FROM '%s' WHERE validity=1 AND storage_path = '%s'", MEDIA_SVC_DB_TABLE_STORAGE, storage_path);
252
253         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
254         SAFE_FREE(storage_path);
255         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
256
257         if (STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0)))
258                 SAFE_STRLCPY(storage_id, (const char *)sqlite3_column_text(sql_stmt, 0), MEDIA_SVC_UUID_SIZE+1);
259
260         SQLITE3_FINALIZE(sql_stmt);
261
262         if (!STRING_VALID(storage_id)) {
263                 media_svc_error("Not found valid storage id [%s]", path);
264                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
265         }
266
267         return ret;
268 }
269
270 int _media_svc_get_storage_type(sqlite3 *handle, const char *storage_id, media_svc_storage_type_e *storage_type)
271 {
272         int ret = MS_MEDIA_ERR_NONE;
273         sqlite3_stmt *sql_stmt = NULL;
274         char *sql = NULL;
275
276         if (!STRING_VALID(storage_id)) {
277                 media_svc_error("Invalid storage_id");
278                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
279         }
280
281         sql = sqlite3_mprintf("SELECT storage_type FROM '%s' WHERE storage_uuid=%Q", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
282
283         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
284
285         if (ret != MS_MEDIA_ERR_NONE) {
286                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD)
287                         media_svc_debug("there is no storage.");
288                 else
289                         media_svc_error("error when _media_svc_get_storage_type. err = [%d]", ret);
290
291                 return ret;
292         }
293
294         *storage_type = sqlite3_column_int(sql_stmt, 0);
295
296         SQLITE3_FINALIZE(sql_stmt);
297
298         return ret;
299 }
300
301 int _media_svc_get_storage_path(sqlite3 *handle, const char *storage_id, char **storage_path)
302 {
303         int ret = MS_MEDIA_ERR_NONE;
304         sqlite3_stmt *sql_stmt = NULL;
305         char *sql = NULL;
306
307         if (!STRING_VALID(storage_id)) {
308                 media_svc_error("Invalid storage_id");
309                 ret = MS_MEDIA_ERR_INVALID_PARAMETER;
310         }
311
312         sql = sqlite3_mprintf("SELECT storage_path FROM '%s' WHERE (storage_uuid=%Q AND validity=1)", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
313
314         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
315
316         if (ret != MS_MEDIA_ERR_NONE) {
317                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD)
318                         media_svc_debug("there is no storage.");
319                 else
320                         media_svc_error("error when _media_svc_get_storage_type. err = [%d]", ret);
321
322                 return ret;
323         }
324
325         *storage_path = g_strdup((char *)sqlite3_column_text(sql_stmt, 0));
326
327         SQLITE3_FINALIZE(sql_stmt);
328
329         return ret;
330 }
331
332 int _media_svc_get_storage_scan_status(sqlite3 *handle, const char *storage_id, media_svc_scan_status_type_e *scan_status)
333 {
334         int ret = MS_MEDIA_ERR_NONE;
335         sqlite3_stmt *sql_stmt = NULL;
336         char *sql = NULL;
337
338         if (!STRING_VALID(storage_id)) {
339                 media_svc_error("Invalid storage_id");
340                 return MS_MEDIA_ERR_INVALID_PARAMETER;
341         }
342
343         sql = sqlite3_mprintf("SELECT scan_status FROM '%s' WHERE (storage_uuid=%Q AND validity=1)", MEDIA_SVC_DB_TABLE_STORAGE, storage_id);
344
345         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
346         if (ret != MS_MEDIA_ERR_NONE) {
347                 if (ret == MS_MEDIA_ERR_DB_NO_RECORD)
348                         media_svc_debug("there is no storage.");
349                 else
350                         media_svc_error("error when _media_svc_get_storage_scan_status. err = [%d]", ret);
351
352                 return ret;
353         }
354
355         *scan_status = sqlite3_column_int(sql_stmt, 0);
356
357         SQLITE3_FINALIZE(sql_stmt);
358
359         return ret;
360 }
361
362 int _media_svc_set_storage_scan_status(const char *storage_id, media_svc_scan_status_type_e scan_status, uid_t uid)
363 {
364         int ret = MS_MEDIA_ERR_NONE;
365         char *sql = NULL;
366
367         if (storage_id == NULL)
368                 sql = sqlite3_mprintf("UPDATE '%s' SET scan_status=%d WHERE storage_uuid != 'media';", MEDIA_SVC_DB_TABLE_STORAGE, scan_status);
369         else
370                 sql = sqlite3_mprintf("UPDATE '%s' SET scan_status=%d WHERE storage_uuid=%Q;", MEDIA_SVC_DB_TABLE_STORAGE, scan_status, storage_id);
371
372         ret = _media_svc_sql_query(sql, uid);
373         SQLITE3_SAFE_FREE(sql);
374
375         return ret;
376 }
377
378 static int __media_svc_count_all_storage(sqlite3 *handle, int *count)
379 {
380         int ret = MS_MEDIA_ERR_NONE;
381         sqlite3_stmt *sql_stmt = NULL;
382         char *sql = sqlite3_mprintf("SELECT count(*) FROM '%s' WHERE validity = 1", MEDIA_SVC_DB_TABLE_STORAGE);
383
384         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
385         if (ret != MS_MEDIA_ERR_NONE) {
386                 media_svc_error("error when _media_svc_sql_prepare_to_step. err = [%d]", ret);
387                 return ret;
388         }
389
390         *count = sqlite3_column_int(sql_stmt, 0);
391
392         SQLITE3_FINALIZE(sql_stmt);
393
394         return MS_MEDIA_ERR_NONE;
395 }
396
397 int _media_svc_get_all_storage(sqlite3 *handle, char ***storage_list, char ***storage_id_list, int **scan_status_list, int *count)
398 {
399         int ret = MS_MEDIA_ERR_NONE;
400         int idx = 0;
401         sqlite3_stmt *sql_stmt = NULL;
402         char *sql = NULL;
403         int cnt = 0;
404
405         ret = __media_svc_count_all_storage(handle, &cnt);
406         if (ret != MS_MEDIA_ERR_NONE) {
407                 media_svc_error("error when __media_svc_count_all_folders. err = [%d]", ret);
408                 return ret;
409         }
410
411         if (cnt > 0) {
412                 sql = sqlite3_mprintf("SELECT storage_path, storage_uuid, scan_status FROM '%s' WHERE validity = 1", MEDIA_SVC_DB_TABLE_STORAGE);
413         } else {
414                 *storage_list = NULL;
415                 *scan_status_list = NULL;
416                 return MS_MEDIA_ERR_NONE;
417         }
418
419         *storage_list = malloc(sizeof(char *) * cnt);
420         *storage_id_list = malloc(sizeof(char *) * cnt);
421         *scan_status_list = malloc(sizeof(int) * cnt);
422         if (*storage_list == NULL || *storage_id_list == NULL || *scan_status_list == NULL) {
423                 media_svc_error("Allocation failed");
424                 SAFE_FREE(*storage_list);
425                 SAFE_FREE(*storage_id_list);
426                 SAFE_FREE(*scan_status_list);
427                 SQLITE3_SAFE_FREE(sql);
428                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
429         }
430
431         ret = _media_svc_sql_prepare_to_step(handle, sql, &sql_stmt);
432         if (ret != MS_MEDIA_ERR_NONE) {
433                 media_svc_error("prepare error [%s]", sqlite3_errmsg(handle));
434                 SAFE_FREE(*storage_list);
435                 SAFE_FREE(*storage_id_list);
436                 SAFE_FREE(*scan_status_list);
437                 return ret;
438         }
439
440         media_svc_debug("QEURY OK");
441
442         while (1) {
443                 (*storage_list)[idx] = g_strdup((char *)sqlite3_column_text(sql_stmt, 0));
444                 (*storage_id_list)[idx] = g_strdup((char *)sqlite3_column_text(sql_stmt, 1));
445                 (*scan_status_list)[idx] = (int)sqlite3_column_int(sql_stmt, 2);
446                 if (sqlite3_step(sql_stmt) != SQLITE_ROW)
447                         break;
448                 idx++;
449         }
450
451         if (cnt == idx + 1) {
452                 *count = cnt;
453                 media_svc_debug("OK");
454         } else {
455                 /* free all data */
456                 int i = 0;
457                 for (i = 0; i < idx; i++) {
458                         SAFE_FREE((*storage_list)[i]);
459                         SAFE_FREE((*storage_id_list)[i]);
460                 }
461                 SAFE_FREE(*storage_list);
462                 SAFE_FREE(*storage_id_list);
463                 SAFE_FREE(*scan_status_list);
464                 *count = 0;
465                 ret = MS_MEDIA_ERR_INTERNAL;
466         }
467
468         SQLITE3_FINALIZE(sql_stmt);
469
470         return ret;
471 }