Append scanner v2 92/49292/1
authorMinje Ahn <minje.ahn@samsung.com>
Mon, 12 Oct 2015 10:42:22 +0000 (19:42 +0900)
committerMinje Ahn <minje.ahn@samsung.com>
Mon, 12 Oct 2015 10:42:22 +0000 (19:42 +0900)
Change-Id: I29760353144a1ca883154cd935936bffaa3f8adb
Signed-off-by: Minje Ahn <minje.ahn@samsung.com>
17 files changed:
Makefile.am
packaging/media-server.spec
src/common/include/media-common-db-svc.h
src/common/media-common-db-svc.c
src/common/media-common-external-storage.c
src/scanner-v2/include/media-scanner-common-v2.h [new file with mode: 0644]
src/scanner-v2/include/media-scanner-dbg-v2.h [new file with mode: 0755]
src/scanner-v2/include/media-scanner-device-block-v2.h [new file with mode: 0755]
src/scanner-v2/include/media-scanner-extract-v2.h [new file with mode: 0755]
src/scanner-v2/include/media-scanner-scan-v2.h [new file with mode: 0755]
src/scanner-v2/include/media-scanner-socket-v2.h [new file with mode: 0755]
src/scanner-v2/media-scanner-common-v2.c [new file with mode: 0644]
src/scanner-v2/media-scanner-device-block-v2.c [new file with mode: 0755]
src/scanner-v2/media-scanner-extract-v2.c [new file with mode: 0755]
src/scanner-v2/media-scanner-scan-v2.c [new file with mode: 0755]
src/scanner-v2/media-scanner-socket-v2.c [new file with mode: 0755]
src/scanner-v2/media-scanner-v2.c [new file with mode: 0755]

index 906b2d5..7059c9d 100755 (executable)
@@ -98,6 +98,7 @@ libmedia_utils_la_LIBADD  =   $(GLIB_LIBS) \
 
 bin_PROGRAMS = media-server \
                media-scanner \
+               media-scanner-v2 \
                mediadb-update
 ######################################################
 #media server
@@ -146,6 +147,29 @@ media_scanner_LDFLAGS = -pie
 media_scanner_LDADD = $(COMMON_LDADD)
 
 ######################################################
+#media scanner v2
+######################################################
+media_scanner_v2_SOURCES = src/common/media-common-utils.c \
+                       src/common/media-common-system.c \
+                        src/common/media-common-external-storage.c \
+                       src/common/media-common-db-svc.c \
+                       src/scanner-v2/media-scanner-common-v2.c \
+                       src/scanner-v2/media-scanner-device-block-v2.c\
+                        src/scanner-v2/media-scanner-scan-v2.c \
+                        src/scanner-v2/media-scanner-socket-v2.c \
+                       src/scanner-v2/media-scanner-extract-v2.c \
+                        src/scanner-v2/media-scanner-v2.c
+
+media_scanner_v2_CFLAGS = -I${srcdir}/src/scanner-v2/include \
+                          $(COMMON_CFLAGS)
+
+media_scanner_v2_CFLAGS += -fPIE
+
+media_scanner_v2_LDFLAGS = -pie
+
+media_scanner_v2_LDADD = $(COMMON_LDADD)
+
+######################################################
 #mediadb_udpate
 ######################################################
 mediadb_update_SOURCES = src/mediadb-update.c
index 6ad4032..627a884 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       media-server
 Summary:    File manager service server.
-Version:    0.2.60
+Version:    0.2.59
 Release:    0
 Group:      Multimedia/Service
 License:    Apache-2.0
@@ -107,6 +107,7 @@ ln -sf ../media-server-user.path  %{_unitdir_user}/default.target.wants/
 %defattr(-,root,root,-)
 %{_bindir}/media-server
 %{_bindir}/media-scanner
+%{_bindir}/media-scanner-v2
 %{_bindir}/mediadb-update
 %exclude %attr(755,-,-) %{_sysconfdir}/rc.d/init.d/mediasvr
 %exclude /etc/rc.d/rc3.d/S46mediasvr
@@ -134,3 +135,4 @@ ln -sf ../media-server-user.path  %{_unitdir_user}/default.target.wants/
 %{_libdir}/libmedia-utils.so
 %{_libdir}/pkgconfig/libmedia-utils.pc
 %{_includedir}/media-utils/*.h
+
index 648c04d..ed6c515 100755 (executable)
@@ -84,7 +84,7 @@ typedef int (*SET_FOLDER_VALIDITY)(void*, const char*, const char*, int, bool, u
 typedef int (*INSERT_FOLDER_BEGIN)(void *, int, char**);
 typedef int (*INSERT_FOLDER_END)(void*, uid_t, char**);
 typedef int (*INSERT_ITEM_SCAN)(void*, const char*, const char*, int, uid_t, char **);
-typedef int (*UPDATE_ITEM_EXTRACT)(void*, const char*, int, int, const char*, uid_t, char **);
+typedef int (*UPDATE_ITEM_EXTRACT)(void*, const char*, int, int, uid_t, const char*, char **);
 
 typedef int (*CHECK_DB)(void*, bool*, uid_t, char **);
 typedef int (*GET_UUID)(void *, char **, char **);
index 5cfbbe6..b99df4a 100755 (executable)
@@ -559,7 +559,7 @@ int ms_insert_item_pass2(void **handle, const char* storage_id, const char *path
        storage_type = ms_get_storage_type_by_full(path, uid);
 
        for (lib_index = 0; lib_index < lib_num; lib_index++) {
-               ret = ((UPDATE_ITEM_EXTRACT)func_array[lib_index][eUPDATE_EXTRACT])(handle[lib_index], storage_id, storage_type, scan_type, path, uid, &err_msg); /*dlopen*/
+               ret = ((UPDATE_ITEM_EXTRACT)func_array[lib_index][eUPDATE_EXTRACT])(handle[lib_index], storage_id, storage_type, scan_type, uid, path, &err_msg); /*dlopen*/
                if (ret != 0) {
                        MS_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path);
                        MS_SAFE_FREE(err_msg);
index 2ab64d9..39e7de7 100755 (executable)
@@ -140,10 +140,11 @@ int ms_present_mmc_status(ms_sdcard_status_type_t status)
 #define DEVICE_INFO_FILE ".device_info_"
 
 struct linux_dirent {
-       int           d_ino;
-       long           d_off;
-       unsigned short d_reclen;
-       char           d_name[];
+       ino64_t            d_ino;        /* 64-bit inode number */
+       off64_t            d_off;        /* 64-bit offset to next structure */
+       unsigned short d_reclen; /* Size of this dirent */
+       unsigned char  d_type;   /* File type */
+       char               d_name[]; /* Filename (null-terminated) */
 };
 
 #define BUF_SIZE 1024
@@ -174,7 +175,6 @@ int ms_read_device_info(const char *root_path, char **device_uuid)
        char buf[BUF_SIZE] = {0,};
        struct linux_dirent *d;
        int bpos = 0;
-       char d_type;
        bool find_uuid = FALSE;
 
        ret = __ms_check_mount_path(root_path);
@@ -205,9 +205,8 @@ int ms_read_device_info(const char *root_path, char **device_uuid)
 
                for (bpos = 0; bpos < nread;) {
                        d = (struct linux_dirent *) (buf + bpos);
-                       d_type = *(buf + bpos + d->d_reclen - 1);
 
-                       if (d_type == DT_REG && (strncmp(d->d_name, DEVICE_INFO_FILE, strlen(DEVICE_INFO_FILE)) == 0)) {
+                       if (d->d_type == DT_REG && (strncmp(d->d_name, DEVICE_INFO_FILE, strlen(DEVICE_INFO_FILE)) == 0)) {
                                MS_DBG_ERR("FIND DEV INFO : %s", d->d_name);
                                bpos += d->d_reclen;
                                find_uuid = TRUE;
diff --git a/src/scanner-v2/include/media-scanner-common-v2.h b/src/scanner-v2/include/media-scanner-common-v2.h
new file mode 100644 (file)
index 0000000..30f6356
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_COMMON_V2_H_
+#define _MEDIA_SCANNER_COMMON_V2_H_
+
+#include "stdbool.h"
+#include "media-common-system.h"
+
+int msc_set_mmc_status(ms_stg_status_e status);
+int msc_get_mmc_status(ms_stg_status_e *status);
+int msc_set_power_status(bool status);
+int msc_get_power_status(bool *status);
+
+#endif /*_MEDIA_SCANNER_COMMON_V2_H_*/
diff --git a/src/scanner-v2/include/media-scanner-dbg-v2.h b/src/scanner-v2/include/media-scanner-dbg-v2.h
new file mode 100755 (executable)
index 0000000..d45d756
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_DBG_V2_H_
+#define _MEDIA_SCANNER_DBG_V2_H_
+#include <sys/syscall.h>
+#include <dlog.h>
+#include <errno.h>
+
+#include "media-common-dbg.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "MEDIA_SCANNER_V2"
+
+#endif /*_MEDIA_SCANNER_DBG_V2_H_*/
+
diff --git a/src/scanner-v2/include/media-scanner-device-block-v2.h b/src/scanner-v2/include/media-scanner-device-block-v2.h
new file mode 100755 (executable)
index 0000000..b70f6d6
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_DEVICE_BLOCK_V2_H_
+#define _MEDIA_SCANNER_DEVICE_BLOCK_V2_H_
+
+#include "media-common-system.h"
+
+void msc_device_block_changed_cb(ms_block_info_s *block_info, void *user_data);
+
+#endif
\ No newline at end of file
diff --git a/src/scanner-v2/include/media-scanner-extract-v2.h b/src/scanner-v2/include/media-scanner-extract-v2.h
new file mode 100755 (executable)
index 0000000..4946e4b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_EXTRACT_V2_H_
+#define _MEDIA_SCANNER_EXTRACT_V2_H_
+
+typedef enum {
+       MS_EXTRACT_STORAGE = 0,
+       MS_EXTRACT_DIRECTORY = 1,
+       MS_EXTRACT_MAX,
+} ms_extract_type_e;
+
+int msc_init_extract_thread();
+int msc_deinit_extract_thread();
+gboolean msc_folder_extract_thread(void *data);
+gboolean msc_storage_extract_thread(void *data);
+void msc_insert_exactor_request(int message_type, bool ins_status, const char *storage_id, const char *path, int pid, uid_t uid);
+int msc_remove_extract_request(const ms_comm_msg_s *recv_msg);
+int msc_set_extract_cancel_path(const char *cancel_path);
+int msc_del_extract_cancel_path(void);
+int msc_set_extract_blocked_path(const char *blocked_path);
+int msc_del_extract_blocked_path(void);
+int msc_push_extract_request(ms_extract_type_e scan_type, ms_comm_msg_s *recv_msg);
+int msc_stop_extract_thread(void);
+int msc_get_remain_extract_request(ms_extract_type_e scan_type, int *remain_request);
+int msc_get_dir_extract_status(bool *extract_status);
+
+#endif /*_MEDIA_SCANNER_EXTRACT_V2_H_*/
diff --git a/src/scanner-v2/include/media-scanner-scan-v2.h b/src/scanner-v2/include/media-scanner-scan-v2.h
new file mode 100755 (executable)
index 0000000..261fb1f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_SCAN_V2_H_
+#define _MEDIA_SCANNER_SCAN_V2_H_
+
+#include "media-common-system.h"
+
+typedef enum {
+       MS_SCAN_STORAGE = 0,
+       MS_SCAN_DIRECTORY = 1,
+       MS_SCAN_REGISTER = 2,
+       MS_SCAN_MAX,
+} ms_scan_type_e;
+
+gboolean msc_directory_scan_thread(void *data);
+gboolean msc_register_thread(void *data);
+gboolean msc_storage_scan_thread(void *data);
+int msc_check_remain_task(void);
+ms_db_status_type_t msc_check_scanning_status(void);
+int msc_set_cancel_path(const char *cancel_path);
+int msc_del_cancel_path(void);
+int msc_init_scan_thread();
+int msc_deinit_scan_thread();
+int msc_set_blocked_path(const char *blocked_path);
+int msc_del_blocked_path(void);
+int msc_init_scanner(void);
+int msc_deinit_scanner(void);
+int msc_set_mmc_status(ms_stg_status_e status);
+int msc_push_scan_request(ms_scan_type_e scan_type, ms_comm_msg_s *recv_msg);
+int msc_stop_scan_thread(void);
+int msc_get_remain_scan_request(ms_scan_type_e scan_type, int *remain_request);
+int msc_get_dir_scan_status(bool *scan_status);
+
+#endif /*_MEDIA_SCANNER_SCAN_V2_H_*/
\ No newline at end of file
diff --git a/src/scanner-v2/include/media-scanner-socket-v2.h b/src/scanner-v2/include/media-scanner-socket-v2.h
new file mode 100755 (executable)
index 0000000..15434bf
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _MEDIA_SCANNER_SOCKET_V2_H_
+#define _MEDIA_SCANNER_SOCKET_V2_H_
+
+#include "media-common-types.h"
+#include "media-server-ipc.h"
+
+gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer data);
+
+int msc_send_ready(void);
+
+int msc_send_result(int result, ms_comm_msg_s *scan_data);
+
+#endif /*_MEDIA_SCANNER_SOCKET_V2_H_*/
diff --git a/src/scanner-v2/media-scanner-common-v2.c b/src/scanner-v2/media-scanner-common-v2.c
new file mode 100644 (file)
index 0000000..b747376
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "media-util-err.h"
+
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-common-v2.h"
+
+int mmc_state2 = 0;
+bool power_off2;
+
+int msc_set_mmc_status(ms_stg_status_e status)
+{
+       mmc_state2 = status;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_get_mmc_status(ms_stg_status_e *status)
+{
+       *status = mmc_state2;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_set_power_status(bool status)
+{
+       power_off2 = status;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_get_power_status(bool *status)
+{
+       *status = power_off2;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
diff --git a/src/scanner-v2/media-scanner-device-block-v2.c b/src/scanner-v2/media-scanner-device-block-v2.c
new file mode 100755 (executable)
index 0000000..9564130
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <vconf.h>
+
+#include "media-util.h"
+
+#include "media-common-utils.h"
+#include "media-common-db-svc.h"
+#include "media-common-external-storage.h"
+
+#include "media-util-err.h"
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-scan-v2.h"
+#include "media-scanner-extract-v2.h"
+#include "media-scanner-device-block-v2.h"
+
+static void __msc_usb_remove_event(const char *mount_path)
+{
+       MS_DBG_ERR("===========================================================");
+       MS_DBG_ERR("USB REMOVED, mountpath : %s", mount_path);
+       MS_DBG_ERR("===========================================================");
+       int update_status  = -1;
+       int remain_request = 0;
+       bool status = FALSE;
+
+       if(!ms_config_get_int(VCONFKEY_FILEMANAGER_DB_STATUS, &update_status)) {
+               MS_DBG_ERR("ms_config_get_int[VCONFKEY_FILEMANAGER_DB_STATUS]");
+       }
+
+       if (msc_get_remain_scan_request(MS_SCAN_STORAGE, &remain_request) == MS_MEDIA_ERR_NONE) {
+               if (!(remain_request == 0 && update_status == VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       msc_set_blocked_path(mount_path);
+               }
+               remain_request = 0;
+       }
+
+
+       if (msc_get_dir_scan_status(&status) == MS_MEDIA_ERR_NONE) {
+               if (status == TRUE) {
+                       MS_DBG_ERR("Doing directory scanning. Set cancel path");
+                       msc_set_cancel_path(mount_path);
+               }
+               status = FALSE;
+       }
+
+       if (msc_get_remain_extract_request(MS_EXTRACT_STORAGE, &remain_request) == MS_MEDIA_ERR_NONE) {
+               if (!(remain_request == 0 && update_status == VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       msc_set_extract_blocked_path(mount_path);
+               }
+               remain_request = 0;
+       }
+
+       if (msc_get_dir_scan_status(&status) == MS_MEDIA_ERR_NONE) {
+               if (status == true) {
+                       MS_DBG_ERR("Doing directory extracting. Set cancel path");
+                       msc_set_extract_cancel_path(mount_path);
+               }
+               status = FALSE;
+       }
+
+       return;
+}
+
+int msc_mmc_remove_handler(const char *mount_path)
+{
+       return MS_MEDIA_ERR_NONE;
+}
+
+void _msc_mmc_changed_event(const char *mount_path, ms_stg_status_e mount_status)
+{
+       /* If scanner is not working, media server executes media scanner and sends request. */
+       /* If scanner is working, it detects changing status of SD card. */
+       if (mount_status == MS_STG_INSERTED) {
+               /*DO NOT THING*/
+       } else if (mount_status == MS_STG_REMOVED) {
+               msc_set_mmc_status(MS_STG_REMOVED);
+               msc_mmc_remove_handler(mount_path);
+       }
+
+       return;
+}
+
+
+void msc_device_block_changed_cb(ms_block_info_s *block_info, void *user_data)
+{
+       if (block_info->block_type == 0) {
+               MS_DBG_ERR("GET THE USB EVENT");
+               if (block_info->state == MS_STG_INSERTED) {
+                       /*DO NOT THING*/
+               } else {
+                       __msc_usb_remove_event(block_info->mount_path);
+               }
+       } else {
+               MS_DBG_ERR("GET THE MMC EVENT");
+               _msc_mmc_changed_event(block_info->mount_path, block_info->state);
+       }
+}
diff --git a/src/scanner-v2/media-scanner-extract-v2.c b/src/scanner-v2/media-scanner-extract-v2.c
new file mode 100755 (executable)
index 0000000..de8ca15
--- /dev/null
@@ -0,0 +1,763 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <dirent.h>     /* Defines DT_* constants */
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <malloc.h>
+#include <pmapi.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-ipc.h"
+#include "media-common-utils.h"
+#include "media-common-db-svc.h"
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-common-v2.h"
+#include "media-scanner-socket-v2.h"
+#include "media-scanner-extract-v2.h"
+
+GAsyncQueue *storage_extract_queue;
+GAsyncQueue *folder_extract_queue;
+GMutex extract_req_mutex;
+GMutex extract_blocked_mutex;
+char *g_extract_cancel_path;
+char *g_extract_blocked_path;
+bool g_directory_extract_processing;
+int stg_extract_status;
+
+GCond extract_data_cond;
+GMutex extract_data_mutex;
+
+
+#ifdef FMS_PERF
+extern struct timeval g_mmc_start_time;
+extern struct timeval g_mmc_end_time;
+#endif
+
+static int __msc_check_extract_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path);
+static int __msc_set_storage_extract_status(ms_storage_scan_status_e status);
+static int __msc_get_storage_extract_status(ms_storage_scan_status_e *status);
+static int __msc_resume_extract();
+static int __msc_pause_extract();
+static int __msc_extract_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type);
+static int __msc_extract_set_power_mode(ms_db_status_type_t status);
+
+int msc_init_extract_thread()
+{
+       if (!storage_extract_queue) storage_extract_queue = g_async_queue_new();
+       if (!folder_extract_queue) folder_extract_queue = g_async_queue_new();
+
+       g_mutex_init(&extract_req_mutex);
+       g_mutex_init(&extract_blocked_mutex);
+       g_mutex_init(&extract_data_mutex);
+
+       g_cond_init(&extract_data_cond);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_deinit_extract_thread()
+{
+       if (storage_extract_queue) g_async_queue_unref(storage_extract_queue);
+       if (folder_extract_queue) g_async_queue_unref(folder_extract_queue);
+
+       g_mutex_clear(&extract_req_mutex);
+       g_mutex_clear(&extract_blocked_mutex);
+       g_mutex_clear(&extract_data_mutex);
+
+       g_cond_clear(&extract_data_cond);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean msc_folder_extract_thread(void *data)
+{
+       ms_comm_msg_s *extract_data = NULL;
+       int err;
+       int ret;
+       void **handle = NULL;
+       int scan_type;
+       int storage_type;
+       char *storage_id = NULL;
+       char *update_path = NULL;
+       bool power_off_status = FALSE;
+
+       while (1) {
+               extract_data = g_async_queue_pop(folder_extract_queue);
+               if (extract_data->pid == POWEROFF) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               MS_DBG_ERR("[No-Error] DIRECTORY EXTRACT START folder_path [%s], scan_type [%d]", extract_data->msg, extract_data->msg_type);
+
+               g_directory_extract_processing = true;
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = ms_connect_db(&handle, extract_data->uid);
+               if (err != MS_MEDIA_ERR_NONE)
+                       continue;
+
+               scan_type = extract_data->msg_type;
+
+               storage_id = strdup(extract_data->storage_id);
+               if (storage_id == NULL) {
+                       MS_DBG_ERR("storage_id NULL");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               MS_DBG("path : [%s], storage_id : [%s]", extract_data->msg, storage_id);
+
+               update_path = strndup(extract_data->msg, extract_data->msg_size);
+
+               if (strlen(storage_id) == 0) {
+                       MS_DBG_ERR("storage_id length is 0. There is no information of your request [%s]", extract_data->msg);
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               if (scan_type != MS_MSG_DIRECTORY_SCANNING
+                       && scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                       MS_DBG_ERR("Invalid request");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               storage_type = ms_get_storage_type_by_full(extract_data->msg, extract_data->uid);
+               ret = __msc_check_extract_stop_status(extract_data->msg_type, storage_type, update_path);
+
+               if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
+                       MS_DBG_ERR("MS_MEDIA_ERR_SCANNER_FORCE_STOP");
+                       goto NEXT;
+               }
+
+               /*insert data into media db */
+               ret = ms_insert_item_pass2(handle, extract_data->storage_id, update_path, scan_type, extract_data->uid);
+               msc_del_extract_cancel_path();
+
+               /*call for bundle commit*/
+               //__msc_bacth_commit_disable(handle, TRUE, TRUE, extract_data->storage_id, ret);
+
+NEXT:
+               msc_get_power_status(&power_off_status);
+               if (power_off_status) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               /*Active flush */
+               malloc_trim(0);
+
+               if (extract_data->result) {
+                       msc_send_result(ret, extract_data);
+               }
+
+               MS_SAFE_FREE(update_path);
+               MS_SAFE_FREE(extract_data);
+               MS_SAFE_FREE(storage_id);
+
+               g_directory_extract_processing = false;
+
+               MS_DBG_ERR("[No-Error] DIRECTORY EXTRACT END [%d]", ret);
+
+               ms_storage_scan_status_e storage_scan_status = MS_STORAGE_SCAN_NONE;
+               ret = __msc_get_storage_extract_status(&storage_scan_status);
+               if (ret == MS_MEDIA_ERR_NONE) {
+                       /*get storage list and scan status from media db*/
+                       if (storage_scan_status != MS_STORAGE_SCAN_COMPLETE) {
+                               __msc_resume_extract();
+                               MS_DBG_ERR("extract RESUME OK");
+                       }
+               }
+
+               /*disconnect form media db*/
+               if (handle) ms_disconnect_db(&handle);
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(update_path);
+       MS_SAFE_FREE(extract_data);
+       MS_SAFE_FREE(storage_id);
+
+       if (handle) ms_disconnect_db(&handle);
+
+       return false;
+}
+
+gboolean msc_storage_extract_thread(void *data)
+{
+       ms_comm_msg_s *extract_data = NULL;
+       int ret;
+       int err;
+       void **handle = NULL;
+       ms_storage_type_t storage_type = MS_STORAGE_INTERNAL;
+       int scan_type;
+       //bool valid_status = TRUE;
+       char *update_path = NULL;
+       //GArray *dir_array = NULL;
+       bool power_off_status = FALSE;
+
+       while (1) {
+               __msc_set_storage_extract_status(MS_STORAGE_SCAN_DONE);
+               extract_data = g_async_queue_pop(storage_extract_queue);
+               if (extract_data->pid == POWEROFF) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_PROCESSING);
+               MS_DBG_ERR("STORAGE extract START ");
+
+               scan_type = extract_data->msg_type;
+               if (scan_type != MS_MSG_STORAGE_ALL
+                       && scan_type != MS_MSG_STORAGE_PARTIAL
+                       && scan_type != MS_MSG_STORAGE_INVALID) {
+                       MS_DBG_ERR("Invalid request[%d]", scan_type);
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = ms_connect_db(&handle, extract_data->uid);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_connect_db falied!");
+                       continue;
+               }
+
+               update_path = strndup(extract_data->msg, extract_data->msg_size);
+               MS_DBG_ERR("extract storage_id is [%s], path [%s]", extract_data->storage_id, update_path);
+
+               ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_PROCESSING, extract_data->uid);
+               storage_type = ms_get_storage_type_by_full(extract_data->msg, extract_data->uid);
+               __msc_extract_set_db_status(MS_DB_UPDATING, storage_type);
+
+               ret = __msc_check_extract_stop_status(extract_data->msg_type, storage_type, update_path);
+               if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
+                       MS_DBG_ERR("MS_MEDIA_ERR_SCANNER_FORCE_STOP");
+                       goto NEXT;
+               }
+
+               /*extract meta*/
+               ret = ms_insert_item_pass2(handle, extract_data->storage_id, update_path, scan_type, extract_data->uid);
+
+               storage_type = ms_get_storage_type_by_full(extract_data->msg, extract_data->uid);
+               //update_path = strndup(extract_data->msg, extract_data->msg_size);
+
+               msc_del_extract_blocked_path();
+
+               MS_DBG_ERR("extract PAUSE");
+               __msc_pause_extract();
+               MS_DBG_ERR("extract RESUME");
+
+               if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
+                       ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_STOP, extract_data->uid);
+                       __msc_set_storage_extract_status(MS_STORAGE_SCAN_META_STOP);
+                       /*set vconf key mmc loading for indicator */
+                       __msc_extract_set_db_status(MS_DB_STOPPED, storage_type);
+               } else if (extract_data->result == TRUE) {
+                       MS_DBG_ERR("extract_data->result == TRUE, MS_STORAGE_SCAN_COMPLETE");
+                       ms_set_storage_scan_status(handle, extract_data->storage_id, MEDIA_EXTRACT_COMPLETE, extract_data->uid);
+                       __msc_set_storage_extract_status(MS_STORAGE_SCAN_COMPLETE);
+                       ms_delete_invalid_items(handle, extract_data->storage_id, storage_type, extract_data->uid);
+                       /*set vconf key mmc loading for indicator */
+                       __msc_extract_set_db_status(MS_DB_UPDATED, storage_type);
+               }
+
+#if 0
+               if (scan_type == MS_MSG_STORAGE_PARTIAL && storage_type == MS_STORAGE_INTERNAL) {
+                       ms_validaty_change_all_items(handle, storage_id, storage_type, true);
+
+                       /* find and compare modified time */
+                       ret = __msc_compare_with_db(handle, storage_id, update_path, scan_data->msg_type, &dir_array);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_WARN("__msc_compare_with_db is falied");
+                               goto NEXT;
+                       }
+
+                       if (dir_array->len != 0) {
+                               MSC_DBG_INFO("DB UPDATING IS NEEDED");
+                               ret = _msc_db_update_partial(handle, storage_id, storage_type, dir_array);
+                       } else {
+                               MSC_DBG_INFO("THERE IS NO UPDATE");
+                       }
+               } else {
+                       if (scan_type == MS_MSG_STORAGE_ALL) {
+                               /*  Delete all data before full scanning */
+                               if (!ms_delete_all_items(handle, storage_id, storage_type)) {
+                                       MS_DBG_ERR("msc_delete_all_record fails");
+                               }
+                       } else if (scan_type == MS_MSG_STORAGE_PARTIAL) {
+                                       ms_validaty_change_all_items(handle, storage_id, storage_type, false);
+                       }
+
+                       ret = __msc_db_update(handle, storage_id, scan_data);
+               }
+
+               /*call for bundle commit*/
+               if (extract_data.msg_type != MS_MSG_STORAGE_INVALID)
+                       __msc_bacth_commit_disable(handle, TRUE, valid_status, scan_data->storage_id, ret);
+
+               if (scan_type == MS_MSG_STORAGE_PARTIAL && ret == MS_MEDIA_ERR_NONE) {
+                       int del_count = 0;
+
+                       /*check delete count*/
+                       MSC_DBG_INFO("update path : %s", update_path);
+
+                       ms_count_delete_items_in_folder(handle, storage_id, update_path, &del_count);
+
+                       /*if there is no delete content, do not call delete API*/
+                       if (del_count != 0) {
+                               MS_DBG_ERR("storage thread delete count [%d]", del_count);
+                               ms_delete_invalid_items(handle, storage_id, storage_type);
+                       }
+               }
+
+               /* send notification */
+               ms_send_dir_update_noti(handle,  storage_id, update_path);
+#endif
+
+NEXT:
+
+               MS_SAFE_FREE(update_path);
+
+               msc_get_power_status(&power_off_status);
+               if (power_off_status) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               /*disconnect form media db*/
+               if (handle) ms_disconnect_db(&handle);
+
+               /*Active flush */
+               malloc_trim(0);
+
+               if(extract_data->result)
+               {
+                       msc_send_result(ret, extract_data);
+               }
+
+               MS_SAFE_FREE(extract_data);
+
+               MS_DBG_ERR("STORAGE EXTRACT END[%d]", ret);
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(extract_data);
+       if (handle) ms_disconnect_db(&handle);
+
+       return false;
+}
+
+void msc_insert_exactor_request(int message_type, bool ins_status, const char *storage_id, const char *path, int pid, uid_t uid)
+{
+       ms_comm_msg_s *extract_data = NULL;
+       MS_MALLOC(extract_data, sizeof(ms_comm_msg_s));
+       if (extract_data == NULL) {
+               MS_DBG_ERR("MS_MALLOC failed");
+               return;
+       }
+
+       extract_data->msg_type = message_type;
+       extract_data->pid = pid;
+       extract_data->uid = uid;
+       extract_data->result = ins_status;
+       extract_data->msg_size = strlen(path);
+       strncpy(extract_data->msg, path, extract_data->msg_size );
+       strncpy(extract_data->storage_id, storage_id, MS_UUID_SIZE-1);
+
+       if (message_type == MS_MSG_STORAGE_ALL || message_type == MS_MSG_STORAGE_PARTIAL || message_type == MS_MSG_STORAGE_INVALID) {
+               g_async_queue_push(storage_extract_queue, GINT_TO_POINTER(extract_data));
+               MS_DBG("insert to storage exactor queue. msg_type [%d]", ins_status);
+       } else if(message_type == MS_MSG_DIRECTORY_SCANNING || message_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+               g_async_queue_push(folder_extract_queue, GINT_TO_POINTER(extract_data));
+               MS_DBG("insert to dir exactor queue. msg_type [%d]", ins_status);
+       } else {
+               MS_DBG_ERR("try to insert to exactor scan with msg_type [%d]", message_type);
+               MS_SAFE_FREE(extract_data);
+       }
+
+       return;
+}
+
+int msc_remove_extract_request(const ms_comm_msg_s *recv_msg)
+{
+       if(recv_msg == NULL) {
+               MS_DBG_ERR("recv_msg is null");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+       const char *storageid = recv_msg->storage_id;
+       int len = g_async_queue_length(storage_extract_queue);
+       ms_comm_msg_s *msg = NULL;
+       GAsyncQueue *temp_queue = NULL;
+
+       MS_DBG_WARN("exactor_req_mutex is LOCKED");
+       g_mutex_lock(&extract_req_mutex);
+
+       if (len == 0) {
+               MS_DBG_ERR("Request is not stacked");
+               goto END_REMOVE_REQUEST;
+       }
+
+       temp_queue = g_async_queue_new();
+       int i = 0;
+       for (; i <len; i++) {
+               /*create new queue to compare request*/
+               msg = g_async_queue_pop(storage_extract_queue);
+               if ((strcmp(msg->storage_id, storageid) == 0)) {
+                       MS_SAFE_FREE(msg);
+               } else {
+                       g_async_queue_push(temp_queue, GINT_TO_POINTER(msg));
+               }
+       }
+       g_async_queue_unref (storage_extract_queue);
+       storage_extract_queue = temp_queue;
+
+END_REMOVE_REQUEST:
+       g_mutex_unlock(&extract_req_mutex);
+       MS_DBG_WARN("exactor_req_mutex is UNLOCKED");
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_set_extract_cancel_path(const char *cancel_path)
+{
+       if (g_extract_cancel_path != NULL) {
+               MS_DBG_WARN("g_extract_cancel_path is not NULL");
+               free(g_extract_cancel_path);
+               g_extract_cancel_path = NULL;
+       }
+
+       g_extract_cancel_path = strdup(cancel_path);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_del_extract_cancel_path(void)
+{
+       if (g_extract_cancel_path != NULL) {
+               MS_DBG_WARN("g_extract_cancel_path is not NULL");
+               free(g_extract_cancel_path);
+               g_extract_cancel_path = NULL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_set_extract_blocked_path(const char *blocked_path)
+{
+       MS_DBG_FENTER();
+
+       g_mutex_lock(&extract_blocked_mutex);
+
+       if (g_extract_blocked_path != NULL) {
+               MS_DBG_ERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
+               free(g_extract_blocked_path);
+               g_extract_blocked_path = NULL;
+       }
+
+       g_extract_blocked_path = strdup(blocked_path);
+
+       g_mutex_unlock(&extract_blocked_mutex);
+
+       MS_DBG_FLEAVE();
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_del_extract_blocked_path(void)
+{
+       MS_DBG_FENTER();
+
+       g_mutex_lock(&extract_blocked_mutex);
+
+       if (g_extract_blocked_path != NULL) {
+               MS_DBG_ERR("g_extract_blocked_path is not NULL [%s]", g_extract_blocked_path);
+               free(g_extract_blocked_path);
+               g_extract_blocked_path = NULL;
+       }
+
+       g_mutex_unlock(&extract_blocked_mutex);
+
+       MS_DBG_FLEAVE();
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_check_extract_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       bool power_off_status = FALSE;
+
+       /*check poweroff status*/
+       msc_get_power_status(&power_off_status);
+       if (power_off_status) {
+               MS_DBG_ERR("Power off");
+               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+       }
+
+       if (scan_type == MS_MSG_DIRECTORY_SCANNING || scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+               g_mutex_lock(&extract_req_mutex);
+               /* check cancel path */
+               if (g_extract_cancel_path != NULL) {
+                       MS_DBG_ERR("check cancel storage [%s][%s]", g_extract_cancel_path, start_path);
+                       if (strncmp(g_extract_cancel_path, start_path, strlen(g_extract_cancel_path)) == 0) {
+                               MS_DBG_ERR("Receive cancel request [%s][%s]. STOP extract!!", g_extract_cancel_path, start_path);
+                               unsigned int path_len = strlen(g_extract_cancel_path);
+
+                               if (strlen(start_path) > path_len) {
+                                       if (start_path[path_len] == '/') {
+                                               MS_DBG_ERR("start path is same as cancel path");
+                                               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                                       } else {
+                                               MS_DBG_ERR("start path is not same as cancel path");
+                                       }
+                               } else {
+                                       ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                               }
+                       }
+
+                       MS_SAFE_FREE(g_extract_cancel_path);
+               }
+
+               g_mutex_unlock(&extract_req_mutex);
+       }
+
+       if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
+               if (g_directory_extract_processing == true) {
+                       MS_DBG_ERR("Now directory extract is start. So, storage extract is stopped.");
+                       __msc_pause_extract();
+                       MS_DBG_ERR("Now directory extract is end. So, storage extract is resumed.");
+               }
+
+               g_mutex_lock(&extract_blocked_mutex);
+               /* check block path */
+               if (g_extract_blocked_path != NULL) {
+                       MS_DBG_ERR("check blocked storage [%s][%s]", g_extract_blocked_path, start_path);
+                       if (strncmp(start_path, g_extract_blocked_path, strlen(start_path)) == 0) {
+                               MS_DBG_ERR("Receive blocked message[%s][%s]. STOP extract!!", g_extract_blocked_path, start_path);
+                               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                       }
+
+                       MS_SAFE_FREE(g_extract_blocked_path);
+               }
+
+               g_mutex_unlock(&extract_blocked_mutex);
+       }
+
+       return ret;
+}
+
+static int __msc_set_storage_extract_status(ms_storage_scan_status_e status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+
+       stg_extract_status = status;
+
+       return res;
+}
+
+static int __msc_get_storage_extract_status(ms_storage_scan_status_e *status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+
+       *status = stg_extract_status;
+
+       return res;
+}
+
+static int __msc_resume_extract()
+{
+       g_mutex_lock (&extract_data_mutex);
+
+       g_cond_signal (&extract_data_cond);
+
+       g_mutex_unlock (&extract_data_mutex);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_pause_extract()
+{
+       g_mutex_lock (&extract_data_mutex);
+
+       while (g_directory_extract_processing)
+               g_cond_wait (&extract_data_cond, &extract_data_mutex);
+
+       g_mutex_unlock (&extract_data_mutex);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_extract_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int err = 0;
+
+       if (status == MS_DB_UPDATING) {
+               if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       } else if (status == MS_DB_UPDATED) {
+               if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS,  VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       } else {
+               if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS,  VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       }
+
+       err = __msc_extract_set_power_mode(status);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("__msc_tv_set_power_mode fail");
+               res = err;
+       }
+
+       return res;
+}
+
+static int __msc_extract_set_power_mode(ms_db_status_type_t status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int err;
+
+       switch (status) {
+       case MS_DB_UPDATING:
+               err = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+               if (err != 0)
+                       res = MS_MEDIA_ERR_INTERNAL;
+               break;
+       case MS_DB_UPDATED:
+               err = pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
+               if (err != 0)
+                       res = MS_MEDIA_ERR_INTERNAL;
+               break;
+       default:
+               MS_DBG_ERR("Unacceptable type : %d", status);
+               break;
+       }
+
+       return res;
+}
+
+int msc_push_extract_request(ms_extract_type_e scan_type, ms_comm_msg_s *recv_msg)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       switch(scan_type) {
+               case MS_EXTRACT_STORAGE:
+                       g_async_queue_push(storage_extract_queue, GINT_TO_POINTER(recv_msg));
+                       break;
+               case MS_EXTRACT_DIRECTORY:
+                       g_async_queue_push(folder_extract_queue, GINT_TO_POINTER(recv_msg));
+                       break;
+               default:
+                       MS_DBG_ERR("invalid parameter");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       break;
+       }
+
+       return ret;
+}
+
+int msc_stop_extract_thread(void)
+{
+       ms_comm_msg_s *data = NULL;
+
+       if (storage_extract_queue) {
+               /*notify to register thread*/
+               MS_MALLOC(data, sizeof(ms_comm_msg_s));
+               data->pid = POWEROFF;
+               msc_push_extract_request(MS_EXTRACT_STORAGE, data);
+       }
+
+       if (folder_extract_queue) {
+               /*notify to register thread*/
+               MS_MALLOC(data, sizeof(ms_comm_msg_s));
+               data->pid = POWEROFF;
+               msc_push_extract_request(MS_EXTRACT_DIRECTORY, data);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_get_remain_extract_request(ms_extract_type_e scan_type, int *remain_request)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       switch(scan_type) {
+               case MS_EXTRACT_STORAGE:
+                       *remain_request = g_async_queue_length(storage_extract_queue);
+                       break;
+               case MS_EXTRACT_DIRECTORY:
+                       *remain_request = g_async_queue_length(folder_extract_queue);
+                       break;
+               default:
+                       MS_DBG_ERR("invalid parameter");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       break;
+       }
+
+       return ret;
+}
+
+int msc_get_dir_extract_status(bool *extract_status)
+{
+       *extract_status = g_directory_extract_processing;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
diff --git a/src/scanner-v2/media-scanner-scan-v2.c b/src/scanner-v2/media-scanner-scan-v2.c
new file mode 100755 (executable)
index 0000000..82f986f
--- /dev/null
@@ -0,0 +1,1773 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <dirent.h>     /* Defines DT_* constants */
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <malloc.h>
+#include <pmapi.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-ipc.h"
+#include "media-common-utils.h"
+#include "media-common-external-storage.h"
+#include "media-common-db-svc.h"
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-common-v2.h"
+#include "media-scanner-socket-v2.h"
+#include "media-scanner-scan-v2.h"
+#include "media-scanner-extract-v2.h"
+#define MAX_SCAN_COUNT 300
+
+GAsyncQueue *storage_queue2;
+GAsyncQueue *scan_queue2;
+GAsyncQueue *reg_queue2;
+GMutex scan_req_mutex2;
+GMutex blocked_mutex2;
+char *g_cancel_path2;
+char *g_blocked_path2;
+bool g_directory_scan_processing2;
+
+int stg_scan_status2;
+
+#ifdef FMS_PERF
+extern struct timeval g_mmc_start_time;
+extern struct timeval g_mmc_end_time;
+#endif
+
+static int __msc_set_power_mode(ms_db_status_type_t status);
+static int __msc_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type);
+static int __msc_check_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path);
+static int __msc_db_update(void **handle, const char *storage_id, const ms_comm_msg_s * scan_data);
+static int __msc_check_file_path(const char *file_path, uid_t uid);
+static int __msc_make_file_list(char *file_path, GArray **path_array, uid_t uid);
+static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array, uid_t uid);
+static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data);
+static int __msc_clear_file_list(GArray *path_array);
+static int __msc_check_scan_ignore(char * path);
+static bool __msc_is_valid_path(const char *path, uid_t uid);
+static void __msc_check_dir_path(char *dir_path);
+static void __msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data);
+static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid);
+static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status, const char *path, int result, uid_t uid);
+static int __msc_set_storage_scan_status(ms_storage_scan_status_e status);
+static int __msc_get_storage_scan_status(ms_storage_scan_status_e *status);
+static int __msc_dir_scan(void **handle, const char *storage_id, const char*start_path, ms_storage_type_t storage_type, int scan_type, uid_t uid);
+static bool __msc_storage_mount_status(const char* start_path);
+static char* __msc_get_path(uid_t uid);
+
+static char* __msc_get_path(uid_t uid)
+{
+       int result_size = 0;
+       char *result_psswd = NULL;
+       struct group *grpinfo = NULL;
+       if (uid == getuid()) {
+               result_psswd = strndup(MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL));
+               grpinfo = getgrnam("users");
+               if(grpinfo == NULL) {
+                       MS_DBG_ERR("getgrnam(users) returns NULL !");
+                       return NULL;
+               }
+       } else {
+               struct passwd *userinfo = getpwuid(uid);
+               if (userinfo == NULL) {
+                       MS_DBG_ERR("getpwuid(%d) returns NULL !", uid);
+                       return NULL;
+               }
+               grpinfo = getgrnam("users");
+               if (grpinfo == NULL) {
+                       MS_DBG_ERR("getgrnam(users) returns NULL !");
+                       return NULL;
+               }
+               // Compare git_t type and not group name
+               if (grpinfo->gr_gid != userinfo->pw_gid) {
+                       MS_DBG_ERR("UID [%d] does not belong to 'users' group!", uid);
+                       return NULL;
+               }
+               result_size = strlen(userinfo->pw_dir) + strlen(MEDIA_CONTENT_PATH) + 2;
+
+               MS_MALLOC(result_psswd, result_size);
+               snprintf(result_psswd, result_size, "%s/%s", userinfo->pw_dir, MEDIA_CONTENT_PATH);
+       }
+
+       return result_psswd;
+}
+
+static int __msc_set_power_mode(ms_db_status_type_t status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int err;
+
+       switch (status) {
+       case MS_DB_UPDATING:
+               err = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+               if (err != 0)
+                       res = MS_MEDIA_ERR_INTERNAL;
+               break;
+       case MS_DB_UPDATED:
+               err = pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
+               if (err != 0)
+                       res = MS_MEDIA_ERR_INTERNAL;
+               break;
+       default:
+               MS_DBG_ERR("Unacceptable type : %d", status);
+               break;
+       }
+
+       return res;
+}
+
+static int __msc_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int err = 0;
+
+       if (status == MS_DB_UPDATING) {
+               if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       } else if (status == MS_DB_UPDATED) {
+               if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS,  VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       } else {
+               if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS,  VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                       res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                       MS_DBG_ERR("ms_config_set_int failed");
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+       }
+
+       err = __msc_set_power_mode(status);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("__msc_tv_set_power_mode fail");
+               res = err;
+       }
+
+       return res;
+}
+
+static int __msc_check_scan_ignore(char * path)
+{
+       int fd = -1;
+       int exist = -1;
+       const char *ignore_path = "/.scan_ignore";
+       char *check_ignore_file = NULL;
+       int ret = MS_MEDIA_ERR_NONE;
+
+       if(strstr(path, "/."))
+       {
+               MS_DBG_ERR("hidden path");
+               ret = MS_MEDIA_ERR_INVALID_PATH;
+               goto ERROR;
+       }
+
+       fd = open(path, O_RDONLY | O_DIRECTORY);
+       if (fd == -1) {
+               MS_DBG_ERR("%s folder opendir fails", path);
+               ret = MS_MEDIA_ERR_INVALID_PATH;
+
+               if (strstr(path, MEDIA_ROOT_PATH_USB) != NULL) {
+                       if (errno == ENOENT) {
+                               /*if the directory does not exist, check the device is unmounted*/
+                               if(!__msc_storage_mount_status(path)) {
+                                       MS_DBG_ERR("Device is unmounted[%s]", path);
+                                       ret = MS_MEDIA_ERR_USB_UNMOUNTED;
+                                       goto ERROR;
+                               }
+                       }
+               }
+
+               struct stat folder_st;
+               if(stat(path, &folder_st) == 0) {
+                       MS_DBG_ERR("DEV[%ld] INODE[%lld] UID[%ld] GID[%ld] MODE[%lo] PATH[%s]", (long)folder_st.st_dev, (long long)folder_st.st_ino,
+                               (long)folder_st.st_uid, (long)folder_st.st_gid, (unsigned long) folder_st.st_mode, path);
+               } else {
+                       MS_DBG_ERR("%s folder stat fails", path);
+               }
+
+               goto ERROR;
+       } else {
+               /* check the file exits actually */
+               int path_len = 0;
+
+               path_len = strlen(path) + strlen(ignore_path) + 1;
+               check_ignore_file = malloc(path_len);
+               if(check_ignore_file != NULL) {
+                       memset(check_ignore_file, 0x0, path_len);
+                       snprintf(check_ignore_file, path_len, "%s%s", path, ignore_path);
+
+                       exist = open(check_ignore_file, O_RDONLY);
+                       if(exist >=  0) {
+                               MS_DBG_ERR("scan_ignore exists [%s]", check_ignore_file);
+                               ret = MS_MEDIA_ERR_INVALID_PATH;
+                       }
+
+                       MS_SAFE_FREE(check_ignore_file);
+               } else {
+                       MS_DBG_ERR("malloc failed");
+                       ret = MS_MEDIA_ERR_OUT_OF_MEMORY;
+               }
+       }
+
+ERROR:
+
+       if(fd != -1) {
+               close(fd);
+               fd = -1;
+       }
+
+       if (exist >= 0) close(exist);
+
+       return ret;
+}
+
+GCond data_cond2;   /* Must be initialized somewhere */
+GMutex data_mutex2; /* Must be initialized somewhere */
+gpointer current_data2 = NULL;
+
+int msc_init_scan_thread()
+{
+       g_mutex_init(&data_mutex2);
+       g_mutex_init(&blocked_mutex2);
+
+       g_cond_init(&data_cond2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_deinit_scan_thread()
+{
+       g_mutex_clear(&data_mutex2);
+       g_mutex_clear(&blocked_mutex2);
+
+       g_cond_clear(&data_cond2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_resume_scan()
+{
+       g_mutex_lock (&data_mutex2);
+
+       g_cond_signal (&data_cond2);
+
+       g_mutex_unlock (&data_mutex2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+static int __msc_pause_scan()
+{
+       g_mutex_lock (&data_mutex2);
+
+       while (g_directory_scan_processing2)
+               g_cond_wait (&data_cond2, &data_mutex2);
+
+       g_mutex_unlock (&data_mutex2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+
+static int __msc_check_stop_status(int scan_type, ms_storage_type_t storage_type, const char *start_path)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       bool power_off_status = FALSE;
+
+       /*check poweroff status*/
+       msc_get_power_status(&power_off_status);
+       if (power_off_status) {
+               MS_DBG_ERR("Power off");
+               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+       }
+
+       if (scan_type == MS_MSG_DIRECTORY_SCANNING ||scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+               g_mutex_lock(&scan_req_mutex2);
+               /* check cancel path */
+               if (g_cancel_path2 != NULL) {
+                       MS_DBG_ERR("check blocked storage [%s][%s]", g_cancel_path2, start_path);
+                       if (strncmp(g_cancel_path2, start_path, strlen(g_cancel_path2)) == 0) {
+                               MS_DBG_ERR("Receive cancel request [%s][%s]. STOP scan!!",
+                               g_cancel_path2, start_path);
+                               unsigned int path_len = strlen(g_cancel_path2);
+
+                               if (strlen(start_path) > path_len) {
+                                       if (start_path[path_len] == '/') {
+                                               MS_DBG_ERR("start path is same as cancel path");
+                                               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                                       } else {
+                                               MS_DBG_ERR("start path is not same as cancel path");
+                                       }
+                               } else {
+                                       ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                               }
+                       }
+
+                       MS_SAFE_FREE(g_cancel_path2);
+               }
+
+               g_mutex_unlock(&scan_req_mutex2);
+       }
+
+       if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
+               if (g_directory_scan_processing2 == true) {
+                       MS_DBG_ERR("Now directory scanning is start. So, storage scannig is stopped.");
+                       __msc_pause_scan();
+                       MS_DBG_ERR("Now directory scanning is end. So, storage scannig is resumed.");
+               }
+
+               g_mutex_lock(&blocked_mutex2);
+               /* check cancel path */
+               if (g_blocked_path2!= NULL) {
+                       MS_DBG_ERR("check blocked storage [%s][%s]", g_blocked_path2, start_path);
+                       if (strncmp(start_path, g_blocked_path2, strlen(start_path)) == 0) {
+                               MS_DBG_ERR("Receive blocked message[%s][%s]. STOP scan!!",
+                               g_blocked_path2, start_path);
+                               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+                       }
+
+                       MS_SAFE_FREE(g_blocked_path2);
+               }
+
+               g_mutex_unlock(&blocked_mutex2);
+       }
+
+       return ret;
+}
+
+static void __msc_check_dir_path(char *dir_path)
+{
+       /* need implementation */
+       /* if dir_path is not NULL terminated, this function will occure crash */
+       int len = strlen(dir_path);
+
+       if (dir_path[len -1] == '/')
+               dir_path[len -1] = '\0';
+}
+
+struct linux_dirent {
+       ino64_t            d_ino;        /* 64-bit inode number */
+       off64_t            d_off;        /* 64-bit offset to next structure */
+       unsigned short d_reclen; /* Size of this dirent */
+       unsigned char  d_type;   /* File type */
+       char               d_name[]; /* Filename (null-terminated) */
+};
+
+#define BUF_SIZE 1024
+
+static int __msc_dir_scan(void **handle, const char *storage_id, const char*start_path, ms_storage_type_t storage_type, int scan_type, uid_t uid)
+{
+       GArray *dir_array = NULL;
+       int ret = MS_MEDIA_ERR_NONE;
+       char *new_path = NULL;
+       char *current_path = NULL;
+       char path[MS_FILE_PATH_LEN_MAX] = {0, };
+       int (*scan_function)(void **, const char*, const char*, uid_t) = NULL;
+       bool is_recursive = true;
+       char *new_start_path = NULL;
+
+       int fd = -1;
+       int nread = 0;
+       char buf[BUF_SIZE] = {0, };
+       struct linux_dirent *d;
+       int bpos = 0;
+       int scan_count = 0;
+
+       const char *trash = "$RECYCLE.BIN";
+
+       MS_DBG_ERR("storage id [%s] start path [%s]", storage_id, start_path);
+
+       /* make new array for storing directory */
+       dir_array = g_array_new (FALSE, FALSE, sizeof (char*));
+
+       if (dir_array == NULL) {
+               MS_DBG_ERR("g_array_new failed");
+               return MS_MEDIA_ERR_OUT_OF_MEMORY;
+       }
+       /* add first direcotiry to directory array */
+       new_start_path = strdup(start_path);
+       if (new_start_path == NULL){
+               MS_DBG_ERR("strdup failed");
+               g_array_free(dir_array, FALSE);
+               return MS_MEDIA_ERR_OUT_OF_MEMORY;
+       }
+
+       MS_DBG_ERR("new start path [%s]", new_start_path);
+       g_array_append_val (dir_array, start_path);
+       if(ms_insert_folder(handle, storage_id, new_start_path, uid) != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("insert folder failed");
+       }
+
+       scan_function = (scan_type == MS_MSG_STORAGE_ALL) ? ms_scan_item_batch : ms_scan_validate_item;
+       is_recursive = (scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) ? false : true;
+
+       /* folder validity set 0 under the start_path in folder table*/
+       if (scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE || scan_type == MS_MSG_DIRECTORY_SCANNING) {
+               if(ms_set_folder_validity(handle, storage_id, new_start_path, MS_INVALID, is_recursive, uid) != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("set_folder_validity failed [%d] ", scan_type);
+               }
+       }
+
+       /*start db update. the number of element in the array , db update is complete.*/
+       while (dir_array->len != 0) {
+               /*check poweroff status*/
+               ret = __msc_check_stop_status(scan_type, storage_type, new_start_path);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       goto STOP_SCAN;
+               }
+               /* get the current path from directory array */
+               current_path = g_array_index(dir_array , char*, 0);
+               g_array_remove_index (dir_array, 0);
+
+               ret = __msc_check_scan_ignore(current_path);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("%s is ignore", current_path);
+                       MS_SAFE_FREE(current_path);
+                       if (ret == MS_MEDIA_ERR_USB_UNMOUNTED) {
+                               goto STOP_SCAN;
+                       } else {
+                               ret = MS_MEDIA_ERR_NONE;
+                       }
+
+                       continue;
+               }
+
+               ms_insert_folder_start(handle);
+
+               fd = open(current_path, O_RDONLY | O_DIRECTORY);
+               if (fd == -1) {
+                       MS_DBG_STRERROR("open fails");
+                       continue;
+               }
+
+               for ( ; ; ) {
+                       nread = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
+
+                       if (nread == -1) {
+                               MS_DBG_STRERROR("getdents");
+                               break;
+                       }
+
+                       /*check poweroff status*/
+                       ret = __msc_check_stop_status(scan_type, storage_type, new_start_path);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               goto STOP_SCAN;
+                       }
+
+                       if (nread == 0)
+                               break;
+
+                       for (bpos = 0; bpos < nread;) {
+                               /*check poweroff status*/
+                               ret = __msc_check_stop_status(scan_type, storage_type, new_start_path);
+                               if (ret != MS_MEDIA_ERR_NONE) {
+                                       goto STOP_SCAN;
+                               }
+
+                               d = (struct linux_dirent *) (buf + bpos);
+
+                               if (d->d_name[0] == '.') {
+                                       bpos += d->d_reclen;
+                                       continue;
+                               }
+
+                               if (strcmp(d->d_name, trash) == 0) {
+                                       MS_DBG_ERR("trash directory");
+                                       bpos += d->d_reclen;
+                                       continue;
+                               }
+
+                               if (ms_strappend(path, sizeof(path), "%s/%s", current_path, d->d_name) != MS_MEDIA_ERR_NONE) {
+                                       MS_DBG_ERR("ms_strappend failed");
+                                       bpos += d->d_reclen;
+                                       continue;
+                               }
+
+                               if (d->d_type == DT_REG) {
+                                       MS_DBG_ERR("INSERT DT_REG");
+                                       /* insert into media DB */
+                                       if (scan_function(handle,storage_id, path, uid) != MS_MEDIA_ERR_NONE) {
+                                               MS_DBG_ERR("failed to update db : %d\n", scan_type);
+                                               bpos += d->d_reclen;
+                                               continue;
+                                       }
+                                       else {
+                                               ++scan_count;
+                                               //MSC_DBG_ERR("insert count %d", nScanCount);
+                                               if(scan_count/MAX_SCAN_COUNT>0) {
+                                                       scan_count = 0;
+                                                       MS_DBG_ERR("storage_id = [%s]", storage_id);
+                                                       msc_insert_exactor_request(scan_type, FALSE, storage_id, current_path, 0, uid);
+                                               }
+                                       }
+                               } else if (d->d_type == DT_DIR) {
+                                       MS_DBG_ERR("INSERT DT_DIR");
+                                       if  (scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                                               /* this request is recursive scanning */
+                                               /* add new directory to dir_array */
+                                               new_path = strdup(path);
+                                               g_array_append_val (dir_array, new_path);
+
+                                               if(ms_insert_folder(handle, storage_id, new_path, uid) != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("insert folder failed");
+                                               }
+                                       } else {
+                                               /* this request is non-recursive scanning */
+                                               /* don't add new directory to dir_array */
+                                               if(ms_insert_folder(handle, storage_id, path, uid) != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("insert folder failed");
+                                                       bpos += d->d_reclen;
+                                                       continue;
+                                               }
+                                       }
+                               }
+
+                               bpos += d->d_reclen;
+                       }
+               }
+
+               ms_insert_folder_end(handle, uid);
+//             msc_insert_exactor_request(scan_type, FALSE, storage_id, current_path, 0);
+//             scan_count = 0;
+
+               if(fd != -1) {
+                       close(fd);
+                       fd = -1;
+               }
+
+               MS_SAFE_FREE(current_path);
+       }
+
+       /*remove invalid folder in folder table.*/
+       if (scan_type == MS_MSG_STORAGE_ALL || scan_type == MS_MSG_STORAGE_PARTIAL) {
+               if (__msc_storage_mount_status(new_start_path)) {
+                       if(ms_delete_invalid_folder(handle, storage_id, uid) != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_ERR("delete invalid folder failed");
+                               ret =  MS_MEDIA_ERR_DB_DELETE_FAIL;
+                       }
+               } else {
+                       MS_DBG_ERR("start path is unmounted");
+               }
+       }
+STOP_SCAN:
+       if(fd != -1) {
+               close(fd);
+               fd = -1;
+       }
+
+       MS_SAFE_FREE(new_start_path);
+
+       __msc_clear_file_list(dir_array);
+
+       if (ret != MS_MEDIA_ERR_NONE) MS_DBG_INFO("ret : %d", ret);
+
+       return ret;
+}
+
+static int __msc_db_update(void **handle, const char *storage_id, const ms_comm_msg_s * scan_data)
+{
+       int scan_type;
+       int err = MS_MEDIA_ERR_NONE;
+       char *start_path = NULL;
+       ms_storage_type_t storage_type;
+
+       storage_type = ms_get_storage_type_by_full(scan_data->msg, scan_data->uid);
+       scan_type = scan_data->msg_type;
+
+       /*if scan type is not MS_SCAN_NONE, check data in db. */
+       if (scan_type != MS_MSG_STORAGE_INVALID) {
+               MS_DBG_ERR("INSERT");
+               start_path = strndup(scan_data->msg, scan_data->msg_size);
+               scan_type = scan_data->msg_type;
+
+               err = __msc_dir_scan(handle, storage_id, start_path, storage_type, scan_type, scan_data->uid);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("error : %d", err);
+               }
+       } else if ( scan_type == MS_MSG_STORAGE_INVALID) {
+               MS_DBG_ERR("INVALID");
+               /*In this case, update just validation record*/
+               /*update just valid type*/
+               err = ms_validaty_change_all_items(handle, storage_id, storage_type, false, scan_data->uid);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("error : %d", err);
+               }
+
+               /* folder validity set 0 under the start_path in folder table*/
+               if(ms_set_folder_validity(handle, storage_id, scan_data->msg, MS_INVALID, TRUE, scan_data->uid) != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("set_folder_validity failed");
+               }
+               msc_remove_extract_request(scan_data);
+       }
+
+       sync();
+
+       return err;
+}
+static int __msc_pop_new_request(ms_comm_msg_s **scan_data)
+{
+       *scan_data = g_async_queue_pop(scan_queue2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean msc_directory_scan_thread(void *data)
+{
+       ms_comm_msg_s *scan_data = NULL;
+       int err;
+       int ret;
+       void **handle = NULL;
+       int scan_type;
+       char *noti_path = NULL;
+       char *storage_id = NULL;
+       bool power_off_status = FALSE;
+
+       while (1) {
+               __msc_pop_new_request(&scan_data);
+
+               if (scan_data->pid == POWEROFF) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               MS_DBG_ERR("DIRECTORY SCAN START [%s, %d]", scan_data->msg, scan_data->msg_type);
+
+               g_directory_scan_processing2 = true;
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = ms_connect_db(&handle, scan_data->uid);
+               if (err != MS_MEDIA_ERR_NONE)
+                       continue;
+
+               scan_type = scan_data->msg_type;
+
+               storage_id = strdup(scan_data->storage_id);
+               if (storage_id == NULL) {
+                       MS_DBG_ERR("storage_id NULL");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               MS_DBG("path [%s], storage_id [%s], scan_type [%d]", scan_data->msg, storage_id, scan_type);
+
+               if (strlen(storage_id) == 0) {
+                       MS_DBG_ERR("storage_id length is 0. There is no information of your request [%s]", scan_data->msg);
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               if (scan_type != MS_MSG_DIRECTORY_SCANNING
+                       && scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                       MS_DBG_ERR("Invalid request");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               __msc_check_dir_path(scan_data->msg);
+
+               /*change validity before scanning*/
+               if (scan_type == MS_MSG_DIRECTORY_SCANNING) {
+                       err = ms_set_folder_item_validity(handle, storage_id, scan_data->msg, MS_INVALID, MS_RECURSIVE, scan_data->uid);
+               } else {
+
+                       err = ms_set_folder_item_validity(handle, storage_id, scan_data->msg, MS_INVALID, MS_NON_RECURSIVE, scan_data->uid);
+               }
+
+               if (err != MS_MEDIA_ERR_NONE)
+                       MS_DBG_ERR("error : %d", err);
+
+               /*call for bundle commit*/
+               __msc_bacth_commit_enable(handle, TRUE, TRUE, MS_NOTI_SWITCH_OFF, 0);
+
+               /*insert data into media db */
+               ret = __msc_db_update(handle, storage_id, scan_data);
+               msc_del_cancel_path();
+
+               /*call for bundle commit*/
+               __msc_bacth_commit_disable(handle, TRUE, TRUE, scan_data->msg, ret, scan_data->uid);
+
+               MS_DBG_ERR("storage_id = [%s], scan_data->storage_id = [%s]", storage_id, scan_data->storage_id);
+               msc_insert_exactor_request(scan_type, TRUE, scan_data->storage_id, scan_data->msg, scan_data->pid, scan_data->uid);
+
+               if (ret == MS_MEDIA_ERR_NONE) {
+                       MS_DBG_INFO("working normally");
+                       int count = 0;
+                       bool is_recursive = true;
+                       int insert_count = ms_get_insert_count();
+
+                       noti_path = strndup(scan_data->msg, scan_data->msg_size);
+
+                       ms_count_delete_items_in_folder(handle, storage_id, noti_path, &count);
+
+                       MS_DBG_ERR("delete count %d", count);
+                       MS_DBG_ERR("insert count %d", insert_count);
+
+                       if (scan_type == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE)
+                               is_recursive = false;
+
+                       ms_delete_invalid_items_in_folder(handle, storage_id, scan_data->msg, is_recursive, scan_data->uid);
+
+                       if ( !(count == 0 && insert_count == 0)) {
+                               ms_send_dir_update_noti(handle, storage_id, noti_path, NULL, MS_ITEM_UPDATE, scan_data->pid);
+                       }
+                       MS_SAFE_FREE(noti_path);
+               }
+
+               ms_reset_insert_count();
+
+               msc_get_power_status(&power_off_status);
+               if (power_off_status) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+NEXT:
+               /*Active flush */
+               malloc_trim(0);
+
+//             msc_send_result(ret, scan_data);
+
+               MS_SAFE_FREE(scan_data);
+               MS_SAFE_FREE(storage_id);
+
+               g_directory_scan_processing2 = false;
+
+               MS_DBG_ERR("DIRECTORY SCAN END [%d]", ret);
+
+               ms_storage_scan_status_e storage_scan_status = MS_STORAGE_SCAN_NONE;
+               ret = __msc_get_storage_scan_status(&storage_scan_status);
+               if (ret == MS_MEDIA_ERR_NONE) {
+                       /*get storage list and scan status from media db*/
+                       if (storage_scan_status != MS_STORAGE_SCAN_DONE) {
+                               __msc_resume_scan();
+                               MS_DBG_ERR("RESUME OK");
+                       }
+               }
+
+               /*disconnect form media db*/
+               if (handle) ms_disconnect_db(&handle);
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(scan_data);
+       if (handle) ms_disconnect_db(&handle);
+
+       return false;
+}
+
+/* this thread process only the request of media-server */
+static int _check_folder_from_list(char *folder_path, GArray *dir_array)
+{
+       int i;
+       int array_len = dir_array->len;
+       ms_dir_info_s* dir_info = NULL;
+       struct stat buf;
+       time_t mtime;
+       bool find_flag = false;
+
+       if(stat(folder_path, &buf) == 0) {
+               mtime = buf.st_mtime;
+       } else {
+               return MS_MEDIA_ERR_INTERNAL;
+       }
+
+       for (i = 0; i < array_len; i++) {
+               dir_info = g_array_index (dir_array, ms_dir_info_s*, i);
+               if (strcmp(folder_path, dir_info->dir_path) == 0) {
+                       /* if modified time is same, the folder does not need updating */
+                       if (mtime == dir_info->modified_time) {
+                               g_array_remove_index (dir_array, i);
+                               MS_SAFE_FREE(dir_info->dir_path);
+                               MS_SAFE_FREE(dir_info);
+                       }
+                       find_flag = true;
+                       break;
+               }
+       }
+
+       /* this folder does not exist in media DB, so this folder has to insert to DB */
+       if (find_flag == false) {
+               dir_info = NULL;
+               dir_info = malloc(sizeof(ms_dir_info_s));
+               if (dir_info == NULL) {
+                       MS_DBG_ERR("MALLOC failed");
+                       return MS_MEDIA_ERR_OUT_OF_MEMORY;
+               }
+               dir_info->dir_path = strdup(folder_path);
+               dir_info->modified_time = -1;
+               g_array_append_val(dir_array, dir_info);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_compare_with_db(void **handle, const char *storage_id, const char*update_path, int scan_type, GArray **dir_array)
+{
+       DIR *dp = NULL;
+       GArray *read_dir_array = NULL;
+       struct dirent entry;
+       struct dirent *result = NULL;
+       int ret = MS_MEDIA_ERR_NONE;
+       char *new_path = NULL;
+       char *current_path = NULL;
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char * start_path = strdup(update_path);
+
+       MS_DBG_FENTER();
+
+       /*get directories list from media db*/
+       ret = ms_get_folder_list(handle, storage_id, start_path, dir_array);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("msc_tv_get_folder_list is failed", ret);
+               return ret;
+       }
+
+       /* make new array for storing directory */
+       read_dir_array = g_array_new (FALSE, FALSE, sizeof (char*));
+       if (read_dir_array == NULL){
+               MS_DBG_ERR("g_array_new failed");
+               return MS_MEDIA_ERR_OUT_OF_MEMORY;
+       }
+       /* add first direcotiry to directory array */
+       g_array_append_val (read_dir_array, start_path);
+
+       /*start db update. the number of element in the array , db update is complete.*/
+       while (read_dir_array->len != 0) {
+               /* get the current path from directory array */
+               current_path = g_array_index(read_dir_array , char*, 0);
+               g_array_remove_index (read_dir_array, 0);
+//             MSC_DBG_ERR("%s", current_path);
+
+               if (__msc_check_scan_ignore(current_path) != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("%s is ignore", current_path);
+                       MS_SAFE_FREE(current_path);
+                       continue;
+               }
+
+               dp = opendir(current_path);
+               if (dp != NULL) {
+                       /* find and compare modified time */
+                       _check_folder_from_list(current_path, *dir_array);
+
+                       while (!readdir_r(dp, &entry, &result)) {
+                               if (result == NULL)
+                                       break;
+
+                               if (entry.d_name[0] == '.') {
+                                       continue;
+                               }
+
+                                if (entry.d_type & DT_DIR) {
+                                        if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) {
+                                               MS_DBG_ERR("ms_strappend failed");
+                                               continue;
+                                       }
+                                       /* add new directory to dir_array */
+                                       new_path = strdup(path);
+                                       g_array_append_val (read_dir_array, new_path);
+                               }
+                       }
+               } else {
+                       MS_DBG_ERR("%s folder opendir fails", current_path);
+               }
+               if (dp) closedir(dp);
+               dp = NULL;
+               MS_SAFE_FREE(current_path);
+       }               /*db update while */
+
+       __msc_clear_file_list(read_dir_array);
+
+       MS_DBG_INFO("ret : %d", ret);
+       MS_DBG_INFO("update count : %d", (*dir_array)->len);
+
+       return ret;
+}
+
+static int _msc_db_update_partial(void **handle, const char *storage_id, ms_storage_type_t storage_type, GArray *dir_array, uid_t uid)
+{
+       unsigned int i;
+       int err = MS_MEDIA_ERR_NONE;
+       ms_dir_info_s* dir_info = NULL;
+       char *update_path = NULL;
+
+       for (i = 0; i < dir_array->len; i ++) {
+               dir_info = g_array_index (dir_array, ms_dir_info_s*, i);
+               update_path = strdup(dir_info->dir_path);
+               if (update_path == NULL) {
+                       MS_DBG_ERR("malloc failed");
+                       return MS_MEDIA_ERR_OUT_OF_MEMORY;
+               }
+
+               if (dir_info->modified_time != -1) {
+                       err = ms_set_folder_item_validity(handle, storage_id, update_path, MS_INVALID, MS_NON_RECURSIVE, uid);
+                       if (err != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_SLOG("update_path : %s, %d", update_path, dir_info->modified_time);
+                               MS_DBG_ERR("error : %d", err);
+                       }
+               }
+
+               __msc_dir_scan(handle, storage_id, update_path, storage_type, MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE, uid);
+       }
+
+       /*delete all node*/
+       while(dir_array->len != 0) {
+               ms_dir_info_s *data = NULL;
+               data = g_array_index(dir_array , ms_dir_info_s*, 0);
+               g_array_remove_index (dir_array, 0);
+               MS_SAFE_FREE(data->dir_path);
+               MS_SAFE_FREE(data);
+       }
+       g_array_free(dir_array, FALSE);
+       dir_array = NULL;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean msc_storage_scan_thread(void *data)
+{
+       ms_comm_msg_s *scan_data = NULL;
+       int ret;
+       int err;
+       void **handle = NULL;
+       ms_storage_type_t storage_type = MS_STORAGE_INTERNAL;
+       int scan_type;
+       bool valid_status = TRUE;
+       char *update_path = NULL;
+       GArray *dir_array = NULL;
+       bool power_off_status = FALSE;
+
+       while (1) {
+               __msc_set_storage_scan_status(MS_STORAGE_SCAN_PREPARE);
+               scan_data = g_async_queue_pop(storage_queue2);
+               if (scan_data->pid == POWEROFF) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               __msc_set_storage_scan_status(MS_STORAGE_SCAN_PROCESSING);
+               MS_DBG_ERR("STORAGE SCAN START [%s]", scan_data->msg);
+
+               scan_type = scan_data->msg_type;
+               if (scan_type != MS_MSG_STORAGE_ALL
+                       && scan_type != MS_MSG_STORAGE_PARTIAL
+                       && scan_type != MS_MSG_STORAGE_INVALID) {
+                       MS_DBG_ERR("Invalid request[%d]", scan_type);
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = ms_connect_db(&handle, scan_data->uid);
+               if (err != MS_MEDIA_ERR_NONE)
+                       continue;
+
+               storage_type = ms_get_storage_type_by_full(scan_data->msg, scan_data->uid);
+               update_path = strndup(scan_data->msg, scan_data->msg_size);
+
+               ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_PROCESSING, scan_data->uid);
+
+               /*start db updating */
+               __msc_set_db_status(MS_DB_UPDATING, storage_type);
+
+               valid_status = (scan_type == MS_MSG_STORAGE_PARTIAL) ? TRUE : FALSE;
+
+               if (scan_type != MS_MSG_STORAGE_INVALID)
+                       __msc_bacth_commit_enable(handle, TRUE, valid_status, MS_NOTI_SWITCH_OFF, 0);
+
+               if (scan_type == MS_MSG_STORAGE_PARTIAL && storage_type == MS_STORAGE_INTERNAL) {
+                       ms_validaty_change_all_items(handle, scan_data->storage_id, storage_type, true, scan_data->uid);
+
+                       /* find and compare modified time */
+                       ret = __msc_compare_with_db(handle, scan_data->storage_id, update_path, scan_data->msg_type, &dir_array);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_WARN("__msc_compare_with_db is falied");
+                               goto NEXT;
+                       }
+
+                       if (dir_array->len != 0) {
+                               MS_DBG_INFO("DB UPDATING IS NEEDED");
+                               ret = _msc_db_update_partial(handle, scan_data->storage_id, storage_type, dir_array, scan_data->uid);
+                       } else {
+                               MS_DBG_INFO("THERE IS NO UPDATE");
+                       }
+               } else {
+                       if (scan_type == MS_MSG_STORAGE_ALL) {
+                               /*  Delete all data before full scanning */
+                               if (!ms_delete_all_items(handle, scan_data->storage_id, storage_type, scan_data->uid)) {
+                                       MS_DBG_ERR("msc_delete_all_record fails");
+                               }
+                       } else if (scan_type == MS_MSG_STORAGE_PARTIAL) {
+                                       ms_validaty_change_all_items(handle, scan_data->storage_id, storage_type, false, scan_data->uid);
+                       }
+
+                       ret = __msc_db_update(handle, scan_data->storage_id, scan_data);
+               }
+
+               msc_del_blocked_path();
+
+               /*call for bundle commit*/
+               if (scan_type != MS_MSG_STORAGE_INVALID) {
+                       __msc_bacth_commit_disable(handle, TRUE, valid_status, scan_data->msg, ret, scan_data->uid);
+               }
+
+               MS_DBG_ERR("scan_data->storage_id = [%s]", scan_data->storage_id);
+
+               msc_insert_exactor_request(scan_type, TRUE, scan_data->storage_id, scan_data->msg, scan_data->pid, scan_data->uid);
+
+               MS_DBG_ERR("PAUSE");
+               __msc_pause_scan();
+               MS_DBG_ERR("RESUME");
+               /* move to msc_tv_storage_extract_thread */
+               if (0) {
+                       int del_count = 0;
+
+                       /*check delete count*/
+                       MS_DBG_INFO("update path : %s", update_path);
+
+                       ms_count_delete_items_in_folder(handle, scan_data->storage_id, update_path, &del_count);
+
+                       /*if there is no delete content, do not call delete API*/
+                       if (del_count != 0) {
+                               MS_DBG_ERR("storage thread delete count [%d]", del_count);
+                               ms_delete_invalid_items(handle, scan_data->storage_id, storage_type, scan_data->uid);
+                       }
+               }
+
+               /* send notification */
+               ms_send_dir_update_noti(handle,  scan_data->storage_id, update_path, NULL, MS_ITEM_UPDATE, scan_data->pid);
+
+               if (ret == MS_MEDIA_ERR_SCANNER_FORCE_STOP) {
+                       ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_STOP, scan_data->uid);
+                       __msc_set_storage_scan_status(MS_STORAGE_SCAN_STOP);
+                       /*set vconf key mmc loading for indicator */
+                       __msc_set_db_status(MS_DB_STOPPED, storage_type);
+               } else {
+                       ms_set_storage_scan_status(handle, scan_data->storage_id, MEDIA_SCAN_COMPLETE, scan_data->uid);
+                       __msc_set_storage_scan_status(MS_STORAGE_SCAN_DONE);
+                       /*set vconf key mmc loading for indicator */
+                       __msc_set_db_status(MS_DB_UPDATED, storage_type);
+               }
+
+NEXT:
+
+               MS_SAFE_FREE(update_path);
+
+               msc_get_power_status(&power_off_status);
+               if (power_off_status) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               /*disconnect form media db*/
+               if (handle) ms_disconnect_db(&handle);
+
+               /*Active flush */
+               malloc_trim(0);
+
+//             msc_send_result(ret, scan_data);
+
+               MS_SAFE_FREE(scan_data);
+
+               MS_DBG_ERR("STORAGE SCAN END[%d]", ret);
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(scan_data);
+       if (handle) ms_disconnect_db(&handle);
+
+       return false;
+}
+
+static void __msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data)
+{
+       MS_DBG_SLOG("path : %s", insert_data->msg);
+
+       if (insert_data->pid == POWEROFF) {
+               g_array_prepend_val(register_array, insert_data);
+       } else if (insert_data->msg_type == MS_MSG_BURSTSHOT_INSERT) {
+               g_array_prepend_val(register_array, insert_data);
+       } else {
+               g_array_append_val(register_array, insert_data);
+       }
+}
+
+static bool __msc_is_valid_path(const char *path, uid_t uid)
+{
+       bool ret = false;
+       char *usr_path = NULL;
+
+       if (path == NULL)
+               return false;
+
+       usr_path = __msc_get_path(uid);
+       if(usr_path == NULL)
+               return false;
+
+       if (strncmp(path, usr_path, strlen(usr_path)) == 0) {
+               ret = true;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
+               ret = true;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_USB, strlen(MEDIA_ROOT_PATH_USB)) == 0) {
+               ret = true;
+       } else {
+               ret = false;
+       }
+
+       MS_SAFE_FREE(usr_path);
+
+       return ret;
+}
+
+static int __msc_check_file_path(const char *file_path, uid_t uid)
+{
+       int exist;
+       struct stat file_st;
+
+       /* check location of file */
+       /* file must exists under "/opt/usr/media" or "/opt/storage/sdcard" */
+       if(!__msc_is_valid_path(file_path, uid)) {
+               MS_DBG_ERR("Invalid path : %s", file_path);
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       /* check the file exits actually */
+       exist = open(file_path, O_RDONLY);
+       if(exist < 0) {
+               MS_DBG_ERR("[%s]open files");
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+       close(exist);
+
+       /* check type of the path */
+       /* It must be a regular file */
+       memset(&file_st, 0, sizeof(struct stat));
+       if(stat(file_path, &file_st) == 0) {
+               if(!S_ISREG(file_st.st_mode)) {
+                       /* In this case, it is not a regula file */
+                       MS_DBG_ERR("this path is not a file");
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+       } else {
+               MS_DBG_STRERROR("stat failed");
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_clear_file_list(GArray *path_array)
+{
+       if (path_array) {
+               while(path_array->len != 0) {
+                       char *data = NULL;
+                       data = g_array_index(path_array , char*, 0);
+                       g_array_remove_index (path_array, 0);
+                       MS_SAFE_FREE(data);
+               }
+               g_array_free(path_array, FALSE);
+               path_array = NULL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_check_ignore_dir(const char *full_path, uid_t uid)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       char *dir_path = NULL;
+       char *leaf_path = NULL;
+
+       ret = __msc_check_file_path(full_path, uid);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("invalid path : %s", full_path);
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       dir_path = g_path_get_dirname(full_path);
+       if (strcmp(dir_path, ".") == 0) {
+               MS_DBG_ERR("getting directory path is failed : %s", full_path);
+               MS_SAFE_FREE(dir_path);
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       while(1) {
+               if(__msc_check_scan_ignore(dir_path) != MS_MEDIA_ERR_NONE) {
+                       ret = MS_MEDIA_ERR_INVALID_PATH;
+                       break;
+               }
+
+               /*If root path, Stop Scanning*/
+               if(strcmp(dir_path, __msc_get_path(uid)) == 0)
+                       break;
+               else if(strcmp(dir_path, MEDIA_ROOT_PATH_SDCARD) == 0)
+                       break;
+               else if(strcmp(dir_path, MEDIA_ROOT_PATH_USB) == 0)
+                       break;
+
+               leaf_path = strrchr(dir_path, '/');
+               if(leaf_path != NULL) {
+                               int seek_len = leaf_path -dir_path;
+                               dir_path[seek_len] = '\0';
+               } else {
+                       MS_DBG_ERR("Fail to find leaf path");
+                       ret = MS_MEDIA_ERR_INVALID_PATH;
+                       break;
+               }
+       }
+
+       MS_SAFE_FREE(dir_path);
+
+       return ret;
+}
+
+static int __msc_make_file_list(char *file_path, GArray **path_array, uid_t uid)
+{
+       FILE *fp = NULL;
+       char buf[MS_FILE_PATH_LEN_MAX] = {0,};
+       char *path = NULL;
+       int length;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret = MS_MEDIA_ERR_NONE;
+
+       /* load the file list from file */
+       fp = fopen(file_path, "rt");
+       if (fp == NULL) {
+               MS_DBG_STRERROR("fopen failed");
+               res = MS_MEDIA_ERR_FILE_OPEN_FAIL;
+               goto FREE_RESOURCE;
+       }
+
+       memset(buf, 0x0, MS_FILE_PATH_LEN_MAX);
+       /* This is an array for storing the path of insert datas*/
+       *path_array = g_array_new (FALSE, FALSE, sizeof (char *));
+       if (*path_array == NULL) {
+               MS_DBG_ERR("g_array_new failed");
+               res = MS_MEDIA_ERR_OUT_OF_MEMORY;
+               goto FREE_RESOURCE;
+       }
+
+       /* read registering file path from stored file */
+       while(fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) {
+               length = strlen(buf); /*the return value of function, strlen(), includes "\n" */
+               path = strndup(buf, length - 1); /*copying except "\n" and strndup fuction adds "\0" at the end of the copying string */
+
+               /* check valid path */
+               ret = __msc_check_ignore_dir(path, uid);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("invalide path : %s", path);
+                       MS_SAFE_FREE(path);
+                       continue;
+               }
+               /* insert getted path to the list */
+               if (g_array_append_val(*path_array, path)  == NULL) {
+                       MS_DBG_ERR("g_array_append_val failed");
+                       res = MS_MEDIA_ERR_OUT_OF_MEMORY;
+                       goto FREE_RESOURCE;
+               }
+       }
+
+       if(fp) fclose(fp);
+       fp = NULL;
+
+       return MS_MEDIA_ERR_NONE;
+
+FREE_RESOURCE:
+
+       __msc_clear_file_list(*path_array);
+
+       if(fp) fclose(fp);
+       fp = NULL;
+
+       return res;
+}
+
+static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array, uid_t uid)
+{
+       int err;
+       unsigned int i;
+       void **handle = NULL;
+       char *insert_path = NULL;
+       int (*insert_function)(void **, const char*, const char*, uid_t) = NULL;
+       char storage_id[MS_UUID_SIZE] = {0,};
+       bool power_off_status = FALSE;
+
+       insert_function = (current_msg == MS_MSG_BULK_INSERT) ? ms_insert_item_batch : ms_insert_burst_item;
+
+       /* connect to media db, if conneting is failed, db updating is stopped */
+       err = ms_connect_db(&handle, uid);
+       if (err != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+
+       /*start db updating */
+       /*call for bundle commit*/
+       __msc_bacth_commit_enable(handle, TRUE, FALSE, MS_NOTI_SWITCH_ON, pid);
+
+       MS_DBG_ERR("BULK REGISTER START");
+
+       /* get the inserting file path from array  and insert to db */
+       for (i = 0; i < path_array->len; i++) {
+
+               insert_path =  g_array_index(path_array, char*, i);
+
+               /* get storage list */
+               memset(storage_id, 0x0, MS_UUID_SIZE);
+               if (ms_get_storage_id(handle, insert_path, storage_id) < 0) {
+                       MS_DBG_ERR("There is no storage id in media db");
+                       continue;
+               }
+
+               /* insert to db */
+               err = insert_function(handle, storage_id, insert_path, uid);
+
+               msc_get_power_status(&power_off_status);
+               if (power_off_status) {
+                       MS_DBG_ERR("power off");
+                       /*call for bundle commit*/
+                       break;
+               }
+       }
+
+       /*call for bundle commit*/
+       __msc_bacth_commit_disable(handle, TRUE, FALSE, NULL, MS_MEDIA_ERR_NONE, uid);
+
+       /*disconnect form media db*/
+       if (handle) ms_disconnect_db(&handle);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data)
+{
+       int remain_request;
+       ms_comm_msg_s *insert_data = NULL;
+
+       while (1) {
+               remain_request  = g_async_queue_length(reg_queue2);
+
+               /*updating requests remain*/
+               if (register_array->len != 0 && remain_request == 0) {
+                       *register_data = g_array_index(register_array, ms_comm_msg_s*, 0);
+                       g_array_remove_index (register_array, 0);
+                       break;
+               } else if (remain_request != 0) {
+                       insert_data = g_async_queue_pop(reg_queue2);
+                       __msc_insert_register_request(register_array, insert_data);
+                       continue;
+               } else if (register_array->len == 0 && remain_request == 0) {
+               /*Threre is no request, Wait until pushung new request*/
+                       insert_data = g_async_queue_pop(reg_queue2);
+                       __msc_insert_register_request(register_array, insert_data);
+                       continue;
+               }
+       }
+
+       if(((*register_data)->msg_size <= 0) ||((*register_data)->msg_size > MS_FILE_PATH_LEN_MAX)) {
+               MS_DBG_ERR("message size[%d] is wrong", (*register_data)->msg_size);
+               return MS_MEDIA_ERR_INVALID_IPC_MESSAGE;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+
+}
+
+gboolean msc_register_thread(void *data)
+{
+       ms_comm_msg_s *register_data = NULL;
+       GArray *register_array = NULL;
+       GArray *path_array = NULL;
+       char *file_path = NULL;
+       int ret;
+       int pid = 0;
+       ms_msg_type_e current_msg = MS_MSG_MAX;
+
+       /*create array for processing overlay data*/
+       register_array = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *));
+       if (register_array == NULL) {
+               MS_DBG_ERR("g_array_new error");
+               return false;
+       }
+
+       while (1) {
+               ret = __msc_pop_register_request(register_array, &register_data);
+               if (register_data->pid == POWEROFF) {
+                       MS_DBG_ERR("power off");
+                       goto _POWEROFF;
+               }
+
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("__msc_tv_pop_register_request failed [%d]", ret);
+                       goto FREE_RESOURCE;
+               }
+
+               /* check current request */
+               current_msg = register_data->msg_type;
+               pid = register_data->pid;
+
+               if ((current_msg != MS_MSG_BULK_INSERT) &&
+                       (current_msg != MS_MSG_BURSTSHOT_INSERT)) {
+                       MS_DBG_ERR("wrong message type");
+                       goto FREE_RESOURCE;
+               }
+
+               file_path = strndup(register_data->msg, register_data->msg_size);
+               if (file_path == NULL) {
+                       MS_DBG_ERR("file path is NULL");
+                       goto FREE_RESOURCE;
+               }
+
+               ret = __msc_make_file_list(file_path, &path_array, register_data->uid);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("__msc_tv_make_file_list failed [%d]", ret);
+                       goto FREE_RESOURCE;
+               }
+
+               ret = __msc_batch_insert(current_msg, pid, path_array, register_data->uid);
+
+FREE_RESOURCE:
+               /*Active flush */
+               malloc_trim(0);
+
+               /* If register_files operation is stopped, there is no necessrty for sending result. */
+               msc_send_result(ret, register_data);
+
+               MS_DBG_ERR("BULK REGISTER END [%d |%s]", ret, register_data->msg);
+
+               __msc_clear_file_list(path_array);
+
+               MS_SAFE_FREE(file_path);
+               MS_SAFE_FREE(register_data);
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(file_path);
+       MS_SAFE_FREE(register_data);
+       if (register_array) {
+               while(register_array->len != 0) {
+                       ms_comm_msg_s *data = NULL;
+                       data = g_array_index(register_array , ms_comm_msg_s*, 0);
+                       g_array_remove_index (register_array, 0);
+                       MS_SAFE_FREE(data);
+               }
+               g_array_free (register_array, FALSE);
+               register_array = NULL;
+       }
+
+       __msc_clear_file_list(path_array);
+
+       return false;
+}
+
+static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid)
+{
+       /*call for bundle commit*/
+       if (ins_status) ms_register_start(handle, noti_enable, pid);
+       if (valid_status) ms_validate_start(handle);
+
+       return;
+}
+
+static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status, const char *path, int result, uid_t uid)
+{
+       /*call for bundle commit*/
+       if (valid_status) ms_validate_end(handle, uid);
+       if (ins_status) ms_register_end(handle, path, uid);
+
+       return;
+}
+
+int msc_set_cancel_path(const char *cancel_path)
+{
+       if (g_cancel_path2 != NULL) {
+               MS_DBG_WARN("g_cancel_path2 is not NULL");
+               free(g_cancel_path2);
+               g_cancel_path2 = NULL;
+       }
+
+       g_cancel_path2 = strdup(cancel_path);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_del_cancel_path()
+{
+       if (g_cancel_path2 != NULL) {
+               MS_DBG_WARN("g_tv_cancel_path is not NULL");
+               free(g_cancel_path2);
+               g_cancel_path2 = NULL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __msc_set_storage_scan_status(ms_storage_scan_status_e status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+#if 0
+       if (!ms_config_set_int(MS_SCANNER_STATUS, status)) {
+               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+               MSC_DBG_ERR("ms_config_set_int failed");
+       }
+#else
+       stg_scan_status2 = status;
+#endif
+       return res;
+}
+
+static int __msc_get_storage_scan_status(ms_storage_scan_status_e *status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+
+#if 0
+       if (!ms_config_get_int(MS_SCANNER_STATUS, status)) {
+               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+               MSC_DBG_ERR("ms_config_get_int failed");
+       }
+#else
+       *status = stg_scan_status2;
+#endif
+
+       return res;
+}
+
+static bool __msc_storage_mount_status(const char* start_path)
+{
+       bool ret = false;
+       char *storage_path = NULL;
+       char *remain_path = NULL;
+       int remain_len = 0;
+       GArray *dev_list = NULL;
+
+       remain_path = strstr(start_path+strlen(MEDIA_ROOT_PATH_EXTERNAL) +1, "/");
+       if (remain_path != NULL)
+               remain_len = strlen(remain_path);
+
+       storage_path = strndup(start_path, strlen(start_path) - remain_len);
+
+       MS_DBG_ERR("storage_path [%s]", storage_path);
+
+       ret = ms_sys_get_device_list(MS_STG_TYPE_ALL, &dev_list);
+       if (ret == MS_MEDIA_ERR_NONE) {
+               if (dev_list != NULL) {
+                       MS_DBG_ERR("DEV FOUND[%d]", dev_list->len);
+                       int i = 0 ;
+                       int dev_num = dev_list->len;
+                       ms_block_info_s *block_info = NULL;
+
+                       for (i = 0; i < dev_num; i ++) {
+                               block_info = (ms_block_info_s *)g_array_index(dev_list , ms_stg_type_e*, i);
+                               if (strcmp(block_info->mount_path, storage_path) == 0) {
+                                       ret = TRUE;
+                                       MS_DBG_ERR("STORAGE FOUND [%s]", block_info->mount_path);
+                                       break;
+                               }
+                       }
+                       ms_sys_release_device_list(&dev_list);
+               } else {
+                       MS_DBG_ERR("DEV NOT FOUND");
+               }
+       } else {
+               MS_DBG_ERR("ms_sys_get_device_list failed");
+       }
+
+       MS_SAFE_FREE(storage_path);
+
+       return ret;
+}
+
+int msc_set_blocked_path(const char *blocked_path)
+{
+       MS_DBG_FENTER();
+
+       g_mutex_lock(&blocked_mutex2);
+
+       if (g_blocked_path2 != NULL) {
+               MS_DBG_ERR("g_blocked_path is not NULL [%s]", g_blocked_path2);
+               free(g_blocked_path2);
+               g_blocked_path2 = NULL;
+       }
+
+       g_blocked_path2 = strdup(blocked_path);
+
+       g_mutex_unlock(&blocked_mutex2);
+
+       MS_DBG_FLEAVE();
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_del_blocked_path(void)
+{
+       MS_DBG_FENTER();
+
+       g_mutex_lock(&blocked_mutex2);
+
+       if (g_blocked_path2 != NULL) {
+               MS_DBG_ERR("g_blocked_path is not NULL [%s]", g_blocked_path2);
+               free(g_blocked_path2);
+               g_blocked_path2 = NULL;
+       }
+
+       g_mutex_unlock(&blocked_mutex2);
+
+       MS_DBG_FLEAVE();
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_init_scanner(void)
+{
+       if (!scan_queue2) scan_queue2 = g_async_queue_new();
+       if (!reg_queue2) reg_queue2 = g_async_queue_new();
+       if (!storage_queue2) storage_queue2 = g_async_queue_new();
+
+       /*Init mutex variable*/
+       g_mutex_init(&scan_req_mutex2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+int msc_deinit_scanner(void)
+{
+       if (scan_queue2) g_async_queue_unref(scan_queue2);
+       if (reg_queue2) g_async_queue_unref(reg_queue2);
+       if (storage_queue2) g_async_queue_unref(storage_queue2);
+
+       /*Clear db mutex variable*/
+       g_mutex_clear(&scan_req_mutex2);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_push_scan_request(ms_scan_type_e scan_type, ms_comm_msg_s *recv_msg)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       switch(scan_type) {
+               case MS_SCAN_STORAGE:
+                       g_async_queue_push(storage_queue2, GINT_TO_POINTER(recv_msg));
+                       break;
+               case MS_SCAN_DIRECTORY:
+                       g_async_queue_push(scan_queue2, GINT_TO_POINTER(recv_msg));
+                       break;
+               case MS_SCAN_REGISTER:
+                       g_async_queue_push(reg_queue2, GINT_TO_POINTER(recv_msg));
+                       break;
+               default:
+                       MS_DBG_ERR("invalid parameter");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       break;
+       }
+
+       return ret;
+}
+
+int msc_stop_scan_thread(void)
+{
+       ms_comm_msg_s *data = NULL;
+
+       msc_set_power_status(TRUE);
+
+       if (scan_queue2) {
+               /*notify to scannig thread*/
+               MS_MALLOC(data, sizeof(ms_comm_msg_s));
+               data->pid = POWEROFF;
+               msc_push_scan_request(MS_SCAN_DIRECTORY, data);
+       }
+
+       if (reg_queue2) {
+               /*notify to register thread*/
+               MS_MALLOC(data, sizeof(ms_comm_msg_s));
+               data->pid = POWEROFF;
+               msc_push_scan_request(MS_SCAN_REGISTER, data);
+       }
+
+       if (storage_queue2) {
+               /*notify to register thread*/
+               MS_MALLOC(data, sizeof(ms_comm_msg_s));
+               data->pid = POWEROFF;
+               msc_push_scan_request(MS_SCAN_STORAGE, data);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int msc_get_remain_scan_request(ms_scan_type_e scan_type, int *remain_request)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       switch(scan_type) {
+               case MS_SCAN_STORAGE:
+                       *remain_request = g_async_queue_length(storage_queue2);
+                       break;
+               case MS_SCAN_DIRECTORY:
+                       *remain_request = g_async_queue_length(scan_queue2);
+                       break;
+               case MS_SCAN_REGISTER:
+                       *remain_request = g_async_queue_length(reg_queue2);
+                       break;
+               default:
+                       MS_DBG_ERR("invalid parameter");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       break;
+       }
+
+       return ret;
+}
+
+int msc_get_dir_scan_status(bool *scan_status)
+{
+       *scan_status = g_directory_scan_processing2;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
diff --git a/src/scanner-v2/media-scanner-socket-v2.c b/src/scanner-v2/media-scanner-socket-v2.c
new file mode 100755 (executable)
index 0000000..3184848
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/un.h>
+#include <malloc.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-ipc.h"
+#include "media-common-types.h"
+#include "media-common-utils.h"
+#include "media-common-db-svc.h"
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-scan-v2.h"
+#include "media-scanner-socket-v2.h"
+#include "media-scanner-extract-v2.h"
+
+extern GAsyncQueue *storage_queue2;
+extern GAsyncQueue *scan_queue2;
+extern GAsyncQueue *reg_queue2;
+extern GMutex scan_req_mutex2;
+extern GAsyncQueue *folder_extract_queue;
+
+static int _msc_remove_request(GAsyncQueue *req_queue, ms_comm_msg_s *recv_msg)
+{
+       char *cancel_path = recv_msg->msg;
+       int pid = recv_msg->pid;
+       int i = 0;
+       int len = g_async_queue_length(req_queue);
+       ms_comm_msg_s *msg = NULL;
+       GAsyncQueue *temp_scan_queue = NULL;
+
+       MS_DBG_WARN("scan_req_mutex2 is LOCKED");
+       g_mutex_lock(&scan_req_mutex2);
+
+       if (len == 0) {
+               MS_DBG_WARN("Request is not stacked");
+               goto END_REMOVE_REQUEST;
+       }
+
+       msc_set_cancel_path(recv_msg->msg);
+       msc_set_extract_cancel_path(recv_msg->msg);
+
+       temp_scan_queue = g_async_queue_new();
+
+       for (i = 0; i <len; i++) {
+               /*create new queue to compare request*/
+               msg = g_async_queue_pop(scan_queue2);
+               if ((strcmp(msg->msg, cancel_path) == 0) && (pid == msg->pid)) {
+                       MS_SAFE_FREE(msg);
+               } else {
+                       g_async_queue_push(temp_scan_queue, GINT_TO_POINTER(msg));
+               }
+       }
+       g_async_queue_unref (scan_queue2);
+       scan_queue2 = temp_scan_queue;
+
+END_REMOVE_REQUEST:
+       g_mutex_unlock(&scan_req_mutex2);
+       MS_DBG_WARN("scan_req_mutex2 is UNLOCKED");
+
+       GAsyncQueue *temp_extract_queue = NULL;
+       int len_extract = g_async_queue_length(folder_extract_queue);
+       if(len_extract != 0)
+       {
+               temp_extract_queue = g_async_queue_new();
+               for (i = 0; i <len_extract; i++) {
+                       /*create new queue to compare request*/
+                       msg = g_async_queue_pop(folder_extract_queue);
+                       if ((strcmp(msg->msg, cancel_path) == 0) && (pid == msg->pid)) {
+                               MS_SAFE_FREE(msg);
+                       } else {
+                               g_async_queue_push(temp_extract_queue, GINT_TO_POINTER(msg));
+                       }
+               }
+               g_async_queue_unref (folder_extract_queue);
+               folder_extract_queue = temp_extract_queue;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       ms_comm_msg_s *recv_msg = NULL;
+       int sockfd = MS_SOCK_NOT_ALLOCATE;
+       int req_num = MS_MSG_MAX;
+       int err = -1;
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       MS_MALLOC(recv_msg, sizeof(ms_comm_msg_s));
+       if (recv_msg == NULL) {
+               MS_DBG_ERR("MS_MALLOC failed");
+               return TRUE;
+       }
+
+       /* read() is blocked until media scanner sends message */
+       err = read(sockfd, recv_msg, sizeof(ms_comm_msg_s));
+       if (err < 0) {
+               MS_DBG_STRERROR("fifo read failed");
+               MS_SAFE_FREE(recv_msg);
+               return MS_MEDIA_ERR_FILE_READ_FAIL;
+       }
+
+       MS_DBG_SLOG("receive msg from [%d] %d, %s", recv_msg->pid, recv_msg->msg_type, recv_msg->msg);
+
+       /* copy from recived data */
+       req_num = recv_msg->msg_type;
+
+       switch(req_num){
+               case MS_MSG_BULK_INSERT:
+               case MS_MSG_BURSTSHOT_INSERT:
+                       {
+                               MS_DBG_INFO("BULK INSERT");
+                               /* request bulk insert*/
+                               msc_push_scan_request(MS_SCAN_REGISTER, recv_msg);
+                       }
+                       break;
+               case MS_MSG_DIRECTORY_SCANNING:
+               case MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE:
+                       {
+                               /* this request from another apps */
+                               /* set the scan data for scanning thread */
+                               msc_push_scan_request(MS_SCAN_DIRECTORY, recv_msg);
+                       }
+                       break;
+               case MS_MSG_STORAGE_ALL:
+               case MS_MSG_STORAGE_PARTIAL:
+               case MS_MSG_STORAGE_INVALID:
+                       {
+                               /* this request from media-server */
+                               msc_push_scan_request(MS_SCAN_STORAGE, recv_msg);
+                       }
+                       break;
+               case MS_MSG_DIRECTORY_SCANNING_CANCEL:
+                       {
+                               _msc_remove_request(scan_queue2, recv_msg);
+                               MS_SAFE_FREE(recv_msg);
+                       }
+                       break;
+               default:
+                       {
+                               MS_DBG_ERR("THIS REQUEST IS INVALID %d", req_num);
+                               MS_SAFE_FREE(recv_msg);
+                       }
+                       break;
+       }
+
+       /*Active flush */
+       malloc_trim(0);
+
+       return TRUE;
+}
+
+int msc_send_ready(void)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       ms_comm_msg_s send_msg;
+       int fd = -1;
+       int err = -1;
+
+       fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY);
+       if (fd < 0) {
+               MS_DBG_STRERROR("fifo read failed");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+
+       /* send ready message */
+       memset(&send_msg, 0, sizeof(send_msg));
+       send_msg.msg_type = MS_MSG_SCANNER_READY;
+
+       /* send ready message */
+       err = write(fd, &send_msg, sizeof(send_msg));
+       if (err < 0) {
+               MS_DBG_STRERROR("fifo write failed");
+               res = MS_MEDIA_ERR_FILE_READ_FAIL;
+       }
+
+       close(fd);
+
+       return res;
+}
+
+int msc_send_result(int result, ms_comm_msg_s *res_data)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       ms_comm_msg_s send_msg;
+       int fd = -1;
+       int err = -1;
+
+       fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY);
+       if (fd < 0) {
+               MS_DBG_STRERROR("fifo open failed");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+
+       /* send result message */
+       memset(&send_msg, 0x0, sizeof(ms_comm_msg_s));
+       send_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT;
+       send_msg.pid = res_data->pid;
+       send_msg.result = result;
+       send_msg.msg_size = res_data->msg_size;
+       strncpy(send_msg.msg, res_data->msg, send_msg.msg_size);
+
+       /* send ready message */
+       err = write(fd, &send_msg, sizeof(send_msg));
+       if (err < 0) {
+               MS_DBG_STRERROR("fifo write failed");
+               res = MS_MEDIA_ERR_FILE_READ_FAIL;
+       }
+
+       close(fd);
+
+       return res;
+}
+
diff --git a/src/scanner-v2/media-scanner-v2.c b/src/scanner-v2/media-scanner-v2.c
new file mode 100755 (executable)
index 0000000..294a94c
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ *  Media Server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pmapi.h>
+
+#include "media-common-utils.h"
+#include "media-common-external-storage.h"
+#include "media-common-system.h"
+#include "media-common-db-svc.h"
+
+#include "media-util.h"
+#include "media-scanner-dbg-v2.h"
+#include "media-scanner-common-v2.h"
+#include "media-scanner-device-block-v2.h"
+#include "media-scanner-scan-v2.h"
+#include "media-scanner-socket-v2.h"
+#include "media-scanner-extract-v2.h"
+
+static GMainLoop *scanner_mainloop2 = NULL;
+
+static void __msc_power_off_cb(ms_power_info_s *power_info, void* data);
+static void __msc_add_event_receiver(void *data);
+static void __msc_remove_event_receiver(void);
+
+int main(int argc, char **argv)
+{
+       GThread *storage_scan_thread = NULL;
+       GThread *scan_thread = NULL;
+       GThread *register_thread = NULL;
+       GThread *storage_extract_thread = NULL;
+       GThread *folder_extract_thread = NULL;
+       GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+       bool power_off_status = FALSE;
+
+       int err = -1;
+       int fd = -1;
+
+       MS_DBG_ERR("[No-Error] ========== Scanner start ========");
+
+       __msc_add_event_receiver(NULL);
+
+       /*load functions from plusin(s)*/
+       err = ms_load_functions();
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("function load failed[%d]", err);
+               goto EXIT;
+       }
+
+       /*Init main loop*/
+       scanner_mainloop2 = g_main_loop_new(NULL, FALSE);
+
+       msc_init_scanner();
+       msc_init_extract_thread();
+       msc_init_scan_thread();
+
+       /* Create pipe */
+       err = unlink(MS_SCANNER_FIFO_PATH_REQ);
+       if (err !=0) {
+               MS_DBG_STRERROR("[No-Error] unlink failed");
+       }
+
+       err = mkfifo(MS_SCANNER_FIFO_PATH_REQ, MS_SCANNER_FIFO_MODE);
+       if (err !=0) {
+               MS_DBG_STRERROR("mkfifo failed");
+               return MS_MEDIA_ERR_INTERNAL;
+       }
+
+       fd = open(MS_SCANNER_FIFO_PATH_REQ, O_RDWR);
+       if (fd < 0) {
+               MS_DBG_STRERROR("fifo open failed");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+
+       context = g_main_loop_get_context(scanner_mainloop2);
+
+       /* Create new channel to watch pipe */
+       channel = g_io_channel_unix_new(fd);
+       source = g_io_create_watch(channel, G_IO_IN);
+
+       /* Set callback to be called when pipe is readable */
+       g_source_set_callback(source, (GSourceFunc)msc_receive_request, NULL, NULL);
+       g_source_attach(source, context);
+       g_source_unref(source);
+
+       /*create each threads*/
+       storage_scan_thread = g_thread_new("storage_scan_thread", (GThreadFunc)msc_storage_scan_thread, NULL);
+       scan_thread = g_thread_new("scanner_thread", (GThreadFunc)msc_directory_scan_thread, NULL);
+       register_thread = g_thread_new("register_thread", (GThreadFunc)msc_register_thread, NULL);
+       storage_extract_thread = g_thread_new("storage_extract_thread", (GThreadFunc)msc_storage_extract_thread, NULL);
+       folder_extract_thread = g_thread_new("folder_extract_thread", (GThreadFunc)msc_folder_extract_thread, NULL);
+
+       if (ms_is_mmc_inserted()) {
+               msc_set_mmc_status(MS_STG_INSERTED);
+       }
+
+       msc_send_ready();
+       MS_DBG_ERR("[No-Error] ========== Scanner is ready ========");
+
+       MS_DBG_ERR("[No-Error] ========== Scanner is running  ========");
+
+       g_main_loop_run(scanner_mainloop2);
+
+       g_thread_join (scan_thread);
+       g_thread_join (register_thread);
+       g_thread_join (storage_scan_thread);
+       g_thread_join (storage_extract_thread);
+       g_thread_join (folder_extract_thread);
+
+       g_io_channel_shutdown(channel, FALSE, NULL);
+       g_io_channel_unref(channel);
+
+       msc_get_power_status(&power_off_status);
+       if (power_off_status) {
+               pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
+       }
+
+       msc_deinit_extract_thread();
+       msc_deinit_scan_thread();
+       msc_deinit_scanner();
+
+       /*close pipe*/
+       close(fd);
+
+       /*unload functions*/
+       ms_unload_functions();
+
+       __msc_remove_event_receiver();
+
+EXIT:
+       MS_DBG_ERR("[No-Error] ========== Scanner end  ========");
+
+       return 0;
+}
+
+
+static void __msc_power_off_cb(ms_power_info_s *power_info, void* data)
+{
+       msc_stop_scan_thread();
+       msc_stop_extract_thread();
+
+       if (g_main_loop_is_running(scanner_mainloop2)) g_main_loop_quit(scanner_mainloop2);
+}
+
+static void __msc_add_event_receiver(void *data)
+{
+       /*set power off callback function*/
+       ms_sys_set_poweroff_cb(__msc_power_off_cb, NULL);
+       ms_sys_set_device_block_event_cb(msc_device_block_changed_cb, NULL);
+}
+
+static void __msc_remove_event_receiver(void)
+{
+       ms_sys_unset_device_block_event_cb();
+       ms_sys_unset_poweroff_cb();
+}
+