Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:50:13 +0000 (01:50 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:50:13 +0000 (01:50 +0900)
69 files changed:
AUTHORS [new file with mode: 0644]
LICENSE.APLv2.0 [new file with mode: 0644]
Makefile.am [new file with mode: 0755]
NOTICE [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
build-aux/depcomp [new file with mode: 0755]
build-aux/install-sh [new file with mode: 0755]
build-aux/missing [new file with mode: 0755]
common/include/media-server-db-svc.h [new file with mode: 0755]
common/include/media-server-db.h [new file with mode: 0755]
common/include/media-server-dbg.h [new file with mode: 0755]
common/include/media-server-dbus-type.h [new file with mode: 0755]
common/include/media-server-dbus.h [new file with mode: 0755]
common/include/media-server-drm.h [new file with mode: 0755]
common/include/media-server-external-storage.h [new file with mode: 0755]
common/include/media-server-inotify-internal.h [new file with mode: 0755]
common/include/media-server-inotify.h [new file with mode: 0755]
common/include/media-server-scanner.h [new file with mode: 0755]
common/include/media-server-socket.h [new file with mode: 0755]
common/include/media-server-thumb.h [new file with mode: 0755]
common/include/media-server-types.h [new file with mode: 0755]
common/include/media-server-utils.h [new file with mode: 0755]
common/media-server-db-svc.c [new file with mode: 0755]
common/media-server-db.c [new file with mode: 0755]
common/media-server-dbus.c [new file with mode: 0755]
common/media-server-drm.c [new file with mode: 0755]
common/media-server-external-storage.c [new file with mode: 0755]
common/media-server-inotify-internal.c [new file with mode: 0755]
common/media-server-inotify.c [new file with mode: 0755]
common/media-server-main.c [new file with mode: 0755]
common/media-server-scanner.c [new file with mode: 0755]
common/media-server-socket.c [new file with mode: 0755]
common/media-server-thumb.c [new file with mode: 0755]
common/media-server-utils.c [new file with mode: 0755]
common/mediadb-update.c [new file with mode: 0644]
common/scanner/include/media-scanner-db-svc.h [new file with mode: 0755]
common/scanner/include/media-scanner-dbg.h [new file with mode: 0755]
common/scanner/include/media-scanner-drm.h [new file with mode: 0755]
common/scanner/include/media-scanner-scan.h [new file with mode: 0755]
common/scanner/include/media-scanner-socket.h [new file with mode: 0755]
common/scanner/include/media-scanner-utils.h [new file with mode: 0755]
common/scanner/media-scanner-db-svc.c [new file with mode: 0755]
common/scanner/media-scanner-drm.c [new file with mode: 0755]
common/scanner/media-scanner-scan.c [new file with mode: 0755]
common/scanner/media-scanner-socket.c [new file with mode: 0755]
common/scanner/media-scanner-utils.c [new file with mode: 0755]
common/scanner/media-scanner.c [new file with mode: 0755]
config.in [new file with mode: 0644]
configure.ac [new file with mode: 0755]
data/mediasvr [new file with mode: 0755]
lib/include/media-server-ipc.h [new file with mode: 0755]
lib/include/media-util-db.h [new file with mode: 0755]
lib/include/media-util-dbg.h [new file with mode: 0755]
lib/include/media-util-err.h [new file with mode: 0755]
lib/include/media-util-internal.h [new file with mode: 0755]
lib/include/media-util-ipc.h [new file with mode: 0755]
lib/include/media-util-noti.h [new file with mode: 0755]
lib/include/media-util-register.h [new file with mode: 0755]
lib/include/media-util.h [new file with mode: 0755]
lib/media-util-db.c [new file with mode: 0755]
lib/media-util-ipc.c [new file with mode: 0755]
lib/media-util-noti.c [new file with mode: 0755]
lib/media-util-register.c [new file with mode: 0755]
libmedia-utils.manifest [new file with mode: 0644]
libmedia-utils.pc.in [new file with mode: 0755]
media-server.manifest [new file with mode: 0644]
packaging/media-server.service [new file with mode: 0644]
packaging/media-server.spec [new file with mode: 0755]
reset_mediadb.sh [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..699f897
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Yong Yeon Kim <yy9875.kim at samsung dot com>
+Hyunjun Ko <zzoon.ko at samsung dot com>
+Haejeong Kim <backto.kim at samsung dot com>
diff --git a/LICENSE.APLv2.0 b/LICENSE.APLv2.0
new file mode 100644 (file)
index 0000000..8aa906c
--- /dev/null
@@ -0,0 +1,205 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100755 (executable)
index 0000000..a5b44b3
--- /dev/null
@@ -0,0 +1,148 @@
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = .
+
+AM_CPPFLAGS = $(FMS_DEBUG_FLAGS)
+
+AM_LDFLAGS=-Wl,--as-needed -Wl,--hash-style=both
+
+### pkgconfig ###
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = libmedia-utils.pc
+
+nor_directory = /etc/rc.d/rc3.d
+hib_directory = /etc/rc.d/rc5.d
+
+install-data-hook:
+       mkdir $(DESTDIR)/usr/local/bin/ -p
+       cp -a $(CURDIR)/reset_mediadb.sh $(DESTDIR)/usr/local/bin/
+       mkdir $(DESTDIR)$(nor_directory) -p
+       ln -s ../init.d/mediasvr S99mediasvr
+       mv ./S99mediasvr $(DESTDIR)$(nor_directory)
+       mkdir $(DESTDIR)$(hib_directory) -p
+       ln -s ../init.d/mediasvr S99mediasvr
+       mv ./S99mediasvr $(DESTDIR)$(hib_directory)
+
+# init.d script
+fmsvcdir = /etc/rc.d/init.d
+dist_fmsvc_DATA = ./data/mediasvr
+
+### libmedia-utils.la ###
+lib_LTLIBRARIES = libmedia-utils.la
+libmedia_utils_la_SOURCES = lib/media-util-noti.c \
+                            lib/media-util-ipc.c \
+                            lib/media-util-db.c \
+                            lib/media-util-register.c
+
+libmedia_utils_la_CFLAGS = -I${srcdir}/lib/include \
+                              $(GLIB_CFLAGS) \
+                             $(DLOG_CFLAGS) \
+                             $(DBUS_CFLAGS) \
+                             $(SQLITE3_CFLAGS) \
+                             $(DB_UTIL_CFLAGS) \
+                             $(PHONESTATUS_CFLAGS)
+
+libmedia_utils_la_LIBADD  =   $(GLIB_LIBS) \
+                              $(DLOG_LIBS) \
+                              $(DBUS_LIBS) \
+                             $(SQLITE3_LIBS) \
+                             $(DB_UTIL_LIBS) \
+                             $(PHONESTATUS_LIBS)
+
+
+### file-manager-server ###
+bin_PROGRAMS = media-server \
+               media-scanner \
+               mediadb-update
+
+media_server_SOURCES = common/media-server-dbus.c \
+                      common/media-server-drm.c \
+                       common/media-server-utils.c \
+                       common/media-server-external-storage.c \
+                       common/media-server-db-svc.c \
+                       common/media-server-inotify-internal.c \
+                       common/media-server-inotify.c \
+                       common/media-server-db.c \
+                       common/media-server-socket.c \
+                       common/media-server-thumb.c \
+                       common/media-server-scanner.c \
+                       common/media-server-main.c 
+
+media_server_CFLAGS = -I${srcdir}/common/include \
+                      -I${srcdir}/lib/include \
+                             $(GTHREAD_CFLAGS) \
+                             $(GLIB_CFLAGS) \
+                             $(PHONESTATUS_CFLAGS) \
+                             $(DLOG_CFLAGS) \
+                             $(DRM_SERVICE_CFLAGS) \
+                            $(AUL_CFLAG)\
+                            $(LIBPMCONTROL_CFLAGS) \
+                            $(HEYNOTI_CFLAGS) \
+                            $(DBUS_CFLAGS) \
+                             $(STATUS_CFLAGS)
+
+media_server_LDADD = libmedia-utils.la \
+                             $(GLIB_LIBS) \
+                              $(GTHREAD_LIBS) \
+                              $(PHONESTATUS_LIBS) \
+                              $(DLOG_LIBS) \
+                              $(DRM_SERVICE_LIBS) \
+                             $(AUL_LIBS) \
+                             $(LIBPMCONTROL_LIBS) \
+                             $(HEYNOTI_LIBS) \
+                             $(DBUS_LIBS) \
+                              -ldl \
+                              $(STATUS_LIBS)
+
+media_scanner_SOURCES = common/scanner/media-scanner-drm.c \
+                       common/scanner/media-scanner-utils.c \
+                       common/scanner/media-scanner-db-svc.c \
+                       common/scanner/media-scanner-scan.c \
+                       common/scanner/media-scanner-socket.c \
+                       common/scanner/media-scanner.c
+
+media_scanner_CFLAGS = -I${srcdir}/common/scanner/include \
+                       -I${srcdir}/lib/include \
+                       -I${srcdir}/common/include \
+                             $(GTHREAD_CFLAGS) \
+                             $(GLIB_CFLAGS) \
+                             $(PHONESTATUS_CFLAGS) \
+                             $(DLOG_CFLAGS) \
+                             $(DRM_SERVICE_CFLAGS) \
+                             $(AUL_CFLAG)\
+                             $(LIBPMCONTROL_CFLAGS) \
+                             $(HEYNOTI_CFLAGS) \
+                             $(DBUS_CFLAGS)
+
+media_scanner_LDADD = libmedia-utils.la \
+                              $(GLIB_LIBS) \
+                              $(GTHREAD_LIBS) \
+                              $(PHONESTATUS_LIBS) \
+                              $(DLOG_LIBS) \
+                              $(DRM_SERVICE_LIBS) \
+                              $(AUL_LIBS) \
+                              $(LIBPMCONTROL_LIBS) \
+                              $(THUMB_GEN_LIBS) \
+                              $(HEYNOTI_LIBS) \
+                              $(DBUS_LIBS) \
+                              -ldl #this is for using dlsym
+
+mediadb_update_SOURCES = common/mediadb-update.c
+
+mediadb_update_CFLAGS = -I${srcdir}/lib/include \
+                             $(GTHREAD_CFLAGS) \
+                             $(GLIB_CFLAGS)
+
+mediadb_update_LDADD = libmedia-utils.la \
+                              $(GLIB_LIBS) \
+                              $(GTHREAD_LIBS)
+
+### includeheaders ###
+includeheadersdir = $(includedir)/media-utils
+includeheaders_HEADERS = lib/include/media-util-noti.h \
+                         lib/include/media-util-register.h \
+                         lib/include/media-util-err.h \
+                         lib/include/media-util-db.h \
+                         lib/include/media-util-ipc.h \
+                         lib/include/media-util.h \
+                         lib/include/media-server-ipc.h
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..ccdad52
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..a9d7ee4
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+rm -rf autom4te.cache
+rm -f aclocal.m4 ltmain.sh
+mkdir -p m4
+
+echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || exit 1
+echo "Running autoheader..." ; autoheader || exit 1
+echo "Running autoconf..." ; autoconf || exit 1
+echo "Running libtoolize..." ; (libtoolize --copy --automake --force || glibtoolize --automake) || exit 1
+echo "Running automake..." ; automake --add-missing --copy --foreign --force-missing || exit 1
+echo "You can now compile and build package."
diff --git a/build-aux/depcomp b/build-aux/depcomp
new file mode 100755 (executable)
index 0000000..df8eea7
--- /dev/null
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[     ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+              s/^ *//
+              s/ \\*$//
+              s/$/:/
+              p
+            }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::     \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/install-sh b/build-aux/install-sh
new file mode 100755 (executable)
index 0000000..6781b98
--- /dev/null
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""       $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+       shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+       case $mode in
+         *' '* | *'    '* | *'
+'*       | *'*'* | *'?'* | *'['*)
+           echo "$0: invalid mode: $mode" >&2
+           exit 1;;
+       esac
+       shift;;
+
+    -o) chowncmd="$chownprog $2"
+       shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+       shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)        shift
+       break;;
+
+    -*)        echo "$0: invalid option: $1" >&2
+       exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dst_arg: Is a directory" >&2
+       exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+       (dirname "$dst") 2>/dev/null ||
+       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+            X"$dst" : 'X\(//\)[^/]' \| \
+            X"$dst" : 'X\(//\)$' \| \
+            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+       echo X"$dst" |
+           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)[^/].*/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\).*/{
+                  s//\1/
+                  q
+                }
+                s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+       # Create intermediate dirs using mode 755 as modified by the umask.
+       # This is like FreeBSD 'install' as of 1997-10-28.
+       umask=`umask`
+       case $stripcmd.$umask in
+         # Optimize common cases.
+         *[2367][2367]) mkdir_umask=$umask;;
+         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+         *[0-7])
+           mkdir_umask=`expr $umask + 22 \
+             - $umask % 100 % 40 + $umask % 20 \
+             - $umask % 10 % 4 + $umask % 2
+           `;;
+         *) mkdir_umask=$umask,go-w;;
+       esac
+
+       # With -d, create the new directory with the user-specified mode.
+       # Otherwise, rely on $mkdir_umask.
+       if test -n "$dir_arg"; then
+         mkdir_mode=-m$mode
+       else
+         mkdir_mode=
+       fi
+
+       posix_mkdir=false
+       case $umask in
+         *[123567][0-7][0-7])
+           # POSIX mkdir -p sets u+wx bits regardless of umask, which
+           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+           ;;
+         *)
+           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+           if (umask $mkdir_umask &&
+               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+           then
+             if test -z "$dir_arg" || {
+                  # Check for POSIX incompatibilities with -m.
+                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                  # other-writeable bit of parent directory when it shouldn't.
+                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                  case $ls_ld_tmpdir in
+                    d????-?r-*) different_mode=700;;
+                    d????-?--*) different_mode=755;;
+                    *) false;;
+                  esac &&
+                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                  }
+                }
+             then posix_mkdir=:
+             fi
+             rmdir "$tmpdir/d" "$tmpdir"
+           else
+             # Remove any dirs left behind by ancient mkdir implementations.
+             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+           fi
+           trap '' 0;;
+       esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+       umask $mkdir_umask &&
+       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+       /*) prefix='/';;
+       -*) prefix='./';;
+       *)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+       test -z "$d" && continue
+
+       prefix=$prefix$d
+       if test -d "$prefix"; then
+         prefixes=
+       else
+         if $posix_mkdir; then
+           (umask=$mkdir_umask &&
+            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+           # Don't fail if two instances are running concurrently.
+           test -d "$prefix" || exit 1
+         else
+           case $prefix in
+             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+             *) qprefix=$prefix;;
+           esac
+           prefixes="$prefixes '$qprefix'"
+         fi
+       fi
+       prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+       # Don't fail if two instances are running concurrently.
+       (umask $mkdir_umask &&
+        eval "\$doit_exec \$mkdirprog $prefixes") ||
+         test -d "$dstdir" || exit 1
+       obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+       # Now remove or move aside any old file at destination location.
+       # We try this two ways since rm can't unlink itself on some
+       # systems and the destination file might be busy for other
+       # reasons.  In this case, the final cleanup might fail but the new
+       # file should still install successfully.
+       {
+         test ! -f "$dst" ||
+         $doit $rmcmd -f "$dst" 2>/dev/null ||
+         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+         } ||
+         { echo "$0: cannot unlink or rename $dst" >&2
+           (exit 1); exit 1
+         }
+       } &&
+
+       # Now rename the file to the real destination.
+       $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755 (executable)
index 0000000..28055d2
--- /dev/null
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+       case $LASTARG in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f y.tab.h; then
+       echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+       case $LASTARG in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f lex.yy.c; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+       /^@setfilename/{
+         s/.* \([^ ]*\) *$/\1/
+         p
+         q
+       }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case $firstarg in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case $firstarg in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/common/include/media-server-db-svc.h b/common/include/media-server-db-svc.h
new file mode 100755 (executable)
index 0000000..903837a
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-db-svc.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SERVER_DB_SVC_H_
+#define _MEDIA_SERVER_DB_SVC_H_
+
+#include "media-server-types.h"
+#if MS_INOTI_ENABLE
+typedef int (*CHECK_ITEM)(const char*, const char*, char **);
+typedef int (*CONNECT)(void**, char **);
+typedef int (*DISCONNECT)(void*, char **);
+typedef int (*CHECK_ITEM_EXIST)(void*, const char*, int, char **);
+typedef int (*INSERT_ITEM_BEGIN)(void*, int, char **);
+typedef int (*INSERT_ITEM_END)(void*, char **);
+typedef int (*INSERT_ITEM)(void*, const char*, int, const char*, char **);
+typedef int (*INSERT_ITEM_IMMEDIATELY)(void*, const char*, int, const char*, char **);
+typedef int (*MOVE_ITEM_BEGIN)(void*, int, char **);
+typedef int (*MOVE_ITEM_END)(void*, char **);
+typedef int (*MOVE_ITEM)(void*, const char*, int, const char*, int, const char*, char **);
+typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, char **);
+typedef int (*SET_ITEM_VALIDITY_BEGIN)(void*, int, char **);
+typedef int (*SET_ITEM_VALIDITY_END)(void*, char **);
+typedef int (*SET_ITEM_VALIDITY)(void*, const char*, int, const char*, int, char **);
+typedef int (*DELETE_ITEM)(void*, const char*, int, char **);
+typedef int (*DELETE_ALL_ITEMS_IN_STORAGE)(void*, int, char **);
+typedef int (*DELETE_ALL_INVALID_ITMES_IN_STORAGE)(void*, int, char **);
+typedef int (*UPDATE_BEGIN)(char **);
+typedef int (*UPDATE_END)(char **);
+typedef int (*REFRESH_ITEM)(void*, const char *, int, const char*, char**);
+
+int
+ms_load_functions(void);
+
+void
+ms_unload_functions(void);
+
+int
+ms_connect_db(void ***handle);
+
+int
+ms_disconnect_db(void ***handle);
+
+int
+ms_validate_item(void **handle, char *path);
+
+int
+ms_register_file(void **handle, const char *path, GAsyncQueue* queue);
+
+int
+ms_insert_item_batch(void **handle, const char *path);
+
+int
+ms_insert_item(void **handle, const char *path);
+
+int
+ms_delete_item(void **handle, const char *full_file_path);
+
+int
+ms_move_item(void **handle,
+                       ms_storage_type_t src_store_type,
+                       ms_storage_type_t dest_store_type,
+                       const char *src_file_full_path,
+                       const char *dest_file_full_path);
+
+bool
+ms_delete_all_items(void **handle, ms_storage_type_t store_type);
+
+int
+ms_invalidate_all_items(void **handle, ms_storage_type_t store_type);
+
+bool
+ms_delete_invalid_items(void **handle, ms_storage_type_t store_type);
+
+int
+ms_refresh_item(void **handle, const char *path);
+
+int
+ms_check_exist(void **handle, const char *path);
+
+/****************************************************************************************************
+FOR BULK COMMIT
+*****************************************************************************************************/
+
+void
+ms_register_start(void **handle);
+
+void
+ms_register_end(void **handle);
+
+void
+ms_move_start(void **handle);
+
+void
+ms_move_end(void **handle);
+
+void
+ms_validate_start(void **handle);
+
+void
+ms_validate_end(void **handle);
+#else
+typedef int (*CHECK_ITEM)(const char*, const char*, char **);
+typedef int (*CONNECT)(void**, char **);
+typedef int (*DISCONNECT)(void*, char **);
+typedef int (*CHECK_ITEM_EXIST)(void*, const char*, int, char **);
+typedef int (*INSERT_ITEM_IMMEDIATELY)(void*, const char*, int, const char*, char **);
+typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, char **);
+
+int
+ms_load_functions(void);
+
+void
+ms_unload_functions(void);
+
+int
+ms_connect_db(void ***handle);
+
+int
+ms_disconnect_db(void ***handle);
+
+int
+ms_insert_item(void **handle, const char *path);
+
+int
+ms_register_file(void **handle, const char *path);
+
+int
+ms_check_exist(void **handle, const char *path);
+
+int
+ms_invalidate_all_items(void **handle, ms_storage_type_t store_type);
+#endif
+
+#endif /*_MEDIA_SERVER_DB_SVC_H_*/
diff --git a/common/include/media-server-db.h b/common/include/media-server-db.h
new file mode 100755 (executable)
index 0000000..87f0b00
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  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_SERVER_DB_H_
+#define _MEDIA_SERVER_DB_H_
+
+#include <glib.h>
+
+GMainLoop *ms_db_get_mainloop(void);
+gboolean ms_db_get_thread_status(void);
+gboolean ms_db_thread(void *data);
+
+#endif/* _MEDIA_SERVER_DB_H_ */
diff --git a/common/include/media-server-dbg.h b/common/include/media-server-dbg.h
new file mode 100755 (executable)
index 0000000..64122bc
--- /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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-dbg.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SERVER_DBG_H_
+#define _MEDIA_SERVER_DBG_H_
+
+#include <sys/syscall.h>
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MEDIA_SERVER"
+
+#define MS_DBG(fmt, args...)        LOGD(fmt "\n", ##args);
+
+#define MS_DBG_INFO(fmt, args...) do{ if (true) { \
+               LOGE(fmt "\n" , ##args); \
+               }} while(false)
+
+#define MS_DBG_WARN(fmt, args...) do{ if (true) { \
+               LOGW(fmt "\n", ##args); \
+               }} while(false)
+
+#define MS_DBG_ERR(fmt, args...) do{ if (true) { \
+               LOGE(fmt "\n", ##args); \
+               }} while(false)
+
+#endif /*_MEDIA_SERVER_DBG_H_*/
diff --git a/common/include/media-server-dbus-type.h b/common/include/media-server-dbus-type.h
new file mode 100755 (executable)
index 0000000..54c227a
--- /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_SERVER_DBUS_TYPES_H_
+#define _MEDIA_SERVER_DBUS_TYPES_H_
+
+#define MS_DBUS_PATH "/com/mediaserver/dbus/notify"
+#define MS_DBUS_INTERFACE "com.mediaserver.dbus.Signal"
+#define MS_DBUS_NAME "ms_db_updated"
+#define MS_DBUS_MATCH_RULE "type='signal',interface='com.mediaserver.dbus.Signal'"
+
+typedef enum {
+       MS_DBUS_DB_UPDATED
+} ms_dbus_noti_type_t;
+
+#endif /*_MEDIA_SERVER_DBUS_TYPES_H_*/
\ No newline at end of file
diff --git a/common/include/media-server-dbus.h b/common/include/media-server-dbus.h
new file mode 100755 (executable)
index 0000000..241d543
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  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_SERVER_DBUS_H__
+#define _MEDIA_SERVER_DBUS_H__
+
+#include "media-server-dbus-type.h"
+
+void ms_dbus_init(void);
+
+gboolean ms_dbus_send_noti(ms_dbus_noti_type_t data);
+
+#endif/*_MEDIA_SERVER_DBUS_H__*/
\ No newline at end of file
diff --git a/common/include/media-server-drm.h b/common/include/media-server-drm.h
new file mode 100755 (executable)
index 0000000..27f3dc6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-drm.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+#ifndef _MEDIA_SERVER_DRM_H_
+#define _MEDIA_SERVER_DRM_H_
+
+bool
+ms_is_drm_file(const char *path);
+
+int
+ms_get_mime_in_drm_info(const char *path, char *mime);
+
+int
+ms_drm_register(const char* path);
+
+void
+ms_drm_unregister(const char* path);
+
+void
+ms_drm_unregister_all(void);
+
+bool
+ms_drm_insert_ext_memory(void);
+
+bool
+ms_drm_extract_ext_memory(void);
+
+#endif /*_MEDIA_SERVER_DRM_H_*/
\ No newline at end of file
diff --git a/common/include/media-server-external-storage.h b/common/include/media-server-external-storage.h
new file mode 100755 (executable)
index 0000000..d7deb2c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  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_SERVER_EXTERNAL_STORAGE_H_
+#define _MEDIA_SERVER_EXTERNAL_STORAGE_H_
+
+#include "media-server-types.h"
+
+void
+ms_make_default_path_mmc(void);
+
+int
+ms_update_mmc_info(void);
+
+void
+ms_mmc_removed_handler(void);
+
+int
+ms_present_mmc_insert(void);
+
+void
+ms_mmc_vconf_cb(void *data);
+
+ms_dir_scan_type_t
+ms_get_mmc_state(void);
+
+#endif /*_MEDIA_SERVER_EXTERNAL_STORAGE_H_*/
diff --git a/common/include/media-server-inotify-internal.h b/common/include/media-server-inotify-internal.h
new file mode 100755 (executable)
index 0000000..bbd260c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-inotify-internal.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief              
+ */
+#ifndef _MEDIA_SERVER_INOTIFY_INTERNAL_H_
+#define _MEDIA_SERVER_INOTIFY_INTERNAL_H_
+
+#include <sys/inotify.h>
+#include "media-server-types.h"
+#if MS_INOTI_ENABLE
+#define INOTI_EVENT_SIZE (sizeof(struct inotify_event))
+#define INOTI_BUF_LEN (1024*(INOTI_EVENT_SIZE+16))
+#define INOTI_FOLDER_COUNT_MAX 1024
+
+typedef struct ms_inoti_dir_data {
+       char *name;
+       int wd;
+       struct ms_inoti_dir_data *next;
+} ms_inoti_dir_data;
+
+typedef struct ms_create_file_info {
+       char *name;
+       int wd;
+       struct ms_create_file_info *previous;
+       struct ms_create_file_info *next;
+} ms_create_file_info;
+
+int _ms_inoti_add_create_file_list(int wd, char *name);
+
+int _ms_inoti_delete_create_file_list(ms_create_file_info *node);
+
+ms_create_file_info *_ms_inoti_find_create_file_list(int wd, char *name);
+
+bool _ms_inoti_full_path(int wd, char *name, char *path, int sizeofpath);
+
+bool _ms_inoti_get_full_path(int wd, char *name, char *path, int sizeofpath);
+#endif
+#endif /*_MEDIA_SERVER_INOTIFY_INTERNAL_H_*/
diff --git a/common/include/media-server-inotify.h b/common/include/media-server-inotify.h
new file mode 100755 (executable)
index 0000000..c35d071
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-inotify.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SERVER_INOTI_H_
+#define _MEDIA_SERVER_INOTI_H_
+
+#include <glib.h>
+#include "media-server-types.h"
+
+#if MS_INOTI_ENABLE
+
+typedef struct ms_ignore_file_info {
+       char *path;
+       struct ms_ignore_file_info *previous;
+       struct ms_ignore_file_info *next;
+} ms_ignore_file_info;
+
+int ms_inoti_init(void);
+
+gboolean ms_inoti_thread(gpointer data);
+
+void ms_inoti_add_watch(char *path);
+
+int ms_inoti_add_watch_with_node(ms_dir_scan_info * const current_node, int depth);
+
+void ms_inoti_remove_watch_recursive(char *path);
+
+void ms_inoti_remove_watch(char *path);
+
+void ms_inoti_modify_watch(char *path_from, char *path_to);
+
+int ms_inoti_add_ignore_file(const char *path);
+
+int ms_inoti_delete_ignore_file(ms_ignore_file_info * delete_node);
+
+ms_ignore_file_info *ms_inoti_find_ignore_file(const char *path);
+
+void ms_inoti_delete_mmc_ignore_file(void);
+
+void ms_inoti_add_watch_all_directory(ms_storage_type_t storage_type);
+
+#endif
+#endif/* _MEDIA_SERVER_INOTI_H_ */
diff --git a/common/include/media-server-scanner.h b/common/include/media-server-scanner.h
new file mode 100755 (executable)
index 0000000..735a5df
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  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.
+ *
+ */
+
+int ms_scanner_start(void);
+
+bool ms_get_scanner_status(void);
+
+void ms_reset_scanner_status(void);
+
+int ms_get_scanner_pid(void);
\ No newline at end of file
diff --git a/common/include/media-server-socket.h b/common/include/media-server-socket.h
new file mode 100755 (executable)
index 0000000..f75c981
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-thumb.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SERVER_SOCKET_H_
+#define _MEDIA_SERVER_SOCKET_H_
+
+#include "media-server-types.h"
+#include "media-server-ipc.h"
+
+gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data);
+
+gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data);
+
+int ms_send_scan_request(ms_comm_msg_s *send_msg);
+
+int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type);
+
+gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data);
+gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data);
+
+#endif /*_MEDIA_SERVER_SOCKET_H_*/
diff --git a/common/include/media-server-thumb.h b/common/include/media-server-thumb.h
new file mode 100755 (executable)
index 0000000..f8dc096
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * media-thumbnail-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyunjun Ko <zzoon.ko@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 <glib.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include "media-server-types.h"
+#include "media-server-ipc.h"
+
+#ifndef _MEDIA_SERVER_THUMB_H_
+#define _MEDIA_SERVER_THUMB_H_
+
+GMainLoop *
+ms_get_thumb_thread_mainloop(void);
+
+int
+ms_thumb_get_server_pid();
+
+void
+ms_thumb_reset_server_status();
+
+gpointer
+ms_thumb_agent_start_thread(gpointer data);
+
+int
+_ms_thumb_create_socket(int sock_type, int *sock);
+
+int
+_ms_thumb_create_udp_socket(int *sock);
+
+gboolean
+_ms_thumb_agent_prepare_udp_socket();
+
+int
+_ms_thumb_recv_msg(int sock, int header_size, thumbMsg *msg);
+
+int
+_ms_thumb_recv_udp_msg(int sock, int header_size, thumbMsg *msg, struct sockaddr_in *from_addr, unsigned int *from_size);
+
+int
+_ms_thumb_set_buffer(thumbMsg *req_msg, unsigned char **buf, int *buf_size);
+
+#endif /*_MEDIA_SERVER_THUMB_H_*/
+
diff --git a/common/include/media-server-types.h b/common/include/media-server-types.h
new file mode 100755 (executable)
index 0000000..994493c
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-types.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SERVER_TYPES_H_
+#define _MEDIA_SERVER_TYPES_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#define FMS_PERF
+#define MS_INOTI_ENABLE 0
+
+#define MS_VALIND 1
+#define MS_INVALID 0
+#define MS_RECURSIVE 1
+#define MS_NON_RECURSIVE 0
+
+/*This macro is used to save and check information of inserted memory card*/
+#define MS_MMC_INFO_KEY "db/private/mediaserver/mmc_info"
+
+/* store scanning status of each storage */
+#define MS_SCAN_STATUS_INTERNAL "file/private/mediaserver/scan_internal"
+#define MS_SCAN_STATUS_DIRECTORY "file/private/mediaserver/scan_directory"
+enum{
+       P_VCONF_SCAN_DOING = 0,
+       P_VCONF_SCAN_DONE,
+};
+
+/*Use for Poweroff sequence*/
+#define POWEROFF_NOTI_NAME "power_off_start" /*poeroff noti from system-server*/
+#define POWEROFF_DIR_PATH "/opt/usr/media/_POWER_OFF" /*This path uses for stopping Inotify thread and Socket thread*/
+#define POWEROFF_DIR_NAME "_POWER_OFF" /*This path uses for stopping Inotify thread and Socket thread*/
+#define POWEROFF -1 /*This number uses for stopping Scannig thread*/
+
+#define MS_SAFE_FREE(src)      { if(src) {free(src); src = NULL;} }
+#define MS_MALLOC(src, size)   { if (size > SIZE_MAX || size <= 0) {src = NULL;} \
+                                                       else { src = malloc(size); memset(src, 0x0, size);} }
+
+/*System default folder definition*/
+#define FAT_FILENAME_LEN_MAX          255      /* not inc null */
+#define FAT_FILEPATH_LEN_MAX          4096     /* inc null */
+
+/* The following MACROs(TAF_XXX) are defined in "fs-limit.h"*/
+#define MS_FILE_NAME_LEN_MAX     FAT_FILENAME_LEN_MAX           /**< File name max length on file system */
+#define MS_FILE_PATH_LEN_MAX     FAT_FILEPATH_LEN_MAX           /**< File path max length (include file name) on file system */
+
+#define MS_SOCK_NOT_ALLOCATE -1
+
+typedef enum {
+       MS_STORAGE_INTERNAL,    /**< Stored only in phone */
+       MS_STORAGE_EXTERNAL,         /**< Stored only in MMC */
+} ms_storage_type_t;
+
+typedef enum {
+       MS_SCANNING_INTERNAL,
+       MS_SCANNING_EXTERNAL,
+       MS_SCANNING_DIRECTORY,
+} ms_scanning_location_t;
+
+typedef enum {
+       MS_SCAN_INVALID,
+       MS_SCAN_PART,
+       MS_SCAN_ALL,
+} ms_dir_scan_type_t;
+
+typedef enum {
+       MS_DB_UPDATING = 0,
+       MS_DB_UPDATED = 1
+} ms_db_status_type_t;
+
+typedef struct ms_dir_scan_info {
+       char *name;
+       struct ms_dir_scan_info *parent;
+       struct ms_dir_scan_info *Rbrother;
+       struct ms_dir_scan_info *next;
+} ms_dir_scan_info;
+
+typedef struct {
+       char *path;
+       ms_storage_type_t storage_type;
+       ms_dir_scan_type_t scan_type;
+       int pid;
+       bool recursive_on;
+} ms_scan_data_t;
+
+typedef struct {
+       char *path;
+       int pid;
+} ms_register_data_t;
+
+/**
+ * @}
+ */
+
+#endif /*_MEDIA_SERVER_TYPES_H_*/
diff --git a/common/include/media-server-utils.h b/common/include/media-server-utils.h
new file mode 100755 (executable)
index 0000000..d8b6d96
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-utils.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SERVER_UTILS_H__
+#define _MEDIA_SERVER_UTILS_H__
+
+#include "media-server-types.h"
+
+int
+ms_set_db_status(ms_db_status_type_t status);
+
+int
+ms_db_init(bool need_db_create);
+
+bool
+ms_is_mmc_inserted(void);
+
+void
+ms_usb_vconf_cb(void *data);
+
+int
+ms_start(bool need_db_create);
+
+void
+ms_end(void);
+
+int
+ms_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path, int depth);
+
+ms_storage_type_t
+ms_get_storage_type_by_full(const char *path);
+
+int
+ms_strappend(char *res, const int size, const char *pattern,
+                const char *str1, const char *str2);
+
+int
+ms_strcopy(char *res, const int size, const char *pattern,
+              const char *str1);
+
+bool
+ms_config_get_int(const char *key, int *value);
+
+bool
+ms_config_set_int(const char *key, int value);
+
+bool
+ms_config_get_str(const char *key, char *value);
+
+bool
+ms_config_set_str(const char *key, const char *value);
+
+#ifdef FMS_PERF
+void
+ms_check_start_time(struct timeval *start_time);
+
+void
+ms_check_end_time(struct timeval *end_time);
+
+void
+ms_check_time_diff(struct timeval *start_time, struct timeval *end_time);
+#endif/*FMS_PERF */
+
+
+/**
+ * @}
+ */
+#endif/*_MEDIA_SERVER_UTILS_H__*/
+
diff --git a/common/media-server-db-svc.c b/common/media-server-db-svc.c
new file mode 100755 (executable)
index 0000000..77a320f
--- /dev/null
@@ -0,0 +1,1297 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-db-svc.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+
+#include <dlfcn.h>
+#include <aul/aul.h>
+
+#include "media-util.h"
+
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-inotify.h"
+#include "media-server-drm.h"
+#include "media-server-db-svc.h"
+#if MS_INOTI_ENABLE
+GAsyncQueue* soc_queue;
+GArray *reg_list;
+GMutex *list_mutex;
+GMutex *queue_mutex;
+GMutex * db_mutex;
+
+#define MS_REGISTER_COUNT 100 /*For bundle commit*/
+#define MS_VALID_COUNT 100 /*For bundle commit*/
+#define MS_MOVE_COUNT 100 /*For bundle commit*/
+
+void **func_handle = NULL; /*dlopen handel*/
+
+enum func_list {
+       eCHECK,
+       eCONNECT,
+       eDISCONNECT,
+       eEXIST,
+       eINSERT_BEGIN,
+       eINSERT_END,
+       eINSERT_BATCH,
+       eINSERT,
+       eMOVE_BEGIN,
+       eMOVE_END,
+       eMOVE,
+       eSET_ALL_VALIDITY,
+       eSET_VALIDITY_BEGIN,
+       eSET_VALIDITY_END,
+       eSET_VALIDITY,
+       eDELETE,
+       eDELETE_ALL,
+       eDELETE_INVALID_ITEMS,
+       eUPDATE_BEGIN,
+       eUPDATE_END,
+       eREFRESH_ITEM,
+       eFUNC_MAX
+};
+
+static void
+_ms_insert_reg_list(const char *path)
+{
+       char *reg_path = strdup(path);
+
+       g_mutex_lock(list_mutex);
+
+       g_array_append_val(reg_list, reg_path);
+
+       g_mutex_unlock(list_mutex);
+}
+
+static bool
+_ms_find_reg_list(const char *path)
+{
+       int list_index;
+       int len = reg_list->len;
+       char *data;
+       bool res = false;
+
+       g_mutex_lock(list_mutex);
+       MS_DBG("array length : %d", len);
+
+       for(list_index = 0; list_index < len; list_index++) {
+               data = g_array_index (reg_list, char*, list_index);
+               if(!strcmp(data, path))
+                       res = true;
+       }
+
+       g_mutex_unlock(list_mutex);
+
+       return res;
+}
+
+static void
+_ms_delete_reg_list(const char *path)
+{
+       int list_index;
+       int len = reg_list->len;
+       char *data;
+
+       MS_DBG("Delete : %s", path);
+       g_mutex_lock(list_mutex);
+
+       for(list_index = 0; list_index < len; list_index++) {
+               data = g_array_index (reg_list, char*, list_index);
+               if(!strcmp(data, path)) {
+                       MS_DBG("Delete complete : %s", data);
+                       MS_SAFE_FREE(data);
+                       g_array_remove_index(reg_list, list_index);
+                       break;
+               }
+       }
+
+       g_mutex_unlock(list_mutex);
+}
+
+static int
+_ms_get_mime(const char *path, char *mimetype)
+{
+       int ret = 0;
+
+       if (path == NULL)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       /*get content type and mime type from file. */
+       /*in case of drm file. */
+       if (ms_is_drm_file(path)) {
+#if MS_INOTI_ENABLE
+               ms_inoti_add_ignore_file(path);
+#endif
+               ret =  ms_get_mime_in_drm_info(path, mimetype);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("Fail to get mime");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       } else {
+               /*in case of normal files */
+               if (aul_get_mime_from_file(path, mimetype, 255) < 0) {
+                       MS_DBG_ERR("aul_get_mime_from_file fail");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+#define CONFIG_PATH "/opt/usr/data/file-manager-service/plugin-config"
+#define EXT ".so"
+#define EXT_LEN 3
+
+GArray *so_array;
+void ***func_array;
+int lib_num;
+
+static int
+_ms_check_category(const char *path, const char *mimetype, int index)
+{
+       int ret;
+       char *err_msg = NULL;
+
+       ret = ((CHECK_ITEM)func_array[index][eCHECK])(path, mimetype, &err_msg);
+       if (ret != 0) {
+               MS_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, index), err_msg, path);
+               MS_SAFE_FREE(err_msg);
+       }
+
+       return ret;
+}
+
+static int
+_ms_token_data(char *buf, char **name)
+{
+       int len;
+       char* pos = NULL;
+
+       pos = strstr(buf, EXT);
+       if (pos == NULL) {
+               MS_DBG_ERR("This is not shared object library.");
+               name = NULL;
+               return -1;
+       } else {
+               len = pos - buf + EXT_LEN;
+               *name = strndup(buf, len);
+               MS_DBG("%s", *name);
+       }
+
+       return 0;
+}
+
+
+static bool
+_ms_load_config()
+{
+       int ret;
+       FILE *fp;
+       char *so_name = NULL;
+       char buf[256] = {0};
+
+       fp = fopen(CONFIG_PATH, "rt");
+       if (fp == NULL) {
+               MS_DBG_ERR("fp is NULL");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+       while(1) {
+               if (fgets(buf, 256, fp) == NULL) {
+                       MS_DBG_ERR("fgets failed");
+                       break;
+               }
+
+               ret = _ms_token_data(buf, &so_name);
+               if (ret == 0) {
+                       /*add to array*/
+                       g_array_append_val(so_array, so_name);
+                       so_name = NULL;
+               }
+       }
+
+       fclose(fp);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_load_functions(void)
+{
+       int lib_index = 0, func_index;
+       char func_list[eFUNC_MAX][40] = {
+               "check_item",
+               "connect",
+               "disconnect",
+               "check_item_exist",
+               "insert_item_begin",
+               "insert_item_end",
+               "insert_item",
+               "insert_item_immediately",
+               "move_item_begin",
+               "move_item_end",
+               "move_item",
+               "set_all_storage_items_validity",
+               "set_item_validity_begin",
+               "set_item_validity_end",
+               "set_item_validity",
+               "delete_item",
+               "delete_all_items_in_storage",
+               "delete_all_invalid_items_in_storage",
+               "update_begin",
+               "update_end",
+               "refresh_item"
+               };
+       /*init array for adding name of so*/
+       so_array = g_array_new(FALSE, FALSE, sizeof(char*));
+
+       /*load information of so*/
+       _ms_load_config();
+
+       if(so_array->len == 0) {
+               MS_DBG("There is no information for functions");
+               return MS_MEDIA_ERR_DYNAMIC_LINK;
+       }
+
+       /*the number of functions*/
+       lib_num = so_array->len;
+
+       MS_DBG("The number of information of so : %d", lib_num);
+       MS_MALLOC(func_handle, sizeof(void*) * lib_num);
+       if (func_handle == NULL) {
+               MS_DBG_ERR("malloc failed");
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       while(lib_index < lib_num) {
+               /*get handle*/
+               MS_DBG("[name of so : %s]", g_array_index(so_array, char*, lib_index));
+               func_handle[lib_index] = dlopen(g_array_index(so_array, char*, lib_index), RTLD_LAZY);
+               if (!func_handle[lib_index]) {
+                       MS_DBG_ERR("%s", dlerror());
+                       MS_SAFE_FREE(func_handle);
+                       return MS_MEDIA_ERR_DYNAMIC_LINK;
+               }
+               lib_index++;
+       }
+
+       dlerror();    /* Clear any existing error */
+
+       /*allocate for array of functions*/
+       MS_MALLOC(func_array, sizeof(void*) * lib_num);
+       if (func_array == NULL) {
+               MS_DBG_ERR("malloc failed");
+               MS_SAFE_FREE(func_handle);
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       for(lib_index = 0 ; lib_index < lib_num; lib_index ++) {
+               MS_MALLOC(func_array[lib_index], sizeof(void*) * eFUNC_MAX);
+               if (func_array[lib_index] == NULL) {
+                       int index;
+
+                       for (index = 0; index < lib_index; index ++) {
+                               MS_SAFE_FREE(func_array[index]);
+                       }
+                       MS_SAFE_FREE(func_array);
+                       MS_SAFE_FREE(func_handle);
+
+                       MS_DBG_ERR("malloc failed");
+                       return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+               }
+       }
+
+       /*add functions to array */
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               for (func_index = 0; func_index < eFUNC_MAX ; func_index++) {
+                       func_array[lib_index][func_index] = dlsym(func_handle[lib_index], func_list[func_index]);
+                       if (func_array[lib_index][func_index] == NULL) {
+                               int index;
+
+                               for (index = 0; index < lib_index; index ++) {
+                                       MS_SAFE_FREE(func_array[index]);
+                               }
+                               MS_SAFE_FREE(func_array);
+                               MS_SAFE_FREE(func_handle);
+
+                               MS_DBG_ERR("dlsym failed");
+                               return MS_MEDIA_ERR_DYNAMIC_LINK;
+                       }
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void
+ms_unload_functions(void)
+{
+       int lib_index;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index ++)
+               dlclose(func_handle[lib_index]);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+                       if (func_array[lib_index]) {
+                               MS_SAFE_FREE(func_array[lib_index]);
+                       }
+       }
+
+       MS_SAFE_FREE (func_array);
+       MS_SAFE_FREE (func_handle);
+       if (so_array) g_array_free(so_array, TRUE);
+}
+
+int
+ms_connect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       /*Lock mutex for openning db*/
+       g_mutex_lock(db_mutex);
+
+       MS_MALLOC(*handle, sizeof (void*) * lib_num);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CONNECT)func_array[lib_index][eCONNECT])(&((*handle)[lib_index]), &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       g_mutex_unlock(db_mutex);
+
+                       return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+               }
+       }
+
+       MS_DBG("connect Media DB");
+
+       g_mutex_unlock(db_mutex);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_disconnect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DISCONNECT)func_array[lib_index][eDISCONNECT])((*handle)[lib_index], &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return MS_MEDIA_ERR_DB_DISCONNECT_FAIL;
+               }
+       }
+
+       MS_SAFE_FREE(*handle);
+
+       MS_DBG("Disconnect Media DB");
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_validate_item(void **handle, char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+       char mimetype[255] = {0};
+       ms_storage_type_t storage_type;
+
+       ret = _ms_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = ms_get_storage_type_by_full(path);
+
+       MS_DBG("[%s] %s", mimetype, path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(path, mimetype, lib_index)) {
+                       /*check exist in Media DB, If file is not exist, insert data in DB. */
+                       ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG("not exist in %d. insert data", lib_index);
+                               MS_SAFE_FREE(err_msg);
+
+                               ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, mimetype, &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);
+                                       res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                               }
+                       } else {
+                               /*if meta data of file exist, change valid field to "1" */
+                               ret = ((SET_ITEM_VALIDITY)func_array[lib_index][eSET_VALIDITY])(handle[lib_index], path, true, mimetype, true, &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);
+                                       res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+                               }
+                       }
+               }
+       }
+
+       if (ms_is_drm_file(path)) {
+               ret = ms_drm_register(path);
+       }
+
+       return res;
+}
+
+int
+ms_invalidate_all_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+       MS_DBG("");
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ALL_STORAGE_ITEMS_VALIDITY)func_array[lib_index][eSET_ALL_VALIDITY])(handle[lib_index], store_type, false, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+               }
+       }
+       MS_DBG("");
+       return res;
+}
+
+int
+ms_register_file(void **handle, const char *path, GAsyncQueue* queue)
+{
+       MS_DBG("[%d]register file : %s", syscall(__NR_gettid), path);
+
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+
+       if (path == NULL) {
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       /*check item in DB. If it exist in DB, return directly.*/
+       ret = ms_check_exist(handle, path);
+       if (ret == MS_MEDIA_ERR_NONE) {
+               MS_DBG("Already exist");
+               return MS_MEDIA_ERR_NONE;
+       }
+
+       g_mutex_lock(queue_mutex);
+       /*first request for this file*/
+       if(!_ms_find_reg_list(path)) {
+               /*insert registering file list*/
+               _ms_insert_reg_list(path);
+       } else {
+               MS_DBG("______________________ALREADY INSERTING");
+               if(queue != NULL) {
+                       MS_DBG("Need reply");
+                       soc_queue = queue;
+               }
+               g_mutex_unlock(queue_mutex);
+               return MS_MEDIA_ERR_NOW_REGISTER_FILE;
+       }
+       g_mutex_unlock(queue_mutex);
+
+       ret = ms_insert_item(handle, path);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               int lib_index;
+               char mimetype[255];
+               ms_storage_type_t storage_type;
+
+               ret = _ms_get_mime(path, mimetype);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+                       res = MS_MEDIA_ERR_MIME_GET_FAIL;
+                       goto END;
+               }
+               storage_type = ms_get_storage_type_by_full(path);
+
+               MS_DBG("[%s] %s", mimetype, path);
+
+               for (lib_index = 0; lib_index < lib_num; lib_index++) {
+                       /*check item is already inserted*/
+                       if (!_ms_check_category(path, mimetype, lib_index)) {
+                               char *err_msg = NULL;
+
+                               ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+                               if (ret == 0) {
+                                       res = MS_MEDIA_ERR_NONE;
+                               } else {
+                                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                                       MS_SAFE_FREE(err_msg);
+                                       res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                               }
+                       }
+               }
+       }
+END:
+       if (ms_is_drm_file(path)) {
+               ret = ms_drm_register(path);
+       }
+
+       g_mutex_lock(queue_mutex);
+
+       _ms_delete_reg_list(path);
+
+       if (soc_queue != NULL) {
+               MS_DBG("%d", res);
+               g_async_queue_push(soc_queue, GINT_TO_POINTER(res+MS_MEDIA_ERR_MAX));
+               MS_DBG("Return OK");
+       }
+       soc_queue = NULL;
+       g_mutex_unlock(queue_mutex);
+
+       return res;
+}
+
+int
+ms_insert_item_batch(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255] = {0};
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       ret = _ms_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = ms_get_storage_type_by_full(path);
+
+       MS_DBG("[%s] %s", mimetype, path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(path, mimetype, lib_index)) {
+                       ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                       }
+               }
+       }
+
+       if (ms_is_drm_file(path)) {
+               ret = ms_drm_register(path);
+               res = ret;
+       }
+
+       return res;
+}
+
+int
+ms_insert_item(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255] = {0};
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       ret = _ms_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = ms_get_storage_type_by_full(path);
+
+       MS_DBG("[%s] %s", mimetype, path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(path, mimetype, lib_index)) {
+                       ret = ((INSERT_ITEM_IMMEDIATELY)func_array[lib_index][eINSERT])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                       }
+               }
+       }
+
+       return res;
+}
+
+int
+ms_delete_item(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       storage_type = ms_get_storage_type_by_full(path);
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+               if (ret == 0) {
+                       ret = ((DELETE_ITEM)func_array[lib_index][eDELETE])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+                       if (ret !=0 ) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_DELETE_FAIL;
+                       }
+               } else {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       res = MS_MEDIA_ERR_DB_DELETE_FAIL;
+               }
+       }
+
+       if (ms_is_drm_file(path)) {
+               ms_drm_unregister(path);
+       }
+
+       return res;
+}
+
+int
+ms_move_item(void **handle,
+               ms_storage_type_t src_store, ms_storage_type_t dst_store,
+               const char *src_path, const char *dst_path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255];
+       char *err_msg = NULL;
+
+       ret = _ms_get_mime(dst_path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       MS_DBG("[%s] %s", mimetype, dst_path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(dst_path, mimetype, lib_index)) {
+                       ret = ((MOVE_ITEM)func_array[lib_index][eMOVE])(handle[lib_index], src_path, src_store,
+                                                       dst_path, dst_store, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+                       }
+               }
+       }
+
+       return res;
+}
+
+bool
+ms_delete_all_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       /* To reset media db when differnet mmc is inserted. */
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DELETE_ALL_ITEMS_IN_STORAGE)func_array[lib_index][eDELETE_ALL])(handle[lib_index], store_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+bool
+ms_delete_invalid_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DELETE_ALL_INVALID_ITMES_IN_STORAGE)func_array[lib_index][eDELETE_INVALID_ITEMS])(handle[lib_index], store_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+int
+ms_refresh_item(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255];
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       ret = _ms_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       MS_DBG("[%s] %s", mimetype, path);
+
+       storage_type = ms_get_storage_type_by_full(path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(path, mimetype, lib_index)) {
+                       ret = ((REFRESH_ITEM)func_array[lib_index][eREFRESH_ITEM])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+                       }
+               }
+       }
+
+       return res;
+}
+
+int
+ms_check_exist(void **handle, const char *path)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       storage_type = ms_get_storage_type_by_full(path);
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       return MS_MEDIA_ERR_DB_EXIST_ITEM_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+/****************************************************************************************************
+FOR BULK COMMIT
+*****************************************************************************************************/
+
+void
+ms_register_start(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((INSERT_ITEM_BEGIN)func_array[lib_index][eINSERT_BEGIN])(handle[lib_index], MS_REGISTER_COUNT, &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+ms_register_end(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((INSERT_ITEM_END)func_array[lib_index][eINSERT_END])(handle[lib_index], &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+ms_validate_start(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ITEM_VALIDITY_BEGIN)func_array[lib_index][eSET_VALIDITY_BEGIN])(handle[lib_index], MS_VALID_COUNT, &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+ms_validate_end(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ITEM_VALIDITY_END)func_array[lib_index][eSET_VALIDITY_END])(handle[lib_index], &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+ms_move_start(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((MOVE_ITEM_BEGIN)func_array[lib_index][eMOVE_BEGIN])(handle[lib_index], MS_MOVE_COUNT, &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+ms_move_end(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+              ret = ((MOVE_ITEM_END)func_array[lib_index][eMOVE_END])(handle[lib_index], &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+#else
+
+GMutex * db_mutex;
+#define CONFIG_PATH "/opt/usr/data/file-manager-service/plugin-config"
+#define EXT ".so"
+#define EXT_LEN 3
+
+GArray *so_array;
+void ***func_array;
+int lib_num;
+
+void **func_handle = NULL; /*dlopen handle*/
+
+enum func_list {
+       eCHECK,
+       eCONNECT,
+       eDISCONNECT,
+       eEXIST,
+       eINSERT,
+       eSET_ALL_VALIDITY,
+       eFUNC_MAX
+};
+
+static int
+_ms_get_mime(const char *path, char *mimetype)
+{
+       int ret = 0;
+
+       if (path == NULL)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       /*get content type and mime type from file. */
+       /*in case of drm file. */
+       if (ms_is_drm_file(path)) {
+#if MS_INOTI_ENABLE
+               ms_inoti_add_ignore_file(path);
+#endif
+               ret =  ms_get_mime_in_drm_info(path, mimetype);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("Fail to get mime");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       } else {
+               /*in case of normal files */
+               if (aul_get_mime_from_file(path, mimetype, 255) < 0) {
+                       MS_DBG_ERR("aul_get_mime_from_file fail");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int
+_ms_check_category(const char *path, const char *mimetype, int index)
+{
+       int ret;
+       char *err_msg = NULL;
+
+       ret = ((CHECK_ITEM)func_array[index][eCHECK])(path, mimetype, &err_msg);
+       if (ret != 0) {
+               MS_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, index), err_msg, path);
+               MS_SAFE_FREE(err_msg);
+       }
+
+       return ret;
+}
+
+static int
+_ms_token_data(char *buf, char **name)
+{
+       int len;
+       char* pos = NULL;
+
+       pos = strstr(buf, EXT);
+       if (pos == NULL) {
+               MS_DBG_ERR("This is not shared object library.");
+               name = NULL;
+               return -1;
+       } else {
+               len = pos - buf + EXT_LEN;
+               *name = strndup(buf, len);
+               MS_DBG("%s", *name);
+       }
+
+       return 0;
+}
+
+static bool
+_ms_load_config()
+{
+       int ret;
+       FILE *fp;
+       char *so_name = NULL;
+       char buf[256] = {0};
+
+       fp = fopen(CONFIG_PATH, "rt");
+       if (fp == NULL) {
+               MS_DBG_ERR("fp is NULL");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+       while(1) {
+               if (fgets(buf, 256, fp) == NULL) {
+                       MS_DBG_ERR("fgets failed");
+                       break;
+               }
+
+               ret = _ms_token_data(buf, &so_name);
+               if (ret == 0) {
+                       /*add to array*/
+                       g_array_append_val(so_array, so_name);
+                       so_name = NULL;
+               }
+       }
+
+       fclose(fp);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_load_functions(void)
+{
+       int lib_index = 0, func_index;
+       char func_list[eFUNC_MAX][40] = {
+               "check_item",
+               "connect",
+               "disconnect",
+               "check_item_exist",
+               "insert_item_immediately",
+               "set_all_storage_items_validity",
+               };
+       /*init array for adding name of so*/
+       so_array = g_array_new(FALSE, FALSE, sizeof(char*));
+
+       /*load information of so*/
+       _ms_load_config();
+
+       if(so_array->len == 0) {
+               MS_DBG("There is no information for functions");
+               return MS_MEDIA_ERR_DYNAMIC_LINK;
+       }
+
+       /*the number of functions*/
+       lib_num = so_array->len;
+
+       MS_DBG("The number of information of so : %d", lib_num);
+       MS_MALLOC(func_handle, sizeof(void*) * lib_num);
+       if (func_handle == NULL) {
+               MS_DBG_ERR("malloc failed");
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       while(lib_index < lib_num) {
+               /*get handle*/
+               MS_DBG("[name of so : %s]", g_array_index(so_array, char*, lib_index));
+               func_handle[lib_index] = dlopen(g_array_index(so_array, char*, lib_index), RTLD_LAZY);
+               if (!func_handle[lib_index]) {
+                       MS_DBG_ERR("%s", dlerror());
+                       MS_SAFE_FREE(func_handle);
+                       return MS_MEDIA_ERR_DYNAMIC_LINK;
+               }
+               lib_index++;
+       }
+
+       dlerror();    /* Clear any existing error */
+
+       /*allocate for array of functions*/
+       MS_MALLOC(func_array, sizeof(void*) * lib_num);
+       if (func_array == NULL) {
+               MS_DBG_ERR("malloc failed");
+               MS_SAFE_FREE(func_handle);
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       for(lib_index = 0 ; lib_index < lib_num; lib_index ++) {
+               MS_MALLOC(func_array[lib_index], sizeof(void*) * eFUNC_MAX);
+               if (func_array[lib_index] == NULL) {
+                       int index;
+
+                       for (index = 0; index < lib_index; index ++) {
+                               MS_SAFE_FREE(func_array[index]);
+                       }
+                       MS_SAFE_FREE(func_array);
+                       MS_SAFE_FREE(func_handle);
+
+                       MS_DBG_ERR("malloc failed");
+                       return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+               }
+       }
+
+       /*add functions to array */
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               for (func_index = 0; func_index < eFUNC_MAX ; func_index++) {
+                       func_array[lib_index][func_index] = dlsym(func_handle[lib_index], func_list[func_index]);
+                       if (func_array[lib_index][func_index] == NULL) {
+                               int index;
+
+                               for (index = 0; index < lib_index; index ++) {
+                                       MS_SAFE_FREE(func_array[index]);
+                               }
+                               MS_SAFE_FREE(func_array);
+                               MS_SAFE_FREE(func_handle);
+
+                               MS_DBG_ERR("dlsym failed");
+                               return MS_MEDIA_ERR_DYNAMIC_LINK;
+                       }
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void
+ms_unload_functions(void)
+{
+       int lib_index;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index ++)
+               dlclose(func_handle[lib_index]);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+                       if (func_array[lib_index]) {
+                               MS_SAFE_FREE(func_array[lib_index]);
+                       }
+       }
+
+       MS_SAFE_FREE (func_array);
+       MS_SAFE_FREE (func_handle);
+       if (so_array) g_array_free(so_array, TRUE);
+}
+
+int
+ms_connect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       /*Lock mutex for openning db*/
+       g_mutex_lock(db_mutex);
+
+       MS_MALLOC(*handle, sizeof (void*) * lib_num);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CONNECT)func_array[lib_index][eCONNECT])(&((*handle)[lib_index]), &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       g_mutex_unlock(db_mutex);
+
+                       return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+               }
+       }
+
+       MS_DBG("connect Media DB");
+
+       g_mutex_unlock(db_mutex);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_disconnect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DISCONNECT)func_array[lib_index][eDISCONNECT])((*handle)[lib_index], &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return MS_MEDIA_ERR_DB_DISCONNECT_FAIL;
+               }
+       }
+
+       MS_SAFE_FREE(*handle);
+
+       MS_DBG("Disconnect Media DB");
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_check_exist(void **handle, const char *path)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       storage_type = ms_get_storage_type_by_full(path);
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       return MS_MEDIA_ERR_DB_EXIST_ITEM_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_insert_item(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255] = {0};
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       ret = _ms_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("err : _ms_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = ms_get_storage_type_by_full(path);
+
+       MS_DBG("[%s] %s", mimetype, path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_ms_check_category(path, mimetype, lib_index)) {
+                       ret = ((INSERT_ITEM_IMMEDIATELY)func_array[lib_index][eINSERT])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                       }
+               }
+       }
+
+       return res;
+}
+
+int
+ms_register_file(void **handle, const char *path)
+{
+       MS_DBG("[%d]register file : %s", syscall(__NR_gettid), path);
+
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+
+       if (path == NULL) {
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       /*check item in DB. If it exist in DB, return directly.*/
+       ret = ms_check_exist(handle, path);
+       if (ret == MS_MEDIA_ERR_NONE) {
+               MS_DBG("Already exist");
+               return MS_MEDIA_ERR_NONE;
+       }
+
+       ret = ms_insert_item(handle, path);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               res = ret;
+               MS_DBG_ERR("ms_insert_item failed [%d]", ret);
+       }
+
+       if (ms_is_drm_file(path)) {
+               ret = ms_drm_register(path);
+       }
+
+       return res;
+}
+
+int
+ms_invalidate_all_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+       MS_DBG("");
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ALL_STORAGE_ITEMS_VALIDITY)func_array[lib_index][eSET_ALL_VALIDITY])(handle[lib_index], store_type, false, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+               }
+       }
+       MS_DBG("");
+       return res;
+}
+
+#endif
diff --git a/common/media-server-db.c b/common/media-server-db.c
new file mode 100755 (executable)
index 0000000..ebd6425
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of media db write.
+ *
+ * @file               media-server-db.c
+ * @author     Haejeong Kim(backto.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <unistd.h>
+
+#include "media-util.h"
+
+#include "media-server-dbg.h"
+#include "media-server-db.h"
+#include "media-server-types.h"
+#include "media-server-socket.h"
+#include "media-server-db.h"
+#include "media-server-ipc.h"
+
+static GMainLoop *g_db_mainloop = NULL;
+static bool db_thread_ready = FALSE;
+
+GMainLoop *ms_db_get_mainloop(void)
+{
+       return g_db_mainloop;
+}
+gboolean ms_db_get_thread_status(void)
+{
+       return db_thread_ready;
+}
+
+gboolean ms_db_thread(void *data)
+{
+       int sockfd = -1;
+       int tcp_sockfd = -1;
+       int ret = MS_MEDIA_ERR_NONE;
+       GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GSource *tcp_source = NULL;
+       GIOChannel *tcp_channel = NULL;
+       GMainContext *context = NULL;
+       MediaDBHandle *db_handle = NULL;
+
+       /* Connect Media DB*/
+       if(media_db_connect(&db_handle) != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("Failed to connect DB\n");
+               return FALSE;
+       }
+
+       /* Create Socket*/
+       ret = ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_DB_UPDATE_PORT, &sockfd);
+       if(ret != MS_MEDIA_ERR_NONE) {
+               /* Disconnect DB*/
+               media_db_disconnect(db_handle);
+
+               MS_DBG_ERR("Failed to create socket\n");
+               return FALSE;
+       }
+
+       /* Create TCP Socket for batch query*/
+       ret = ms_ipc_create_server_socket(MS_PROTOCOL_TCP, MS_DB_BATCH_UPDATE_PORT, &tcp_sockfd);
+       if(ret != MS_MEDIA_ERR_NONE) {
+               /* Disconnect DB*/
+               media_db_disconnect(db_handle);
+
+               MS_DBG_ERR("Failed to create socket\n");
+               return FALSE;
+       }
+
+       context = g_main_context_new();
+       /*Init main loop*/
+       g_db_mainloop = g_main_loop_new(context, FALSE);
+       //context = g_main_loop_get_context(g_db_mainloop);
+
+       /* Create new channel to watch udp socket */
+       channel = g_io_channel_unix_new(sockfd);
+       source = g_io_create_watch(channel, G_IO_IN);
+
+       /* Set callback to be called when socket is readable */
+       g_source_set_callback(source, (GSourceFunc)ms_read_db_socket, db_handle, NULL);
+       g_source_attach(source, context);
+
+       /* Create new channel to watch TCP socket */
+       tcp_channel = g_io_channel_unix_new(tcp_sockfd);
+       tcp_source = g_io_create_watch(tcp_channel, G_IO_IN);
+
+       /* Set callback to be called when socket is readable */
+       g_source_set_callback(tcp_source, (GSourceFunc)ms_read_db_tcp_socket, db_handle, NULL);
+       g_source_attach(tcp_source, context);
+
+       g_main_context_push_thread_default(context);
+
+       MS_DBG("*******************************************");
+       MS_DBG("*** Media Server DB thread is running ***");
+       MS_DBG("*******************************************");
+
+       db_thread_ready = TRUE;
+
+       g_main_loop_run(g_db_mainloop);
+
+       MS_DBG("*** Media Server DB thread will be closed ***");
+
+       db_thread_ready = FALSE;
+
+       g_io_channel_shutdown(channel,  FALSE, NULL);
+       g_io_channel_unref(channel);
+
+       /* Disconnect DB*/
+       media_db_disconnect(db_handle);
+
+       /*close socket*/
+       close(sockfd);
+
+       g_main_loop_unref(g_db_mainloop);
+
+       return FALSE;
+}
diff --git a/common/media-server-dbus.c b/common/media-server-dbus.c
new file mode 100755 (executable)
index 0000000..718f939
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  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 <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "media-server-dbg.h"
+#include "media-server-types.h"
+#include "media-server-dbus.h"
+
+void ms_dbus_init(void)
+{
+       DBusConnection *bus;
+       DBusError error;
+
+       /* Get a connection to the session bus */
+       dbus_error_init (&error);
+       bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+       if (!bus) {
+               MS_DBG ("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free (&error);
+               return;
+       }
+
+       /* Set up this connection to work in a GLib event loop */
+       dbus_connection_setup_with_g_main (bus, NULL);
+}
+
+gboolean ms_dbus_send_noti(ms_dbus_noti_type_t data)
+{
+       MS_DBG("");
+       DBusMessage *message;
+       DBusConnection *bus;
+       DBusError error;
+       dbus_uint16_t noti_type = data;
+
+       /* Get a connection to the session bus */
+       dbus_error_init (&error);
+       bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+       if (!bus) {
+               MS_DBG ("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free (&error);
+               return false;
+       }
+
+       /* Create a new signal on the "MS_DBUS_INTERFACE" interface,
+       * from the object "MS_DBUS_PATH". */
+       message = dbus_message_new_signal (MS_DBUS_PATH, MS_DBUS_INTERFACE, MS_DBUS_NAME);
+
+       /* Append the notification type to the signal */
+       dbus_message_append_args (message, DBUS_TYPE_UINT16, &noti_type, DBUS_TYPE_INVALID);
+
+       /* Send the signal */
+       dbus_connection_send (bus, message, NULL);
+
+       /* Free the signal now we have finished with it */
+       dbus_message_unref (message);
+
+       /* Return TRUE to tell the event loop we want to be called again */
+       return true;
+}
\ No newline at end of file
diff --git a/common/media-server-drm.c b/common/media-server-drm.c
new file mode 100755 (executable)
index 0000000..65687f2
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-drm.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+#include <drm_client_types.h>
+#include <drm_client.h>
+
+#include "media-util.h"
+
+#include "media-server-dbg.h"
+#include "media-server-types.h"
+#include "media-server-inotify.h"
+#include "media-server-drm.h"
+
+bool
+ms_is_drm_file(const char *path)
+{
+       int ret;
+       drm_bool_type_e is_drm_file = DRM_UNKNOWN;
+
+       ret = drm_is_drm_file(path,&is_drm_file);
+       if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file)
+               return true;
+
+       return false;
+}
+
+int
+ms_get_mime_in_drm_info(const char *path, char *mime)
+{
+       int ret;
+       drm_content_info_s contentInfo;
+
+       if (path == NULL || mime == NULL)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       memset(&contentInfo,0x0,sizeof(drm_content_info_s));
+       ret = drm_get_content_info(path, &contentInfo);
+       if (ret != DRM_RETURN_SUCCESS) {
+               MS_DBG_ERR("drm_svc_get_content_info() fails. ");
+               return MS_MEDIA_ERR_DRM_GET_INFO_FAIL;
+       }
+
+       strncpy(mime, contentInfo.mime_type, 100);
+       MS_DBG("DRM contentType : %s", contentInfo.mime_type);
+       MS_DBG("DRM mime : %s", mime);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_drm_register(const char* path)
+{
+       MS_DBG("THIS IS DRM FILE");
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+#if MS_INOTI_ENABLE
+//     ms_inoti_add_ignore_file(path);
+#endif
+       ret = drm_process_request(DRM_REQUEST_TYPE_REGISTER_FILE, (void *)path, NULL);
+       if (ret != DRM_RETURN_SUCCESS) {
+               MS_DBG_ERR("drm_svc_register_file error : %d", ret);
+               res = MS_MEDIA_ERR_DRM_REGISTER_FAIL;
+       }
+
+       return res;
+}
+
+void
+ms_drm_unregister(const char* path)
+{
+       int ret;
+#if MS_INOTI_ENABLE
+       ms_ignore_file_info *ignore_file;
+#endif
+       ret = drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_FILE, (void *)path, NULL);
+       if (ret != DRM_RETURN_SUCCESS)
+               MS_DBG_ERR("drm_process_request error : %d", ret);
+#if MS_INOTI_ENABLE
+       ignore_file = ms_inoti_find_ignore_file(path);
+       if (ignore_file != NULL)
+               ms_inoti_delete_ignore_file(ignore_file);
+#endif
+}
+
+void
+ms_drm_unregister_all(void)
+{
+       if (drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_ALL_FILES , NULL, NULL) == DRM_RETURN_SUCCESS)
+               MS_DBG("drm_svc_unregister_all_contents OK");
+}
+
+bool
+ms_drm_insert_ext_memory(void)
+{
+       MS_DBG("");
+       if (drm_process_request(DRM_REQUEST_TYPE_INSERT_EXT_MEMORY, NULL, NULL) != DRM_RETURN_SUCCESS)
+               return false;
+
+       return true;
+}
+
+bool
+ms_drm_extract_ext_memory(void)
+{
+       MS_DBG("");
+       if (drm_process_request(DRM_REQUEST_TYPE_EXTRACT_EXT_MEMORY , NULL, NULL)  != DRM_RETURN_SUCCESS)
+               return false;
+
+       return true;
+}
+
diff --git a/common/media-server-external-storage.c b/common/media-server-external-storage.c
new file mode 100755 (executable)
index 0000000..e5abd5b
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ *  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 <locale.h>
+#include <libintl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <vconf.h>
+#include <notification.h>
+
+#include "media-util.h"
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-ipc.h"
+#include "media-server-socket.h"
+#include "media-server-inotify.h"
+#include "media-server-db-svc.h"
+#include "media-server-scanner.h"
+#include "media-server-external-storage.h"
+#include "media-server-drm.h"
+
+#define MMC_INFO_SIZE 256
+
+int mmc_state = 0;
+
+char default_path[][MS_FILE_NAME_LEN_MAX + 1] = {
+               {"/opt/storage/sdcard/Images"},
+               {"/opt/storage/sdcard/Videos"},
+               {"/opt/storage/sdcard/Sounds"},
+               {"/opt/storage/sdcard/Downloads"},
+               {"/opt/storage/sdcard/Camera"}
+};
+
+#define DIR_NUM       ((int)(sizeof(default_path)/sizeof(default_path[0])))
+
+void
+ms_make_default_path_mmc(void)
+{
+       int i = 0;
+       int ret = 0;
+       DIR *dp = NULL;
+
+       for (i = 0; i < DIR_NUM; ++i) {
+               dp = opendir(default_path[i]);
+               if (dp == NULL) {
+                       ret = mkdir(default_path[i], 0777);
+                       if (ret < 0) {
+                               MS_DBG("make fail");
+                       } else {
+#if MS_INOTI_ENABLE
+                               ms_inoti_add_watch(default_path[i]);
+#endif
+                               /*this fuction for emulator*/
+                               /*at the first time, the directroies are made permission 755*/
+                               chmod(default_path[i], 0777);
+                               chown(default_path[i], 5000, 5000);
+                       }
+               } else {
+                       closedir(dp);
+               }
+       }
+}
+
+int
+_ms_update_mmc_info(const char *cid)
+{
+       bool res;
+
+       if (cid == NULL) {
+               MS_DBG_ERR("Parameters are invalid");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res = ms_config_set_str(MS_MMC_INFO_KEY, cid);
+       if (!res) {
+               MS_DBG_ERR("fail to get MS_MMC_INFO_KEY");
+               return MS_MEDIA_ERR_VCONF_SET_FAIL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+bool
+_ms_check_mmc_info(const char *cid)
+{
+       char pre_mmc_info[MMC_INFO_SIZE] = { 0 };
+       bool res = false;
+
+       if (cid == NULL) {
+               MS_DBG_ERR("Parameters are invalid");
+               return false;
+       }
+
+       res = ms_config_get_str(MS_MMC_INFO_KEY, pre_mmc_info);
+       if (!res) {
+               MS_DBG_ERR("fail to get MS_MMC_INFO_KEY");
+               return false;
+       }
+
+       MS_DBG("Last MMC info   = %s", pre_mmc_info);
+       MS_DBG("Current MMC info = %s", cid);
+
+       if (strcmp(pre_mmc_info, cid) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+static int
+_get_contents(const char *filename, char *buf)
+{
+       FILE *fp;
+
+       fp = fopen(filename, "rt");
+       if (fp == NULL) {
+               MS_DBG_ERR("fp is NULL. file name : %s", filename);
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+       if (fgets(buf, 255, fp) == NULL)
+               MS_DBG_ERR("fgets failed");
+
+       fclose(fp);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+/*need optimize*/
+int
+_ms_get_mmc_info(char *cid)
+{
+       int i;
+       int j;
+       int len;
+       int err = -1;
+       bool getdata = false;
+       bool bHasColon = false;
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char mmcpath[MS_FILE_PATH_LEN_MAX] = { 0 };
+
+       DIR *dp;
+       struct dirent ent;
+       struct dirent *res = NULL;
+
+       /* mmcblk0 and mmcblk1 is reserved for movinand */
+       for (j = 1; j < 3; j++) {
+               len = snprintf(mmcpath, MS_FILE_PATH_LEN_MAX, "/sys/class/mmc_host/mmc%d/", j);
+               if (len < 0) {
+                       MS_DBG_ERR("FAIL : snprintf");
+                       return MS_MEDIA_ERR_INTERNAL;
+               }
+               else {
+                       mmcpath[len] = '\0';
+               }
+
+               dp = opendir(mmcpath);
+               if (dp == NULL) {
+                       MS_DBG_ERR("dp is NULL");
+                       return MS_MEDIA_ERR_DIR_OPEN_FAIL;
+               }
+
+               while (!readdir_r(dp, &ent, &res)) {
+                        /*end of read dir*/
+                       if (res == NULL)
+                               break;
+
+                       bHasColon = false;
+                       if (ent.d_name[0] == '.')
+                               continue;
+
+                       if (ent.d_type == DT_DIR) {
+                               /*ent->d_name is including ':' */
+                               for (i = 0; i < strlen(ent.d_name); i++) {
+                                       if (ent.d_name[i] == ':') {
+                                               bHasColon = true;
+                                               break;
+                                       }
+                               }
+
+                               if (bHasColon) {
+                                       /*check serial */
+                                       err = ms_strappend(path, sizeof(path), "%s%s/cid", mmcpath, ent.d_name);
+                                       if (err < 0) {
+                                               MS_DBG_ERR("ms_strappend error : %d", err);
+                                               continue;
+                                       }
+
+                                       if (_get_contents(path, cid) != MS_MEDIA_ERR_NONE)
+                                               break;
+                                       else
+                                               getdata = true;
+                               }
+                       }
+               }
+               closedir(dp);
+
+               if (getdata == true) {
+                       break;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+ms_dir_scan_type_t
+ms_get_mmc_state(void)
+{
+       char cid[MMC_INFO_SIZE] = { 0 };
+       ms_dir_scan_type_t ret = MS_SCAN_ALL;
+
+       /*get new info */
+       _ms_get_mmc_info(cid);
+
+       /*check it's same mmc */
+       if (_ms_check_mmc_info(cid)) {
+               ret = MS_SCAN_PART;
+       }
+
+       return ret;
+}
+
+int
+ms_update_mmc_info(void)
+{
+       int err;
+       char cid[MMC_INFO_SIZE] = { 0 };
+
+       err = _ms_get_mmc_info(cid);
+
+       err = _ms_update_mmc_info(cid);
+
+       /*Active flush */
+       if (!malloc_trim(0))
+               MS_DBG_ERR("malloc_trim is failed");
+
+       return err;
+}
+
+#define _GETSYSTEMSTR(ID)      dgettext("sys_string", (ID))
+
+void update_lang(void)
+{
+       char *lang;
+       char *r;
+
+       lang = vconf_get_str(VCONFKEY_LANGSET);
+       if (lang) {
+               setenv("LANG", lang, 1);
+               setenv("LC_MESSAGES", lang, 1);
+               r = setlocale(LC_ALL, "");
+               if (r == NULL) {
+                       r = setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
+                       MS_DBG_ERR("*****appcore setlocale=%s\n", r);
+               }
+               free(lang);
+       }
+}
+
+int
+ms_present_mmc_insert(void)
+{
+       int ret;
+
+       update_lang();
+
+       ret = notification_status_message_post(_GETSYSTEMSTR("IDS_COM_BODY_PREPARING_SD_CARD"));
+       if(ret != NOTIFICATION_ERROR_NONE)
+               return MS_MEDIA_ERR_INTERNAL;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void
+ms_mmc_vconf_cb(void *data)
+{
+       int status = 0;
+
+       if (!ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) {
+               MS_DBG_ERR("Get VCONFKEY_SYSMAN_MMC_STATUS failed.");
+       }
+
+       MS_DBG("VCONFKEY_SYSMAN_MMC_STATUS :%d", status);
+
+       mmc_state = 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 (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
+               mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) {
+
+               /*remove added watch descriptors */
+#if MS_INOTI_ENABLE
+               ms_inoti_remove_watch_recursive(MEDIA_ROOT_PATH_SDCARD);
+               ms_inoti_delete_mmc_ignore_file();
+#endif
+               if (!ms_get_scanner_status()) {
+                       if (!ms_drm_extract_ext_memory())
+                               MS_DBG_ERR("ms_drm_extract_ext_memory failed");
+
+                       ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, MS_SCAN_INVALID);
+               }
+       } else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) {
+
+               ms_make_default_path_mmc();
+#if MS_INOTI_ENABLE
+               ms_inoti_add_watch_all_directory(MS_STORAGE_EXTERNAL);
+#endif
+               ms_present_mmc_insert();
+
+               if (!ms_get_scanner_status()) {
+                       if (!ms_drm_insert_ext_memory())
+                               MS_DBG_ERR("ms_drm_insert_ext_memory failed");
+
+                       ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, ms_get_mmc_state());
+               }
+       }
+
+       return;
+}
+
diff --git a/common/media-server-inotify-internal.c b/common/media-server-inotify-internal.c
new file mode 100755 (executable)
index 0000000..136e380
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-inotify-internal.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief23
+ */
+#include "media-util.h"
+
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-inotify-internal.h"
+#if MS_INOTI_ENABLE
+int inoti_fd;
+ms_create_file_info *latest_create_file;
+extern ms_inoti_dir_data *first_inoti_node;
+
+int _ms_inoti_add_create_file_list(int wd, char *name)
+{
+       ms_create_file_info *new_node;
+
+       new_node = malloc(sizeof(ms_create_file_info));
+       new_node->name = strdup(name);
+       new_node->wd = wd;
+
+       /*first created file */
+       if (latest_create_file == NULL) {
+               latest_create_file = malloc(sizeof(ms_create_file_info));
+               new_node->previous = NULL;
+       } else {
+               latest_create_file->next = new_node;
+               new_node->previous = latest_create_file;
+       }
+       new_node->next = NULL;
+
+       latest_create_file = new_node;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int _ms_inoti_delete_create_file_list(ms_create_file_info *node)
+{
+       if (node->previous != NULL)
+               node->previous->next = node->next;
+       if (node->next != NULL)
+               node->next->previous = node->previous;
+
+       if (node == latest_create_file) {
+               latest_create_file = node->previous;
+       }
+
+       MS_SAFE_FREE(node->name);
+       MS_SAFE_FREE(node);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+ms_create_file_info *_ms_inoti_find_create_file_list(int wd, char *name)
+{
+       ms_create_file_info *node = NULL;
+       node = latest_create_file;
+
+       while (node != NULL) {
+               if ((node->wd == wd) && (strcmp(node->name, name) == 0)) {
+                       return node;
+               }
+
+               node = node->previous;
+       }
+
+       return NULL;
+}
+
+bool _ms_inoti_get_full_path(int wd, char *name, char *path, int sizeofpath)
+{
+       int err;
+       ms_inoti_dir_data *node = NULL;
+
+       if (name == NULL || path == NULL)
+               return false;
+
+       if (first_inoti_node != NULL) {
+               node = first_inoti_node;
+               while (node->next != NULL) {
+                       if (wd == node->wd) {
+                               break;
+                       }
+                       node = node->next;
+               }
+       } else {
+               return false;
+       }
+
+       err = ms_strappend(path, sizeofpath, "%s/%s", node->name, name);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_strappend error : %d", err);
+               return false;
+       }
+       MS_DBG("full path : %s", path);
+       return true;
+}\r
+
+#endif
diff --git a/common/media-server-inotify.c b/common/media-server-inotify.c
new file mode 100755 (executable)
index 0000000..3f922ff
--- /dev/null
@@ -0,0 +1,889 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-inotify.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#include <errno.h>
+#include <dirent.h>
+#include <malloc.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-db-svc.h"
+#include "media-server-inotify-internal.h"
+#include "media-server-inotify.h"
+
+#if MS_INOTI_ENABLE
+
+bool power_off;
+extern int inoti_fd;
+extern int mmc_state;
+ms_inoti_dir_data *first_inoti_node;
+ms_ignore_file_info *latest_ignore_file;
+
+int _ms_inoti_directory_scan_and_register_file(void **handle, char *dir_path)
+{
+       struct dirent ent;
+       struct dirent *res = NULL;
+       DIR *dp = NULL;
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       int err;
+
+       if (dir_path == NULL)
+               return MS_MEDIA_ERR_INVALID_PATH;
+
+       dp = opendir(dir_path);
+       if (dp == NULL) {
+               MS_DBG_ERR("Fail to open dir %s", dir_path);
+               return MS_MEDIA_ERR_DIR_OPEN_FAIL;
+       }
+
+       ms_inoti_add_watch(dir_path);
+
+       while (!readdir_r(dp, &ent, &res)) {
+               if (res == NULL)
+                       break;
+
+               if (ent.d_name[0] == '.')
+                       continue;
+
+               err = ms_strappend(path, sizeof(path), "%s/%s", dir_path, ent.d_name);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_strappend error : %d", err);
+                       continue;
+               }
+
+               /*in case of directory */
+               if (ent.d_type == DT_DIR) {
+                       _ms_inoti_directory_scan_and_register_file(handle, path);
+               } else {
+                       err = ms_register_file(handle, path, NULL);
+                       if (err != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_ERR("ms_register_file error : %d", err);
+                               continue;
+                       }
+               }
+       }
+
+       closedir(dp);
+
+       return 0;
+}
+
+int _ms_inoti_scan_renamed_folder(void **handle, char *org_path, char *chg_path)
+{
+       int err = -1;
+       struct dirent ent;
+       struct dirent *res = NULL;
+
+       DIR *dp = NULL;
+       char path_from[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char path_to[MS_FILE_PATH_LEN_MAX] = { 0 };
+       ms_storage_type_t src_storage = 0;
+       ms_storage_type_t des_storage = 0;
+
+       if (org_path == NULL || chg_path == NULL) {
+               MS_DBG_ERR("Parameter is wrong");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       dp = opendir(chg_path);
+       if (dp == NULL) {
+               MS_DBG_ERR("Fail to open dir %s", chg_path);
+               return MS_MEDIA_ERR_DIR_OPEN_FAIL;
+       } else {
+               MS_DBG("Modify added watch");
+               ms_inoti_modify_watch(org_path, chg_path);
+       }
+
+       while (!readdir_r(dp, &ent, &res)) {
+               if (res == NULL)
+                       break;
+
+               if (ent.d_name[0] == '.')
+                       continue;
+
+               err = ms_strappend(path_from, sizeof(path_from), "%s/%s", org_path, ent.d_name);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_strappend error : %d", err);
+                       continue;
+               }
+
+               err =  ms_strappend(path_to, sizeof(path_to), "%s/%s", chg_path, ent.d_name);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_strappend error : %d", err);
+                       continue;
+               }
+
+               /*in case of directory */
+               if (ent.d_type == DT_DIR) {
+                       _ms_inoti_scan_renamed_folder(handle, path_from, path_to);
+               }
+
+               /*in case of file */
+               if (ent.d_type == DT_REG) {
+                       src_storage = ms_get_storage_type_by_full(path_from);
+                       des_storage = ms_get_storage_type_by_full(path_to);
+
+                       if ((src_storage != MS_MEDIA_ERR_INVALID_PATH)
+                           && (des_storage != MS_MEDIA_ERR_INVALID_PATH))
+                               ms_move_item(handle, src_storage, des_storage, path_from, path_to);
+                       else {
+                               MS_DBG_ERR("src_storage : %s", src_storage);
+                               MS_DBG_ERR("des_storage : %s", des_storage);
+                       }
+               }
+       }
+
+       closedir(dp);
+
+       return 0;
+}
+
+int ms_inoti_add_ignore_file(const char *path)
+{
+       ms_ignore_file_info *new_node;
+
+       new_node = ms_inoti_find_ignore_file(path);
+       if (new_node != NULL)
+               return MS_MEDIA_ERR_NONE;
+
+       new_node = malloc(sizeof(ms_ignore_file_info));
+       new_node->path = strdup(path);
+
+       /*first created file */
+       if (latest_ignore_file == NULL) {
+               latest_ignore_file = malloc(sizeof(ms_ignore_file_info));
+               new_node->previous = NULL;
+       } else {
+               latest_ignore_file->next = new_node;
+               new_node->previous = latest_ignore_file;
+       }
+       new_node->next = NULL;
+
+       latest_ignore_file = new_node;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int ms_inoti_delete_ignore_file(ms_ignore_file_info * delete_node)
+{
+       if (delete_node->previous != NULL)
+               delete_node->previous->next = delete_node->next;
+       if (delete_node->next != NULL)
+               delete_node->next->previous = delete_node->previous;
+
+       if (delete_node == latest_ignore_file) {
+               latest_ignore_file = delete_node->previous;
+       }
+
+       MS_SAFE_FREE(delete_node->path);
+       MS_SAFE_FREE(delete_node);
+
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+ms_ignore_file_info *ms_inoti_find_ignore_file(const char *path)
+{
+       ms_ignore_file_info *node = NULL;
+       
+       node = latest_ignore_file;
+       while (node != NULL) {
+               if (strcmp(node->path, path) == 0) {
+                       return node;
+               }
+
+               node = node->previous;
+       }
+
+       return NULL;
+}
+
+void ms_inoti_delete_mmc_ignore_file(void)
+{
+       ms_ignore_file_info *prv_node = NULL;
+       ms_ignore_file_info *cur_node = NULL;
+       ms_ignore_file_info *del_node = NULL;
+
+       if (latest_ignore_file != NULL) {
+               cur_node = latest_ignore_file;
+               while (cur_node != NULL) {
+                       if (strstr(cur_node->path, MEDIA_ROOT_PATH_SDCARD) != NULL) {
+                               if (prv_node != NULL) {
+                                       prv_node->previous = cur_node->previous;
+                               }
+
+                               if (cur_node == latest_ignore_file)
+                                       latest_ignore_file = latest_ignore_file->previous;
+
+                               del_node = cur_node;
+                       } else {
+                               prv_node = cur_node;
+                       }
+
+                       cur_node = cur_node->previous;
+
+                       if (del_node != NULL) {
+                               MS_SAFE_FREE(del_node->path);
+                               MS_SAFE_FREE(del_node);
+                       }
+               }
+       }
+
+       /*active flush */
+       malloc_trim(0);
+}
+
+int ms_inoti_init(void)
+{
+       inoti_fd = inotify_init();
+       if (inoti_fd < 0) {
+               perror("inotify_init");
+               MS_DBG_ERR("inotify_init failed");
+               return inoti_fd;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void ms_inoti_add_watch(char *path)
+{
+       ms_inoti_dir_data *current_dir = NULL;
+       ms_inoti_dir_data *prv_node = NULL;
+       ms_inoti_dir_data *last_node = NULL;
+
+       /*find same folder */
+       if (first_inoti_node != NULL) {
+               last_node = first_inoti_node;
+               while (last_node != NULL) {
+                       if (strcmp(path, last_node->name) == 0) {
+                               MS_DBG("watch is already added: %s", path);
+                               return;
+                       }
+                       prv_node = last_node;
+                       last_node = last_node->next;
+               }
+       }
+
+       /*there is no same path. */
+       current_dir = malloc(sizeof(ms_inoti_dir_data));
+       current_dir->wd = inotify_add_watch(inoti_fd, path,
+                             IN_CLOSE_WRITE | IN_CREATE | IN_DELETE |
+                             IN_MOVED_FROM | IN_MOVED_TO);
+
+       if (current_dir->wd > 0) {
+               current_dir->name = strdup(path);
+               current_dir->next = NULL;
+
+               if (first_inoti_node == NULL) {
+                       first_inoti_node = current_dir;
+               } else {
+                       /*if next node of current node is NULL, it is the lastest node. */
+                       prv_node->next = current_dir;
+               }
+               MS_DBG("add watch : %s", path);
+       } else {
+               MS_DBG_ERR("inotify_add_watch failed");
+               MS_SAFE_FREE(current_dir);
+       }
+}
+
+int ms_inoti_add_watch_with_node(ms_dir_scan_info * const node, int depth)
+{
+       int err;
+       char full_path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       ms_inoti_dir_data *current_dir = NULL;
+       ms_inoti_dir_data *prv_node = NULL;
+       ms_inoti_dir_data *last_node = NULL;
+
+       err = ms_get_full_path_from_node(node, full_path, depth);
+       if (err != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_INVALID_PATH;
+
+       /*find same folder */
+       if (first_inoti_node != NULL) {
+               last_node = first_inoti_node;
+               while (last_node != NULL) {
+                       if (strcmp(full_path, last_node->name) == 0) {
+                               return MS_MEDIA_ERR_NONE;
+                       }
+                       prv_node = last_node;
+                       last_node = last_node->next;
+               }
+       }
+
+       /*there is no same path. */
+       current_dir = malloc(sizeof(ms_inoti_dir_data));
+       current_dir->wd = inotify_add_watch(inoti_fd, full_path,
+                             IN_CLOSE_WRITE | IN_CREATE | IN_DELETE |
+                             IN_MOVED_FROM | IN_MOVED_TO);
+       if( current_dir->wd > 0) {
+               current_dir->name = strdup(full_path);
+               current_dir->next = NULL;
+
+               if (first_inoti_node == NULL) {
+                       first_inoti_node = current_dir;
+               } else {
+                       /*if next node of current node is NULL, it is the lastest node. */
+                       prv_node->next = current_dir;
+               }
+               MS_DBG("add watch : %s", full_path);
+       } else {
+               MS_DBG_ERR("inotify_add_watch  failed : %d", current_dir->wd);
+               MS_SAFE_FREE(current_dir);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void ms_inoti_remove_watch_recursive(char *path)
+{
+       ms_inoti_dir_data *prv_node = NULL;
+       ms_inoti_dir_data *cur_node = NULL;
+       ms_inoti_dir_data *del_node = NULL;
+
+       if (first_inoti_node != NULL) {
+               cur_node = first_inoti_node;
+               while (cur_node != NULL) {
+                       if (strstr(cur_node->name, path) != NULL) {
+                               if (prv_node != NULL) {
+                                       prv_node->next =
+                                           cur_node->next;
+                               }
+
+                               if (cur_node == first_inoti_node)
+                                       first_inoti_node =
+                                           first_inoti_node->next;
+
+                               del_node = cur_node;
+                       } else {
+                               prv_node = cur_node;
+                       }
+
+                       cur_node = cur_node->next;
+
+                       if (del_node != NULL) {
+                               MS_SAFE_FREE(del_node->name);
+                               MS_SAFE_FREE(del_node);
+                       }
+               }
+       }
+
+       /*active flush */
+        malloc_trim(0);
+}
+
+void ms_inoti_remove_watch(char *path)
+{
+       ms_inoti_dir_data *del_node = NULL;
+       ms_inoti_dir_data *prv_node = NULL;
+
+       if (strcmp(first_inoti_node->name, path) == 0) {
+               del_node = first_inoti_node;
+               first_inoti_node = first_inoti_node->next;
+       } else {
+               /*find same folder */
+               if (first_inoti_node != NULL) {
+                       del_node = first_inoti_node;
+                       while (del_node != NULL) {
+                               MS_DBG("current node %s", del_node->name);
+                               if (strcmp(path, del_node->name) == 0) {
+                                       MS_DBG("find delete node: %s", del_node->name);
+                                       if (prv_node != NULL) {
+                                               MS_DBG("previous_node : %s", prv_node->name);
+                                               prv_node->next = del_node->next;
+                                       }
+                                       /*free deleted node */
+                                       MS_SAFE_FREE(del_node->name);
+                                       MS_SAFE_FREE(del_node);
+                                       break;
+                               }
+                               prv_node = del_node;
+                               del_node = del_node->next;
+                       }
+               }
+       }
+
+       /*active flush */
+       malloc_trim(0);
+}
+
+void ms_inoti_modify_watch(char *path_from, char *path_to)
+{
+       bool find = false;
+       ms_inoti_dir_data *mod_node;
+
+       if (strcmp(first_inoti_node->name, path_from) == 0) {
+               mod_node = first_inoti_node;
+       } else {
+               /*find same folder */
+               if (first_inoti_node != NULL) {
+                       mod_node = first_inoti_node;
+                       while (mod_node != NULL) {
+                               /*find previous directory*/
+                               if (strcmp(path_from, mod_node->name) == 0) { 
+                                       /*change path of directory*/
+                                       /*free previous name of node */
+                                       MS_SAFE_FREE(mod_node->name);
+
+                                       /*add new name */
+                                       mod_node->name = strdup(path_to);
+
+                                       /*active flush */
+                                       malloc_trim(0);
+
+                                       find = true;
+                                       break;
+                               }
+                               mod_node = mod_node->next;
+                       }
+               }
+       }
+
+       /*this is new directory*/
+       if (find == false) {
+               ms_inoti_add_watch(path_to);
+       }
+}
+
+#define STOP_INOTI "stop_inoti"
+
+gboolean ms_inoti_thread(void *data)
+{
+       uint32_t i;
+       int length;
+       int err;
+       int prev_mask = 0;
+       int prev_wd = -1;
+       bool res;
+       char name[MS_FILE_NAME_LEN_MAX + 1] = { 0 };
+       char prev_name[MS_FILE_NAME_LEN_MAX + 1] = { 0 };
+       char buffer[INOTI_BUF_LEN] = { 0 };
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       struct inotify_event *event;
+       void **handle = NULL;
+
+       MS_DBG("START INOTIFY");
+
+       err = ms_connect_db(&handle);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR(" INOTIFY : sqlite3_open: ret = %d", err);
+               return false;
+       }
+
+       while (1) {
+               i = 0;
+               length = read(inoti_fd, buffer, sizeof(buffer) - 1);
+
+               if (length < 0 || length > sizeof(buffer)) {    /*this is error */
+                       continue;
+               }
+
+               while (i < length && i < INOTI_BUF_LEN) {
+                       /*check poweroff status*/
+                       if(power_off) {
+                               MS_DBG("power off");
+                               goto _POWEROFF;
+                       }
+
+                       /*it's possible that ums lets reset phone data... */
+                       event = (struct inotify_event *)&buffer[i];
+
+                       if (strcmp(event->name, POWEROFF_DIR_NAME) == 0) {
+                               MS_DBG("power off");
+                               goto _POWEROFF;
+                       } else if (strcmp(event->name, STOP_INOTI) == 0) {
+                               MS_DBG("stop inotify thread");
+                               goto _POWEROFF;
+                       } else if (event->name[0] == '.') {
+                               /*event of hidden folder is ignored */
+                               goto NEXT_INOTI_EVENT;
+                       } else if (event->wd < 1) {
+                               /*this is error */
+                               MS_DBG_ERR("invalid wd : %d", event->wd);
+                               goto NEXT_INOTI_EVENT;
+                       }
+
+                       /*start of one event */
+                       if (event->len && (event->len <= MS_FILE_NAME_LEN_MAX + 1)) {
+                               /*Add for fixing prevent defect 2011-02-15 */
+                               err = ms_strcopy(name, sizeof(name), "%s", event->name);
+                               if (err != MS_MEDIA_ERR_NONE) {
+                                       MS_DBG_ERR("ms_strcopy error : %d", err);
+                                       goto NEXT_INOTI_EVENT;
+                               }
+
+                               /*get full path of file or directory */
+                               res = _ms_inoti_get_full_path(event->wd, name, path, sizeof(path));
+                               if (res == false) {
+                                       MS_DBG_ERR("_ms_inoti_get_full_path error");
+                                       goto NEXT_INOTI_EVENT;
+                               }
+
+                               MS_DBG("INOTIFY[%d : %s]", event->wd, name);
+                               if (event->mask & IN_ISDIR) {
+                                       MS_DBG("DIRECTORY INOTIFY");
+                                       
+                                       if (event->mask & IN_MOVED_FROM) {
+                                               MS_DBG("MOVED_FROM");
+
+                                               prev_mask = event->mask;
+                                               prev_wd = event->wd;
+
+                                               err = ms_strcopy(prev_name, sizeof(prev_name), "%s", event->name);
+                                               if (err != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("ms_strcopy fail");
+                                                       goto NEXT_INOTI_EVENT;
+                                               }
+                                       } 
+                                       else if (event->mask & IN_MOVED_TO) {
+                                               MS_DBG("MOVED_TO");
+
+                                               char full_path_from[MS_FILE_PATH_LEN_MAX] = { 0 };
+
+                                               res = _ms_inoti_get_full_path(prev_wd, prev_name, full_path_from, sizeof(full_path_from));
+                                               if (res == false) {
+                                                       MS_DBG_ERR("_ms_inoti_get_full_path error");
+                                                       goto NEXT_INOTI_EVENT;
+                                               }
+                                               /*enable bundle commit*/
+                                               ms_move_start(handle);
+
+                                               /*need update file information under renamed directory */
+                                               _ms_inoti_scan_renamed_folder(handle, full_path_from, path);
+
+                                               /*disable bundle commit*/
+                                               ms_move_end(handle);
+
+                                               prev_mask = prev_wd = 0;        /*reset */
+                                       }
+                                       else if (event->mask & IN_CREATE) {
+                                               MS_DBG("CREATE");
+
+                                               _ms_inoti_directory_scan_and_register_file(handle, path);
+                                               prev_mask = event->mask;
+                                       }
+                                       else if (event->mask & IN_DELETE) {
+                                               MS_DBG("DELETE");
+
+                                               ms_inoti_remove_watch(path);
+                                       }
+                               }
+                               else {
+                                       MS_DBG("FILE INOTIFY");
+
+                                       if (event->mask & IN_MOVED_FROM) {
+                                               MS_DBG("MOVED_FROM");
+
+                                               err = ms_delete_item(handle, path);
+                                               if (err != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("ms_media_db_delete fail error : %d", err);
+                                               }
+                                       }
+                                       else if (event->mask & IN_MOVED_TO) {
+                                               MS_DBG("MOVED_TO");
+
+                                               err = ms_register_file(handle, path, NULL);
+                                               if (err != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("ms_register_file error : %d", err);
+                                               }
+                                       }
+                                       else if (event->mask & IN_CREATE) {
+                                               MS_DBG("CREATE");
+
+                                               _ms_inoti_add_create_file_list(event->wd, name);
+                                       }
+                                       else if (event->mask & IN_DELETE) {
+                                               MS_DBG("DELETE");
+                                               
+                                               err = ms_delete_item(handle, path);
+                                               if (err != MS_MEDIA_ERR_NONE) {
+                                                       MS_DBG_ERR("ms_media_db_delete error : %d", err);
+                                               }
+                                       }
+                                       else if (event->mask & IN_CLOSE_WRITE) {
+                                               MS_DBG("CLOSE_WRITE");
+                                               ms_create_file_info *node;
+
+                                               node = _ms_inoti_find_create_file_list (event->wd, name);
+                                               if (node != NULL || ((prev_mask & IN_ISDIR) & IN_CREATE)) {
+                                                       err = ms_register_file(handle, path, NULL);
+                                                       if (err != MS_MEDIA_ERR_NONE) {
+                                                               MS_DBG_ERR("ms_register_file error : %d", err);
+                                                       }
+                                                       if (node != NULL)
+                                                               _ms_inoti_delete_create_file_list(node);
+                                               }
+                                               else {
+                                                       ms_ignore_file_info  *ignore_file;
+
+                                                       ignore_file = ms_inoti_find_ignore_file(path);
+                                                       if (ignore_file == NULL) {
+                                                               /*in case of replace */
+                                                               MS_DBG("This case is replacement or changing meta data.");
+                                                               err = ms_refresh_item(handle, path);
+                                                               if (err != MS_MEDIA_ERR_NONE) {
+                                                                       MS_DBG_ERR("ms_refresh_item error : %d", err);
+                                                                       goto NEXT_INOTI_EVENT;
+                                                               }
+                                                       } else {
+                                                               /*This is ignore case*/
+                                                       }
+                                               }
+                                               prev_mask = prev_wd = 0;        /*reset */
+                                       }
+                               }
+                       } /*end of one event */
+                       else {
+                               /*This is ignore case*/
+                               if (event->mask & IN_IGNORED) {
+                                       MS_DBG("This case is ignored");
+                               }
+                       }
+ NEXT_INOTI_EVENT:     ;
+                       i += INOTI_EVENT_SIZE + event->len;
+               }
+
+               /*Active flush */
+               malloc_trim(0);
+       }
+_POWEROFF:
+       ms_inoti_remove_watch_recursive(MEDIA_ROOT_PATH_INTERNAL);
+       ms_inoti_remove_watch_recursive(MEDIA_ROOT_PATH_SDCARD);
+
+       close(inoti_fd);
+
+       if (handle) ms_disconnect_db(&handle);
+
+       return false;
+}
+
+int _ms_get_path_from_current_node(int find_folder,
+                                  ms_dir_scan_info **current_root,
+                                  ms_dir_scan_info **real_root, char **path, int *depth)
+{
+       int err = MS_MEDIA_ERR_NONE;
+       char get_path[FAT_FILEPATH_LEN_MAX] = { 0 };
+
+       if (find_folder == 0) {
+               if ((*current_root)->Rbrother != NULL) {
+                       *current_root = (*current_root)->Rbrother;
+               } else {
+                       while (1) {
+                               if ((*current_root)->parent == *real_root
+                                   || (*current_root)->parent == NULL) {
+                                       *current_root = NULL;
+                                       *depth = 0;
+                                       return MS_MEDIA_ERR_NONE;
+                               } else if ((*current_root)->parent->Rbrother == NULL) {
+                                       *current_root = (*current_root)->parent;
+                                       (*depth) --;
+                               } else {
+                                       *current_root = (*current_root)->parent->Rbrother;
+                                       (*depth) --;
+                                       break;
+                               }
+                       }
+               }
+               (*depth) --;
+       }
+
+       err = ms_get_full_path_from_node(*current_root, get_path, *depth);
+       if (err != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_INVALID_PATH;
+
+       *path = strdup(get_path);
+
+       return err;
+}
+
+void ms_inoti_add_watch_all_directory(ms_storage_type_t storage_type)
+{
+       int err = 0;
+       int depth = 0;
+       int find_folder = 0;
+       char get_path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char *path = NULL;
+       DIR *dp = NULL;
+       struct dirent entry;
+       struct dirent *result;
+
+       ms_dir_scan_info *root;
+       ms_dir_scan_info *tmp_root = NULL;
+       ms_dir_scan_info *cur_node = NULL; /*current node*/
+       ms_dir_scan_info *prv_node = NULL; /*previous node*/
+       ms_dir_scan_info *next_node = NULL;
+
+       root = malloc(sizeof(ms_dir_scan_info));
+       if (root == NULL) {
+               MS_DBG_ERR("malloc fail");
+               return;
+       }
+
+       if (storage_type == MS_STORAGE_INTERNAL)
+               root->name = strdup(MEDIA_ROOT_PATH_INTERNAL);
+       else
+               root->name = strdup(MEDIA_ROOT_PATH_SDCARD);
+       if (root->name  == NULL) {
+               MS_DBG_ERR("strdup fail");
+               MS_SAFE_FREE(root);
+               return;
+       }
+
+       root->parent = NULL;
+       root->Rbrother = NULL;
+       root->next = NULL;
+       tmp_root = root;
+       prv_node = root;
+
+       path = malloc(sizeof(char) * MS_FILE_PATH_LEN_MAX);
+
+       err = ms_get_full_path_from_node(tmp_root, path, depth);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_SAFE_FREE(path);
+               MS_SAFE_FREE(root);
+               return;
+       }
+
+       ms_inoti_add_watch_with_node(root, depth);
+
+       while (1) {
+               /*check poweroff status*/
+               if (power_off) {
+                       MS_DBG("Power off");
+                       goto FREE_RESOURCES;
+               }
+
+               /*check SD card in out*/
+               if ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (storage_type == MS_STORAGE_EXTERNAL))
+                       goto FREE_RESOURCES;
+
+               depth ++;
+               dp = opendir(path);
+               if (dp == NULL) {
+                       MS_DBG_ERR("%s folder opendir fails", path);
+                       goto NEXT_DIR;
+               }
+
+               while (!readdir_r(dp, &entry, &result)) {
+                       /*check poweroff status*/
+                       if (power_off) {
+                               MS_DBG("Power off");
+                               goto FREE_RESOURCES;
+                       }
+
+                       if (result == NULL)
+                               break;
+
+                       if (entry.d_name[0] == '.')
+                               continue;
+
+                       /*check SD card in out*/
+                       if ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (storage_type == MS_STORAGE_EXTERNAL)) {
+                               goto FREE_RESOURCES;
+                       }
+
+                       if (entry.d_type & DT_DIR) {
+                               DIR *tmp_dp = NULL;
+                               err = ms_strappend(get_path, sizeof(get_path), "%s/%s",path, entry.d_name);
+                               if (err != MS_MEDIA_ERR_NONE) {
+                                       MS_DBG_ERR("ms_strappend error");
+                                       continue;
+                               }
+
+                               tmp_dp = opendir(get_path);
+                               if (tmp_dp == NULL) {
+                                       MS_DBG_ERR("%s folder opendir fails", get_path);
+                                       MS_DBG("error : %d, %s", errno ,strerror(errno));
+                                       continue;
+                               }
+                               else
+                                       closedir(tmp_dp);
+
+                               cur_node = malloc(sizeof(ms_dir_scan_info));
+                               if (cur_node == NULL) {
+                                       MS_DBG_ERR("malloc fail");
+
+                                       goto FREE_RESOURCES;
+                               }
+
+                               cur_node->name = strdup(entry.d_name);
+                               cur_node->Rbrother = NULL;
+                               cur_node->next = NULL;
+
+                               /*1. 1st folder */
+                               if (find_folder == 0) {
+                                       cur_node->parent = tmp_root;
+                                       tmp_root = cur_node;
+                               } else {
+                                       cur_node->parent = tmp_root->parent;
+                                       prv_node->Rbrother = cur_node;
+                               }
+                               prv_node->next = cur_node;
+
+                               /*add watch */
+                               ms_inoti_add_watch_with_node(cur_node, depth);
+
+                               /*change previous */
+                               prv_node = cur_node;
+                               find_folder++;
+                       }
+               }
+NEXT_DIR:
+               if (dp) closedir(dp);
+               MS_SAFE_FREE(path);
+               dp = NULL;
+               path = NULL;
+
+               err = _ms_get_path_from_current_node(find_folder, &tmp_root, &root, &path, &depth);
+               if (err != MS_MEDIA_ERR_NONE)
+                       break;
+
+               if (tmp_root == NULL)
+                       break;
+
+               find_folder = 0;
+       }
+
+FREE_RESOURCES:
+       /*free allocated memory */
+       if (dp) closedir(dp);
+       MS_SAFE_FREE(path);
+
+       cur_node = root;
+       while (cur_node != NULL) {
+               next_node = cur_node->next;
+               MS_SAFE_FREE(cur_node->name);
+               MS_SAFE_FREE(cur_node);
+               cur_node = next_node;
+       }
+}
+
+#endif
\ No newline at end of file
diff --git a/common/media-server-main.c b/common/media-server-main.c
new file mode 100755 (executable)
index 0000000..ae232d7
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-main.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <malloc.h>
+#include <vconf.h>
+#include <heynoti.h>
+
+#include "media-util.h"
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-external-storage.h"
+#include "media-server-db-svc.h"
+#include "media-server-inotify.h"
+#include "media-server-socket.h"
+#include "media-server-db.h"
+#include "media-server-drm.h"
+#include "media-server-dbus.h"
+#include "media-server-thumb.h"
+#include "media-server-scanner.h"
+
+#define APP_NAME "media-server"
+
+extern GMutex *scanner_mutex;
+extern GMutex *db_mutex;
+extern int mmc_state;
+
+#if MS_INOTI_ENABLE
+extern GAsyncQueue* ret_queue;
+extern GMutex *list_mutex;
+extern GMutex *queue_mutex;
+extern GArray *reg_list;
+extern bool power_off; /*If this is TRUE, poweroff notification received*/
+#endif
+GMainLoop *mainloop = NULL;
+
+bool check_process()
+{
+       DIR *pdir;
+       struct dirent pinfo;
+       struct dirent *result = NULL;
+       bool ret = false;
+       int find_pid = 0;
+       pid_t current_pid = 0;
+
+       current_pid = getpid();
+
+       pdir = opendir("/proc");
+       if (pdir == NULL) {
+               MS_DBG_ERR("err: NO_DIR\n");
+               return 0;
+       }
+
+       while (!readdir_r(pdir, &pinfo, &result)) {
+               if (result == NULL)
+                       break;
+
+               if (pinfo.d_type != 4 || pinfo.d_name[0] == '.'
+                   || pinfo.d_name[0] > 57)
+                       continue;
+
+               FILE *fp;
+               char buff[128];
+               char path[128];
+
+               ms_strcopy(path, sizeof(path), "/proc/%s/status", pinfo.d_name);
+               fp = fopen(path, "rt");
+               if (fp) {
+                       if (fgets(buff, 128, fp) == NULL)
+                               MS_DBG_ERR("fgets failed");
+                       fclose(fp);
+
+                       if (strstr(buff, APP_NAME)) {
+                               find_pid = atoi(pinfo.d_name);
+                               if (find_pid == current_pid)
+                                       ret = true;
+                               else {
+                                       ret = false;
+                                       break;
+                               }
+                       }
+               } else {
+                       MS_DBG_ERR("Can't read file [%s]", path);
+               }
+       }
+
+       closedir(pdir);
+
+       return ret;
+}
+
+void init_process()
+{
+
+}
+
+static void _power_off_cb(void* data)
+{
+       MS_DBG("++++++++++++++++++++++++++++++++++++++");
+       MS_DBG("POWER OFF");
+       MS_DBG("++++++++++++++++++++++++++++++++++++++");
+#if MS_INOTI_ENABLE
+       power_off = true;
+#endif
+       /*Quit Thumbnail Thread*/
+       GMainLoop *thumb_mainloop = ms_get_thumb_thread_mainloop();
+       if (thumb_mainloop && g_main_is_running(thumb_mainloop)) {
+               g_main_loop_quit(thumb_mainloop);
+       }
+
+       /*Quit DB Thread*/
+       GMainLoop *db_mainloop = ms_db_get_mainloop();
+       if(db_mainloop && g_main_loop_is_running(db_mainloop)) {
+               g_main_loop_quit(db_mainloop);
+       }
+
+       /*Quit Main Thread*/
+       if (mainloop && g_main_loop_is_running(mainloop)) {
+               g_main_loop_quit(mainloop);
+       }
+
+       return;
+}
+
+static bool _db_clear(void** handle)
+{
+       int err;
+       int db_status;
+       bool need_db_create = false;
+
+       /*update just valid type*/
+       err = ms_invalidate_all_items(handle, MS_STORAGE_EXTERNAL);
+       if (err != MS_MEDIA_ERR_NONE)
+               MS_DBG_ERR("ms_change_valid_type fail");
+
+       ms_config_get_int(MS_SCAN_STATUS_INTERNAL, &db_status);
+       MS_DBG("finish_phone_init_data  db = %d", db_status);
+
+       if (db_status == P_VCONF_SCAN_DOING) {
+               need_db_create = true;
+
+               err = ms_invalidate_all_items(handle, MS_STORAGE_INTERNAL);
+               if (err != MS_MEDIA_ERR_NONE)
+                       MS_DBG_ERR("ms_change_valid_type fail");
+       }
+
+//     ms_set_db_status(MS_DB_UPDATED);
+
+       return need_db_create;
+}
+
+void _ms_signal_handler(int n)
+{
+       MS_DBG("Receive SIGNAL");
+       int stat, pid, thumb_pid;
+       int scanner_pid;
+
+       thumb_pid = ms_thumb_get_server_pid();
+       MS_DBG("Thumbnail server pid : %d", thumb_pid);
+
+       scanner_pid = ms_get_scanner_pid();
+
+       pid = waitpid(-1, &stat, WNOHANG);
+       /* check pid of child process of thumbnail thread */
+       MS_DBG("[PID %d] signal ID %d", pid, n);
+
+       if (pid == thumb_pid) {
+               MS_DBG("Thumbnail server is dead");
+               ms_thumb_reset_server_status();
+       } else if (pid == scanner_pid) {
+               MS_DBG("Scanner is dead");
+               ms_reset_scanner_status();
+       } else if (pid == -1) {
+               MS_DBG("%s", strerror(errno));
+       }
+
+       if (WIFEXITED(stat)) {
+               MS_DBG("normal termination , exit status : %d", WEXITSTATUS(stat));
+       } else if (WIFSIGNALED(stat)) {
+               MS_DBG("abnormal termination , signal number : %d", WTERMSIG(stat));
+       } else if (WIFSTOPPED(stat)) {
+               MS_DBG("child process is stoped, signal number : %d", WSTOPSIG(stat));
+       }
+
+       return;
+}
+
+static void _ms_new_global_variable(void)
+{
+#if MS_INOTI_ENABLE
+       /*Init for register file*/
+       if (!list_mutex) list_mutex = g_mutex_new();
+       if (!queue_mutex) queue_mutex = g_mutex_new();
+       if (!reg_list) reg_list = g_array_new(TRUE, TRUE, sizeof(char*));
+       /*These are a communicator for thread*/
+       if (!ret_queue) ret_queue = g_async_queue_new();
+#endif
+       /*Init mutex variable*/
+       if (!db_mutex) db_mutex = g_mutex_new();
+
+       /*media scanner stop/start mutex*/
+       if (!scanner_mutex) scanner_mutex = g_mutex_new();
+}
+
+static void _ms_free_global_variable(void)
+{
+#if MS_INOTI_ENABLE
+       if (list_mutex) g_mutex_free(list_mutex);
+       if (queue_mutex)g_mutex_free(queue_mutex);
+       if (reg_list) g_array_free(reg_list, true);
+       if (ret_queue) g_async_queue_unref(ret_queue);
+#endif
+       /*Clear mutex variable*/
+       if (db_mutex) g_mutex_free (db_mutex);
+
+       if (scanner_mutex) g_mutex_free(scanner_mutex);
+}
+
+int main(int argc, char **argv)
+{
+#if MS_INOTI_ENABLE
+       GThread *inoti_thread = NULL;
+#endif
+       GThread *db_thread = NULL;
+       GThread *thumb_thread = NULL;
+       GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+       int sockfd = MS_SOCK_NOT_ALLOCATE;
+       int err;
+       int heynoti_id;
+       bool check_result = false;
+       bool need_db_create;
+       void **handle = NULL;
+       struct sigaction sigset;
+
+       check_result = check_process();
+       if (check_result == false)
+               exit(0);
+
+       if (!g_thread_supported()) {
+               g_thread_init(NULL);
+       }
+
+       /*Init main loop*/
+       mainloop = g_main_loop_new(NULL, FALSE);
+#if MS_INOTI_ENABLE
+       /*inotify setup */
+       ms_inoti_init();
+#endif
+       /*heynoti for power off*/
+       if ((heynoti_id = heynoti_init()) <0) {
+               MS_DBG("heynoti_init failed");
+       } else {
+               err = heynoti_subscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb, NULL);
+               if (err < 0)
+                       MS_DBG("heynoti_subscribe failed");
+
+               err = heynoti_attach_handler(heynoti_id);
+               if (err < 0)
+                       MS_DBG("heynoti_attach_handler failed");
+       }
+
+       /*load functions from plusin(s)*/
+       err = ms_load_functions();
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("function load failed");
+               exit(0);
+       }
+
+       _ms_new_global_variable();
+
+       /*connect to media db, if conneting is failed, db updating is stopped*/
+       ms_connect_db(&handle);
+
+       ms_dbus_init();
+#if MS_INOTI_ENABLE
+       ms_inoti_add_watch_all_directory(MS_STORAGE_INTERNAL);
+#endif
+       /*prepare socket*/
+       /* Create and bind new UDP socket */
+       if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_SCANNER_PORT, &sockfd)
+               != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("Failed to create socket");
+       } else {
+               context = g_main_loop_get_context(mainloop);
+
+               /* Create new channel to watch udp socket */
+               channel = g_io_channel_unix_new(sockfd);
+               source = g_io_create_watch(channel, G_IO_IN);
+
+               /* Set callback to be called when socket is readable */
+               g_source_set_callback(source, (GSourceFunc)ms_read_socket, handle, NULL);
+               g_source_attach(source, context);
+               g_source_unref(source);
+       }
+
+       /*create each threads*/
+#if MS_INOTI_ENABLE
+       inoti_thread = g_thread_new("inotify_thread", (GThreadFunc)ms_inoti_thread, NULL);
+#endif
+       db_thread = g_thread_new("db_thread", (GThreadFunc)ms_db_thread, NULL);
+       thumb_thread = g_thread_new("thumb_agent_thread", (GThreadFunc)ms_thumb_agent_start_thread, NULL);
+
+       /*set vconf callback function*/
+       err = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, (vconf_callback_fn) ms_mmc_vconf_cb, NULL);
+       if (err == -1)
+               MS_DBG_ERR("add call back function for event %s fails", VCONFKEY_SYSMAN_MMC_STATUS);
+
+       MS_DBG("*********************************************************");
+       MS_DBG("*** Begin to check tables of file manager in database ***");
+       MS_DBG("*********************************************************");
+
+       /* Add signal handler */
+       sigset.sa_handler = _ms_signal_handler;
+       if (sigaction(SIGCHLD, &sigset, NULL) < 0) {
+               MS_DBG_ERR("sigaction failed [%s]", strerror(errno));
+       } else {
+               MS_DBG("handler ok");
+       }
+
+       /*clear previous data of sdcard on media database and check db status for updating*/
+       while(!ms_db_get_thread_status()) {
+               MS_DBG("wait db thread");
+               sleep(1);
+       }
+
+       need_db_create = _db_clear(handle);
+       if (need_db_create) {
+               /*insert records*/
+               ms_send_storage_scan_request(MS_STORAGE_INTERNAL, MS_SCAN_ALL);
+       } else {
+               ms_send_storage_scan_request(MS_STORAGE_INTERNAL, MS_SCAN_PART);
+       }
+
+       if (ms_is_mmc_inserted()) {
+               mmc_state = VCONFKEY_SYSMAN_MMC_MOUNTED;
+
+               if (!ms_drm_insert_ext_memory())
+                       MS_DBG_ERR("ms_drm_insert_ext_memory failed");
+
+               ms_make_default_path_mmc();
+#if MS_INOTI_ENABLE
+               ms_inoti_add_watch_all_directory(MS_STORAGE_EXTERNAL);
+#endif
+               ms_present_mmc_insert();
+
+               ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, ms_get_mmc_state());
+       }
+
+       /*Active flush */
+       malloc_trim(0);
+
+       MS_DBG("*****************************************");
+       MS_DBG("*** Server of File Manager is running ***");
+       MS_DBG("*****************************************");
+
+       g_main_loop_run(mainloop);
+#if MS_INOTI_ENABLE
+       g_thread_join(inoti_thread);
+#endif
+       g_thread_join(db_thread);
+       g_thread_join(thumb_thread);
+
+       /*close an IO channel*/
+       g_io_channel_shutdown(channel,  FALSE, NULL);
+       g_io_channel_unref(channel);
+
+       heynoti_unsubscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb);
+       heynoti_close(heynoti_id);
+
+       /***********
+       **remove call back functions
+       ************/
+       vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
+                                (vconf_callback_fn) ms_mmc_vconf_cb);
+
+       _ms_free_global_variable();
+
+       /*disconnect form media db*/
+       if (handle) ms_disconnect_db(&handle);
+
+       /*close socket*/
+       close(sockfd);
+
+       /*unload functions*/
+       ms_unload_functions();
+
+       exit(0);
+}
diff --git a/common/media-server-scanner.c b/common/media-server-scanner.c
new file mode 100755 (executable)
index 0000000..ef10f34
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  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 <errno.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <glib.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-types.h"
+#include "media-server-dbg.h"
+#include "media-server-utils.h"
+#include "media-server-socket.h"
+#include "media-server-scanner.h"
+
+#define MS_NO_REMAIN_TASK 0
+
+extern GMainLoop *mainloop;
+extern GArray *owner_list;
+GMutex *scanner_mutex;
+
+static bool scanner_ready;
+static int alarm_id;
+static int receive_id;
+static int child_pid;
+
+
+
+static int _ms_check_remain_task(void)
+{
+       int remain_task;
+
+       if (owner_list != NULL)
+               remain_task = owner_list->len;
+       else
+               remain_task = MS_NO_REMAIN_TASK;
+
+       return remain_task;
+}
+
+ms_db_status_type_t ms_check_scanning_status(void)
+{
+       int status;
+
+       if(ms_config_get_int(VCONFKEY_FILEMANAGER_DB_STATUS, &status)) {
+               if (status == VCONFKEY_FILEMANAGER_DB_UPDATING) {
+                       return MS_DB_UPDATING;
+               }
+       }
+
+       return MS_DB_UPDATED;
+}
+
+static gboolean _ms_stop_scanner (gpointer user_data)
+{
+       int sockfd;
+       int task_num;
+       GIOChannel *src = user_data;
+
+       g_mutex_lock(scanner_mutex);
+
+       /* check status of scanner */
+       /* If some task remain or scanner is running, scanner must not stop*/
+       task_num = _ms_check_remain_task();
+       if (task_num != MS_NO_REMAIN_TASK) {
+               MS_DBG("[%d] task(s) remains", task_num);
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       }
+
+       if (ms_check_scanning_status() == MS_DB_UPDATING) {
+               MS_DBG("DB is updating");
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       } else {
+               MS_DBG("DB updating is not working");
+       }
+
+       /* stop media scanner */
+       if (child_pid >0 ) {
+               if (kill(child_pid, SIGKILL) < 0) {
+                       MS_DBG_ERR("kill failed : %s", strerror(errno));
+                       g_mutex_unlock(scanner_mutex);
+                       return TRUE;
+               }
+       }
+       /* close socket */
+       sockfd = g_io_channel_unix_get_fd(src);
+       g_io_channel_shutdown(src, FALSE, NULL);
+       g_io_channel_unref(src);
+       close(sockfd);
+
+       g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), alarm_id));
+       g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), receive_id));
+
+       return FALSE;
+}
+
+
+static void _ms_add_timeout(guint interval, GSourceFunc func, gpointer data)
+{
+       MS_DBG("");
+       GSource *src;
+
+       src = g_timeout_source_new_seconds(interval);
+       g_source_set_callback(src, func, data, NULL);
+       alarm_id = g_source_attach(src, g_main_loop_get_context (mainloop));
+       g_source_unref(src);
+}
+
+int
+ms_scanner_start(void)
+{
+       int pid;
+
+       g_mutex_lock(scanner_mutex);
+
+       if (child_pid > 0) {
+               MS_DBG_ERR("media scanner is already started");
+               g_mutex_unlock(scanner_mutex);
+               return MS_MEDIA_ERR_NONE;
+       }
+
+       if((pid = fork()) < 0) {
+               MS_DBG_ERR("Fork error\n");
+       } else if (pid > 0) {
+               /* parent process */
+               /* wait until scanner is ready*/
+               int ret = MS_MEDIA_ERR_NONE;
+               int sockfd = -1;
+               int err = -1;
+               int n_reuse = 1;
+               struct sockaddr_in serv_addr;
+               unsigned int serv_addr_len = -1;
+               int port = MS_SCAN_COMM_PORT;
+               ms_comm_msg_s recv_msg;
+
+               GSource *res_source = NULL;
+               GIOChannel *res_channel = NULL;
+               GMainContext *res_context = NULL;
+
+               /*Create Socket*/
+               ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sockfd);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_ipc_create_client_socket failed [%d]",ret);
+                       g_mutex_unlock(scanner_mutex);
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+
+               /* set socket re-use */
+               if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n_reuse, sizeof(n_reuse)) == -1) {
+                       MS_DBG_ERR("setsockopt failed: %s", strerror(errno));
+                       close(sockfd);
+                       g_mutex_unlock(scanner_mutex);
+                       return MS_MEDIA_ERR_SOCKET_INTERNAL;
+               }
+
+               /*Set server Address*/
+               memset(&serv_addr, 0, sizeof(serv_addr));
+               serv_addr.sin_family = AF_INET;
+               serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
+               serv_addr.sin_port = htons(port);
+
+               /* Bind to the local address */
+               if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+                       MS_DBG_ERR("bind failed [%s]", strerror(errno));
+                       close(sockfd);
+                       g_mutex_unlock(scanner_mutex);
+                       return MS_MEDIA_ERR_SOCKET_BIND;
+               }
+
+               /*Receive Response*/
+               serv_addr_len = sizeof(serv_addr);
+               err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       ret = err;
+                       close(sockfd);
+               } else {
+                       int scanner_status = recv_msg.msg_type;
+                       if (scanner_status == MS_MSG_SCANNER_READY) {
+                               MS_DBG("RECEIVE OK [%d] %d", recv_msg.msg_type, pid);
+                               scanner_ready = true;
+                               child_pid = pid;
+
+                               /* attach result receiving socket to mainloop */
+                               res_context = g_main_loop_get_context(mainloop);
+
+                               /* Create new channel to watch udp socket */
+                               res_channel = g_io_channel_unix_new(sockfd);
+                               res_source = g_io_create_watch(res_channel, G_IO_IN);
+
+                               /* Set callback to be called when socket is readable */
+                               g_source_set_callback(res_source, (GSourceFunc)ms_receive_message_from_scanner, NULL, NULL);
+                               receive_id = g_source_attach(res_source, res_context);
+                               g_source_unref(res_source);
+
+                               _ms_add_timeout(30, (GSourceFunc)_ms_stop_scanner, res_channel);
+
+                               ret = MS_MEDIA_ERR_NONE;
+                       } else {
+                               MS_DBG_ERR("Receive wrong message from scanner[%d]", scanner_status);
+                               close(sockfd);
+                               ret = MS_MEDIA_ERR_SOCKET_RECEIVE;
+                       }
+               }
+
+               g_mutex_unlock(scanner_mutex);
+
+               return ret;
+               /* attach socket receive message callback */
+       } else if(pid == 0) {
+               /* child process */
+               MS_DBG_ERR("CHILD PROCESS");
+               MS_DBG("EXECUTE MEDIA SCANNER");
+               execl("/usr/bin/media-scanner", "media-scanner", NULL);
+               g_mutex_unlock(scanner_mutex);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+bool ms_get_scanner_status(void)
+{
+       return scanner_ready;
+}
+
+void ms_reset_scanner_status(void)
+{
+       child_pid = 0;
+       scanner_ready = false;
+
+       /* scanning is done */
+       if (!ms_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DONE)) {
+               MS_DBG_ERR("ms_config_set_int failed");
+       }
+
+       g_mutex_unlock(scanner_mutex);
+}
+
+int ms_get_scanner_pid(void)
+{
+       return child_pid;
+}
\ No newline at end of file
diff --git a/common/media-server-socket.c b/common/media-server-socket.c
new file mode 100755 (executable)
index 0000000..ae9f30b
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-thumb.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <malloc.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-util-internal.h"
+#include "media-server-dbg.h"
+#include "media-server-ipc.h"
+#include "media-server-db-svc.h"
+#include "media-server-utils.h"
+#include "media-server-scanner.h"
+#include "media-server-socket.h"
+#include "media-server-db.h"
+
+extern GAsyncQueue *scan_queue;
+GAsyncQueue* ret_queue;
+GArray *owner_list;
+extern GMutex *scanner_mutex;
+
+typedef struct ms_req_owner_data
+{
+       int pid;
+       struct sockaddr_in *client_addr;
+}ms_req_owner_data;
+
+int _ms_add_owner(ms_req_owner_data *owner_data)
+{
+//     MS_DBG("the length of array : %d", owner_list->len);
+//     MS_DBG("pid : %d", owner_data->pid);
+//     MS_DBG("client_addr : %p", owner_data->client_addr);
+
+       g_array_append_val(owner_list, owner_data);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int _ms_find_owner(int pid, ms_req_owner_data **owner_data)
+{
+       int i;
+       int len = owner_list->len;
+       bool find_flag = false;
+       ms_req_owner_data *data = NULL;
+
+       MS_DBG("length list :  %d", len);
+
+       for (i=0; i < len; i++) {
+               data = g_array_index(owner_list, ms_req_owner_data*, i);
+               MS_DBG("%d %d", data->pid, pid);
+               if (data->pid == pid) {
+                       find_flag = true;
+                       break;
+               }
+       }
+
+       if (find_flag == true) {
+               *owner_data = data;
+               MS_DBG("FIND OWNER");
+       } else {
+               *owner_data = NULL;
+               MS_DBG("DO NOT FIND OWNER");
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int _ms_delete_owner(ms_req_owner_data *owner_data)
+{
+       int i;
+       int len = owner_list->len;
+       ms_req_owner_data *data = NULL;
+
+       for (i=0; i < len; i++) {
+               data = g_array_index(owner_list, ms_req_owner_data*, i);
+               if (data->pid == owner_data->pid) {
+                       if (data->client_addr == owner_data->client_addr) {
+                               g_array_remove_index(owner_list, i);
+                               MS_SAFE_FREE(owner_data->client_addr);
+                               MS_SAFE_FREE(owner_data);
+                       }
+                       break;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       struct sockaddr_in *client_addr = NULL;
+       socklen_t client_addr_len;
+       ms_comm_msg_s recv_msg;
+       ms_comm_msg_s result_msg;
+       ms_comm_msg_s scan_msg;
+       int msg_size;
+       int sockfd = MS_SOCK_NOT_ALLOCATE;
+       int ret;
+       int pid;
+       int req_num;
+       int path_size;
+       void **handle = data;
+       char *path = NULL;
+
+       g_mutex_lock(scanner_mutex);
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       }
+
+       /* Socket is readable */
+       MS_MALLOC(client_addr, sizeof(struct sockaddr_in));
+       if (client_addr == NULL) {
+               MS_DBG_ERR("malloc failed");
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       }
+
+       client_addr_len = sizeof(struct sockaddr_in);
+       ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), client_addr, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_receive_message failed");
+               MS_SAFE_FREE(client_addr);
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       }
+
+       MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
+
+       if (recv_msg.msg_size > 0 && recv_msg.msg_size < MS_FILE_PATH_LEN_MAX) {
+               msg_size = recv_msg.msg_size;
+               path_size = msg_size + 1;
+       } else {
+               /*NEED IMPLEMETATION*/
+               MS_SAFE_FREE(client_addr);
+               g_mutex_unlock(scanner_mutex);
+               return TRUE;
+       }
+
+       /* copy received data */
+       req_num = recv_msg.msg_type;
+       pid = recv_msg.pid;
+
+       /* register file request
+         * media server inserts the meta data of one file into media db */
+       if (req_num == MS_MSG_DB_UPDATE) {
+               MS_MALLOC(path, path_size);
+               if  (path !=  NULL) {
+                       ret = ms_strcopy(path, path_size, "%s", recv_msg.msg);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               MS_SAFE_FREE(path);
+                               MS_SAFE_FREE(client_addr);
+                               g_mutex_unlock(scanner_mutex);
+                               return TRUE;
+                       }
+
+                       MS_DBG("REQUEST FILE REGISTER");
+#if MS_INOTI_ENABLE
+                       ret = ms_register_file(handle, path, ret_queue);
+                       if (ret == MS_MEDIA_ERR_NOW_REGISTER_FILE) {
+                               ret= GPOINTER_TO_INT(g_async_queue_pop(ret_queue)) - MS_MEDIA_ERR_MAX;
+                       }
+#else
+                       ret = ms_register_file(handle, path);
+#endif
+                       MS_DBG_INFO("register result : %d", ret);
+                       /* the result of inserting to db */
+                       result_msg.result = ret;
+               } else {
+                       MS_DBG_ERR("malloc failed");
+                       result_msg.result = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+               }
+
+               ms_ipc_send_msg_to_client(sockfd, &result_msg, client_addr);
+
+               MS_SAFE_FREE(path);
+               MS_SAFE_FREE(client_addr);
+
+               g_mutex_unlock(scanner_mutex);
+       } else if (req_num == MS_MSG_DIRECTORY_SCANNING
+               ||req_num == MS_MSG_BULK_INSERT
+               ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+               /* this request process in media scanner */
+
+               ms_req_owner_data *owner_data = NULL;
+
+               /* If owner list is NULL, create it */
+               /* pid and client address are stored in ower list */
+               /* These are used for sending result of scanning */
+               if (owner_list == NULL) {
+                       /*create array for processing overlay data*/
+                       owner_list = g_array_new (FALSE, FALSE, sizeof (ms_req_owner_data *));
+                       if (owner_list == NULL) {
+                               MS_DBG_ERR("g_array_new error");
+                               MS_SAFE_FREE(client_addr);
+                               g_mutex_unlock(scanner_mutex);
+                               return TRUE;
+                       }
+               }
+
+               /* store pid and client address */
+               MS_MALLOC(owner_data, sizeof(ms_req_owner_data));
+               owner_data->pid = recv_msg.pid;
+               owner_data->client_addr = client_addr;
+
+               _ms_add_owner(owner_data);
+
+               /* create send message for media scanner */
+               scan_msg.msg_type = req_num;
+               scan_msg.pid = pid;
+               scan_msg.msg_size = msg_size;
+               ms_strcopy(scan_msg.msg, path_size, "%s", recv_msg.msg);
+
+               /* change the status of media scanner for directory scanning */
+               if (req_num == MS_MSG_DIRECTORY_SCANNING
+                       || req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                       MS_DBG("DIRECTORY SCANNING IS START");
+                       if (!ms_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DOING)) {
+                               MS_DBG_ERR("ms_config_set_int failed");
+                       }
+               }
+
+               g_mutex_unlock(scanner_mutex);
+
+               if (ms_get_scanner_status()) {
+                       MS_DBG("Scanner is ready");
+                       ms_send_scan_request(&scan_msg);
+               } else {
+                       MS_DBG("Scanner starts");
+                       ret = ms_scanner_start();
+                       if(ret == MS_MEDIA_ERR_NONE) {
+                               ms_send_scan_request(&scan_msg);
+                       } else {
+                               MS_DBG("Scanner starting failed. %d", ret);
+                       }
+               }
+       } else {
+               /* NEED IMPLEMENTATION */
+               MS_SAFE_FREE(client_addr);
+               g_mutex_unlock(scanner_mutex);
+       }
+
+       /*Active flush */
+       malloc_trim(0);
+
+       return TRUE;
+}
+gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       ms_comm_msg_s recv_msg;
+       int sockfd = MS_SOCK_NOT_ALLOCATE;
+       int msg_type;
+       int ret;
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       /* Socket is readable */
+       ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), NULL, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_receive_message failed [%s]", strerror(errno));
+               return TRUE;
+       }
+
+       MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg);
+
+       msg_type = recv_msg.msg_type;
+       if ((msg_type == MS_MSG_SCANNER_RESULT) ||
+               (msg_type == MS_MSG_SCANNER_BULK_RESULT)) {
+               if (owner_list != NULL) {
+                       /* If the owner of result message is not media-server, media-server notify to the owner */
+                       /* The owner of message is distingushied by pid in received message*/
+                       /* find owner data */
+                       ms_req_owner_data *owner_data = NULL;
+
+                       _ms_find_owner(recv_msg.pid, &owner_data);
+                       if (owner_data != NULL) {
+                               MS_DBG("PID : %d", owner_data->pid);
+                               ms_comm_msg_s *result_msg;
+
+                               if (msg_type == MS_MSG_SCANNER_RESULT) {
+                                       MS_DBG("DIRECTORY SCANNING IS DONE");
+                                       if (!ms_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DONE)) {
+                                               MS_DBG_ERR("ms_config_set_int failed");
+                                       }
+                               }
+
+                               MS_MALLOC(result_msg, sizeof(ms_comm_msg_s));
+                               /* owner data exists */
+                               /* send result to the owner of request */
+                               ms_ipc_send_msg_to_client(sockfd, &recv_msg, owner_data->client_addr);
+
+                               /* free owner data*/
+                               _ms_delete_owner(owner_data);
+
+                               MS_SAFE_FREE(result_msg);
+                       }
+               } else {
+                       /* owner data does not exist*/
+                       /*  this is result of request of media server*/
+               }
+       } else {
+               MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type );
+       }
+
+       return TRUE;
+}
+
+int ms_send_scan_request(ms_comm_msg_s *send_msg)
+{
+       int ret;
+       int res = MS_MEDIA_ERR_NONE;
+       int sockfd = -1;
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
+       if (ret != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_SOCKET_CONN;
+
+       ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_DAEMON_PORT, send_msg, NULL);
+       if (ret != MS_MEDIA_ERR_NONE)
+               res = ret;
+
+       close(sockfd);
+
+       return res;
+}
+
+int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       ms_comm_msg_s scan_msg = {
+               .msg_type = MS_MSG_STORAGE_INVALID,
+               .pid = 0, /* pid 0 means media-server */
+               .result = -1,
+               .msg_size = 0,
+               .msg = {0},
+       };
+
+       /* msg_type */
+       switch (scan_type) {
+               case MS_SCAN_PART:
+                       scan_msg.msg_type = MS_MSG_STORAGE_PARTIAL;
+                       break;
+               case MS_SCAN_ALL:
+                       scan_msg.msg_type = MS_MSG_STORAGE_ALL;
+                       break;
+               case MS_SCAN_INVALID:
+                       scan_msg.msg_type = MS_MSG_STORAGE_INVALID;
+                       break;
+               default :
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
+                       goto ERROR;
+                       break;
+       }
+
+       /* msg_size & msg */
+       switch (storage_type) {
+               case MS_STORAGE_INTERNAL:
+                       scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_INTERNAL);
+                       strncpy(scan_msg.msg, MEDIA_ROOT_PATH_INTERNAL, scan_msg.msg_size );
+                       break;
+               case MS_STORAGE_EXTERNAL:
+                       scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_SDCARD);
+                       strncpy(scan_msg.msg, MEDIA_ROOT_PATH_SDCARD, scan_msg.msg_size );
+                       break;
+               default :
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       MS_DBG_ERR("ms_send_storage_scan_request invalid parameter");
+                       goto ERROR;
+                       break;
+       }
+
+       g_mutex_lock(scanner_mutex);
+
+       if (ms_get_scanner_status()) {
+               ms_send_scan_request(&scan_msg);
+               g_mutex_unlock(scanner_mutex);
+       } else {
+               g_mutex_unlock(scanner_mutex);
+
+               ret = ms_scanner_start();
+               if(ret == MS_MEDIA_ERR_NONE) {
+                       ms_send_scan_request(&scan_msg);
+               } else {
+                       MS_DBG("Scanner starting failed. ");
+               }
+       }
+
+ERROR:
+
+       return ret;
+}
+
+gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       struct sockaddr_in client_addr;
+
+       ms_comm_msg_s recv_msg;
+       int send_msg = MS_MEDIA_ERR_NONE;
+       int sockfd = MS_SOCK_NOT_ALLOCATE;
+       int ret = MS_MEDIA_ERR_NONE;
+       MediaDBHandle *db_handle = (MediaDBHandle *)data;
+       ms_comm_msg_s msg;
+       char * sql_query = NULL;
+       size_t sql_query_size = 0;
+
+       memset(&recv_msg, 0, sizeof(recv_msg));
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), &client_addr, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_receive_message failed");
+               return TRUE;
+       }
+
+//     MS_DBG("msg_type[%d], msg_size[%d] msg[%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
+
+       if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX)  || (!MS_STRING_VALID(recv_msg.msg))) {
+               MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
+               return TRUE;
+       }
+
+       sql_query_size = recv_msg.msg_size + 1;
+       MS_MALLOC(sql_query, sql_query_size);
+       if (sql_query != NULL) {
+               ret = ms_strcopy(sql_query, sql_query_size, "%s", recv_msg.msg);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MS_DBG_ERR("ms_strcopy failed");
+                       MS_SAFE_FREE(sql_query);
+                       return TRUE;
+               }
+
+               ret = media_db_update_db(db_handle, sql_query);
+               if (ret != MS_MEDIA_ERR_NONE)
+                       MS_DBG_ERR("media_db_update_db error : %d", ret);
+
+               send_msg = ret;
+               MS_SAFE_FREE(sql_query);
+       } else {
+               send_msg = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       memset(&msg, 0x0, sizeof(ms_comm_msg_s));
+       msg.result = send_msg;
+
+       ms_ipc_send_msg_to_client(sockfd, &msg, &client_addr);
+
+       /*Active flush */
+       malloc_trim(0);
+
+       return TRUE;
+}
+
+gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       struct sockaddr_in client_addr;
+       unsigned int client_addr_len;
+
+       ms_comm_msg_s recv_msg;
+       int sock = -1;
+       int client_sock = -1;
+       int send_msg = MS_MEDIA_ERR_NONE;
+       int recv_msg_size = -1;
+       int ret = MS_MEDIA_ERR_NONE;
+       char * sql_query = NULL;
+       size_t sql_query_size = 0;
+       MediaDBHandle *db_handle = (MediaDBHandle *)data;
+
+       sock = g_io_channel_unix_get_fd(src);
+       if (sock < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+       memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
+
+       if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
+               MS_DBG_ERR("accept failed : %s", strerror(errno));
+               return TRUE;
+       }
+
+       MS_DBG("Client[%d] is accepted", client_sock);
+
+       while(1) {
+               if ((recv_msg_size = recv(client_sock, &recv_msg, sizeof(ms_comm_msg_s), 0)) < 0) {
+                       MS_DBG_ERR("recv failed : %s", strerror(errno));
+
+                       close(client_sock);
+                       if (errno == EWOULDBLOCK) {
+                               MS_DBG_ERR("Timeout. Can't try any more");
+                               return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
+                       } else {
+                               MS_DBG_ERR("recv failed : %s", strerror(errno));
+                               return MS_MEDIA_ERR_SOCKET_RECEIVE;
+                       }
+               }
+
+               MS_DBG("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg);
+
+               if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX)  || (!MS_STRING_VALID(recv_msg.msg))) {
+                       MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size);
+                       close(client_sock);
+                       return TRUE;
+               }
+
+               sql_query_size = recv_msg.msg_size + 1;
+               MS_MALLOC(sql_query, sql_query_size);
+               if (sql_query != NULL) {
+                       ret = ms_strcopy(sql_query, sql_query_size, "%s", recv_msg.msg);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               MS_DBG_ERR("ms_strcopy failed");
+                               MS_SAFE_FREE(sql_query);
+                               close(client_sock);
+                               return TRUE;
+                       }
+
+                       if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) {
+                               ret = media_db_update_db_batch_start(sql_query);
+                       } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) {
+                               ret = media_db_update_db_batch_end(db_handle, sql_query);
+                       } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH) {
+                               ret = media_db_update_db_batch(sql_query);
+                       } else {
+
+                       }
+
+                       MS_SAFE_FREE(sql_query);
+                       send_msg = ret;
+
+                       if (send(client_sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
+                               MS_DBG_ERR("send failed : %s", strerror(errno));
+                       } else {
+                               MS_DBG("Sent successfully");
+                       }
+
+                       if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END)
+                               break;
+
+                       memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s));
+               } else {
+                       MS_DBG_ERR("MS_MALLOC failed");
+                       close(client_sock);
+                       return TRUE;
+               }
+
+       }
+
+       close(client_sock);
+       return TRUE;
+}
diff --git a/common/media-server-thumb.c b/common/media-server-thumb.c
new file mode 100755 (executable)
index 0000000..edbc7cc
--- /dev/null
@@ -0,0 +1,1115 @@
+/*
+ * media-thumbnail-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hyunjun Ko <zzoon.ko@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 <errno.h>
+
+#include "media-util.h"
+#include "media-server-dbg.h"
+#include "media-server-thumb.h"
+#include "media-server-utils.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "MEDIA_SERVER_THUMB"
+
+#define THUMB_SERVER_NAME "media-thumbnail"
+
+gboolean _ms_thumb_agent_timer();
+
+static GMainLoop *g_thumb_agent_loop = NULL;
+static GIOChannel *g_udp_channel = NULL;
+static gboolean g_folk_thumb_server = FALSE;
+static gboolean g_thumb_server_extracting = FALSE;
+static int g_communicate_sock = 0;
+static int g_timer_id = 0;
+static int g_server_pid = 0;
+
+static GQueue *g_request_queue = NULL;
+static int g_queue_work = 0;
+
+typedef struct {
+       int client_sock;
+       thumbMsg *recv_msg;
+} thumbRequest;
+
+gboolean _ms_thumb_agent_start_jobs(gpointer data)
+{
+       MS_DBG("");
+
+       return FALSE;
+}
+
+void _ms_thumb_agent_finish_jobs()
+{
+       MS_DBG("");
+
+       return;
+}
+
+GMainLoop *
+ms_get_thumb_thread_mainloop(void)
+{
+       return g_thumb_agent_loop;
+}
+
+int ms_thumb_get_server_pid()
+{
+       return g_server_pid;
+}
+
+void ms_thumb_reset_server_status()
+{
+       g_folk_thumb_server = FALSE;
+
+       if (g_timer_id > 0) {
+               g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_timer_id));
+               g_timer_id = 0;
+       }
+
+       if (g_thumb_server_extracting) {
+               /* Need to inplement when crash happens */
+#if 0
+               /* Restart thumbnail server */
+               if (_ms_thumb_agent_execute_server() < 0) {
+                       MS_DBG_ERR("starting thumbnail-server failed");
+               } else {
+                       MS_DBG("Thumbnail-server is started");
+               }
+
+               thumbMsg msg;
+               thumbMsg recv_msg;
+               memset((void *)&msg, 0, sizeof(msg));
+               memset((void *)&recv_msg, 0, sizeof(recv_msg));
+
+               msg.msg_type = 2; // THUMB_REQUEST_ALL_MEDIA
+               msg.org_path[0] = '\0';
+               msg.origin_path_size = 1;
+               msg.dst_path[0] = '\0';
+               msg.dest_path_size = 1;
+
+               /* Command all thumbnail extraction to thumbnail server */
+               if (!_ms_thumb_agent_send_msg_to_thumb_server(&msg, &recv_msg)) {
+                       MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
+               }
+
+               _ms_thumb_create_timer(g_timer_id);
+#else
+               MS_DBG_ERR("Thumbnail server is dead when processing all-thumbs extraction");
+               g_thumb_server_extracting = FALSE;
+               g_server_pid = 0;
+#endif
+       } else {
+               g_thumb_server_extracting = FALSE;
+               g_server_pid = 0;
+       }
+
+       return;
+}
+
+void _ms_thumb_create_timer(int id)
+{
+       if (id > 0)
+               g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), id));
+
+       GSource *timer_src = g_timeout_source_new_seconds(MS_TIMEOUT_SEC_20);
+       g_source_set_callback (timer_src, _ms_thumb_agent_timer, NULL, NULL);
+       g_timer_id = g_source_attach (timer_src, g_main_context_get_thread_default());
+
+}
+
+/* This checks if thumbnail server is running */
+bool _ms_thumb_check_process()
+{
+       DIR *pdir;
+       struct dirent pinfo;
+       struct dirent *result = NULL;
+       bool ret = FALSE;
+
+       pdir = opendir("/proc");
+       if (pdir == NULL) {
+               MS_DBG_ERR("err: NO_DIR\n");
+               return 0;
+       }
+
+       while (!readdir_r(pdir, &pinfo, &result)) {
+               if (result == NULL)
+                       break;
+
+               if (pinfo.d_type != 4 || pinfo.d_name[0] == '.'
+                   || pinfo.d_name[0] > 57)
+                       continue;
+
+               FILE *fp;
+               char buff[128];
+               char path[128];
+
+               ms_strcopy(path, sizeof(path), "/proc/%s/status", pinfo.d_name);
+               fp = fopen(path, "rt");
+               if (fp) {
+                       if (fgets(buff, 128, fp) == NULL)
+                               MS_DBG_ERR("fgets failed");
+                       fclose(fp);
+
+                       if (strstr(buff, THUMB_SERVER_NAME)) {
+                               ret = TRUE;
+                               break;
+                       }
+               } else {
+                       MS_DBG_ERR("Can't read file [%s]", path);
+               }
+       }
+
+       closedir(pdir);
+
+       return ret;
+}
+int
+_ms_thumb_create_socket(int sock_type, int *sock)
+{
+       int sock_fd = 0;
+
+       if ((sock_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+               MS_DBG_ERR("socket failed: %s", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       if (sock_type == CLIENT_SOCKET) {
+
+               struct timeval tv_timeout = { MS_TIMEOUT_SEC_10, 0 };
+
+               if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) {
+                       MS_DBG_ERR("setsockopt failed: %s", strerror(errno));
+                       close(sock_fd);
+                       return MS_MEDIA_ERR_SOCKET_INTERNAL;
+               }
+       } else if (sock_type == SERVER_SOCKET) {
+
+               int n_reuse = 1;
+
+               if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &n_reuse, sizeof(n_reuse)) == -1) {
+                       MS_DBG_ERR("setsockopt failed: %s", strerror(errno));
+                       close(sock_fd);
+                       return MS_MEDIA_ERR_SOCKET_INTERNAL;
+               }
+       }
+
+       *sock = sock_fd;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+
+int
+_ms_thumb_create_udp_socket(int *sock)
+{
+       int sock_fd = 0;
+
+       if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+               MS_DBG_ERR("socket failed: %s", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       struct timeval tv_timeout = { MS_TIMEOUT_SEC_10, 0 };
+
+       if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) {
+               MS_DBG_ERR("setsockopt failed: %s", strerror(errno));
+               close(sock_fd);
+               return MS_MEDIA_ERR_SOCKET_INTERNAL;
+       }
+
+       *sock = sock_fd;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int _media_thumb_get_error()
+{
+       if (errno == EWOULDBLOCK) {
+               MS_DBG_ERR("Timeout. Can't try any more");
+               return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
+       } else {
+               MS_DBG_ERR("recvfrom failed : %s", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_RECEIVE;
+       }
+}
+
+int
+_ms_thumb_recv_msg(int sock, int header_size, thumbMsg *msg)
+{
+       int recv_msg_len = 0;
+       unsigned char *buf = NULL;
+
+       buf = (unsigned char*)malloc(header_size);
+
+       if ((recv_msg_len = recv(sock, buf, header_size, 0)) < 0) {
+               MS_DBG_ERR("recv failed : %s", strerror(errno));
+               MS_SAFE_FREE(buf);
+               return _media_thumb_get_error();
+       }
+
+       memcpy(msg, buf, header_size);
+       //MS_DBG("origin_path_size : %d, dest_path_size : %d", msg->origin_path_size, msg->dest_path_size);
+
+       MS_SAFE_FREE(buf);
+
+       if (msg->origin_path_size <= 0  || msg->origin_path_size > MS_FILE_PATH_LEN_MAX) {
+               MS_SAFE_FREE(buf);
+               MS_DBG_ERR("msg->origin_path_size is invalid %d", msg->origin_path_size );
+               return MS_MEDIA_ERR_DATA_TAINTED;
+       }
+
+       buf = (unsigned char*)malloc(msg->origin_path_size);
+
+       if ((recv_msg_len = recv(sock, buf, msg->origin_path_size, 0)) < 0) {
+               MS_DBG_ERR("recv failed : %s", strerror(errno));
+               MS_SAFE_FREE(buf);
+               return _media_thumb_get_error();
+       }
+
+       strncpy(msg->org_path, (char*)buf, msg->origin_path_size);
+       //MS_DBG("original path : %s", msg->org_path);
+
+       MS_SAFE_FREE(buf);
+
+       if (msg->dest_path_size <= 0  || msg->dest_path_size > MS_FILE_PATH_LEN_MAX) {
+               MS_SAFE_FREE(buf);
+               MS_DBG_ERR("msg->dest_path_size is invalid %d", msg->dest_path_size );
+               return MS_MEDIA_ERR_DATA_TAINTED;
+       }
+
+       buf = (unsigned char*)malloc(msg->dest_path_size);
+
+       if ((recv_msg_len = recv(sock, buf, msg->dest_path_size, 0)) < 0) {
+               MS_DBG_ERR("recv failed : %s", strerror(errno));
+               MS_SAFE_FREE(buf);
+               return _media_thumb_get_error();
+       }
+
+       strncpy(msg->dst_path, (char*)buf, msg->dest_path_size);
+       //MS_DBG("destination path : %s", msg->dst_path);
+
+       MS_SAFE_FREE(buf);
+       return MS_MEDIA_ERR_NONE;
+}
+
+
+int
+_ms_thumb_recv_udp_msg(int sock, int header_size, thumbMsg *msg, struct sockaddr_in *from_addr, unsigned int *from_size)
+{
+       int recv_msg_len = 0;
+       unsigned int from_addr_size = sizeof(struct sockaddr_in);
+       unsigned char *buf = NULL;
+
+       buf = (unsigned char*)malloc(sizeof(thumbMsg));
+
+       recv_msg_len = ms_ipc_wait_message(sock, buf, sizeof(thumbMsg), from_addr, &from_addr_size);
+       if (recv_msg_len != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_wait_message failed : %s", strerror(errno));
+               MS_SAFE_FREE(buf);
+               return _media_thumb_get_error();
+       }
+
+       memcpy(msg, buf, header_size);
+       //MS_DBG("origin_path_size : %d, dest_path_size : %d", msg->origin_path_size, msg->dest_path_size);
+
+       if (msg->origin_path_size <= 0  || msg->origin_path_size > MS_FILE_PATH_LEN_MAX) {
+               MS_SAFE_FREE(buf);
+               MS_DBG_ERR("msg->origin_path_size is invalid %d", msg->origin_path_size );
+               return MS_MEDIA_ERR_DATA_TAINTED;
+       }
+
+       strncpy(msg->org_path, (char*)buf + header_size, msg->origin_path_size);
+       //MS_DBG("original path : %s", msg->org_path);
+
+       if (msg->dest_path_size <= 0  || msg->dest_path_size > MS_FILE_PATH_LEN_MAX) {
+               MS_SAFE_FREE(buf);
+               MS_DBG_ERR("msg->origin_path_size is invalid %d", msg->dest_path_size );
+               return MS_MEDIA_ERR_DATA_TAINTED;
+       }
+
+       strncpy(msg->dst_path, (char*)buf + header_size + msg->origin_path_size, msg->dest_path_size);
+       //MS_DBG("destination path : %s", msg->dst_path);
+
+       MS_SAFE_FREE(buf);
+       *from_size = from_addr_size;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+_ms_thumb_set_buffer(thumbMsg *req_msg, unsigned char **buf, int *buf_size)
+{
+       if (req_msg == NULL || buf == NULL) {
+               return -1;
+       }
+
+       int org_path_len = 0;
+       int dst_path_len = 0;
+       int size = 0;
+       int header_size = 0;
+
+       header_size = sizeof(thumbMsg) - MAX_MSG_SIZE*2;
+       org_path_len = strlen(req_msg->org_path) + 1;
+       dst_path_len = strlen(req_msg->dst_path) + 1;
+
+       //MS_DBG("Basic Size : %d, org_path : %s[%d], dst_path : %s[%d]", header_size, req_msg->org_path, org_path_len, req_msg->dst_path, dst_path_len);
+
+       size = header_size + org_path_len + dst_path_len;
+       *buf = malloc(size);
+       memcpy(*buf, req_msg, header_size);
+       memcpy((*buf)+header_size, req_msg->org_path, org_path_len);
+       memcpy((*buf)+header_size + org_path_len, req_msg->dst_path, dst_path_len);
+
+       *buf_size = size;
+
+       return 0;
+}
+
+/*
+void _ms_thumb_agent_child_handler(GPid pid, gint status, gpointer user_data)
+{
+       MS_DBG_WARN("media-thumbnail-server[%d] is shutdown : %d", pid, status);
+       g_folk_thumb_server = FALSE;
+}
+*/
+gboolean _ms_thumb_agent_child_handler(gpointer data)
+{
+       int pid = GPOINTER_TO_INT(data);
+       MS_DBG("media-thumbnail-server[%d] is killed", pid);
+       return FALSE;
+}
+
+gboolean _ms_thumb_agent_recv_msg_from_server()
+{
+       if (g_communicate_sock <= 0) {
+               _ms_thumb_agent_prepare_udp_socket();
+       }
+
+       ms_thumb_server_msg recv_msg;
+       int recv_msg_size = 0;
+
+       recv_msg_size = ms_ipc_receive_message(g_communicate_sock, & recv_msg, sizeof(ms_thumb_server_msg),  NULL, NULL);
+       if (recv_msg_size != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_receive_message failed : %s\n", strerror(errno));
+               return FALSE;
+       }
+
+       //MS_DBG("Receive : %d(%d)", recv_msg.msg_type, recv_msg_size);
+       if (recv_msg.msg_type == MS_MSG_THUMB_SERVER_READY) {
+               MS_DBG("Thumbnail server is ready");
+       }
+
+       return TRUE;
+}
+
+gboolean _ms_thumb_agent_recv_thumb_done_from_server(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       int sockfd = -1;
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return FALSE;
+       }
+
+       ms_thumb_server_msg recv_msg;
+       int recv_msg_size = 0;
+
+       recv_msg_size = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(ms_thumb_server_msg), NULL, NULL);
+       if (recv_msg_size != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("ms_ipc_receive_message failed : %s\n", strerror(errno));
+               return FALSE;
+       }
+
+       MS_DBG("Receive : %d(%d)", recv_msg.msg_type, recv_msg_size);
+       if (recv_msg.msg_type == MS_MSG_THUMB_EXTRACT_ALL_DONE) {
+               MS_DBG("Thumbnail extracting done");
+               g_thumb_server_extracting = FALSE;
+
+               return FALSE;
+       }
+
+       return FALSE;
+}
+
+gboolean _ms_thumb_agent_execute_server()
+{
+       int pid;
+       pid = fork();
+
+       if (pid < 0) {
+               return FALSE;
+       } else if (pid == 0) {
+               execl("/usr/bin/media-thumbnail-server", "media-thumbnail-server", NULL);
+       } else {
+               MS_DBG("Child process is %d", pid);
+               g_folk_thumb_server = TRUE;
+       }
+#if 0
+       GSource *child_watch_src =  g_child_watch_source_new(pid);
+       g_source_set_callback(child_watch_src, _ms_thumb_agent_child_handler, GINT_TO_POINTER(pid), NULL);
+       g_source_attach(child_watch_src, g_main_context_get_thread_default());
+#endif
+       //g_child_watch_add(pid, _ms_thumb_agent_child_handler, NULL);
+       g_server_pid = pid;
+
+       if (!_ms_thumb_agent_recv_msg_from_server()) {
+               MS_DBG_ERR("_ms_thumb_agent_recv_msg_from_server is failed");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+gboolean _ms_thumb_agent_send_msg_to_thumb_server(thumbMsg *recv_msg, thumbMsg *res_msg)
+{
+       int sock;
+       const char *serv_ip = "127.0.0.1";
+       struct sockaddr_in serv_addr;
+
+       int send_str_len = strlen(recv_msg->org_path);
+
+       if (send_str_len > MAX_MSG_SIZE) {
+               MS_DBG_ERR("original path's length exceeds %d(max packet size)", MAX_MSG_SIZE);
+               return FALSE;
+       }
+
+#if 0
+       /* Creaete a datagram/UDP socket */
+       if (_ms_thumb_create_udp_socket(&sock) < 0) {
+               MS_DBG_ERR("_ms_thumb_create_udp_socket failed");
+               return FALSE;
+       }
+#endif
+       if (ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sock) < 0) {
+               MS_DBG_ERR("ms_ipc_create_client_socket failed");
+               return FALSE;
+       }
+
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_addr.s_addr = inet_addr(serv_ip);
+       serv_addr.sin_port = htons(MS_THUMB_DAEMON_PORT);
+
+       int buf_size = 0;
+       int header_size = 0;
+       unsigned char *buf = NULL;
+       _ms_thumb_set_buffer(recv_msg, &buf, &buf_size);
+
+       //MS_DBG("buffer size : %d", buf_size);
+       if (sendto(sock, buf, buf_size, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != buf_size) {
+               MS_DBG_ERR("sendto failed: %s\n", strerror(errno));
+               MS_SAFE_FREE(buf);
+               close(sock);
+               return FALSE;
+       }
+
+       MS_SAFE_FREE(buf);
+       MS_DBG("Sending msg to thumbnail server is successful");
+
+       struct sockaddr_in client_addr;
+       unsigned int client_addr_len;
+       header_size = sizeof(thumbMsg) - MAX_MSG_SIZE*2;
+
+       if (_ms_thumb_recv_udp_msg(sock, header_size, res_msg, &client_addr, &client_addr_len) < 0) {
+               MS_DBG_ERR("_ms_thumb_recv_udp_msg failed");
+               close(sock);
+               return FALSE;
+       }
+
+       MS_DBG("recv %s from thumb daemon is successful", res_msg->dst_path);
+       close(sock);
+
+       if (res_msg->msg_type == 2 && g_communicate_sock > 0) { // THUMB_REQUEST_ALL_MEDIA
+               /* Create new channel to watch udp socket */
+               GSource *source = NULL;
+               if (g_udp_channel == NULL)
+                       g_udp_channel = g_io_channel_unix_new(g_communicate_sock);
+               source = g_io_create_watch(g_udp_channel, G_IO_IN);
+
+               /* Set callback to be called when socket is readable */
+               g_source_set_callback(source, (GSourceFunc)_ms_thumb_agent_recv_thumb_done_from_server, NULL, NULL);
+               g_source_attach(source, g_main_context_get_thread_default());
+
+               g_thumb_server_extracting = TRUE;
+       }
+
+       return TRUE;
+}
+
+gboolean _ms_thumb_agent_timer()
+{
+       if (g_thumb_server_extracting) {
+               MS_DBG("Timer is called.. But media-thumbnail-server[%d] is busy.. so timer is recreated", g_server_pid);
+
+               _ms_thumb_create_timer(g_timer_id);
+               return FALSE;
+       }
+
+       g_timer_id = 0;
+       MS_DBG("Timer is called.. Now killing media-thumbnail-server[%d]", g_server_pid);
+
+       if (g_server_pid > 0) {
+#if 0
+               if (kill(g_server_pid, SIGKILL) < 0) {
+                       MS_DBG_ERR("kill failed : %s", strerror(errno));
+               }
+#else
+               /* Kill thumbnail server */
+               thumbMsg msg;
+               thumbMsg recv_msg;
+               memset((void *)&msg, 0, sizeof(msg));
+               memset((void *)&recv_msg, 0, sizeof(recv_msg));
+
+               msg.msg_type = 5; // THUMB_REQUEST_KILL_SERVER
+               msg.org_path[0] = '\0';
+               msg.origin_path_size = 1;
+               msg.dst_path[0] = '\0';
+               msg.dest_path_size = 1;
+
+               /* Command Kill to thumbnail server */
+               if (!_ms_thumb_agent_send_msg_to_thumb_server(&msg, &recv_msg)) {
+                       MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
+               }
+#endif
+               usleep(200000);
+       } else {
+               MS_DBG_ERR("g_server_pid is %d. Maybe there's problem in thumbnail-server", g_server_pid);
+       }
+
+       return FALSE;
+}
+
+#if 0
+gboolean _ms_thumb_agent_read_socket(GIOChannel *src,
+                                                                       GIOCondition condition,
+                                                                       gpointer data)
+{
+       struct sockaddr_in client_addr;
+       unsigned int client_addr_len;
+
+       thumbMsg recv_msg;
+       thumbMsg res_msg;
+       int header_size = 0;
+       int sock = -1;
+       int client_sock = -1;
+
+       sock = g_io_channel_unix_get_fd(src);
+       if (sock < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       memset((void *)&recv_msg, 0, sizeof(thumbMsg));
+       memset((void *)&res_msg, 0, sizeof(res_msg));
+       header_size = sizeof(thumbMsg) - MAX_MSG_SIZE*2;
+
+       if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
+               MS_DBG_ERR("accept failed : %s", strerror(errno));
+               return TRUE;
+       }
+
+       MS_DBG("Client[%d] is accepted", client_sock);
+
+       if (_ms_thumb_recv_msg(client_sock, header_size, &recv_msg) < 0) {
+               MS_DBG_ERR("_ms_thumb_recv_msg failed ");
+               close(client_sock);
+               return TRUE;
+       }
+
+       MS_DBG("Received [%d] %s(%d) from PID(%d) \n", recv_msg.msg_type, recv_msg.org_path, strlen(recv_msg.org_path), recv_msg.pid);
+
+       if (g_folk_thumb_server == FALSE && g_thumb_server_extracting == FALSE) {
+               if(_ms_thumb_check_process() == FALSE) { // This logic is temporary
+               MS_DBG_WARN("Thumb server is not running.. so start it");
+               if (!_ms_thumb_agent_execute_server()) {
+                       MS_DBG_ERR("_ms_thumb_agent_execute_server is failed");
+                       return TRUE;
+               } else {
+
+                       GSource *timer_src = g_timeout_source_new_seconds(MS_TIMEOUT_SEC_20);
+                       g_source_set_callback (timer_src, _ms_thumb_agent_timer, NULL, NULL);
+                       g_timer_id = g_source_attach (timer_src, g_main_context_get_thread_default());
+               }
+               }
+       } else {
+               if (g_timer_id > 0) {
+                       g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_timer_id));
+                       //MS_DBG("Timer is recreated");
+                       GSource *timer_src = g_timeout_source_new_seconds(MS_TIMEOUT_SEC_20);
+                       g_source_set_callback (timer_src, _ms_thumb_agent_timer, NULL, NULL);
+                       g_timer_id = g_source_attach (timer_src, g_main_context_get_thread_default());
+               }
+       }
+
+       if (!_ms_thumb_agent_send_msg_to_thumb_server(&recv_msg, &res_msg)) {
+               MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
+
+               return TRUE;
+       }
+
+       strncpy(res_msg.org_path, recv_msg.org_path, recv_msg.origin_path_size);
+       res_msg.origin_path_size = recv_msg.origin_path_size;
+       res_msg.dest_path_size = strlen(res_msg.dst_path) + 1;
+
+       int buf_size = 0;
+       unsigned char *buf = NULL;
+       _ms_thumb_set_buffer(&res_msg, &buf, &buf_size);
+
+       //MS_DBG("buffer size : %d", buf_size);
+
+       if (send(client_sock, buf, buf_size, 0) != buf_size) {
+               MS_DBG_ERR("sendto failed : %s", strerror(errno));
+       } else {
+               MS_DBG("Sent %s(%d) \n", res_msg.dst_path, strlen(res_msg.dst_path));
+       }
+
+       close(client_sock);
+       MS_SAFE_FREE(buf);
+       return TRUE;
+}
+#else
+int _ms_thumb_cancel_media(const char *path, int pid)
+{
+       int ret = -1;
+       int i = 0;
+       int req_len = 0;
+
+       req_len = g_queue_get_length(g_request_queue);
+
+       MS_DBG("Queue length : %d", req_len);
+
+       for (i = 0; i < req_len; i++) {
+               thumbRequest *req = NULL;
+               req = (thumbRequest *)g_queue_peek_nth(g_request_queue, i);
+               if (req == NULL) continue;
+
+               if ((req->recv_msg->pid) == pid && (strncmp(path, req->recv_msg->org_path, strlen(path))) == 0) {
+                       MS_DBG("Remove %s from queue", req->recv_msg->org_path);
+                       g_queue_pop_nth(g_request_queue, i);
+
+                       close(req->client_sock);
+                       MS_SAFE_FREE(req->recv_msg);
+                       MS_SAFE_FREE(req);
+                       ret = 0;
+
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+int _ms_thumb_cancel_all(int pid)
+{
+       int ret = -1;
+       int i = 0;
+       int req_len = 0;
+
+       req_len = g_queue_get_length(g_request_queue);
+
+       MS_DBG("Queue length : %d", req_len);
+
+       for (i = 0; i < req_len; i++) {
+               thumbRequest *req = NULL;
+               req = (thumbRequest *)g_queue_peek_nth(g_request_queue, i);
+               if (req == NULL) continue;
+
+               if (req->recv_msg->pid == pid) {
+                       MS_DBG("Remove [%d] %s from queue", req->recv_msg->pid, req->recv_msg->org_path);
+                       g_queue_pop_nth(g_request_queue, i);
+                       i--;
+                       req_len--;
+
+                       close(req->client_sock);
+                       MS_SAFE_FREE(req->recv_msg);
+                       MS_SAFE_FREE(req);
+                       ret = 0;
+               }
+       }
+
+       return ret;
+}
+
+void _ms_thumb_cancle_request(thumbRequest *thumb_req)
+{
+       MS_DBG("");
+       int ret = -1;
+
+       if (thumb_req == NULL) return;
+
+       thumbMsg *recv_msg = thumb_req->recv_msg;
+       if (recv_msg == NULL) {
+               MS_SAFE_FREE(thumb_req);
+               return;
+       }
+
+       if (recv_msg->msg_type == 3)
+               ret = _ms_thumb_cancel_media(recv_msg->org_path, recv_msg->pid);
+       else if (recv_msg->msg_type == 4)
+               ret = _ms_thumb_cancel_all(recv_msg->pid);
+
+       if (ret == 0) {
+               recv_msg->status = 0;  // THUMB_SUCCESS
+       } else {
+               recv_msg->status = 0;  // THUMB_SUCCESS
+       }
+
+       if (recv_msg->origin_path_size <= 0  || recv_msg->origin_path_size > MS_FILE_PATH_LEN_MAX) {
+               MS_DBG_ERR("recv_msg->origin_path_size is invalid %d", recv_msg->origin_path_size );
+               return;
+       }
+
+       recv_msg->dest_path_size = recv_msg->origin_path_size;
+       strncpy(recv_msg->dst_path, recv_msg->org_path, recv_msg->dest_path_size);
+/*
+       int buf_size = 0;
+       unsigned char *buf = NULL;
+       _ms_thumb_set_buffer(recv_msg, &buf, &buf_size);
+
+       if (send(thumb_req->client_sock, buf, buf_size, 0) != buf_size) {
+               MS_DBG_ERR("sendto failed : %s", strerror(errno));
+       } else {
+               MS_DBG("Sent response");
+       }
+*/
+       close(thumb_req->client_sock);
+       //MS_SAFE_FREE(buf);
+       MS_SAFE_FREE(thumb_req->recv_msg);
+       MS_SAFE_FREE(thumb_req);
+
+       return;
+}
+
+gboolean _ms_thumb_request_to_server(gpointer data)
+{
+       int req_len = 0;
+
+       req_len = g_queue_get_length(g_request_queue);
+
+       MS_DBG("Queue length : %d", req_len);
+
+       if (req_len <= 0) {
+               MS_DBG("There is no request job in the queue");
+               g_queue_work = 0;
+               return FALSE;
+       }
+
+       if (g_folk_thumb_server == FALSE && g_thumb_server_extracting == FALSE) {
+               if(_ms_thumb_check_process() == FALSE) { // This logic is temporary
+                       MS_DBG_WARN("Thumb server is not running.. so start it");
+                       if (!_ms_thumb_agent_execute_server()) {
+                               MS_DBG_ERR("_ms_thumb_agent_execute_server is failed");
+                               g_queue_work = 0;
+                               return FALSE;
+                       } else {
+                               _ms_thumb_create_timer(g_timer_id);
+                       }
+               }
+       } else {
+               /* Timer is re-created*/
+               _ms_thumb_create_timer(g_timer_id);
+       }
+
+       thumbRequest *req = NULL;
+       req = (thumbRequest *)g_queue_pop_head(g_request_queue);
+
+       if (req == NULL) {
+               MS_DBG_ERR("Failed to get a request job from queue");
+               return TRUE;
+       }
+
+       int client_sock = -1;
+       thumbMsg *recv_msg = NULL;
+       thumbMsg res_msg;
+       memset((void *)&res_msg, 0, sizeof(res_msg));
+
+       client_sock = req->client_sock;
+       recv_msg = req->recv_msg;
+
+       if (req->client_sock <=0 || req->recv_msg == NULL) {
+               MS_DBG_ERR("client sock is below 0 or recv msg is NULL");
+               MS_SAFE_FREE(req->recv_msg);
+               MS_SAFE_FREE(req);
+               return TRUE;
+       }
+
+       if (recv_msg) {
+               if (!_ms_thumb_agent_send_msg_to_thumb_server(recv_msg, &res_msg)) {
+                       MS_DBG_ERR("_ms_thumb_agent_send_msg_to_thumb_server is failed");
+
+                       close(client_sock);
+                       MS_SAFE_FREE(req->recv_msg);
+                       MS_SAFE_FREE(req);
+                       return TRUE;
+               }
+       } else {
+               MS_DBG_ERR("recv_msg is NULL from queue request");
+       }
+
+       strncpy(res_msg.org_path, recv_msg->org_path, recv_msg->origin_path_size);
+       res_msg.origin_path_size = recv_msg->origin_path_size;
+       res_msg.dest_path_size = strlen(res_msg.dst_path) + 1;
+
+       int buf_size = 0;
+       unsigned char *buf = NULL;
+       _ms_thumb_set_buffer(&res_msg, &buf, &buf_size);
+
+       if (send(client_sock, buf, buf_size, 0) != buf_size) {
+               MS_DBG_ERR("sendto failed : %s", strerror(errno));
+       } else {
+               MS_DBG("Sent %s(%d) \n", res_msg.dst_path, strlen(res_msg.dst_path));
+       }
+
+       close(client_sock);
+       MS_SAFE_FREE(buf);
+       MS_SAFE_FREE(req->recv_msg);
+       MS_SAFE_FREE(req);
+
+       return TRUE;
+}
+
+gboolean _ms_thumb_agent_read_socket(GIOChannel *src,
+                                                                       GIOCondition condition,
+                                                                       gpointer data)
+{
+       struct sockaddr_in client_addr;
+       unsigned int client_addr_len;
+
+       thumbMsg *recv_msg = NULL;
+       int header_size = 0;
+       int sock = -1;
+       int client_sock = -1;
+
+       sock = g_io_channel_unix_get_fd(src);
+       if (sock < 0) {
+               MS_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       header_size = sizeof(thumbMsg) - MAX_MSG_SIZE*2;
+       client_addr_len = sizeof(client_addr);
+
+       if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) {
+               MS_DBG_ERR("accept failed : %s", strerror(errno));
+               return TRUE;
+       }
+
+       MS_DBG("Client[%d] is accepted", client_sock);
+
+       recv_msg = calloc(1, sizeof(thumbMsg));
+       if (recv_msg == NULL) {
+               MS_DBG_ERR("Failed to allocate memory");
+               close(client_sock);
+               return TRUE;
+       }
+
+       if (_ms_thumb_recv_msg(client_sock, header_size, recv_msg) < 0) {
+               MS_DBG_ERR("_ms_thumb_recv_msg failed ");
+               close(client_sock);
+               MS_SAFE_FREE(recv_msg);
+               return TRUE;
+       }
+
+       MS_DBG("Received [%d] %s(%d) from PID(%d) \n", recv_msg->msg_type, recv_msg->org_path, strlen(recv_msg->org_path), recv_msg->pid);
+
+       thumbRequest *thumb_req = NULL;
+       thumb_req = calloc(1, sizeof(thumbRequest));
+       if (thumb_req == NULL) {
+               MS_DBG_ERR("Failed to create request element");
+               close(client_sock);
+               MS_SAFE_FREE(recv_msg);
+               return TRUE;
+       }
+
+       thumb_req->client_sock = client_sock;
+       thumb_req->recv_msg = recv_msg;
+
+       if (recv_msg->msg_type == 3 || recv_msg->msg_type == 4) { // THUMB_REQUEST_CANCEL_MEDIA || THUMB_REQUEST_CANCEL_ALL
+               _ms_thumb_cancle_request(thumb_req);
+               return TRUE;
+       }
+
+       if (g_request_queue == NULL) {
+               MS_DBG_WARN("queue is init");
+                g_request_queue = g_queue_new();
+       }
+
+       MS_DBG("%s is queued", recv_msg->org_path);
+       g_queue_push_tail(g_request_queue, (gpointer)thumb_req);
+
+       if (!g_queue_work) {
+               GSource *src_request = NULL;
+               src_request = g_idle_source_new ();
+               g_source_set_callback (src_request, _ms_thumb_request_to_server, NULL, NULL);
+               //g_source_set_priority(src_request, G_PRIORITY_LOW);
+               g_source_attach (src_request, g_main_context_get_thread_default());
+               g_queue_work = 1;
+       }
+
+       return TRUE;
+}
+#endif
+
+
+gboolean _ms_thumb_agent_prepare_tcp_socket(int *sock_fd)
+{
+       int sock;
+       unsigned short serv_port;
+
+       serv_port = MS_THUMB_CREATOR_PORT;
+
+#if 0
+       struct sockaddr_in serv_addr;
+
+       /* Create a TCP socket */
+       if (_ms_thumb_create_socket(SERVER_SOCKET, &sock) < 0) {
+               MS_DBG_ERR("_ms_thumb_create_socket failed");
+               return FALSE;
+       }
+
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       serv_addr.sin_port = htons(serv_port);
+
+       /* Bind to the local address */
+       if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+               MS_DBG_ERR("bind failed");
+               return FALSE;
+       }
+
+       MS_DBG("bind success");
+
+       /* Listening */
+       if (listen(sock, SOMAXCONN) < 0) {
+               MS_DBG_ERR("listen failed : %s", strerror(errno));
+               return FALSE;
+       }
+
+       MS_DBG("Listening...");
+#endif
+       if (ms_ipc_create_server_socket(MS_PROTOCOL_TCP, serv_port, &sock) < 0) {
+               MS_DBG_ERR("_ms_thumb_create_socket failed");
+               return FALSE;
+       }
+
+       *sock_fd = sock;
+
+       return TRUE;
+}
+
+gboolean _ms_thumb_agent_prepare_udp_socket()
+{
+       int sock;
+       unsigned short serv_port;
+
+       serv_port = MS_THUMB_COMM_PORT;
+
+       if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, serv_port, &sock) < 0) {
+               MS_DBG_ERR("ms_ipc_create_client_socket failed");
+               return FALSE;
+       }
+#if 0
+       struct sockaddr_in serv_addr;
+
+       /* Creaete a UDP socket */
+       if (_ms_thumb_create_udp_socket(&sock) < 0) {
+               MS_DBG_ERR("_ms_thumb_create_udp_socket failed");
+               return FALSE;
+       }
+
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       serv_addr.sin_port = htons(serv_port);
+
+       /* Bind to the local address */
+       if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+               MS_DBG_ERR("bind failed");
+               return FALSE;
+       }
+
+       MS_DBG("bind success");
+#endif
+       g_communicate_sock = sock;
+
+       return TRUE;
+}
+
+gpointer ms_thumb_agent_start_thread(gpointer data)
+{
+       MS_DBG("");
+       int sockfd = -1;
+
+    GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+
+       /* Create and bind new TCP socket */
+       if (!_ms_thumb_agent_prepare_tcp_socket(&sockfd)) {
+               MS_DBG_ERR("Failed to create socket\n");
+               return NULL;
+       }
+
+       context = g_main_context_new();
+
+       if (context == NULL) {
+               MS_DBG_ERR("g_main_context_new failed");
+       } else {
+               MS_DBG("g_main_context_new success");
+       }
+
+       g_thumb_agent_loop = g_main_loop_new(context, FALSE);
+       g_main_context_push_thread_default(context);
+
+       /* Create new channel to watch udp socket */
+       channel = g_io_channel_unix_new(sockfd);
+       source = g_io_create_watch(channel, G_IO_IN);
+
+       /* Set callback to be called when socket is readable */
+       g_source_set_callback(source, (GSourceFunc)_ms_thumb_agent_read_socket, NULL, NULL);
+       g_source_attach(source, context);
+
+
+       MS_DBG("************************************");
+       MS_DBG("*** Thumbnail Agent thread is running ***");
+       MS_DBG("************************************");
+
+       g_main_loop_run(g_thumb_agent_loop);
+
+       MS_DBG("Thumbnail Agent thread is shutting down...");
+       _ms_thumb_agent_finish_jobs();
+
+       /*close an IO channel*/
+       g_io_channel_shutdown(channel,  FALSE, NULL);
+       g_io_channel_shutdown(g_udp_channel,  FALSE, NULL);
+       g_io_channel_unref(channel);
+       close(g_communicate_sock);
+
+       g_main_loop_unref(g_thumb_agent_loop);
+
+       return NULL;
+}
+
diff --git a/common/media-server-utils.c b/common/media-server-utils.c
new file mode 100755 (executable)
index 0000000..360f52c
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-utils.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+
+#include <errno.h>
+#include <pmapi.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-server-dbg.h"
+#include "media-server-ipc.h"
+#include "media-server-inotify.h"
+#include "media-server-utils.h"
+#include "media-server-drm.h"
+#include "media-server-dbus.h"
+#include "media-server-socket.h"
+
+#ifdef FMS_PERF
+#include <sys/time.h>
+#define MILLION 1000000L
+struct timeval g_mmc_start_time;
+struct timeval g_mmc_end_time;
+#endif
+
+#define MS_DRM_CONTENT_TYPE_LENGTH 100
+
+extern int mmc_state;
+
+static int
+_ms_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
+ms_set_db_status(ms_db_status_type_t status)
+{
+       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;
+       } 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;
+               /*notify to other application about db updated by DBUS*/
+               ms_dbus_send_noti(MS_DBUS_DB_UPDATED);
+       }
+
+       err = _ms_set_power_mode(status);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_DBG_ERR("_ms_set_power_mode fail");
+               res = err;
+       }
+
+       return res;
+}
+
+#ifdef FMS_PERF
+void
+ms_check_start_time(struct timeval *start_time)
+{
+       gettimeofday(start_time, NULL);
+}
+
+void
+ms_check_end_time(struct timeval *end_time)
+{
+       gettimeofday(end_time, NULL);
+}
+
+void
+ms_check_time_diff(struct timeval *start_time, struct timeval *end_time)
+{
+       struct timeval time;
+       long difftime;
+
+       time.tv_sec = end_time->tv_sec - start_time->tv_sec;
+       time.tv_usec = end_time->tv_usec - start_time->tv_usec;
+       difftime = MILLION * time.tv_sec + time.tv_usec;
+       MS_DBG("The function_to_time took %ld microseconds or %f seconds.",
+              difftime, difftime / (double)MILLION);
+}
+#endif
+
+bool
+ms_is_mmc_inserted(void)
+{
+       int data = -1;
+       ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &data);
+       if (data != VCONFKEY_SYSMAN_MMC_MOUNTED) {
+               return false;
+       } else {
+               return true;
+       }
+}
+
+/*CAUTION : Before using this function, Have to allocate static memory of ret_path*/
+/*And the array length does not over MS_FILE_PATH_LEN_MAX*/
+/*for example : char path[MS_FILE_PATH_LEN_MAX] = {0};*/
+int
+ms_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path, int depth)
+{
+       int i = 0;
+       int path_length = 0;
+       int length = 0;
+       ms_dir_scan_info *cur_node;
+       char **path_array;
+
+       if (depth < 0) {
+               MS_DBG_ERR("depth < 0");
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       MS_MALLOC(path_array, sizeof(char*) * (depth + 1));
+
+       cur_node = node;
+
+       while (1) {
+               path_array[i] = cur_node->name;
+               if (cur_node->parent == NULL)
+                       break;
+
+               cur_node = cur_node->parent;
+               i++;
+       }
+
+       for(i = depth ; i >= 0 ; i --) {
+               length = strlen(path_array[i]);
+
+               if (path_length + length > MS_FILE_PATH_LEN_MAX) {
+                       MS_DBG_ERR("This is invalid path, %s, %d", node->name, depth);
+                       MS_SAFE_FREE(path_array);
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+
+               strncpy(ret_path+path_length, path_array[i], length);
+               path_length += length;
+
+               ret_path[path_length] = '/';
+               path_length ++;
+       }
+
+       ret_path[-- path_length] = '\0';
+
+       MS_SAFE_FREE(path_array);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+ms_storage_type_t
+ms_get_storage_type_by_full(const char *path)
+{
+       if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) {
+               return MS_STORAGE_INTERNAL;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
+               return MS_STORAGE_EXTERNAL;
+       } else
+               return MS_MEDIA_ERR_INVALID_PATH;
+}
+
+int
+ms_strappend(char *res, const int size, const char *pattern,
+            const char *str1, const char *str2)
+{
+       int len = 0;
+       int real_size = size - 1;
+
+       if (!res ||!pattern || !str1 ||!str2 )
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       if (real_size < (strlen(str1) + strlen(str2)))
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       len = snprintf(res, real_size, pattern, str1, str2);
+       if (len < 0) {
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res[len] = '\0';
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+ms_strcopy(char *res, const int size, const char *pattern, const char *str1)
+{
+       int len = 0;
+       int real_size = size;
+
+       if (!res || !pattern || !str1) {
+               MS_DBG_ERR("parameta is invalid");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       if (real_size < strlen(str1)) {
+               MS_DBG_ERR("size is wrong");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       len = snprintf(res, real_size, pattern, str1);
+       if (len < 0) {
+               MS_DBG_ERR("snprintf failed");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res[len] = '\0';
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+bool
+ms_config_get_int(const char *key, int *value)
+{
+       int err;
+
+       if (!key || !value) {
+               MS_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       err = vconf_get_int(key, value);
+       if (err == 0)
+               return true;
+       else if (err == -1)
+               return false;
+       else
+               MS_DBG_ERR("Unexpected error code: %d", err);
+
+       return false;
+}
+
+bool
+ms_config_set_int(const char *key, int value)
+{
+       int err;
+
+       if (!key) {
+               MS_DBG_ERR("Arguments key is NULL");
+               return false;
+       }
+
+       err = vconf_set_int(key, value);
+       if (err == 0)
+               return true;
+       else if (err == -1)
+               return false;
+       else
+               MS_DBG_ERR("Unexpected error code: %d", err);
+
+       return false;
+}
+
+bool
+ms_config_get_str(const char *key, char *value)
+{
+       char *res;
+       if (!key || !value) {
+               MS_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       res = vconf_get_str(key);
+       if (res) {
+               strncpy(value, res, strlen(res) + 1);
+               return true;
+       }
+
+       return false;
+}
+
+bool
+ms_config_set_str(const char *key, const char *value)
+{
+       int err;
+
+       if (!key || !value) {
+               MS_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       err = vconf_set_str(key, value);
+       if (err == 0)
+               return true;
+       else
+               MS_DBG_ERR("fail to vconf_set_str %d", err);
+
+       return false;
+}
+
diff --git a/common/mediadb-update.c b/common/mediadb-update.c
new file mode 100644 (file)
index 0000000..034b4d6
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ *  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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+
+
+#include <glib.h>
+#include "media-util.h"
+
+GMainLoop * mainloop = NULL;
+
+void callback(media_request_result_s * result, void *user_data)
+{
+       printf("db updating done\n");
+
+       g_main_loop_quit(mainloop);
+}
+
+void print_help()
+{
+       printf("=======================================================================================\n");
+       printf("\n");
+       printf("mediadb-update [option] <directory path> \n");
+       printf("\n");
+       printf("[option]\n");
+       printf("        -r : [only directory] update all directory recursivly under <directory path>\n");
+       printf("\n");
+       printf("mediadb-update --help for check this messages.\n");
+       printf("\n");
+       printf("A file or directory must exists under /opt/usr/media or /opt/storage/sdcard.\n");
+       printf("Using /opt/storage/sdcard is allowed SD card is mounted.\n");
+       printf("\n");
+       printf("=======================================================================================\n");
+       exit(1);
+}
+
+int dir_scan_non_recursive(char *path)
+{
+       return media_directory_scanning_async(path, FALSE, callback, NULL);
+}
+
+int dir_scan_recursive(char *path)
+{
+       return media_directory_scanning_async(path, TRUE, callback, NULL);
+}
+
+typedef enum {
+       DIRECTORY_OK,
+       FILE_OK,
+       NOT_OK,
+}check_result;
+
+check_result check_path(char *path)
+{
+       struct stat buf;
+       DIR *dp = NULL;
+
+       /*check the path directory or file*/
+       if (stat(path, &buf) == 0) {
+               if (S_ISDIR(buf.st_mode)) {
+                       printf("This is directory\n");
+                       return DIRECTORY_OK;
+               } else {
+                       dp = opendir(path);
+                       if (dp == NULL) {
+                               /*if openning directory is failed, check it exists. */
+                               if (errno == ENOENT) {
+                                       /* this directory is deleted */
+                                       return DIRECTORY_OK;
+                               }
+                       } else {
+                               closedir(dp);
+                       }
+                       printf("[%d]invalid path\n", __LINE__);
+                       print_help();
+               }
+       } else {
+               printf("stat error : %s\n", strerror(errno));
+       }
+
+       return NOT_OK;
+}
+
+int main(int argc, char **argv)
+{
+       int ret;
+       char *argv1 = NULL;
+       char *argv2 = NULL;
+
+       if (argc > 3 || argc < 2) {
+               print_help();
+       }
+
+       argv1 = strdup(argv[1]);
+
+       mainloop = g_main_loop_new(NULL, FALSE);
+
+       if (argc == 2) {
+               if (strcmp(argv1 , "--help") == 0) {
+                       print_help();
+               }
+
+               if (check_path(argv1) == DIRECTORY_OK) {
+                       ret = dir_scan_non_recursive(argv1);
+                       if (ret != 0) {
+                               printf("error : %d\n", ret);
+                               exit(1);
+                       }
+               } else {
+                       print_help();
+               }
+       } else if (argc == 3) {
+               argv2 = strdup(argv[2]);
+               if (strcmp(argv1, "-r") == 0) {
+                       if (check_path(argv2) == DIRECTORY_OK) {
+                               ret = dir_scan_recursive(argv2);
+                               if (ret != 0) {
+                                       printf("error : %d\n", ret);
+                                       exit(1);
+                               }
+                       } else {
+                               print_help();
+                       }
+               } else {
+                       printf("[%d] invalide option\n", __LINE__);
+                       print_help();
+               }
+       }
+
+       g_main_loop_run(mainloop);
+
+       exit(0);
+}
diff --git a/common/scanner/include/media-scanner-db-svc.h b/common/scanner/include/media-scanner-db-svc.h
new file mode 100755 (executable)
index 0000000..06bc60c
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-db-svc.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SCANNER_DB_SVC_H_
+#define _MEDIA_SCANNER_DB_SVC_H_
+
+#include "media-server-types.h"
+
+typedef int (*CHECK_ITEM)(const char*, const char*, char **);
+typedef int (*CONNECT)(void**, char **);
+typedef int (*DISCONNECT)(void*, char **);
+typedef int (*CHECK_ITEM_EXIST)(void*, const char*, int, char **);
+typedef int (*INSERT_ITEM_BEGIN)(void*, int, char **);
+typedef int (*INSERT_ITEM_END)(void*, char **);
+typedef int (*INSERT_ITEM)(void*, const char*, int, const char*, char **);
+typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, char **);
+typedef int (*SET_ITEM_VALIDITY_BEGIN)(void*, int, char **);
+typedef int (*SET_ITEM_VALIDITY_END)(void*, char **);
+typedef int (*SET_ITEM_VALIDITY)(void*, const char*, int, const char*, int, char **);
+typedef int (*DELETE_ALL_ITEMS_IN_STORAGE)(void*, int, char **);
+typedef int (*DELETE_ALL_INVALID_ITMES_IN_STORAGE)(void*, int, char **);
+typedef int (*UPDATE_BEGIN)(void);
+typedef int (*UPDATE_END)(void);
+typedef int (*SET_FOLDER_ITEM_VALIDITY)(void*, const char*, int, int, char**);
+typedef int (*DELETE_ALL_INVALID_ITEMS_IN_FOLDER)(void*, const char*, char**);
+
+int
+msc_load_functions(void);
+
+void
+msc_unload_functions(void);
+
+int
+msc_connect_db(void ***handle);
+
+int
+msc_disconnect_db(void ***handle);
+
+int
+msc_validate_item(void **handle, char *path);
+
+int
+msc_insert_item_batch(void **handle, const char *path);
+
+bool
+msc_delete_all_items(void **handle, ms_storage_type_t store_type);
+
+int
+msc_invalidate_all_items(void **handle, ms_storage_type_t store_type);
+
+bool
+msc_delete_invalid_items(void **handle, ms_storage_type_t store_type);
+
+int
+msc_set_folder_validity(void **handle, const char *path, int validity, int recursive);
+
+int
+msc_delete_invalid_items_in_folder(void **handle, const char*path);
+
+/****************************************************************************************************
+FOR BULK COMMIT
+*****************************************************************************************************/
+
+void
+msc_register_start(void **handle);
+
+void
+msc_register_end(void **handle);
+
+void
+msc_validate_start(void **handle);
+
+void
+msc_validate_end(void **handle);
+
+#endif /*_MEDIA_SCANNER_DB_SVC_H_*/
diff --git a/common/scanner/include/media-scanner-dbg.h b/common/scanner/include/media-scanner-dbg.h
new file mode 100755 (executable)
index 0000000..6c892f3
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-scanner-dbg.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SCANNER_DBG_H_
+#define _MEDIA_SCANNER_DBG_H_
+#include <sys/syscall.h>
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MEDIA_SCANNER"
+#define MSC_DBG_INFO(fmt, args...)        LOGD(fmt "\n" , ##args);
+#define MSC_DBG_ERR(fmt, args...) do{ if (true) { \
+               LOGE(fmt "\n", ##args); \
+               }} while(false)
+
+/**
+ * @}
+ */
+#endif /*_MEDIA_SCANNER_DBG_H_*/
+
diff --git a/common/scanner/include/media-scanner-drm.h b/common/scanner/include/media-scanner-drm.h
new file mode 100755 (executable)
index 0000000..33ef8f2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-drm.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+#ifndef _MEDIA_SCANNER_DRM_H_
+#define _MEDIA_SCANNER_DRM_H_
+
+bool
+msc_is_drm_file(const char *path);
+
+int
+msc_get_mime_in_drm_info(const char *path, char *mime);
+
+int
+msc_drm_register(const char* path);
+
+void
+msc_drm_unregister(const char* path);
+
+void
+msc_drm_unregister_all(void);
+
+bool
+msc_drm_insert_ext_memory(void);
+
+bool
+msc_drm_extract_ext_memory(void);
+
+#endif /*_MEDIA_SCANNER_DRM_H_*/
\ No newline at end of file
diff --git a/common/scanner/include/media-scanner-scan.h b/common/scanner/include/media-scanner-scan.h
new file mode 100755 (executable)
index 0000000..49e32c9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-scan.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SCANNER_SCAN_H_
+#define _MEDIA_SCANNER_SCAN_H_
+
+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);
+
+#endif /*_MEDIA_SCANNER_SCAN_H_*/
\ No newline at end of file
diff --git a/common/scanner/include/media-scanner-socket.h b/common/scanner/include/media-scanner-socket.h
new file mode 100755 (executable)
index 0000000..68f7dff
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-thumb.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SCANNER_SOCKET_H_
+#define _MEDIA_SCANNER_SOCKET_H_
+
+#include "media-server-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_scan_result(int result, ms_comm_msg_s *scan_data);
+
+int msc_send_register_result(int result, ms_comm_msg_s *reg_data);
+
+#endif /*_MEDIA_SCANNER_SOCKET_H_*/
diff --git a/common/scanner/include/media-scanner-utils.h b/common/scanner/include/media-scanner-utils.h
new file mode 100755 (executable)
index 0000000..a19043d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-utils.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_SCANNER_UTILS_H__
+#define _MEDIA_SCANNER_UTILS_H__
+
+#include "media-server-types.h"
+
+bool
+msc_is_mmc_inserted(void);
+
+int
+msc_update_mmc_info(void);
+
+void
+msc_mmc_vconf_cb(void *data);
+
+int
+msc_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path, int depth);
+
+ms_storage_type_t
+msc_get_storage_type_by_full(const char *path);
+
+int
+msc_strappend(char *res, const int size, const char *pattern,
+                const char *str1, const char *str2);
+
+int
+msc_strcopy(char *res, const int size, const char *pattern,
+              const char *str1);
+
+bool
+msc_config_get_int(const char *key, int *value);
+
+bool
+msc_config_set_int(const char *key, int value);
+
+bool
+msc_config_get_str(const char *key, char *value);
+
+bool
+msc_config_set_str(const char *key, const char *value);
+
+#ifdef FMS_PERF
+void
+msc_check_start_time(struct timeval *start_time);
+
+void
+msc_check_end_time(struct timeval *end_time);
+
+void
+msc_check_time_diff(struct timeval *start_time, struct timeval *end_time);
+#endif/*FMS_PERF */
+
+/**
+ * @}
+ */
+#endif/*_MEDIA_SCANNER_UTILS_H__*/
+
diff --git a/common/scanner/media-scanner-db-svc.c b/common/scanner/media-scanner-db-svc.c
new file mode 100755 (executable)
index 0000000..df0543e
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-db-svc.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+
+#include <dlfcn.h>
+#include <aul/aul.h>
+
+#include "media-util.h"
+
+#include "media-scanner-dbg.h"
+#include "media-scanner-utils.h"
+#include "media-scanner-drm.h"
+#include "media-scanner-db-svc.h"
+
+#define CONFIG_PATH "/opt/usr/data/file-manager-service/plugin-config"
+#define EXT ".so"
+#define EXT_LEN 3
+#define MSC_REGISTER_COUNT 100 /*For bundle commit*/
+#define MSC_VALID_COUNT 100 /*For bundle commit*/
+
+GMutex * db_mutex;
+GArray *so_array;
+void ***func_array;
+int lib_num;
+void **scan_func_handle = NULL; /*dlopen handel*/
+
+enum func_list {
+       eCHECK,
+       eCONNECT,
+       eDISCONNECT,
+       eEXIST,
+       eINSERT_BEGIN,
+       eINSERT_END,
+       eINSERT_BATCH,
+       eSET_ALL_VALIDITY,
+       eSET_VALIDITY_BEGIN,
+       eSET_VALIDITY_END,
+       eSET_VALIDITY,
+       eDELETE_ALL,
+       eDELETE_INVALID_ITEMS,
+       eUPDATE_BEGIN,
+       eUPDATE_END,
+       eSET_FOLDER_VALIDITY,
+       eDELETE_FOLDER,
+       eFUNC_MAX
+};
+
+
+static int
+_msc_get_mime(const char *path, char *mimetype)
+{
+       int ret = 0;
+
+       if (path == NULL)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       /*get content type and mime type from file. */
+       /*in case of drm file. */
+       if (msc_is_drm_file(path)) {
+               ret =  msc_get_mime_in_drm_info(path, mimetype);
+               if (ret != MS_MEDIA_ERR_NONE) {
+                       MSC_DBG_ERR("Fail to get mime");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       } else {
+               /*in case of normal files */
+               if (aul_get_mime_from_file(path, mimetype, 255) < 0) {
+                       MSC_DBG_ERR("aul_get_mime_from_file fail");
+                       return MS_MEDIA_ERR_MIME_GET_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int
+_msc_check_category(const char *path, const char *mimetype, int index)
+{
+       int ret;
+       char *err_msg = NULL;
+
+       ret = ((CHECK_ITEM)func_array[index][eCHECK])(path, mimetype, &err_msg);
+       if (ret != 0) {
+               MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, index), err_msg, path);
+               MS_SAFE_FREE(err_msg);
+       }
+
+       return ret;
+}
+
+static int
+_msc_token_data(char *buf, char **name)
+{
+       int len;
+       char* pos = NULL;
+
+       pos = strstr(buf, EXT);
+       if (pos == NULL) {
+               MSC_DBG_ERR("This is not shared object library.");
+               name = NULL;
+               return -1;
+       } else {
+               len = pos - buf + EXT_LEN;
+               *name = strndup(buf, len);
+               MSC_DBG_INFO("%s", *name);
+       }
+
+       return 0;
+}
+
+static bool
+_msc_load_config()
+{
+       int ret;
+       FILE *fp;
+       char *so_name = NULL;
+       char buf[256] = {0};
+
+       fp = fopen(CONFIG_PATH, "rt");
+       if (fp == NULL) {
+               MSC_DBG_ERR("fp is NULL");
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+       while(1) {
+               if (fgets(buf, 256, fp) == NULL)
+                       break;
+
+               ret = _msc_token_data(buf, &so_name);
+               if (ret == 0) {
+                       /*add to array*/
+                       g_array_append_val(so_array, so_name);
+                       so_name = NULL;
+               }
+       }
+
+       fclose(fp);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_load_functions(void)
+{
+       int lib_index = 0, func_index;
+       char func_list[eFUNC_MAX][40] = {
+               "check_item",
+               "connect",
+               "disconnect",
+               "check_item_exist",
+               "insert_item_begin",
+               "insert_item_end",
+               "insert_item",
+               "set_all_storage_items_validity",
+               "set_item_validity_begin",
+               "set_item_validity_end",
+               "set_item_validity",
+               "delete_all_items_in_storage",
+               "delete_all_invalid_items_in_storage",
+               "update_begin",
+               "update_end",
+               "set_folder_item_validity",
+               "delete_all_invalid_items_in_folder",
+               };
+       /*init array for adding name of so*/
+       so_array = g_array_new(FALSE, FALSE, sizeof(char*));
+
+       /*load information of so*/
+       _msc_load_config();
+
+       if(so_array->len == 0) {
+               MSC_DBG_INFO("There is no information for functions");
+               return MS_MEDIA_ERR_DYNAMIC_LINK;
+       }
+
+       /*the number of functions*/
+       lib_num = so_array->len;
+
+       MSC_DBG_INFO("The number of information of so : %d", lib_num);
+       MS_MALLOC(scan_func_handle, sizeof(void*) * lib_num);
+       if (scan_func_handle == NULL) {
+               MSC_DBG_ERR("malloc failed");
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       while(lib_index < lib_num) {
+               /*get handle*/
+               MSC_DBG_INFO("[name of so : %s]", g_array_index(so_array, char*, lib_index));
+               scan_func_handle[lib_index] = dlopen(g_array_index(so_array, char*, lib_index), RTLD_LAZY);
+               if (!scan_func_handle[lib_index]) {
+                       MSC_DBG_ERR("%s", dlerror());
+                       MS_SAFE_FREE(scan_func_handle);
+                       return MS_MEDIA_ERR_DYNAMIC_LINK;
+               }
+               lib_index++;
+       }
+
+       dlerror();    /* Clear any existing error */
+
+       /*allocate for array of functions*/
+       MS_MALLOC(func_array, sizeof(void*) * lib_num);
+       if (func_array == NULL) {
+               MSC_DBG_ERR("malloc failed");
+               MS_SAFE_FREE(scan_func_handle);
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       for(lib_index = 0 ; lib_index < lib_num; lib_index ++) {
+               MS_MALLOC(func_array[lib_index], sizeof(void*) * eFUNC_MAX);
+               if (func_array[lib_index] == NULL) {
+                       int index;
+
+                       for (index = 0; index < lib_index; index ++) {
+                               MS_SAFE_FREE(func_array[index]);
+                       }
+                       MS_SAFE_FREE(func_array);
+                       MS_SAFE_FREE(scan_func_handle);
+
+                       MSC_DBG_ERR("malloc failed");
+                       return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+               }
+       }
+
+       /*add functions to array */
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               for (func_index = 0; func_index < eFUNC_MAX ; func_index++) {
+                       func_array[lib_index][func_index] = dlsym(scan_func_handle[lib_index], func_list[func_index]);
+                       if (func_array[lib_index][func_index] == NULL) {
+                               int index;
+
+                               for (index = 0; index < lib_index; index ++) {
+                                       MS_SAFE_FREE(func_array[index]);
+                               }
+                               MS_SAFE_FREE(func_array);
+                               MS_SAFE_FREE(scan_func_handle);
+
+                               MSC_DBG_ERR("dlsym failed");
+                               return MS_MEDIA_ERR_DYNAMIC_LINK;
+                       }
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+void
+msc_unload_functions(void)
+{
+       int lib_index;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index ++)
+               dlclose(scan_func_handle[lib_index]);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+                       if (func_array[lib_index]) {
+                               MS_SAFE_FREE(func_array[lib_index]);
+                       }
+       }
+
+       MS_SAFE_FREE (func_array);
+       MS_SAFE_FREE (scan_func_handle);
+       if (so_array) g_array_free(so_array, TRUE);
+}
+
+int
+msc_connect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       /*Lock mutex for openning db*/
+       g_mutex_lock(db_mutex);
+
+       MS_MALLOC(*handle, sizeof (void*) * lib_num);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((CONNECT)func_array[lib_index][eCONNECT])(&((*handle)[lib_index]), &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       g_mutex_unlock(db_mutex);
+
+                       return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+               }
+       }
+
+       MSC_DBG_INFO("connect Media DB");
+
+       g_mutex_unlock(db_mutex);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_disconnect_db(void ***handle)
+{
+       int lib_index;
+       int ret;
+       char * err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DISCONNECT)func_array[lib_index][eDISCONNECT])((*handle)[lib_index], &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return MS_MEDIA_ERR_DB_DISCONNECT_FAIL;
+               }
+       }
+
+       MS_SAFE_FREE(*handle);
+
+       MSC_DBG_INFO("Disconnect Media DB");
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_validate_item(void **handle, char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+       char mimetype[255] = {0};
+       ms_storage_type_t storage_type;
+
+       ret = _msc_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("err : _msc_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = msc_get_storage_type_by_full(path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_msc_check_category(path, mimetype, lib_index)) {
+                       /*check exist in Media DB, If file is not exist, insert data in DB. */
+                       ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MSC_DBG_ERR("not exist in %d. insert data", lib_index);
+                               MS_SAFE_FREE(err_msg);
+
+                               ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                               if (ret != 0) {
+                                       MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path);
+                                       MSC_DBG_ERR("[%s] %s", mimetype, path);
+                                       MS_SAFE_FREE(err_msg);
+                                       res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                               }
+                       } else {
+                               /*if meta data of file exist, change valid field to "1" */
+                               ret = ((SET_ITEM_VALIDITY)func_array[lib_index][eSET_VALIDITY])(handle[lib_index], path, true, mimetype, true, &err_msg); /*dlopen*/
+                               if (ret != 0) {
+                                       MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path);
+                                       MSC_DBG_ERR("[%s] %s", mimetype, path);
+                                       MS_SAFE_FREE(err_msg);
+                                       res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+                               }
+                       }
+               } else {
+                       MSC_DBG_ERR("check category failed");
+                       MSC_DBG_ERR("[%s] %s", mimetype, path);
+               }
+       }
+
+       if (msc_is_drm_file(path)) {
+               ret = msc_drm_register(path);
+       }
+
+       return res;
+}
+
+int
+msc_invalidate_all_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ALL_STORAGE_ITEMS_VALIDITY)func_array[lib_index][eSET_ALL_VALIDITY])(handle[lib_index], store_type, false, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       res = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+               }
+       }
+
+       return res;
+}
+
+int
+msc_insert_item_batch(void **handle, const char *path)
+{
+       int lib_index;
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+       char mimetype[255] = {0};
+       char *err_msg = NULL;
+       ms_storage_type_t storage_type;
+
+       ret = _msc_get_mime(path, mimetype);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("err : _msc_get_mime [%d]", ret);
+               return ret;
+       }
+       storage_type = msc_get_storage_type_by_full(path);
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               if (!_msc_check_category(path, mimetype, lib_index)) {
+                       ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, mimetype, &err_msg); /*dlopen*/
+                       if (ret != 0) {
+                               MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                               MSC_DBG_ERR("[%s] %s", mimetype, path);
+                               MS_SAFE_FREE(err_msg);
+                               res = MS_MEDIA_ERR_DB_INSERT_FAIL;
+                       }
+               } else {
+                       MSC_DBG_ERR("check category failed");
+                       MSC_DBG_ERR("[%s] %s", mimetype, path);
+               }
+       }
+
+       if (msc_is_drm_file(path)) {
+               ret = msc_drm_register(path);
+               res = ret;
+       }
+
+       return res;
+}
+
+bool
+msc_delete_all_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       /* To reset media db when differnet mmc is inserted. */
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DELETE_ALL_ITEMS_IN_STORAGE)func_array[lib_index][eDELETE_ALL])(handle[lib_index], store_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+bool
+msc_delete_invalid_items(void **handle, ms_storage_type_t store_type)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DELETE_ALL_INVALID_ITMES_IN_STORAGE)func_array[lib_index][eDELETE_INVALID_ITEMS])(handle[lib_index], store_type, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+int
+msc_set_folder_validity(void **handle, const char *path, int validity, int recursive)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_FOLDER_ITEM_VALIDITY)func_array[lib_index][eSET_FOLDER_VALIDITY])(handle[lib_index], path, validity, recursive,&err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return MS_MEDIA_ERR_DB_UPDATE_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_delete_invalid_items_in_folder(void **handle, const char*path)
+{
+       int lib_index;
+       int ret;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((DELETE_ALL_INVALID_ITEMS_IN_FOLDER)func_array[lib_index][eDELETE_FOLDER])(handle[lib_index], path, &err_msg); /*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+                       return MS_MEDIA_ERR_DB_UPDATE_FAIL;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+/****************************************************************************************************
+FOR BULK COMMIT
+*****************************************************************************************************/
+
+void
+msc_register_start(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((INSERT_ITEM_BEGIN)func_array[lib_index][eINSERT_BEGIN])(handle[lib_index], MSC_REGISTER_COUNT, &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+msc_register_end(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((INSERT_ITEM_END)func_array[lib_index][eINSERT_END])(handle[lib_index], &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((UPDATE_END)func_array[lib_index][eUPDATE_END])();/*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+msc_validate_start(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ITEM_VALIDITY_BEGIN)func_array[lib_index][eSET_VALIDITY_BEGIN])(handle[lib_index], MSC_VALID_COUNT, &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
+void
+msc_validate_end(void **handle)
+{
+       int lib_index;
+       int ret = 0;
+       char *err_msg = NULL;
+
+       for (lib_index = 0; lib_index < lib_num; lib_index++) {
+               ret = ((SET_ITEM_VALIDITY_END)func_array[lib_index][eSET_VALIDITY_END])(handle[lib_index], &err_msg);/*dlopen*/
+               if (ret != 0) {
+                       MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg);
+                       MS_SAFE_FREE(err_msg);
+               }
+       }
+}
+
diff --git a/common/scanner/media-scanner-drm.c b/common/scanner/media-scanner-drm.c
new file mode 100755 (executable)
index 0000000..8860f90
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-drm.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+#include <drm_client_types.h>
+#include <drm_client.h>
+
+#include "media-util.h"
+
+#include "media-scanner-dbg.h"
+#include "media-server-types.h"
+#include "media-scanner-drm.h"
+
+bool
+msc_is_drm_file(const char *path)
+{
+       int ret;
+       drm_bool_type_e is_drm_file = DRM_UNKNOWN;
+
+       ret = drm_is_drm_file(path,&is_drm_file);
+       if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file)
+               return true;
+
+       return false;
+}
+
+int
+msc_get_mime_in_drm_info(const char *path, char *mime)
+{
+       int ret;
+       drm_content_info_s contentInfo;
+
+       if (path == NULL || mime == NULL)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       memset(&contentInfo,0x0,sizeof(drm_content_info_s));
+       ret = drm_get_content_info(path, &contentInfo);
+       if (ret != DRM_RETURN_SUCCESS) {
+               MSC_DBG_ERR("drm_svc_get_content_info() failed");
+               MSC_DBG_ERR("%s [%d]", path, ret);
+               return MS_MEDIA_ERR_DRM_GET_INFO_FAIL;
+       }
+
+       strncpy(mime, contentInfo.mime_type, 100);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_drm_register(const char* path)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int ret;
+
+       ret = drm_process_request(DRM_REQUEST_TYPE_REGISTER_FILE, (void *)path, NULL);
+       if (ret != DRM_RETURN_SUCCESS) {
+               MSC_DBG_ERR("drm_svc_register_file error : %d %s", ret, path);
+               res = MS_MEDIA_ERR_DRM_REGISTER_FAIL;
+       }
+
+       return res;
+}
+
+void
+msc_drm_unregister(const char* path)
+{
+       int ret;
+
+       ret = drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_FILE, (void *)path, NULL);
+       if (ret != DRM_RETURN_SUCCESS)
+               MSC_DBG_ERR("drm_process_request error : %d", ret);
+}
+
+void
+msc_drm_unregister_all(void)
+{
+       if (drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_ALL_FILES , NULL, NULL) == DRM_RETURN_SUCCESS)
+               MSC_DBG_INFO("drm_svc_unregister_all_contents OK");
+}
+
+bool
+msc_drm_insert_ext_memory(void)
+{
+       if (drm_process_request(DRM_REQUEST_TYPE_INSERT_EXT_MEMORY, NULL, NULL) != DRM_RETURN_SUCCESS)
+               return false;
+
+       return true;
+}
+
+bool
+msc_drm_extract_ext_memory(void)
+{
+       if (drm_process_request(DRM_REQUEST_TYPE_EXTRACT_EXT_MEMORY , NULL, NULL)  != DRM_RETURN_SUCCESS)
+               return false;
+
+       return true;
+}
+
diff --git a/common/scanner/media-scanner-scan.c b/common/scanner/media-scanner-scan.c
new file mode 100755 (executable)
index 0000000..eee8567
--- /dev/null
@@ -0,0 +1,1091 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-scan.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#include <sys/stat.h>
+#include <fcntl.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-scanner-dbg.h"
+#include "media-scanner-utils.h"
+#include "media-scanner-db-svc.h"
+#include "media-scanner-socket.h"
+#include "media-scanner-scan.h"
+
+typedef struct msc_scan_data {
+       char *name;
+       struct msc_scan_data *next;
+} msc_scan_data;
+
+int mmc_state;
+bool power_off;
+GAsyncQueue * storage_queue;
+GAsyncQueue *scan_queue;
+GAsyncQueue *reg_queue;
+
+#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)
+{
+       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:
+               MSC_DBG_ERR("Unacceptable type : %d", status);
+               break;
+       }
+
+       return res;
+}
+
+static int
+_msc_set_db_status(ms_scanning_location_t location, ms_db_status_type_t status)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       int err = 0;
+
+       if (status == MS_DB_UPDATING) {
+               if (location != MS_SCANNING_DIRECTORY) {
+                       if (!msc_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+               /* this is temporay code for tizen 2.0*/
+               if(location == MS_SCANNING_EXTERNAL) {
+                       if (!msc_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+
+               /* Update private vconf key for media server*/
+               if (location == MS_SCANNING_INTERNAL) {
+                       if (!msc_config_set_int(MS_SCAN_STATUS_INTERNAL, P_VCONF_SCAN_DOING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               } else if (location == MS_SCANNING_DIRECTORY) {
+                       if (!msc_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DOING)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+       } else if (status == MS_DB_UPDATED) {
+               if (location != MS_SCANNING_DIRECTORY) {
+                       if(!msc_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS,  VCONFKEY_FILEMANAGER_DB_UPDATED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+
+               /* this is temporay code for tizen 2.0*/
+               if(location == MS_SCANNING_EXTERNAL) {
+                       if (!msc_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+
+               /* Update private vconf key for media server*/
+               if (location == MS_SCANNING_INTERNAL) {
+                       if (!msc_config_set_int(MS_SCAN_STATUS_INTERNAL, P_VCONF_SCAN_DONE)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               } else if (location == MS_SCANNING_DIRECTORY) {
+                       if (!msc_config_set_int(MS_SCAN_STATUS_DIRECTORY, P_VCONF_SCAN_DONE)) {
+                               res = MS_MEDIA_ERR_VCONF_SET_FAIL;
+                               MSC_DBG_ERR("msc_config_set_int failed");
+                       }
+               }
+       }
+
+       err = _msc_set_power_mode(status);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("_msc_set_power_mode fail");
+               res = err;
+       }
+
+       return res;
+}
+
+static int _msc_scan_get_next_path_from_current_node(int find_folder,
+                                  ms_dir_scan_info **current_root,
+                                  ms_dir_scan_info **real_root, char **path, int *depth)
+{
+       int err = MS_MEDIA_ERR_NONE;
+       char get_path[FAT_FILEPATH_LEN_MAX] = { 0 };
+
+       if (find_folder == 0) {
+               if ((*current_root)->Rbrother != NULL) {
+                       *current_root = (*current_root)->Rbrother;
+               } else {
+                       while (1) {
+                               if ((*current_root)->parent == *real_root
+                                   || (*current_root)->parent == NULL) {
+                                       *current_root = NULL;
+                                       *depth = 0;
+                                       return MS_MEDIA_ERR_NONE;
+                               } else if ((*current_root)->parent->Rbrother == NULL) {
+                                       *current_root = (*current_root)->parent;
+                                       (*depth) --;
+                               } else {
+                                       *current_root = (*current_root)->parent->Rbrother;
+                                       (*depth) --;
+                                       break;
+                               }
+                       }
+               }
+               (*depth) --;
+       }
+
+       err = msc_get_full_path_from_node(*current_root, get_path, *depth);
+       if (err != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_INVALID_PATH;
+
+       *path = strdup(get_path);
+
+       return err;
+}
+
+static int _msc_scan_add_node(msc_scan_data **first_node, ms_dir_scan_info *const node, int depth)
+{
+       int err;
+       char full_path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       msc_scan_data *current_dir = NULL;
+       msc_scan_data *prv_node = NULL;
+       msc_scan_data *last_node = NULL;
+
+       err = msc_get_full_path_from_node(node, full_path, depth);
+       if (err != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_INVALID_PATH;
+
+       last_node = *first_node;
+       while (last_node != NULL) {
+               last_node = last_node->next;
+       }
+
+       /*find same folder */
+       if (*first_node != NULL) {
+               last_node = *first_node;
+               while (last_node != NULL) {
+                       if (strcmp(full_path, last_node->name) == 0) {
+                               return MS_MEDIA_ERR_NONE;
+                       }
+                       prv_node = last_node;
+                       last_node = last_node->next;
+               }
+       }
+
+       MS_MALLOC(current_dir, sizeof(msc_scan_data));
+       current_dir->name = strdup(full_path);
+       current_dir->next = NULL;
+
+       if (*first_node == NULL) {
+               *first_node = current_dir;
+       } else {
+               /*if next node of current node is NULL, it is the lastest node. */
+               prv_node->next = current_dir;
+       }
+
+//     MSC_DBG_INFO("scan path : %s %x %p", full_path, first_node, first_node);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static bool _msc_check_scan_ignore(char * path)
+{
+       DIR *dp = NULL;
+       struct dirent entry;
+       struct dirent *result;
+       char *ignore_path = ".scan_ignore";
+
+       dp = opendir(path);
+       if (dp == NULL) {
+               MSC_DBG_ERR("%s folder opendir fails", path);
+               return true;
+       }
+
+       while (!readdir_r(dp, &entry, &result)) {
+               if (result == NULL)
+                       break;
+
+               if (strcmp(entry.d_name, ignore_path) == 0) {
+                       closedir(dp);
+                       return true;
+               }
+       }
+
+       closedir(dp);
+       return false;
+}
+
+static int _ms_check_stop_status(ms_storage_type_t storage_type)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       /*check poweroff status*/
+       if (power_off) {
+               MSC_DBG_INFO("Power off");
+               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+       }
+
+       /*check SD card in out */
+       if ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (storage_type == MS_STORAGE_EXTERNAL)) {
+               MSC_DBG_INFO("Directory scanning is stopped");
+               ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP;
+       }
+
+       return ret;
+}
+
+static void _msc_dir_check(msc_scan_data **first_node, const ms_comm_msg_s *scan_data)
+{
+       int err = 0;
+       int depth = 0;
+       int find_folder = 0;
+       char get_path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char *path = NULL;
+       DIR *dp = NULL;
+       struct dirent entry;
+       struct dirent *result;
+       ms_storage_type_t storage_type;
+
+       ms_dir_scan_info *root = NULL;
+       ms_dir_scan_info *tmp_root = NULL;
+       ms_dir_scan_info *cur_node = NULL; /*current node*/
+       ms_dir_scan_info *prv_node = NULL; /*previous node*/
+       ms_dir_scan_info *next_node = NULL;
+
+       MS_MALLOC(root, sizeof(ms_dir_scan_info));
+       if (root == NULL) {
+               MSC_DBG_ERR("malloc fail");
+               return;
+       }
+
+       storage_type = msc_get_storage_type_by_full(scan_data->msg);
+
+       root->name = strndup(scan_data->msg, scan_data->msg_size);
+       if (root->name == NULL) {
+               MSC_DBG_ERR("strdup fail");
+               MS_SAFE_FREE(root);
+               return;
+       }
+
+       root->parent = NULL;
+       root->Rbrother = NULL;
+       root->next = NULL;
+       tmp_root = root;
+       prv_node = root;
+
+       MS_MALLOC(path, sizeof(char) * MS_FILE_PATH_LEN_MAX);
+
+       err = msc_get_full_path_from_node(tmp_root, path, depth);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MS_SAFE_FREE(path);
+               MS_SAFE_FREE(root);
+               return;
+       }
+
+       _msc_scan_add_node(first_node, root, depth);
+
+       while (1) {
+               /*check poweroff status*/
+               err = _ms_check_stop_status(storage_type);
+               if (err != MS_MEDIA_ERR_NONE) {
+                       goto FREE_RESOURCES;
+               }
+
+               depth ++;
+               dp = opendir(path);
+               if (dp == NULL) {
+                       MSC_DBG_ERR("%s folder opendir fails", path);
+                       goto NEXT_DIR;
+               }
+
+               while (!readdir_r(dp, &entry, &result)) {
+                       /*check poweroff status*/
+                       err = _ms_check_stop_status(storage_type);
+                       if (err != MS_MEDIA_ERR_NONE) {
+                               goto FREE_RESOURCES;
+                       }
+
+                       if (result == NULL)
+                               break;
+
+                       if (entry.d_name[0] == '.')
+                               continue;
+
+                       if (entry.d_type & DT_DIR) {
+                               err = msc_strappend(get_path, sizeof(get_path), "%s/%s",path, entry.d_name);
+                               if (err != MS_MEDIA_ERR_NONE) {
+                                       MSC_DBG_ERR("msc_strappend error");
+                                       continue;
+                               }
+
+                               if (_msc_check_scan_ignore(get_path)) {
+                                       MSC_DBG_ERR("%s is ignore", get_path);
+                                       continue;
+                               }
+
+                               MS_MALLOC(cur_node, sizeof(ms_dir_scan_info));
+                               if (cur_node == NULL) {
+                                       MSC_DBG_ERR("malloc fail");
+
+                                       goto FREE_RESOURCES;
+                               }
+
+                               cur_node->name = strdup(entry.d_name);
+                               cur_node->Rbrother = NULL;
+                               cur_node->next = NULL;
+
+                               /*1. 1st folder */
+                               if (find_folder == 0) {
+                                       cur_node->parent = tmp_root;
+                                       tmp_root = cur_node;
+                               } else {
+                                       cur_node->parent = tmp_root->parent;
+                                       prv_node->Rbrother = cur_node;
+                               }
+                               prv_node->next = cur_node;
+
+                               /*add watch */
+                               _msc_scan_add_node(first_node, cur_node, depth);
+
+                               /*change previous */
+                               prv_node = cur_node;
+                               find_folder++;
+                       }
+               }
+NEXT_DIR:
+               MS_SAFE_FREE(path);
+               if (dp) closedir(dp);
+               dp = NULL;
+
+               err = _msc_scan_get_next_path_from_current_node(find_folder, &tmp_root, &root, &path, &depth);
+               if (err != MS_MEDIA_ERR_NONE)
+                       break;
+
+               if (tmp_root == NULL)
+                       break;
+
+               find_folder = 0;
+       }
+
+FREE_RESOURCES:
+       /*free allocated memory */
+       MS_SAFE_FREE(path);
+       if (dp) closedir(dp);
+       dp = NULL;
+
+       cur_node = root;
+       while (cur_node != NULL) {
+               next_node = cur_node->next;
+               MS_SAFE_FREE(cur_node->name);
+               MS_SAFE_FREE(cur_node);
+               cur_node = next_node;
+       }
+}
+
+static int _msc_dir_scan(void **handle, msc_scan_data **first_node, const ms_comm_msg_s * scan_data)
+{
+       DIR *dp = NULL;
+       int scan_type;
+       int ret = MS_MEDIA_ERR_NONE;
+       int err = 0;
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       msc_scan_data *node;
+       ms_storage_type_t storage_type;
+
+       err = msc_strcopy(path, sizeof(path), "%s", scan_data->msg);
+       if (err != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("error : %d", err );
+               return err;
+       }
+
+       storage_type = msc_get_storage_type_by_full(scan_data->msg);
+       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) {
+               struct dirent entry;
+               struct dirent *result = NULL;
+
+               if (scan_data->msg_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                       _msc_dir_check(first_node, scan_data);
+               } else {
+                       msc_scan_data *scan_node;
+
+                       MS_MALLOC(scan_node, sizeof(msc_scan_data));
+
+                       scan_node->name = strdup(scan_data->msg);
+                       scan_node->next = NULL;
+
+                       *first_node = scan_node;
+               }
+
+               node = *first_node;
+
+               /*start db update. If node is null, db update is done.*/
+               while (node != NULL) {
+                       /*check poweroff status*/
+                       ret = _ms_check_stop_status(storage_type);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               goto STOP_SCAN;
+                       }
+
+                       dp = opendir(node->name);
+                       if (dp != NULL) {
+                               while (!readdir_r(dp, &entry, &result)) {
+                                       /*check poweroff status*/
+                                       ret = _ms_check_stop_status(storage_type);
+                                       if (ret != MS_MEDIA_ERR_NONE) {
+                                               goto STOP_SCAN;
+                                       }
+
+                                       if (result == NULL)
+                                               break;
+
+                                       if (entry.d_name[0] == '.')
+                                               continue;
+
+                                       if (entry.d_type & DT_REG) {
+                                               err = msc_strappend(path, sizeof(path), "%s/%s", node->name, entry.d_name);
+                                               if (err < 0) {
+                                                       MSC_DBG_ERR("error : %d", err);
+                                                       continue;
+                                               }
+
+                                               if (scan_type == MS_MSG_STORAGE_ALL)
+                                                       err = msc_insert_item_batch(handle, path);
+                                               else
+                                                       err = msc_validate_item(handle,path);
+                                               if (err < 0) {
+                                                       MSC_DBG_ERR("failed to update db : %d , %d\n", err, scan_type);
+                                                       continue;
+                                               }
+                                       }
+                               }
+                       } else {
+                               MSC_DBG_ERR("%s folder opendir fails", node->name);
+                       }
+                       if (dp) closedir(dp);
+                       dp = NULL;
+
+                       node = node->next;
+               }               /*db update while */
+       } else if ( scan_type == MS_MSG_STORAGE_INVALID) {
+               /*In this case, update just validation record*/
+               /*update just valid type*/
+               err = msc_invalidate_all_items(handle, storage_type);
+               if (err != MS_MEDIA_ERR_NONE)
+                       MSC_DBG_ERR("error : %d", err);
+       }
+STOP_SCAN:
+       if (dp) closedir(dp);
+
+       /*delete all node*/
+       node = *first_node;
+
+       while (node != NULL) {
+               MS_SAFE_FREE(node->name);
+               MS_SAFE_FREE(node);
+       }
+
+       *first_node = NULL;
+
+       sync();
+
+       MSC_DBG_INFO("ret : %d", ret);
+
+       return ret;
+}
+
+
+static void _msc_insert_array(GArray *garray, ms_comm_msg_s *insert_data)
+{
+       ms_scan_data_t *data;
+       bool insert_ok = false;
+       int len = garray->len;
+       int i;
+
+       MSC_DBG_INFO("the length of array : %d", len);
+       MSC_DBG_INFO("path : %s", insert_data->msg);
+       MSC_DBG_INFO("scan_type : %d", insert_data->msg_type);
+
+       if (insert_data->pid == POWEROFF) {
+               g_array_prepend_val(garray, insert_data);
+       } else {
+               for (i=0; i < len; i++) {
+                       data = g_array_index(garray, ms_scan_data_t*, i);
+/*
+                       if (data->pid != POWEROFF) {
+                               if (data->storage_type == insert_data->storage_type) {
+                                       if(data->scan_type > insert_data->scan_type) {
+                                               g_array_remove_index (garray, i);
+                                               g_array_insert_val(garray, i, insert_data);
+                                               insert_ok =  true;
+                                       }
+                               }
+                       }
+*/
+               }
+
+               if (insert_ok == false)
+                       g_array_append_val(garray, insert_data);
+       }
+}
+
+void _msc_check_dir_path(char *dir_path)
+{
+       int len = strlen(dir_path);
+
+       if (dir_path[len -1] == '/')
+               dir_path[len -1] = '\0';
+}
+
+gboolean msc_directory_scan_thread(void *data)
+{
+       ms_comm_msg_s *scan_data = NULL;
+       ms_comm_msg_s *insert_data = NULL;
+       GArray *garray = NULL;
+       int length;
+       int err;
+       int ret;
+       void **handle = NULL;
+       ms_storage_type_t storage_type;
+       int scan_type;
+       msc_scan_data *first_node = NULL;
+
+       /*create array for processing overlay data*/
+       garray = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *));
+       if (garray == NULL) {
+               MSC_DBG_ERR("g_array_new error");
+               return false;
+       }
+
+       while (1) {
+               length  = g_async_queue_length(scan_queue);
+
+               /*updating requests remain*/
+               if (garray->len != 0 && length == 0) {
+                       scan_data = g_array_index(garray, ms_comm_msg_s*, 0);
+                       g_array_remove_index (garray, 0);
+                       if (scan_data->pid == POWEROFF) {
+                               MSC_DBG_INFO("power off");
+                               goto _POWEROFF;
+                       }
+               } else if (length != 0) {
+                       insert_data = g_async_queue_pop(scan_queue);
+                       _msc_insert_array(garray, insert_data);
+                       continue;
+               } else if (garray->len == 0 && length == 0) {
+                       /*Threre is no request, Wait until pushung new request*/
+                       insert_data = g_async_queue_pop(scan_queue);
+                       _msc_insert_array(garray, insert_data);
+                       continue;
+               }
+
+               MSC_DBG_INFO("DIRECTORY SCAN START");
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = msc_connect_db(&handle);
+               if (err != MS_MEDIA_ERR_NONE)
+                       continue;
+
+               storage_type = msc_get_storage_type_by_full(scan_data->msg);
+               scan_type = scan_data->msg_type;
+
+               if (scan_type != MS_MSG_DIRECTORY_SCANNING
+                       && scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+                       MSC_DBG_ERR("Invalid request");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               /*start db updating */
+//             _msc_set_db_status(MS_SCANNING_DIRECTORY, MS_DB_UPDATING);
+
+               _msc_check_dir_path(scan_data->msg);
+
+               /*change validity before scanning*/
+               if (scan_type == MS_MSG_DIRECTORY_SCANNING)
+                       err = msc_set_folder_validity(handle, scan_data->msg, MS_INVALID, MS_RECURSIVE);
+               else
+                       err = msc_set_folder_validity(handle, scan_data->msg, MS_INVALID, MS_NON_RECURSIVE);
+               if (err != MS_MEDIA_ERR_NONE)
+                       MSC_DBG_ERR("error : %d", err);
+
+               /*call for bundle commit*/
+               msc_register_start(handle);
+               msc_validate_start(handle);
+
+               /*insert data into media db */
+               ret = _msc_dir_scan(handle, &first_node, scan_data);
+
+               /*call for bundle commit*/
+               msc_register_end(handle);
+               msc_validate_end(handle);
+
+               if (ret == MS_MEDIA_ERR_NONE) {
+                       MSC_DBG_INFO("working normally");
+                       msc_delete_invalid_items_in_folder(handle, scan_data->msg);
+               }
+
+               /*set vconf key mmc loading for indicator */
+//             _msc_set_db_status(MS_SCANNING_DIRECTORY, MS_DB_UPDATED);
+
+               if (power_off) {
+                       MSC_DBG_INFO("power off");
+                       goto _POWEROFF;
+               }
+
+               /*disconnect form media db*/
+               if (handle) msc_disconnect_db(&handle);
+NEXT:
+               /*Active flush */
+               malloc_trim(0);
+
+               msc_send_scan_result(ret, scan_data);
+
+//             MS_SAFE_FREE(scan_data->msg);
+               MS_SAFE_FREE(scan_data);
+
+               MSC_DBG_INFO("DIRECTORY SCAN END");
+       }                       /*thread while*/
+
+_POWEROFF:
+//     MS_SAFE_FREE(scan_data->msg);
+       MS_SAFE_FREE(scan_data);
+       if (garray) g_array_free (garray, TRUE);
+       if (handle) msc_disconnect_db(&handle);
+
+       return false;
+}
+
+/* this thread process only the request of media-server */
+gboolean msc_storage_scan_thread(void *data)
+{
+       ms_comm_msg_s *scan_data = NULL;
+       ms_comm_msg_s *insert_data = NULL;
+       GArray *garray = NULL;
+       bool res;
+       int ret;
+       int length;
+       int err;
+       void **handle = NULL;
+       ms_storage_type_t storage_type;
+       int scan_type;
+       msc_scan_data *first_node = NULL;
+
+       /*create array for processing overlay data*/
+       garray = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *));
+       if (garray == NULL) {
+               MSC_DBG_ERR("g_array_new error");
+               return false;
+       }
+
+       while (1) {
+               length  = g_async_queue_length(storage_queue);
+
+               /*updating requests remain*/
+               if (garray->len != 0 && length == 0) {
+                       scan_data = g_array_index(garray, ms_comm_msg_s*, 0);
+                       g_array_remove_index (garray, 0);
+                       if (scan_data->pid == POWEROFF) {
+                               MSC_DBG_INFO("power off");
+                               goto _POWEROFF;
+                       }
+               } else if (length != 0) {
+                       insert_data = g_async_queue_pop(storage_queue);
+                       _msc_insert_array(garray, insert_data);
+                       continue;
+               } else if (garray->len == 0 && length == 0) {
+                       /*Threre is no request, Wait until pushing new request*/
+                       insert_data = g_async_queue_pop(storage_queue);
+                       _msc_insert_array(garray, insert_data);
+                       continue;
+               }
+
+               MSC_DBG_INFO("STORAGE SCAN START");
+
+               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) {
+                       MSC_DBG_ERR("Invalid request");
+                       ret = MS_MEDIA_ERR_INVALID_PARAMETER;
+                       goto NEXT;
+               }
+
+               storage_type = msc_get_storage_type_by_full(scan_data->msg);
+               MSC_DBG_INFO("%d", storage_type);
+
+               /*connect to media db, if conneting is failed, db updating is stopped*/
+               err = msc_connect_db(&handle);
+               if (err != MS_MEDIA_ERR_NONE)
+                       continue;
+
+               /*start db updating */
+               if (storage_type == MS_STORAGE_INTERNAL)
+                       _msc_set_db_status(MS_SCANNING_INTERNAL, MS_DB_UPDATING);
+               else if (storage_type == MS_STORAGE_EXTERNAL)
+                       _msc_set_db_status(MS_SCANNING_EXTERNAL, MS_DB_UPDATING);
+
+               /*Delete all data before full scanning*/
+               if (scan_type == MS_MSG_STORAGE_ALL) {
+                       res = msc_delete_all_items(handle, storage_type);
+                       if (res != true) {
+                               MSC_DBG_ERR("msc_delete_all_record fails");
+                       }
+               } else if (scan_type == MS_MSG_STORAGE_PARTIAL) {
+                       err = msc_invalidate_all_items(handle, storage_type);
+                       if (err != MS_MEDIA_ERR_NONE)
+                               MSC_DBG_ERR("error : %d", err);
+               }
+
+               if (storage_type == MS_STORAGE_EXTERNAL && scan_type == MS_MSG_STORAGE_ALL) {
+                       msc_update_mmc_info();
+               }
+
+#ifdef FMS_PERF
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       msc_check_start_time(&g_mmc_start_time);
+               }
+#endif
+               /*call for bundle commit*/
+               msc_register_start(handle);
+               if (scan_type == MS_MSG_STORAGE_PARTIAL) {
+                       /*enable bundle commit*/
+                       msc_validate_start(handle);
+               }
+
+               /*add inotify watch and insert data into media db */
+               ret = _msc_dir_scan(handle, &first_node, scan_data);
+
+               /*call for bundle commit*/
+               msc_register_end(handle);
+               if (scan_type == MS_MSG_STORAGE_PARTIAL) {
+                       /*disable bundle commit*/
+                       msc_validate_end(handle);
+                       if (ret == MS_MEDIA_ERR_NONE) {
+                               MSC_DBG_INFO("working normally");
+                               msc_delete_invalid_items(handle, storage_type);
+                       }
+               }
+
+#ifdef FMS_PERF
+               if (storage_type == MS_STORAGE_EXTERNAL) {
+                       msc_check_end_time(&g_mmc_end_time);
+                       msc_check_time_diff(&g_mmc_start_time, &g_mmc_end_time);
+               }
+#endif
+
+               /*set vconf key mmc loading for indicator */
+               if (storage_type == MS_STORAGE_INTERNAL)
+                       _msc_set_db_status(MS_SCANNING_INTERNAL, MS_DB_UPDATED);
+               else if (storage_type == MS_STORAGE_EXTERNAL)
+                       _msc_set_db_status(MS_SCANNING_EXTERNAL, MS_DB_UPDATED);
+
+               if (power_off) {
+                       MSC_DBG_INFO("power off");
+                       goto _POWEROFF;
+               }
+
+               /*disconnect form media db*/
+               if (handle) msc_disconnect_db(&handle);
+
+NEXT:
+               /*Active flush */
+               malloc_trim(0);
+
+               msc_send_scan_result(ret, scan_data);
+
+//             MS_SAFE_FREE(scan_data->msg);
+               MS_SAFE_FREE(scan_data);
+
+               MSC_DBG_INFO("STORAGE SCAN END");
+       }                       /*thread while*/
+
+_POWEROFF:
+//     MS_SAFE_FREE(scan_data->msg);
+       MS_SAFE_FREE(scan_data);
+       if (garray) g_array_free (garray, TRUE);
+       if (handle) msc_disconnect_db(&handle);
+
+       return false;
+}
+
+static void _msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data)
+{
+       MSC_DBG_INFO("path : %s", insert_data->msg);
+
+       if (insert_data->pid == POWEROFF) {
+               g_array_prepend_val(register_array, insert_data);
+       } else {
+               g_array_append_val(register_array, insert_data);
+       }
+}
+
+static bool _is_valid_path(const char *path)
+{
+       if (path == NULL)
+               return false;
+
+       if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) {
+               return true;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
+               return true;
+       } else
+               return false;
+
+       return true;
+}
+
+static int _check_file_path(const char *file_path)
+{
+       int exist;
+       struct stat file_st;
+
+       /* check location of file */
+       /* file must exists under "/opt/usr/media" or "/opt/storage/sdcard" */
+       if(!_is_valid_path(file_path)) {
+               MSC_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) {
+               MSC_DBG_ERR("Not exist path : %s", file_path);
+               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 */
+                       MSC_DBG_ERR("this path is not a file");
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+       } else {
+               MSC_DBG_ERR("stat failed [%s]", strerror(errno));
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+gboolean msc_register_thread(void *data)
+{
+       ms_comm_msg_s *register_data = NULL;
+       ms_comm_msg_s *insert_data = NULL;
+       GArray *register_array = NULL;
+       GArray *path_array = NULL;
+       FILE *fp = NULL;
+       char buf[MS_FILE_PATH_LEN_MAX];
+       char *insert_path = NULL;
+       char *path = NULL;
+       char *file_path = NULL;
+       int path_size;
+       int length;
+       int err;
+       int i;
+       int ret;
+       void **handle = NULL;
+
+       /*create array for processing overlay data*/
+       register_array = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *));
+       if (register_array == NULL) {
+               MSC_DBG_ERR("g_array_new error");
+               return false;
+       }
+
+       while (1) {
+               length  = g_async_queue_length(reg_queue);
+
+               /*updating requests remain*/
+               if (register_array->len != 0 && length == 0) {
+                       register_data = g_array_index(register_array, ms_comm_msg_s*, 0);
+                       g_array_remove_index (register_array, 0);
+                       if (register_data->pid == POWEROFF) {
+                               MSC_DBG_INFO("power off");
+                               goto _POWEROFF;
+                       }
+               } else if (length != 0) {
+                       insert_data = g_async_queue_pop(reg_queue);
+                       _msc_insert_register_request(register_array, insert_data);
+                       continue;
+               } else if (register_array->len == 0 && length == 0) {
+                       /*Threre is no request, Wait until pushung new request*/
+                       insert_data = g_async_queue_pop(reg_queue);
+                       _msc_insert_register_request(register_array, insert_data);
+                       continue;
+               }
+
+               if((register_data->msg_size <= 0) ||(register_data->msg_size > MS_FILE_PATH_LEN_MAX)) {
+                       MSC_DBG_ERR("message size[%d] is wrong", register_data->msg_size);
+                       goto FREE_RESOURCE;
+               } else {
+                       path_size = register_data->msg_size + 1;
+               }
+
+               /* copy from received data */
+               MS_MALLOC(file_path, path_size);
+               if (file_path == NULL) {
+                       MSC_DBG_ERR("MS_MALLOC failed");
+                       goto FREE_RESOURCE;
+               }
+
+               ret = msc_strcopy(file_path, path_size, "%s", register_data->msg);
+               if (ret != MS_MEDIA_ERR_NONE){
+                       MSC_DBG_ERR("msc_strcopy failed : %d", ret);
+                       goto FREE_RESOURCE;
+               }
+
+               /* load the file list from file */
+               fp = fopen(register_data->msg, "rt");
+               if (fp == NULL) {
+                       MSC_DBG_ERR("fopen failed [%s]", strerror(errno));
+                       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) {
+                       MSC_DBG_ERR("g_array_new failed");
+                       goto FREE_RESOURCE;
+               }
+
+               /* read registering file path from stored file */
+               while(fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) {
+                       length = strlen(buf);
+                       buf[length - 1] = '\0';
+                       path = strdup(buf);
+                       MSC_DBG_INFO("insert path : %s [%d]", path, strlen(path));
+                       /* insert getted path to the list */
+                       if (g_array_append_val(path_array, path)  == NULL) {
+                               MSC_DBG_ERR("g_array_append_val failed");
+                               goto FREE_RESOURCE;
+                       }
+               }
+
+               /* connect to media db, if conneting is failed, db updating is stopped */
+               err = msc_connect_db(&handle);
+               if (err != MS_MEDIA_ERR_NONE)
+                       goto FREE_RESOURCE;
+
+               /*start db updating */
+               /*call for bundle commit*/
+               msc_register_start(handle);
+
+               /* 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);
+                       /* check the file */
+                       /* it is really existing */
+                       /* it is in /opt/usr/media or /opt/storage/sdcard */
+                       /* it is really regular file */
+                       ret = _check_file_path(insert_path);
+                       if (ret != MS_MEDIA_ERR_NONE) {
+                               MSC_DBG_ERR("Can't insert the meta of the path");
+                               continue;
+                       }
+
+                       /* insert to db */
+                       err = msc_insert_item_batch(handle, insert_path);
+
+                       if (power_off) {
+                               MSC_DBG_INFO("power off");
+                               /*call for bundle commit*/
+                               msc_register_end(handle);
+                               goto _POWEROFF;
+                       }
+               }
+
+               /*call for bundle commit*/
+               msc_register_end(handle);
+
+               /*disconnect form media db*/
+               if (handle) msc_disconnect_db(&handle);
+
+               /*Active flush */
+               malloc_trim(0);
+
+               msc_send_register_result(MS_MEDIA_ERR_NONE, register_data);
+FREE_RESOURCE:
+               if (path_array) {
+                       g_array_free(path_array, TRUE);
+                       path_array = NULL;
+               }
+
+               MS_SAFE_FREE(file_path);
+               MS_SAFE_FREE(register_data);
+
+               if(fp) fclose(fp);
+               fp = NULL;
+       }                       /*thread while*/
+
+_POWEROFF:
+       MS_SAFE_FREE(file_path);
+       MS_SAFE_FREE(register_data);
+       if (register_array) g_array_free (register_array, TRUE);
+       if (path_array) g_array_free (path_array, TRUE);
+       if (handle) msc_disconnect_db(&handle);
+
+       if(fp) fclose(fp);
+
+       return false;
+}
diff --git a/common/scanner/media-scanner-socket.c b/common/scanner/media-scanner-socket.c
new file mode 100755 (executable)
index 0000000..0608cdb
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-thumb.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <malloc.h>
+#include <vconf.h>
+
+#include "media-util.h"
+
+#include "media-server-ipc.h"
+#include "media-server-types.h"
+#include "media-scanner-dbg.h"
+#include "media-scanner-db-svc.h"
+#include "media-scanner-utils.h"
+#include "media-scanner-socket.h"
+
+extern GAsyncQueue *storage_queue;
+extern GAsyncQueue *scan_queue;
+extern GAsyncQueue *reg_queue;
+GMutex *receive_mutex;
+
+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 pid = -1;
+       int ret = MS_MEDIA_ERR_NONE;
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MSC_DBG_ERR("sock fd is invalid!");
+               return TRUE;
+       }
+
+       MS_MALLOC(recv_msg, sizeof(ms_comm_msg_s));
+       if (recv_msg == NULL) {
+               MSC_DBG_ERR("MS_MALLOC failed");
+               return TRUE;
+       }
+
+       /* Socket is readable */
+       ret = ms_ipc_receive_message(sockfd, recv_msg, sizeof(*recv_msg), NULL, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MS_SAFE_FREE(recv_msg);
+               return TRUE;
+       }
+
+       MSC_DBG_INFO("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;
+       pid = recv_msg->pid;
+
+       /* request bulk insert*/
+       if (req_num == MS_MSG_BULK_INSERT) {
+               MSC_DBG_INFO("BULK INSERT");
+               g_async_queue_push(reg_queue, GINT_TO_POINTER(recv_msg));
+       } else if (req_num == MS_MSG_DIRECTORY_SCANNING ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) {
+               /* this request from another apps */
+               /* set the scan data for scanning thread */
+               g_async_queue_push(scan_queue, GINT_TO_POINTER(recv_msg));
+       } else if (req_num == MS_MSG_STORAGE_ALL ||req_num == MS_MSG_STORAGE_PARTIAL || req_num == MS_MSG_STORAGE_INVALID) {
+               /* this request from media-server */
+               g_async_queue_push(storage_queue, GINT_TO_POINTER(recv_msg));
+       } else {
+               MSC_DBG_ERR("THIS REQUEST IS INVALID %d", req_num);
+               MS_SAFE_FREE(recv_msg);
+               return TRUE;
+       }
+
+       /*Active flush */
+       malloc_trim(0);
+
+       return TRUE;
+}
+
+int msc_send_scan_result(int result, ms_comm_msg_s *scan_data)
+{
+       int ret;
+       int res = MS_MEDIA_ERR_NONE;
+       int sockfd = -1;
+       ms_comm_msg_s send_msg;
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
+       if (ret != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_SOCKET_CONN;
+
+       /* send ready message */
+       memset(&send_msg, 0x0, sizeof(ms_comm_msg_s));
+       send_msg.msg_type = MS_MSG_SCANNER_RESULT;
+       send_msg.pid = scan_data->pid;
+       send_msg.result = result;
+       send_msg.msg_size = strlen(scan_data->msg);
+       strncpy(send_msg.msg, scan_data->msg, send_msg.msg_size);
+
+       ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL);
+       if (ret != MS_MEDIA_ERR_NONE)
+               res = ret;
+
+       close(sockfd);
+
+       return res;
+}
+
+int msc_send_register_result(int result, ms_comm_msg_s *reg_data)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int sockfd = -1;
+       ms_comm_msg_s send_msg;
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
+       if (ret != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_SOCKET_CONN;
+
+       /* send ready message */
+       memset(&send_msg, 0x0, sizeof(ms_comm_msg_s));
+       send_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT;
+       send_msg.pid = reg_data->pid;
+       send_msg.result = result;
+       send_msg.msg_size = reg_data->msg_size;
+       strncpy(send_msg.msg, reg_data->msg, send_msg.msg_size);
+
+       ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL);
+
+       close(sockfd);
+
+       return ret;
+}
+
+int msc_send_ready(void)
+{
+       int ret;
+       int res = MS_MEDIA_ERR_NONE;
+       int sockfd = -1;
+       ms_comm_msg_s send_msg;
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
+       if (ret != MS_MEDIA_ERR_NONE)
+               return MS_MEDIA_ERR_SOCKET_CONN;
+
+       /* send ready message */
+       memset(&send_msg, 0, sizeof(send_msg));
+       send_msg.msg_type = MS_MSG_SCANNER_READY;
+       
+       ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL);
+       if (ret != MS_MEDIA_ERR_NONE)
+               res = ret;
+
+       close(sockfd);
+
+       return res;
+}
+
diff --git a/common/scanner/media-scanner-utils.c b/common/scanner/media-scanner-utils.c
new file mode 100755 (executable)
index 0000000..ae20bcf
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-utils.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief       This file implements main database operation.
+ */
+
+#include <dirent.h>
+#include <malloc.h>
+#include <vconf.h>
+
+#include "media-util.h"
+#include "media-scanner-dbg.h"
+#include "media-scanner-utils.h"
+#include "media-scanner-drm.h"
+
+#ifdef FMS_PERF
+#include <sys/time.h>
+#define MILLION 1000000L
+struct timeval g_mmc_start_time;
+struct timeval g_mmc_end_time;
+#endif
+
+#define MMC_INFO_SIZE 256
+
+extern int mmc_state;
+extern GAsyncQueue *storage_queue;
+extern GAsyncQueue *scan_queue;
+
+
+
+#ifdef FMS_PERF
+void
+msc_check_start_time(struct timeval *start_time)
+{
+       gettimeofday(start_time, NULL);
+}
+
+void
+msc_check_end_time(struct timeval *end_time)
+{
+       gettimeofday(end_time, NULL);
+}
+
+void
+msc_check_time_diff(struct timeval *start_time, struct timeval *end_time)
+{
+       struct timeval time;
+       long difftime;
+
+       time.tv_sec = end_time->tv_sec - start_time->tv_sec;
+       time.tv_usec = end_time->tv_usec - start_time->tv_usec;
+       difftime = MILLION * time.tv_sec + time.tv_usec;
+       MSC_DBG_INFO("The function_to_time took %ld microseconds or %f seconds.",
+              difftime, difftime / (double)MILLION);
+}
+#endif
+
+bool
+msc_is_mmc_inserted(void)
+{
+       int data = -1;
+       msc_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &data);
+       if (data != VCONFKEY_SYSMAN_MMC_MOUNTED) {
+               return false;
+       } else {
+               return true;
+       }
+}
+
+int
+_msc_update_mmc_info(const char *cid)
+{
+       bool res;
+
+       if (cid == NULL) {
+               MSC_DBG_ERR("Parameters are invalid");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res = msc_config_set_str(MS_MMC_INFO_KEY, cid);
+       if (!res) {
+               MSC_DBG_ERR("fail to get MS_MMC_INFO_KEY");
+               return MS_MEDIA_ERR_VCONF_SET_FAIL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int
+_msc_get_contents(const char *filename, char *buf)
+{
+       FILE *fp;
+
+       fp = fopen(filename, "rt");
+       if (fp == NULL) {
+               MSC_DBG_ERR("fp is NULL. file name : %s", filename);
+               return MS_MEDIA_ERR_FILE_OPEN_FAIL;
+       }
+
+       if (fgets(buf, 255, fp) == NULL)
+               MSC_DBG_ERR("fgets failed");
+
+       fclose(fp);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+/*need optimize*/
+int
+_msc_get_mmc_info(char *cid)
+{
+       int i;
+       int j;
+       int len;
+       int err = -1;
+       bool getdata = false;
+       bool bHasColon = false;
+       char path[MS_FILE_PATH_LEN_MAX] = { 0 };
+       char mmcpath[MS_FILE_PATH_LEN_MAX] = { 0 };
+
+       DIR *dp;
+       struct dirent ent;
+       struct dirent *res = NULL;
+
+       /* mmcblk0 and mmcblk1 is reserved for movinand */
+       for (j = 1; j < 3; j++) {
+               len = snprintf(mmcpath, MS_FILE_PATH_LEN_MAX, "/sys/class/mmc_host/mmc%d/", j);
+               if (len < 0) {
+                       MSC_DBG_ERR("FAIL : snprintf");
+                       return MS_MEDIA_ERR_INTERNAL;
+               }
+               else {
+                       mmcpath[len] = '\0';
+               }
+
+               dp = opendir(mmcpath);
+               if (dp == NULL) {
+                       MSC_DBG_ERR("dp is NULL");
+                       return MS_MEDIA_ERR_DIR_OPEN_FAIL;
+               }
+
+               while (!readdir_r(dp, &ent, &res)) {
+                        /*end of read dir*/
+                       if (res == NULL)
+                               break;
+
+                       bHasColon = false;
+                       if (ent.d_name[0] == '.')
+                               continue;
+
+                       if (ent.d_type == DT_DIR) {
+                               /*ent->d_name is including ':' */
+                               for (i = 0; i < strlen(ent.d_name); i++) {
+                                       if (ent.d_name[i] == ':') {
+                                               bHasColon = true;
+                                               break;
+                                       }
+                               }
+
+                               if (bHasColon) {
+                                       /*check serial */
+                                       err = msc_strappend(path, sizeof(path), "%s%s/cid", mmcpath, ent.d_name);
+                                       if (err < 0) {
+                                               MSC_DBG_ERR("ms_strappend error : %d", err);
+                                               continue;
+                                       }
+
+                                       if (_msc_get_contents(path, cid) != MS_MEDIA_ERR_NONE)
+                                               break;
+                                       else
+                                               getdata = true;
+                               }
+                       }
+               }
+               closedir(dp);
+
+               if (getdata == true) {
+                       break;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_update_mmc_info(void)
+{
+       int err;
+       char cid[MMC_INFO_SIZE] = { 0 };
+
+       err = _msc_get_mmc_info(cid);
+
+       err = _msc_update_mmc_info(cid);
+
+       /*Active flush */
+       if (!malloc_trim(0))
+               MSC_DBG_ERR("malloc_trim is failed");
+
+       return err;
+}
+
+bool
+_msc_check_mmc_info(const char *cid)
+{
+       char pre_mmc_info[MMC_INFO_SIZE] = { 0 };
+       bool res = false;
+
+       if (cid == NULL) {
+               MSC_DBG_ERR("Parameters are invalid");
+               return false;
+       }
+
+       res = msc_config_get_str(MS_MMC_INFO_KEY, pre_mmc_info);
+       if (!res) {
+               MSC_DBG_ERR("fail to get MS_MMC_INFO_KEY");
+               return false;
+       }
+
+       MSC_DBG_INFO("Last MMC info     = %s", pre_mmc_info);
+       MSC_DBG_INFO("Current MMC info = %s", cid);
+
+       if (strcmp(pre_mmc_info, cid) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+
+ms_dir_scan_type_t
+msc_get_mmc_state(void)
+{
+       char cid[MMC_INFO_SIZE] = { 0 };
+       ms_dir_scan_type_t ret = MS_SCAN_ALL;
+
+       /*get new info */
+       _msc_get_mmc_info(cid);
+
+       /*check it's same mmc */
+       if (_msc_check_mmc_info(cid)) {
+               ret = MS_SCAN_PART;
+       }
+
+       return ret;
+}
+
+void
+msc_mmc_vconf_cb(void *data)
+{
+       int status = 0;
+       ms_comm_msg_s *scan_msg;
+       ms_dir_scan_type_t scan_type = MS_SCAN_PART;
+
+       if (!msc_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) {
+               MSC_DBG_ERR("Get VCONFKEY_SYSMAN_MMC_STATUS failed.");
+       }
+
+       MSC_DBG_INFO("VCONFKEY_SYSMAN_MMC_STATUS :%d", status);
+
+       mmc_state = status;
+
+       MS_MALLOC(scan_msg, sizeof(ms_comm_msg_s));
+
+       if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
+               mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) {
+
+               if (!msc_drm_extract_ext_memory())
+                       MSC_DBG_ERR("ms_drm_extract_ext_memory failed");
+
+               scan_type = MS_SCAN_INVALID;
+       } else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) {
+
+               if (!msc_drm_insert_ext_memory())
+                       MSC_DBG_ERR("ms_drm_insert_ext_memory failed");
+
+               scan_type = msc_get_mmc_state();
+       }
+
+       switch (scan_type) {
+               case MS_SCAN_ALL:
+                       scan_msg->msg_type = MS_MSG_STORAGE_ALL;
+                       break;
+               case MS_SCAN_PART:
+                       scan_msg->msg_type = MS_MSG_STORAGE_PARTIAL;
+                       break;
+               case MS_SCAN_INVALID:
+                       scan_msg->msg_type = MS_MSG_STORAGE_INVALID;
+                       break;
+       }
+
+       scan_msg->pid = 0;
+       scan_msg->msg_size = strlen(MEDIA_ROOT_PATH_SDCARD);
+       msc_strcopy(scan_msg->msg, scan_msg->msg_size+1, "%s", MEDIA_ROOT_PATH_SDCARD);
+
+       MSC_DBG_INFO("ms_get_mmc_state is %d", scan_msg->msg_type);
+
+       g_async_queue_push(storage_queue, GINT_TO_POINTER(scan_msg));
+
+       return;
+}
+
+/*CAUTION : Before using this function, Have to allocate static memory of ret_path*/
+/*And the array length does not over MS_FILE_PATH_LEN_MAX*/
+/*for example : char path[MS_FILE_PATH_LEN_MAX] = {0};*/
+int
+msc_get_full_path_from_node(ms_dir_scan_info * const node, char *ret_path, int depth)
+{
+       int i = 0;
+       int path_length = 0;
+       int length = 0;
+       ms_dir_scan_info *cur_node;
+       char **path_array;
+
+       if (depth < 0) {
+               MSC_DBG_ERR("depth < 0");
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       MS_MALLOC(path_array, sizeof(char*) * (depth + 1));
+
+       cur_node = node;
+
+       while (1) {
+               path_array[i] = cur_node->name;
+               if (cur_node->parent == NULL)
+                       break;
+
+               cur_node = cur_node->parent;
+               i++;
+       }
+
+       for(i = depth ; i >= 0 ; i --) {
+               length = strlen(path_array[i]);
+
+               if (path_length + length > MS_FILE_PATH_LEN_MAX) {
+                       MSC_DBG_ERR("This is invalid path, %s, %d", node->name, depth);
+                       MS_SAFE_FREE(path_array);
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+
+               strncpy(ret_path+path_length, path_array[i], length);
+               path_length += length;
+
+               ret_path[path_length] = '/';
+               path_length ++;
+       }
+
+       ret_path[-- path_length] = '\0';
+
+       MS_SAFE_FREE(path_array);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+ms_storage_type_t
+msc_get_storage_type_by_full(const char *path)
+{
+       if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) {
+               return MS_STORAGE_INTERNAL;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
+               return MS_STORAGE_EXTERNAL;
+       } else
+               return MS_MEDIA_ERR_INVALID_PATH;
+}
+
+int
+msc_strappend(char *res, const int size, const char *pattern,
+            const char *str1, const char *str2)
+{
+       int len = 0;
+       int real_size = size - 1;
+
+       if (!res ||!pattern || !str1 ||!str2 )
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       if (real_size < (strlen(str1) + strlen(str2)))
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       len = snprintf(res, real_size, pattern, str1, str2);
+       if (len < 0) {
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res[len] = '\0';
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int
+msc_strcopy(char *res, const int size, const char *pattern, const char *str1)
+{
+       int len = 0;
+       int real_size = size;
+
+       if (!res || !pattern || !str1)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       if (real_size < strlen(str1))
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       len = snprintf(res, real_size, pattern, str1);
+       if (len < 0) {
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       res[len] = '\0';
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+bool
+msc_config_get_int(const char *key, int *value)
+{
+       int err;
+
+       if (!key || !value) {
+               MSC_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       err = vconf_get_int(key, value);
+       if (err == 0)
+               return true;
+       else if (err == -1)
+               return false;
+       else
+               MSC_DBG_ERR("Unexpected error code: %d", err);
+
+       return false;
+}
+
+bool
+msc_config_set_int(const char *key, int value)
+{
+       int err;
+
+       if (!key) {
+               MSC_DBG_ERR("Arguments key is NULL");
+               return false;
+       }
+
+       err = vconf_set_int(key, value);
+       if (err == 0)
+               return true;
+       else if (err == -1)
+               return false;
+       else
+               MSC_DBG_ERR("Unexpected error code: %d", err);
+
+       return false;
+}
+
+bool
+msc_config_get_str(const char *key, char *value)
+{
+       char *res;
+       if (!key || !value) {
+               MSC_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       res = vconf_get_str(key);
+       if (res) {
+               strncpy(value, res, strlen(res) + 1);
+               return true;
+       }
+
+       return false;
+}
+
+bool
+msc_config_set_str(const char *key, const char *value)
+{
+       int err;
+
+       if (!key || !value) {
+               MSC_DBG_ERR("Arguments key or value is NULL");
+               return false;
+       }
+
+       err = vconf_set_str(key, value);
+       if (err == 0)
+               return true;
+       else
+               MSC_DBG_ERR("fail to vconf_set_str %d", err);
+
+       return false;
+}
+
diff --git a/common/scanner/media-scanner.c b/common/scanner/media-scanner.c
new file mode 100755 (executable)
index 0000000..604a185
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ *  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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-server-main.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <dirent.h>
+#include <vconf.h>
+#include <heynoti.h>
+
+#include "media-util.h"
+#include "media-scanner-dbg.h"
+#include "media-scanner-utils.h"
+#include "media-scanner-db-svc.h"
+#include "media-scanner-scan.h"
+#include "media-scanner-socket.h"
+#include "media-scanner-drm.h"
+
+#define APP_NAME "media-scanner"
+
+static int heynoti_id;
+extern int mmc_state;
+
+extern GAsyncQueue *storage_queue;
+extern GAsyncQueue *scan_queue;
+extern GAsyncQueue *reg_queue;
+extern GMutex *db_mutex;
+extern GMutex *receive_mutex;
+bool power_off; /*If this is TRUE, poweroff notification received*/
+
+static GMainLoop *scanner_mainloop = NULL;
+
+bool check_process(void)
+{
+       DIR *pdir;
+       struct dirent pinfo;
+       struct dirent *result = NULL;
+       bool ret = false;
+       int find_pid = 0;
+       pid_t current_pid = 0;
+
+       current_pid = getpid();
+
+       pdir = opendir("/proc");
+       if (pdir == NULL) {
+               MSC_DBG_ERR("err: NO_DIR\n");
+               return 0;
+       }
+
+       while (!readdir_r(pdir, &pinfo, &result)) {
+               if (result == NULL)
+                       break;
+
+               if (pinfo.d_type != 4 || pinfo.d_name[0] == '.'
+                   || pinfo.d_name[0] > 57)
+                       continue;
+
+               FILE *fp;
+               char buff[128];
+               char path[128];
+
+               msc_strcopy(path, sizeof(path), "/proc/%s/status", pinfo.d_name);
+               fp = fopen(path, "rt");
+               if (fp) {
+                       if (fgets(buff, 128, fp) == NULL)
+                               MSC_DBG_ERR("fgets failed");
+                       fclose(fp);
+
+                       if (strstr(buff, APP_NAME)) {
+                               find_pid = atoi(pinfo.d_name);
+                               if (find_pid == current_pid)
+                                       ret = true;
+                               else {
+                                       ret = false;
+                                       break;
+                               }
+                       }
+               } else {
+                       MSC_DBG_ERR("Can't read file [%s]", path);
+               }
+       }
+
+       closedir(pdir);
+
+       return ret;
+}
+
+void init_process()
+{
+
+}
+
+static void _power_off_cb(void* data)
+{
+       ms_comm_msg_s *scan_data;
+       ms_comm_msg_s *reg_data;
+
+       MSC_DBG_INFO("++++++++++++++++++++++++++++++++++++++");
+       MSC_DBG_INFO("POWER OFF");
+       MSC_DBG_INFO("++++++++++++++++++++++++++++++++++++++");
+
+       power_off = true;
+
+       if (scan_queue) {
+               /*notify to scannig thread*/
+               MS_MALLOC(scan_data, sizeof(ms_comm_msg_s));
+               scan_data->pid = POWEROFF;
+               g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data));
+       }
+
+       if (reg_queue) {
+               /*notify to register thread*/
+               MS_MALLOC(reg_data, sizeof(ms_comm_msg_s));
+               reg_data->pid = POWEROFF;
+               g_async_queue_push(reg_queue, GINT_TO_POINTER(reg_data));
+       }
+
+       if (g_main_loop_is_running(scanner_mainloop)) g_main_loop_quit(scanner_mainloop);
+}
+
+int main(int argc, char **argv)
+{
+       GThread *storage_scan_thread = NULL;
+       GThread *scan_thread = NULL;
+       GThread *register_thread = NULL;
+       GSource *source = NULL;
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+
+       int sockfd = -1;
+       int err;
+
+#if 0 /* temporary */
+       check_result = check_process();
+       if (check_result == false)
+               exit(0);
+#endif
+       if (!g_thread_supported()) {
+               g_thread_init(NULL);
+       }
+
+       /*Init main loop*/
+       scanner_mainloop = g_main_loop_new(NULL, FALSE);
+
+       /*heynoti for power off*/
+       if ((heynoti_id = heynoti_init()) <0) {
+               MSC_DBG_INFO("heynoti_init failed");
+       } else {
+               err = heynoti_subscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb, NULL);
+               if (err < 0)
+                       MSC_DBG_INFO("heynoti_subscribe failed");
+
+               err = heynoti_attach_handler(heynoti_id);
+               if (err < 0)
+                       MSC_DBG_INFO("heynoti_attach_handler failed");
+       }
+
+       /*load functions from plusin(s)*/
+       err = msc_load_functions();
+       if (err != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("function load failed");
+               exit(0);
+       }
+
+       /*Init for register file*/
+       /*These are a communicator for thread*/
+       if (!scan_queue) scan_queue = g_async_queue_new();
+       if (!reg_queue) reg_queue = g_async_queue_new();
+       if (!storage_queue) storage_queue = g_async_queue_new();
+
+       /*Init mutex variable*/
+       if (!db_mutex) db_mutex = g_mutex_new();
+
+       /*prepare socket*/
+       /* Create and bind new UDP socket */
+       if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_SCAN_DAEMON_PORT, &sockfd)
+               != MS_MEDIA_ERR_NONE) {
+               MSC_DBG_ERR("Failed to create socket\n");
+               exit(0);
+       } else {
+               context = g_main_loop_get_context(scanner_mainloop);
+
+               /* Create new channel to watch udp socket */
+               channel = g_io_channel_unix_new(sockfd);
+               source = g_io_create_watch(channel, G_IO_IN);
+
+               /* Set callback to be called when socket 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);
+
+       /*set vconf callback function*/
+       err = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, (vconf_callback_fn) msc_mmc_vconf_cb, NULL);
+       if (err == -1)
+               MSC_DBG_ERR("add call back function for event %s fails", VCONFKEY_SYSMAN_MMC_STATUS);
+
+       if (msc_is_mmc_inserted()) {
+               mmc_state = VCONFKEY_SYSMAN_MMC_MOUNTED;
+       }
+
+       MSC_DBG_INFO("scanner is ready");
+
+       msc_send_ready();
+
+       MSC_DBG_INFO("*****************************************");
+       MSC_DBG_INFO("*** Scanner is running ***");
+       MSC_DBG_INFO("*****************************************");
+
+       g_main_loop_run(scanner_mainloop);
+
+       g_thread_join (scan_thread);
+       g_thread_join (register_thread);
+       g_thread_join (storage_scan_thread);
+
+       if (power_off) {
+               g_io_channel_shutdown(channel, FALSE, NULL);
+               g_io_channel_unref(channel);
+       }
+
+       heynoti_unsubscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb);
+       heynoti_close(heynoti_id);
+
+       if (scan_queue) g_async_queue_unref(scan_queue);
+       if (reg_queue) g_async_queue_unref(reg_queue);
+       if (storage_queue) g_async_queue_unref(storage_queue);
+
+       /*Clear db mutex variable*/
+       if (db_mutex) g_mutex_free (db_mutex);
+
+       /*close socket*/
+       close(sockfd);
+
+       /*unload functions*/
+       msc_unload_functions();
+
+       MSC_DBG_INFO("SCANNER IS END");
+
+       exit(0);
+}
+
diff --git a/config.in b/config.in
new file mode 100644 (file)
index 0000000..e4e5149
--- /dev/null
+++ b/config.in
@@ -0,0 +1,161 @@
+/* config.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if `lstat' has the bug that it succeeds when given the
+   zero-length file name argument. */
+#undef HAVE_LSTAT_EMPTY_STRING_BUG
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#undef HAVE_SYS_VFS_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+   slash. */
+#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..ab227c9
--- /dev/null
@@ -0,0 +1,128 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT([media-server], [1.0])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_HEADERS([config.h:config.in])
+
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+# for platform setting
+AC_CONFIG_MACRO_DIR([m4])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+
+# Check target
+if ! (test "x$ARCH" = "xarmel" -o "x$ARCH" = "xi386"); then
+    echo "$ARCH"
+#      ARCH=ARM
+fi
+
+#if test "x$MACHINE" = "xfloater"; then
+    CPPFLAGS="$CPPFLAGS -D _FM_GENERIC_ -D EXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\""
+    echo ""
+    echo $CPPFLAGS
+    echo "### check point ###"
+    echo ""
+#fi
+
+CPPFLAGS="${CPPFLAGS} -DRND_LINUX"
+
+# FMS_DEBUG - File Manager Service debug options
+# To open debug options:
+# export FMS_DEBUG=1 or configure --enable-debug
+AC_ARG_ENABLE([debug],
+              [AS_HELP_STRING([--enable-debug], [Enable debug options])],
+              [case "x$enableval" in
+               xyes) debug=true;;
+               xno)  debug=false;;
+               *)      AC_MSG_ERROR([Bad value %enableval for --enable-debug]);;
+               esac],
+              [debug=false])
+if test "x$debug" = "xtrue" -o "x$FMS_DEBUG" = "x1"; then
+    FMS_DEBUG_FLAGS="-D FEXPLORER_DEBUG -g"
+else
+    FMS_DEBUG_FLAGS=""
+fi
+AC_SUBST(FMS_DEBUG_FLAGS)
+
+# Checks for libraries.
+PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
+AC_SUBST(GTHREAD_CFLAGS)
+AC_SUBST(GTHREAD_LIBS)
+
+PKG_CHECK_MODULES(GLIB, glib-2.0)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(DLOG, dlog)
+AC_SUBST(DLOG_CFLAGS)
+AC_SUBST(DLOG_LIBS)
+
+PKG_CHECK_MODULES(DRM_SERVICE, drm-client)
+AC_SUBST(DRM_SERVICE_CFLAGS)
+AC_SUBST(DRM_SERVICE_LIBS)
+
+PKG_CHECK_MODULES(PHONESTATUS, vconf)
+AC_SUBST(PHONESTATUS_CFLAGS)
+AC_SUBST(PHONESTATUS_LIBS)
+
+PKG_CHECK_MODULES(AUL, aul)
+AC_SUBST(AUL_CFLAGS)
+AC_SUBST(AUL_LIBS)
+
+PKG_CHECK_MODULES(LIBPMCONTROL, pmapi)
+AC_SUBST(LIBPMCONTROL_CFLAGS)
+AC_SUBST(LIBPMCONTROL_LIBS)
+
+PKG_CHECK_MODULES(HEYNOTI, heynoti)
+AC_SUBST(HEYNOTI_CFLAGS)
+AC_SUBST(HEYNOTI_LIBS)
+
+PKG_CHECK_MODULES(DBUS, dbus-glib-1)
+AC_SUBST(DBUS_CFLAGS)
+AC_SUBST(DBUS_LIBS)
+
+PKG_CHECK_MODULES(SQLITE, sqlite3)
+AC_SUBST(SQLITE3_CFLAGS)
+AC_SUBST(SQLITE3_LIBS)
+
+PKG_CHECK_MODULES(DB_UTIL, db-util)
+AC_SUBST(DB_UTIL_CFLAGS)
+AC_SUBST(DB_UTIL_LIBS)
+
+#ticker noti library
+PKG_CHECK_MODULES(STATUS, notification)
+AC_SUBST(STATUS_CFLAGS)
+AC_SUBST(STATUS_LIBS)
+
+#Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/file.h sys/vfs.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_CLOSEDIR_VOID
+AC_FUNC_FORK
+AC_FUNC_LSTAT
+AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([gettimeofday memset mkdir strcasecmp strstr])
+
+AC_CONFIG_FILES([Makefile
+                                libmedia-utils.pc
+                                ])
+AC_OUTPUT
diff --git a/data/mediasvr b/data/mediasvr
new file mode 100755 (executable)
index 0000000..d109017
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+/usr/bin/media-server&
+
diff --git a/lib/include/media-server-ipc.h b/lib/include/media-server-ipc.h
new file mode 100755 (executable)
index 0000000..bebf961
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines IPC protocol
+ *
+ * @file               media-server-ipc.h
+ * @author     Haejeong Kim(backto.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_SERVER_IPC_H_
+#define _MEDIA_SERVER_IPC_H_
+
+#define MS_TIMEOUT_SEC_3                                       3               /**< Response from Server time out */
+#define MS_TIMEOUT_SEC_10                                      10              /**< Response from Server time out */
+#define MS_TIMEOUT_SEC_20                      20              /**< Response from Media server time out */
+
+#define MS_SCANNER_PORT                        1001            /**< Directory Scanner */
+#define MS_DB_UPDATE_PORT                      1002            /**< Media DB Update */
+#define MS_THUMB_CREATOR_PORT  1003            /**< Create thumbnail */
+#define MS_THUMB_DAEMON_PORT   1004            /**< Port of Thumbnail server */
+#define MS_THUMB_COMM_PORT             1005            /**< Port of communication between creator and server */
+#define MS_DB_BATCH_UPDATE_PORT                1006    /**< Media DB batch update */
+#define MS_SCAN_DAEMON_PORT           1007             /**< Port of communication between scanner and server */
+#define MS_SCAN_COMM_PORT                     1008             /**< Port of communication between scanner and server */
+
+#define MAX_MSG_SIZE                           4096
+
+typedef enum{
+       MS_MSG_DB_UPDATE = 0,           /**< Media DB Update */
+       MS_MSG_DB_UPDATE_BATCH_START,           /**< Start of media DB update batch */
+       MS_MSG_DB_UPDATE_BATCH,                         /**< Perform of media DB update batch */
+       MS_MSG_DB_UPDATE_BATCH_END,             /**< End of media DB update batch */
+       MS_MSG_DIRECTORY_SCANNING,                      /**< Non recursive Directory Scan and Media DB Update*/
+       MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE,/**< Recursive Directory Scan and Media DB Update*/
+       MS_MSG_BULK_INSERT,                                     /**< Request bulk insert */
+       MS_MSG_STORAGE_ALL,
+       MS_MSG_STORAGE_PARTIAL,
+       MS_MSG_STORAGE_INVALID,
+       MS_MSG_THUMB_SERVER_READY,                      /**< Ready from thumbnail server */
+       MS_MSG_THUMB_EXTRACT_ALL_DONE,          /**< Done of all-thumbnail extracting */
+       MS_MSG_SCANNER_READY,                           /**< Ready from media scanner */
+       MS_MSG_SCANNER_RESULT,                          /**< Result of directory scanning */
+       MS_MSG_SCANNER_BULK_RESULT,                     /**< Request bulk insert */
+       MS_MSG_MAX                                                      /**< Invalid msg type */
+}ms_msg_type_e;
+
+typedef struct
+{
+       ms_msg_type_e msg_type;
+       int pid;
+       int result;
+       size_t msg_size; /*this is size of message below and this does not include the terminationg null byte ('\0'). */
+       char msg[MAX_MSG_SIZE];
+}ms_comm_msg_s;
+
+typedef enum {
+       CLIENT_SOCKET,
+       SERVER_SOCKET
+} ms_socket_type_e;
+
+typedef enum {
+       MS_MEDIA_THUMB_LARGE,
+       MS_MEDIA_THUMB_SMALL,
+} ms_thumb_type_e;
+
+typedef struct {
+       ms_msg_type_e msg_type;
+} ms_thumb_server_msg;
+
+typedef struct _thumbMsg{
+       int msg_type;
+       int thumb_type;
+       int status;
+       int pid;
+       int thumb_size;
+       int thumb_width;
+       int thumb_height;
+       int origin_width;
+       int origin_height;
+       int origin_path_size;
+       int dest_path_size;
+       char org_path[MAX_MSG_SIZE];
+       char dst_path[MAX_MSG_SIZE];
+} thumbMsg;
+
+
+#endif /*_MEDIA_SERVER_IPC_H_*/
diff --git a/lib/include/media-util-db.h b/lib/include/media-util-db.h
new file mode 100755 (executable)
index 0000000..435f74a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-noti.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+ #ifndef _MEDIA_UTIL_DB_H_
+#define _MEDIA_UTIL_DB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void MediaDBHandle;            /**< Handle */
+
+int media_db_connect(MediaDBHandle **handle);
+
+int media_db_disconnect(MediaDBHandle *handle);
+
+int media_db_request_update_db(const char *query_str);
+
+int media_db_request_update_db_batch_start(const char *query_str);
+
+int media_db_request_update_db_batch(const char *query_str);
+
+int media_db_request_update_db_batch_end(const char *query_str);
+
+int media_db_request_directory_scan(const char *directory_path);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_MEDIA_UTIL_DB_H_*/
diff --git a/lib/include/media-util-dbg.h b/lib/include/media-util-dbg.h
new file mode 100755 (executable)
index 0000000..eef9866
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-dbg.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_UTIL_DBG_H_
+#define _MEDIA_UTIL_DBG_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "MEDIA_UTIL"
+
+#define FONT_COLOR_RESET    "\033[0m"
+#define FONT_COLOR_RED      "\033[31m"
+#define FONT_COLOR_GREEN    "\033[32m"
+#define FONT_COLOR_YELLOW   "\033[33m"
+#define FONT_COLOR_BLUE     "\033[34m"
+#define FONT_COLOR_PURPLE   "\033[35m"
+#define FONT_COLOR_CYAN     "\033[36m"
+#define FONT_COLOR_GRAY     "\033[37m"
+
+#define MSAPI_DBG(fmt, arg...) do { \
+                       LOGD(FONT_COLOR_RESET fmt, ##arg);     \
+               } while (0)
+
+#define MSAPI_DBG_INFO(fmt, arg...) do { \
+                       LOGD(FONT_COLOR_GREEN fmt, ##arg);     \
+               } while (0)
+
+#define MSAPI_DBG_ERR(fmt, arg...) do { \
+                       LOGE(FONT_COLOR_RED fmt, ##arg);     \
+               } while (0)
+
+#define MSAPI_DBG_FUNC() do { \
+                       LOGD(FONT_COLOR_RESET);     \
+               } while (0)
+
+
+#define MSAPI_RETV_IF(expr, val) do { \
+                       if(expr) { \
+                               LOGE(FONT_COLOR_RED);     \
+                               return (val); \
+                       } \
+               } while (0)
+
+#define MSAPI_RETVM_IF(expr, val, fmt, arg...) do { \
+                       if(expr) { \
+                               LOGE(FONT_COLOR_RED fmt, ##arg);        \
+                               return (val); \
+                       } \
+               } while (0)
+
+#endif /*_MEDIA_UTIL_DBG_H_*/
diff --git a/lib/include/media-util-err.h b/lib/include/media-util-err.h
new file mode 100755 (executable)
index 0000000..bcbba3f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-err.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#ifndef _MEDIA_UTIL_ERR_H_
+#define _MEDIA_UTIL_ERR_H_
+
+#define MS_MEDIA_ERR_NONE 0
+
+/*internal operation error*/
+#define MS_MEDIA_ERR_INTERNAL                          -1
+#define MS_MEDIA_ERR_INVALID_CONTENT           -2   /**< Invalid content */
+#define MS_MEDIA_ERR_INVALID_PARAMETER                 -3   /**< invalid parameter(s) */
+#define MS_MEDIA_ERR_INVALID_PATH                      -4   /**< Invalid path */
+#define MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL      -5   /**< exception of memory allocation */
+#define MS_MEDIA_ERR_DIR_OPEN_FAIL                     -6   /**< exception of dir open*/
+#define MS_MEDIA_ERR_FILE_OPEN_FAIL                    -7   /**< exception of file doesn't exist*/
+
+/*DB operation error*/
+#define MS_MEDIA_ERR_DB_CONNECT_FAIL           -11  /**< connecting database fails */
+#define MS_MEDIA_ERR_DB_DISCONNECT_FAIL                -12  /**< disconnecting database fails */
+#define MS_MEDIA_ERR_DB_INSERT_FAIL                    -13  /**< inserting record fails */
+#define MS_MEDIA_ERR_DB_DELETE_FAIL                    -14  /**< deleting record fails */
+#define MS_MEDIA_ERR_DB_UPDATE_FAIL                    -15  /**< updating record fails */
+#define MS_MEDIA_ERR_DB_EXIST_ITEM_FAIL                -16  /**< item does not exist */
+#define MS_MEDIA_ERR_DB_BUSY_FAIL                      -17  /**< DB Busy */
+
+/*DRM operation error*/
+#define MS_MEDIA_ERR_DRM_REGISTER_FAIL                 -21  /**< interting into drm db fails */
+#define MS_MEDIA_ERR_DRM_GET_INFO_FAIL                 -22  /**< getting inforamtion fails from DRM content */
+
+/*IPC operation error*/
+#define MS_MEDIA_ERR_SOCKET_INTERNAL                   -31  /**< receive error from socket API */
+#define MS_MEDIA_ERR_SOCKET_CONN                               -32  /**< socket connect error */
+#define MS_MEDIA_ERR_SOCKET_BIND                               -33  /**< socket binding fails */
+#define MS_MEDIA_ERR_SOCKET_SEND                               -34  /**< socket sending fails */
+#define MS_MEDIA_ERR_SOCKET_RECEIVE                    -35  /**< socket receiving fails */
+#define MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT    -36  /**< socket receive timeout error */
+#define MS_MEDIA_ERR_DBUS_ADD_FILTER                   -37  /**< DBUS add filter fails*/
+#define MS_MEDIA_ERR_DBUS_GET                                  -38  /**< DBUS get fails */
+#define MS_MEDIA_ERR_DATA_TAINTED                              -39  /**< received data is tainted */
+
+/* SERVER error*/
+#define MS_MEDIA_ERR_NOW_REGISTER_FILE         -41  /**< already inserting into DB */
+#define MS_MEDIA_ERR_SCANNING_BUSY                     -42  /**< already directory scanning is running */
+#define MS_MEDIA_ERR_DB_SERVER_BUSY_FAIL       -43  /**< DB server busy */
+#define MS_MEDIA_ERR_SCANNER_FORCE_STOP                -44  /**< scanning is stopped forcely */
+
+/*ETC*/
+#define MS_MEDIA_ERR_VCONF_SET_FAIL                    -51  /**< vconf set fail*/
+#define MS_MEDIA_ERR_VCONF_GET_FAIL                    -52  /**< vconf get fail*/
+#define MS_MEDIA_ERR_MIME_GET_FAIL                     -53  /**< not media file*/
+#define MS_MEDIA_ERR_SCANNER_NOT_READY         -54  /**< not media file*/
+#define MS_MEDIA_ERR_DYNAMIC_LINK                      -55
+
+#define MS_MEDIA_ERR_MAX                                               -999 /**< not media file*/
+
+#endif /*_MEDIA_UTIL_ERR_H_*/
diff --git a/lib/include/media-util-internal.h b/lib/include/media-util-internal.h
new file mode 100755 (executable)
index 0000000..f964d9f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-internal.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#ifndef _MEDIA_UTIL_INTERNAL_H_
+#define _MEDIA_UTIL_INTERNAL_H_
+
+#include "media-util-db.h"
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+#ifndef TRUE
+#define TRUE   1
+#endif
+
+#define MS_SAFE_FREE(src)      { if(src) {free(src); src = NULL;} }
+#define MS_STRING_VALID(str)   \
+       ((str != NULL && strlen(str) > 0) ? TRUE : FALSE)
+
+#define MS_MEDIA_DBUS_PATH "/com/mediaserver/dbus/notify"
+#define MS_MEDIA_DBUS_INTERFACE "com.mediaserver.dbus.Signal"
+#define MS_MEDIA_DBUS_NAME "ms_db_updated"
+#define MS_MEDIA_DBUS_MATCH_RULE "type='signal',interface='com.mediaserver.dbus.Signal'"
+
+
+#define MS_SCAN_STATUS_DIRECTORY "file/private/mediaserver/scan_directory"
+enum{
+       VCONF_SCAN_DOING = 0,
+       VCONF_SCAN_DONE,
+};
+
+int media_db_update_db(MediaDBHandle *handle, const char *query_str);
+
+int media_db_update_db_batch_start(const char *query_str);
+int media_db_update_db_batch(const char *query_str);
+int media_db_update_db_batch_end(MediaDBHandle *handle, const char *query_str);
+
+#endif /*_MEDIA_UTIL_INTERNAL_H_*/
diff --git a/lib/include/media-util-ipc.h b/lib/include/media-util-ipc.h
new file mode 100755 (executable)
index 0000000..60dd1fa
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of IPC.
+ *
+ * @file               media-util-ipc.h
+ * @author     Haejeong Kim(backto.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+ #ifndef _MEDIA_UTIL_IPC_H_
+#define _MEDIA_UTIL_IPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "media-server-ipc.h"
+
+#define SERVER_IP                      "127.0.0.1"
+
+typedef enum {
+       MS_PROTOCOL_UDP,
+       MS_PROTOCOL_TCP
+} ms_protocol_e;
+
+int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *sock_fd);
+int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd);
+int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, struct sockaddr_in *serv_addr);
+int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_in *client_addr);
+int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_in *client_addr, unsigned int *size);
+int ms_ipc_wait_message(int sockfd, void  *recv_msg, unsigned int msg_size, struct sockaddr_in *recv_addr, unsigned int *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_MEDIA_UTIL_IPC_H_*/
diff --git a/lib/include/media-util-noti.h b/lib/include/media-util-noti.h
new file mode 100755 (executable)
index 0000000..630f42e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-noti.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+ #ifndef _MEDIA_UTIL_NOTI_H_
+#define _MEDIA_UTIL_NOTI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @fn          int media_db_update_subscribe(void);
+* @brief               This function announce media database is updated to other applications.<br>
+* @return      This function returns 0 on success, and -1 on failure.
+* @param[in]   none
+* @remark      This function is recommandation for other application being aware of database updating.<br>
+* @par example
+* @code
+
+#include <stdio.h>
+#include <glib.h>
+#include <media-util-noti.h>
+
+void callback()
+{
+        printf("listen dbus from media-server\n");
+}
+
+int
+main (int argc, char **argv)
+{
+       GMainLoop *loop;
+
+       loop = g_main_loop_new (NULL, FALSE);
+
+       media_db_update_subscribe(callback);
+
+       g_main_loop_run (loop);
+
+       return 0;
+}
+
+*/
+
+typedef void (*db_update_cb)(void);
+
+int media_db_update_subscribe(db_update_cb user_cb);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_MEDIA_UTIL_NOTI_H_*/
diff --git a/lib/include/media-util-register.h b/lib/include/media-util-register.h
new file mode 100755 (executable)
index 0000000..f8dc498
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-register.h
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+ #ifndef _MEDIA_UTIL_REGISTER_H_
+#define _MEDIA_UTIL_REGISTER_H_
+
+#include <glib.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @fn         int ms_media_file_register(const char *file_full_path);
+ * @brief              This function registers multimedia file to media DB
+ *                     When you did some file operations such as Create, Copy, Move, Rename, and Delete in phone or mmc storage, media-server registers the result to database automatically by inotify mechanism.
+ *                     However, automatic registration will have a little delay because the method is asynchronous.
+ *                     If you want to register some files to database immediately, you should use this API.
+ *
+ * @param      file_full_path [in]             full path of file for register
+ * @return     This function returns zero(MEDIA_INFO_ERROR_NONE) on success, or negative value with error code.
+ *                     Please refer 'media-info-error.h' to know the exact meaning of the error.
+ * @see                None.
+ * @pre                None.
+ * @post               None.
+ * @remark     The database name is "/opt/usr/dbspace/.media.db".
+ *                  You have to use this API only for registering multimedia files. If you try to register no multimedia file, this API returns error.
+ * @par example
+ * @code
+
+#include <media-info.h>
+
+int main()
+{
+       int result = -1;
+
+       result = ms_media_file_register("/opt/usr/media/test.mp3");
+       if( result < 0 )
+       {
+               printf("FAIL to mediainfo_register_file\n");
+               return 0;
+       }
+       else
+       {
+               printf("SUCCESS to register file\n");
+       }
+
+       return 0;
+}
+
+ *     @endcode
+ */
+int media_file_register(const char *file_full_path);
+
+typedef enum
+{
+       MEDIA_DIRECTORY_SCAN = 0,
+       MEDIA_FILES_REGISTER,
+} media_request_type_e;
+
+typedef struct
+{
+       int pid;
+       int result;
+       int request_type;
+       char *complete_path; /* if the request type is MEDIA_FILES_REGISTER, this value will be NULL. */
+}media_request_result_s;
+
+typedef void (*scan_complete_cb)(media_request_result_s *, void *);
+typedef void (*insert_complete_cb)(media_request_result_s *, void *);
+
+int media_directory_scanning_async(const char *directory_path, bool recusive_on, scan_complete_cb user_callback, void *user_data);
+
+int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_MEDIA_UTIL_REGISTER_H_*/
diff --git a/lib/include/media-util.h b/lib/include/media-util.h
new file mode 100755 (executable)
index 0000000..4ae7b54
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Media Utility
+ *
+ * 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_UTIL_H_
+#define _MEDIA_UTIL_H_
+
+#include <media-util-err.h>
+#include <media-util-register.h>
+#include <media-util-db.h>
+#include <media-util-noti.h>
+#include <media-util-ipc.h>
+
+#define MOUNT_PATH "/opt/usr"
+
+#define MEDIA_ROOT_PATH_INTERNAL       MOUNT_PATH"/media"
+#define MEDIA_ROOT_PATH_SDCARD "/opt/storage/sdcard"
+#define MEDIA_DATA_PATH                        MOUNT_PATH"/data/file-manager-service"
+#define MEDIA_DB_NAME                          MOUNT_PATH"/dbspace/.media.db"          /**<  media db name*/
+
+#endif /*_MEDIA_UTIL_H_*/
diff --git a/lib/media-util-db.c b/lib/media-util-db.c
new file mode 100755 (executable)
index 0000000..38f6e40
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of Media DB.
+ *
+ * @file               media-util-db.c
+ * @author     Haejeong Kim(backto.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <db-util.h>
+#include "media-server-ipc.h"
+#include "media-util-dbg.h"
+#include "media-util-internal.h"
+#include "media-util.h"
+
+static __thread char **sql_list = NULL;
+static __thread int g_list_idx = 0;
+
+static int __media_db_busy_handler(void *pData, int count);
+static int __media_db_connect_db_with_handle(sqlite3 **db_handle);
+static int __media_db_disconnect_db_with_handle(sqlite3 *db_handle);
+static int __media_db_request_update(ms_msg_type_e msg_type, const char *request_msg);
+
+void __media_db_destroy_sql_list()
+{
+       int i = 0;
+
+       for (i = 0; i < g_list_idx; i++) {
+               MS_SAFE_FREE(sql_list[i]);
+       }
+
+       MS_SAFE_FREE(sql_list);
+       g_list_idx = 0;
+}
+
+static int __media_db_busy_handler(void *pData, int count)
+{
+       usleep(50000);
+
+       MSAPI_DBG("media_db_busy_handler called : %d", count);
+
+       return 100 - count;
+}
+
+static int __media_db_connect_db_with_handle(sqlite3 **db_handle)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       /*Connect DB*/
+       ret = db_util_open(MEDIA_DB_NAME, db_handle, DB_UTIL_REGISTER_HOOK_METHOD);
+
+       if (SQLITE_OK != ret) {
+
+               MSAPI_DBG_ERR("error when db open");
+               *db_handle = NULL;
+               return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+       }
+
+       if (*db_handle == NULL) {
+               MSAPI_DBG_ERR("*db_handle is NULL");
+               return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+       }
+
+       /*Register busy handler*/
+       ret = sqlite3_busy_handler(*db_handle, __media_db_busy_handler, NULL);
+
+       if (SQLITE_OK != ret) {
+
+               if (*db_handle) {
+                       MSAPI_DBG_ERR("[error when register busy handler] %s\n", sqlite3_errmsg(*db_handle));
+               }
+
+               db_util_close(*db_handle);
+               *db_handle = NULL;
+
+               return MS_MEDIA_ERR_DB_CONNECT_FAIL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __media_db_disconnect_db_with_handle(sqlite3 *db_handle)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       ret = db_util_close(db_handle);
+
+       if (SQLITE_OK != ret) {
+               MSAPI_DBG_ERR("error when db close");
+               MSAPI_DBG_ERR("Error : %s", sqlite3_errmsg(db_handle));
+               db_handle = NULL;
+               return MS_MEDIA_ERR_DB_DISCONNECT_FAIL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __media_db_request_update(ms_msg_type_e msg_type, const char *request_msg)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int request_msg_size = 0;
+       int sockfd = -1;
+       int err = -1;
+       struct sockaddr_in serv_addr;
+       unsigned int serv_addr_len = -1;
+       int port = MS_DB_UPDATE_PORT;
+
+       if(msg_type == MS_MSG_DB_UPDATE)
+               port = MS_DB_UPDATE_PORT;
+       else
+               port = MS_SCANNER_PORT;
+
+       if(!MS_STRING_VALID(request_msg))
+       {
+               MSAPI_DBG_ERR("invalid query");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       request_msg_size = strlen(request_msg);
+       if(request_msg_size >= MAX_MSG_SIZE)
+       {
+               MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+//     MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
+
+       ms_comm_msg_s send_msg;
+       memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
+
+       send_msg.msg_type = msg_type;
+       send_msg.msg_size = request_msg_size;
+       strncpy(send_msg.msg, request_msg, request_msg_size);
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_3, &sockfd);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, &serv_addr);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       /*Receive Response*/
+       ms_comm_msg_s recv_msg;
+       serv_addr_len = sizeof(serv_addr);
+       memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s));
+
+       err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL);
+       if (err != MS_MEDIA_ERR_NONE) {
+               ret = err;
+       } else {
+               MSAPI_DBG("RECEIVE OK [%d]", recv_msg.result);
+               ret = recv_msg.result;
+       }
+
+       close(sockfd);
+
+       return ret;
+}
+
+static int g_tcp_client_sock = -1;
+
+static int __media_db_get_client_tcp_sock()
+{
+       return g_tcp_client_sock;
+}
+
+static int __media_db_prepare_tcp_client_socket()
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int sockfd = -1;
+       struct sockaddr_in serv_addr;
+       int port = MS_DB_BATCH_UPDATE_PORT;
+
+       /*Create TCP Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_3, &sockfd);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       /*Set server Address*/
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+       serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
+       serv_addr.sin_port = htons(port);
+
+       /* Connecting to the media db server */
+       if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
+               MSAPI_DBG_ERR("connect error : %s", strerror(errno));
+               close(sockfd);
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       g_tcp_client_sock = sockfd;
+
+       MSAPI_DBG("Connected successfully");
+
+       return 0;
+}
+
+static int __media_db_close_tcp_client_socket()
+{
+       close(g_tcp_client_sock);
+       g_tcp_client_sock = -1;
+
+       return 0;
+}
+
+static int __media_db_request_batch_update(ms_msg_type_e msg_type, const char *request_msg)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int request_msg_size = 0;
+       int sockfd = -1;
+
+       if(!MS_STRING_VALID(request_msg))
+       {
+               MSAPI_DBG_ERR("invalid query");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       request_msg_size = strlen(request_msg);
+       if(request_msg_size >= MAX_MSG_SIZE)
+       {
+               MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
+       ms_comm_msg_s send_msg;
+       memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
+
+       send_msg.msg_type = msg_type;
+       send_msg.msg_size = request_msg_size;
+       strncpy(send_msg.msg, request_msg, request_msg_size);
+
+       sockfd = __media_db_get_client_tcp_sock();
+       if (sockfd <= 0) {
+               return  MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       /* Send request */
+       if (send(sockfd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) {
+               MSAPI_DBG_ERR("send failed : %s", strerror(errno));
+               __media_db_close_tcp_client_socket(sockfd);
+               return MS_MEDIA_ERR_SOCKET_SEND;
+       } else {
+               MSAPI_DBG("Sent successfully");
+       }
+
+       /*Receive Response*/
+       int recv_msg_size = -1;
+       int recv_msg = -1;
+       if ((recv_msg_size = recv(sockfd, &recv_msg, sizeof(recv_msg), 0)) < 0) {
+               MSAPI_DBG_ERR("recv failed : %s", strerror(errno));
+
+               __media_db_close_tcp_client_socket(sockfd);
+               if (errno == EWOULDBLOCK) {
+                       MSAPI_DBG_ERR("Timeout. Can't try any more");
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
+               } else {
+                       MSAPI_DBG_ERR("recv failed : %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE;
+               }
+       }
+
+       MSAPI_DBG("RECEIVE OK [%d]", recv_msg);
+       ret = recv_msg;
+
+       return ret;
+}
+
+static int _media_db_update_directly(sqlite3 *db_handle, const char *sql_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       char *zErrMsg = NULL;
+
+       MSAPI_DBG_INFO("SQL = [%s]", sql_str);
+
+       ret = sqlite3_exec(db_handle, sql_str, NULL, NULL, &zErrMsg);
+
+       if (SQLITE_OK != ret) {
+               MSAPI_DBG_ERR("DB Update Fail SQL:%s [%s], err[%d]", sql_str, zErrMsg, ret);
+               if (ret == SQLITE_BUSY)
+                       ret = MS_MEDIA_ERR_DB_BUSY_FAIL;
+               else
+                       ret = MS_MEDIA_ERR_DB_UPDATE_FAIL;
+       } else {
+               MSAPI_DBG("DB Update Success");
+       }
+
+       if (zErrMsg)
+               sqlite3_free (zErrMsg);
+
+       return ret;
+}
+
+int media_db_connect(MediaDBHandle **handle)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       sqlite3 * db_handle = NULL;
+
+       MSAPI_DBG_FUNC();
+
+       ret = __media_db_connect_db_with_handle(&db_handle);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       *handle = db_handle;
+       return MS_MEDIA_ERR_NONE;
+}
+
+int media_db_disconnect(MediaDBHandle *handle)
+{
+       sqlite3 * db_handle = (sqlite3 *)handle;
+
+       MSAPI_DBG_FUNC();
+
+       MSAPI_RETVM_IF(db_handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
+
+       return __media_db_disconnect_db_with_handle(db_handle);
+}
+
+int media_db_request_update_db(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_DBG_FUNC();
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       ret = __media_db_request_update(MS_MSG_DB_UPDATE, query_str);
+
+       return ret;
+}
+
+int media_db_request_update_db_batch_start(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_DBG_FUNC();
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       ret = __media_db_prepare_tcp_client_socket();
+
+       if (ret < MS_MEDIA_ERR_NONE) {
+               MSAPI_DBG_ERR("__media_db_prepare_tcp_client_socket failed : %d", ret);
+               __media_db_close_tcp_client_socket();
+               return ret;
+       }
+
+       ret = __media_db_request_batch_update(MS_MSG_DB_UPDATE_BATCH_START, query_str);
+
+       return ret;
+}
+
+int media_db_request_update_db_batch(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_DBG_FUNC();
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       ret = __media_db_request_batch_update(MS_MSG_DB_UPDATE_BATCH, query_str);
+
+       return ret;
+}
+
+int media_db_request_update_db_batch_end(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_DBG_FUNC();
+
+       if (!MS_STRING_VALID(query_str)) {
+               MSAPI_DBG_ERR("Invalid Query");
+               __media_db_close_tcp_client_socket();
+               return ret;
+       }
+
+       ret = __media_db_request_batch_update(MS_MSG_DB_UPDATE_BATCH_END, query_str);
+
+       __media_db_close_tcp_client_socket();
+
+       return ret;
+}
+
+int media_db_request_directory_scan(const char *directory_path)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(directory_path), MS_MEDIA_ERR_INVALID_PARAMETER, "Directory Path is NULL");
+
+       ret = __media_db_request_update(MS_MSG_DIRECTORY_SCANNING, directory_path);
+
+       return ret;
+}
+
+int media_db_update_db(MediaDBHandle *handle, const char *query_str)
+{
+       sqlite3 * db_handle = (sqlite3 *)handle;
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_RETVM_IF(db_handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       ret = _media_db_update_directly(db_handle, query_str);
+
+       return ret;
+}
+
+int media_db_update_db_batch_start(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       if (g_list_idx != 0) {
+               MSAPI_DBG_ERR("Current idx is not 0");
+               ret = MS_MEDIA_ERR_DB_SERVER_BUSY_FAIL;
+       } else {
+               sql_list = (char**)malloc(sizeof(char*));
+               MSAPI_RETVM_IF(sql_list == NULL, MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL, "Out of memory");
+               sql_list[g_list_idx++] = strdup(query_str);
+               MSAPI_RETVM_IF(sql_list[g_list_idx - 1] == NULL, MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL, "Out of memory");
+       }
+
+       return ret;
+}
+
+int media_db_update_db_batch(const char *query_str)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+
+       MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query");
+
+       sql_list = (char**)realloc(sql_list, (g_list_idx + 1) * sizeof(char*));
+       MSAPI_RETVM_IF(sql_list == NULL, MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL, "Out of memory");
+
+       sql_list[g_list_idx++] = strdup(query_str);
+       MSAPI_RETVM_IF(sql_list[g_list_idx - 1] == NULL, MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL, "Out of memory");
+
+       return ret;
+}
+
+int media_db_update_db_batch_end(MediaDBHandle *handle, const char *query_str)
+{
+       sqlite3 * db_handle = (sqlite3 *)handle;
+       int ret = MS_MEDIA_ERR_NONE;
+
+       if (db_handle == NULL || (!MS_STRING_VALID(query_str))) {
+               __media_db_destroy_sql_list();
+               MSAPI_DBG_ERR("Handle is NULL");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       sql_list = (char**)realloc(sql_list, (g_list_idx + 1) * sizeof(char*));
+       if (sql_list == NULL) {
+               __media_db_destroy_sql_list();
+               MSAPI_DBG_ERR("Out of memory");
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       sql_list[g_list_idx++] = strdup(query_str);
+       if (sql_list[g_list_idx - 1] == NULL) {
+               __media_db_destroy_sql_list();
+               MSAPI_DBG_ERR("Out of memory");
+               return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL;
+       }
+
+       int i = 0;
+       char *current_sql = NULL;
+       for (i = 0; i < g_list_idx; i++) {
+               current_sql = sql_list[i];
+               ret = _media_db_update_directly(db_handle, current_sql);
+               if (ret < 0) {
+                       if (i == 0) {
+                               /* This is fail of "BEGIN" */
+                               MSAPI_DBG_ERR("Query failed : %s", current_sql);
+                               break;
+                       } else if (i == g_list_idx - 1) {
+                               /* This is fail of "COMMIT" */
+                               MSAPI_DBG_ERR("Query failed : %s", current_sql);
+                               break;
+                       } else {
+                               MSAPI_DBG_ERR("Query failed : %s, but keep going to run remaining queries", current_sql);
+                       }
+               }
+       }
+
+       __media_db_destroy_sql_list();
+
+       return ret;
+}
diff --git a/lib/media-util-ipc.c b/lib/media-util-ipc.c
new file mode 100755 (executable)
index 0000000..1e71ed8
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of IPC.
+ *
+ * @file               media-util-ipc.c
+ * @author     Haejeong Kim(backto.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "media-util-dbg.h"
+#include "media-util.h"
+
+int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *sock_fd)
+{
+       int sock = -1;
+
+       struct timeval tv_timeout = { timeout_sec, 0 };
+
+       if(protocol == MS_PROTOCOL_UDP)
+       {
+               /* Create a datagram/UDP socket */
+               if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+                       MSAPI_DBG_ERR("socket failed: %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+       }
+       else
+       {
+               /*Create TCP Socket*/
+               if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+                       MSAPI_DBG_ERR("socket failed: %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+       }
+
+       if (timeout_sec > 0) {
+               if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) {
+                       MSAPI_DBG_ERR("setsockopt failed: %s", strerror(errno));
+                       close(sock);
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+       }
+
+       *sock_fd = sock;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd)
+{
+       int sock = -1;
+       int n_reuse = 1;
+       struct sockaddr_in serv_addr;
+       unsigned short serv_port;
+
+       serv_port = port;
+
+       if(protocol == MS_PROTOCOL_UDP)
+       {
+               /* Create a datagram/UDP socket */
+               if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+                       MSAPI_DBG_ERR("socket failed: %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+       }
+       else
+       {
+               /* Create a TCP socket */
+               if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+                       MSAPI_DBG_ERR("socket failed: %s", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+       }
+
+       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n_reuse, sizeof(n_reuse)) == -1) {
+               MSAPI_DBG_ERR("setsockopt failed: %s", strerror(errno));
+               close(sock);
+               return MS_MEDIA_ERR_SOCKET_INTERNAL;
+       }
+
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+//     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
+       serv_addr.sin_port = htons(serv_port);
+
+       /* Bind to the local address */
+       if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+               MSAPI_DBG_ERR("bind failed : %s", strerror(errno));
+               close(sock);
+               return MS_MEDIA_ERR_SOCKET_CONN;
+       }
+
+       MSAPI_DBG("bind success");
+
+       /* Listening */
+       if (protocol == MS_PROTOCOL_TCP) {
+               if (listen(sock, SOMAXCONN) < 0) {
+                       MSAPI_DBG_ERR("listen failed : %s", strerror(errno));
+                       close(sock);
+                       return MS_MEDIA_ERR_SOCKET_CONN;
+               }
+
+               MSAPI_DBG("Listening...");
+       }
+
+       *sock_fd = sock;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, struct sockaddr_in *serv_addr)
+{
+       int res = MS_MEDIA_ERR_NONE;
+       struct sockaddr_in addr;
+
+       /* Set server Address */
+       memset(&addr, 0, sizeof(addr));
+       addr.sin_family = AF_INET;
+       addr.sin_addr.s_addr = inet_addr(SERVER_IP);
+       addr.sin_port = htons(port);
+
+       if (sendto(sockfd, send_msg, sizeof(*(send_msg)), 0, (struct sockaddr *)&addr, sizeof(addr)) != sizeof(*(send_msg))) {
+               MSAPI_DBG_ERR("sendto failed [%s]", strerror(errno));
+               res = MS_MEDIA_ERR_SOCKET_SEND;
+       } else {
+               MSAPI_DBG("sent %d", send_msg->result);
+               MSAPI_DBG("sent %s", send_msg->msg);
+               if (serv_addr != NULL)
+                       *serv_addr = addr;
+       }
+
+       return res;
+}
+
+int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_in *client_addr)
+{
+       int res = MS_MEDIA_ERR_NONE;
+
+       if (sendto(sockfd, send_msg, sizeof(*(send_msg)), 0, (struct sockaddr *)client_addr, sizeof(*(client_addr))) != sizeof(*(send_msg))) {
+               MSAPI_DBG_ERR("sendto failed [%s]", strerror(errno));
+               res = MS_MEDIA_ERR_SOCKET_SEND;
+       } else {
+               MSAPI_DBG("sent %d", send_msg->result);
+               MSAPI_DBG("sent %s", send_msg->msg);
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_in *recv_addr, unsigned int *addr_size)
+{
+       int recv_msg_size;
+       struct sockaddr_in addr;
+       socklen_t addr_len;
+
+       if (!recv_msg)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       addr_len = sizeof(struct sockaddr_in);
+
+       if ((recv_msg_size = recvfrom(sockfd, recv_msg, msg_size, 0, (struct sockaddr *)&addr, &addr_len)) < 0) {
+               MSAPI_DBG_ERR("recvfrom failed [%s]", strerror(errno));
+               return MS_MEDIA_ERR_SOCKET_RECEIVE;
+       }
+
+       if (recv_addr != NULL)
+               *recv_addr = addr;
+       if (addr_size != NULL)
+               *addr_size  = addr_len;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int ms_ipc_wait_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_in *recv_addr, unsigned int *addr_size)
+{
+       int recv_msg_size;
+       socklen_t addr_len;
+
+       if (!recv_msg ||!recv_addr)
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+
+       addr_len = sizeof(struct sockaddr_in);
+
+       if ((recv_msg_size = recvfrom(sockfd, recv_msg, msg_size, 0, (struct sockaddr *)recv_addr, &addr_len)) < 0) {
+               MSAPI_DBG_ERR("recvfrom failed [%s]", strerror(errno));
+               if (errno == EWOULDBLOCK) {
+                       MSAPI_DBG_ERR("recvfrom Timeout.");
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
+               } else {
+                       MSAPI_DBG_ERR("recvfrom error [%s]", strerror(errno));
+                       return MS_MEDIA_ERR_SOCKET_RECEIVE;
+               }
+       }
+
+       if (addr_size != NULL)
+               *addr_size  = addr_len;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+
diff --git a/lib/media-util-noti.c b/lib/media-util-noti.c
new file mode 100755 (executable)
index 0000000..a4af345
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-noti.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "media-util-internal.h"
+#include "media-util-dbg.h"
+#include "media-util.h"
+
+static DBusHandlerResult
+__message_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+       db_update_cb user_cb = user_data;
+
+       /* A Ping signal on the com.burtonini.dbus.Signal interface */
+       if (dbus_message_is_signal (message, MS_MEDIA_DBUS_INTERFACE, MS_MEDIA_DBUS_NAME)) {
+               DBusError error;
+               dbus_uint16_t  noti_type;
+
+               dbus_error_init (&error);
+               if (dbus_message_get_args (message, &error, DBUS_TYPE_UINT16, &noti_type, DBUS_TYPE_INVALID)) {
+                       MSAPI_DBG("noti type: %d\n", noti_type);
+                       user_cb();
+               } else {
+                       MSAPI_DBG("messgae received, but error getting message: %s\n", error.message);
+                       dbus_error_free (&error);
+               }
+               return DBUS_HANDLER_RESULT_HANDLED;
+       }
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int media_db_update_subscribe(db_update_cb user_cb)
+{
+       DBusConnection *bus;
+       DBusError error;
+
+       dbus_g_thread_init();
+
+       dbus_error_init (&error);
+
+       bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
+       if (!bus) {
+               MSAPI_DBG ("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free (&error);
+               return MS_MEDIA_ERR_DBUS_GET;
+       }
+
+       dbus_connection_setup_with_g_main (bus, NULL);
+
+       /* listening to messages from all objects as no path is specified */
+       dbus_bus_add_match (bus, MS_MEDIA_DBUS_MATCH_RULE, &error);
+       if( !dbus_connection_add_filter (bus, __message_filter, user_cb, NULL))
+               return MS_MEDIA_ERR_DBUS_ADD_FILTER;
+
+       return MS_MEDIA_ERR_NONE;
+}
+
diff --git a/lib/media-util-register.c b/lib/media-util-register.c
new file mode 100755 (executable)
index 0000000..462d79f
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ *  Media Utility
+ *
+ * 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.
+ *
+ */
+
+/**
+ * This file defines api utilities of contents manager engines.
+ *
+ * @file               media-util-register.c
+ * @author     Yong Yeon Kim(yy9875.kim@samsung.com)
+ * @version    1.0
+ * @brief
+ */
+#include <errno.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <string.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <vconf.h>
+
+#include "media-server-ipc.h"
+#include "media-util-internal.h"
+#include "media-util-dbg.h"
+#include "media-util.h"
+
+typedef struct media_callback_data{
+       GSource *source;
+       scan_complete_cb user_callback;
+       void *user_data;
+} media_callback_data;
+
+static bool _is_valid_path(const char *path)
+{
+       if (path == NULL)
+               return false;
+
+       if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) {
+               return true;
+       } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) {
+               return true;
+       } else
+               return false;
+
+       return true;
+}
+
+static int _check_dir_path(const char *dir_path)
+{
+       struct stat sb;
+       DIR *dp = NULL;
+
+       if (!_is_valid_path(dir_path)) {
+               MSAPI_DBG("Invalid path : %s", dir_path);
+               return MS_MEDIA_ERR_INVALID_PATH;
+       }
+
+       if (stat(dir_path, &sb) == -1) {
+               MSAPI_DBG("stat failed");
+               dp = opendir(dir_path);
+               if (dp == NULL) {
+                       /*if openning directory is failed, check it exists. */
+                       if (errno == ENOENT) {
+                               /* this directory is deleted */
+                               return MS_MEDIA_ERR_NONE;
+                       }
+               } else {
+                       closedir(dp);
+               }
+               return MS_MEDIA_ERR_INTERNAL;
+       } else {
+               if((sb.st_mode & S_IFMT) != S_IFDIR) {
+                       MSAPI_DBG("Invalid path : %s is not directory", dir_path);
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+
+/* receive message from media-server[function : ms_receive_message_from_scanner] */
+gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data)
+{
+       GSource *source = NULL;
+       scan_complete_cb user_callback;
+       void *user_data = NULL;
+       ms_comm_msg_s recv_msg;
+       media_request_result_s req_result;
+       int ret;
+       int sockfd = -1;
+
+       sockfd = g_io_channel_unix_get_fd(src);
+       if (sockfd < 0) {
+               MSAPI_DBG("sock fd is invalid!");
+               return TRUE;
+       }
+
+       memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s));
+
+       /* Socket is readable */
+       ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), NULL, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MSAPI_DBG("ms_ipc_receive_message failed");
+               return TRUE;
+       }
+
+       memset(&req_result, 0x0, sizeof(media_request_result_s));
+       req_result.pid = recv_msg.pid;
+       req_result.result = recv_msg.result;
+       if (recv_msg.msg_type ==MS_MSG_SCANNER_RESULT) {
+               req_result.complete_path = strdup(recv_msg.msg);
+               req_result.request_type = MEDIA_DIRECTORY_SCAN;
+               MSAPI_DBG("complete_path :%d", req_result.complete_path);
+       } else if (recv_msg.msg_type == MS_MSG_SCANNER_BULK_RESULT) {
+               req_result.complete_path = strdup(recv_msg.msg);
+               req_result.request_type = MEDIA_FILES_REGISTER;
+       }
+
+       MSAPI_DBG("pid :%d", req_result.pid);
+       MSAPI_DBG("result :%d", req_result.result);
+       MSAPI_DBG("request_type :%d", req_result.request_type);
+
+       source = ((media_callback_data *)data)->source;
+       user_callback = ((media_callback_data *)data)->user_callback;
+       user_data = ((media_callback_data *)data)->user_data;
+
+       /*call user define function*/
+       user_callback(&req_result, user_data);
+
+       MS_SAFE_FREE(req_result.complete_path);
+
+       /*close an IO channel*/
+       g_io_channel_shutdown(src,  FALSE, NULL);
+       g_io_channel_unref(src);
+
+       g_source_destroy(source);
+       close(sockfd);
+       MS_SAFE_FREE(data);
+
+       return TRUE;
+}
+
+static int _attach_callback(int *sockfd, scan_complete_cb user_callback, void *user_data)
+{
+       GIOChannel *channel = NULL;
+       GMainContext *context = NULL;
+       GSource *source = NULL;
+       media_callback_data *cb_data;
+
+       /*get the global default main context*/
+       context = g_main_context_default();
+
+       /* Create new channel to watch udp socket */
+       channel = g_io_channel_unix_new(*sockfd);
+       source = g_io_create_watch(channel, G_IO_IN);
+
+       cb_data = malloc(sizeof(media_callback_data));
+       cb_data->source = source;
+       cb_data->user_callback = user_callback;
+       cb_data->user_data = user_data;
+
+       /* Set callback to be called when socket is readable */
+       g_source_set_callback(source, (GSourceFunc)_read_socket, cb_data, NULL);
+       g_source_attach(source, context);
+       g_source_unref(source);
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+static int __media_db_request_update_sync(ms_msg_type_e msg_type, const char *request_msg)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int request_msg_size = 0;
+       int sockfd = -1;
+       int err = -1;
+       struct sockaddr_in serv_addr;
+       unsigned int serv_addr_len = -1;
+       int port = MS_SCANNER_PORT;
+       ms_comm_msg_s send_msg;
+
+       if(!MS_STRING_VALID(request_msg))
+       {
+               MSAPI_DBG_ERR("invalid query");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       request_msg_size = strlen(request_msg);
+       if(request_msg_size >= MAX_MSG_SIZE)
+       {
+               MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
+
+       memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
+       send_msg.msg_type = msg_type;
+       send_msg.pid = syscall(__NR_getpid);
+       send_msg.msg_size= request_msg_size;
+       strncpy(send_msg.msg, request_msg, request_msg_size);
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sockfd);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, &serv_addr);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret);
+               close(sockfd);
+               return ret;
+       }
+
+       /*Receive Response*/
+       ms_comm_msg_s recv_msg;
+       serv_addr_len = sizeof(serv_addr);
+
+       memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s));
+       err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL);
+       if (err != MS_MEDIA_ERR_NONE) {
+               ret = err;
+       } else {
+               MSAPI_DBG("RECEIVE OK [%d]", recv_msg.result);
+               ret = recv_msg.result;
+       }
+
+       close(sockfd);
+
+       return ret;
+}
+
+
+static int __media_db_request_update_async(ms_msg_type_e msg_type, const char *request_msg, scan_complete_cb user_callback, void *user_data)
+{
+       int ret = MS_MEDIA_ERR_NONE;
+       int request_msg_size = 0;
+       int sockfd = -1;
+       int port = MS_SCANNER_PORT;
+       ms_comm_msg_s send_msg;
+
+       if(!MS_STRING_VALID(request_msg))
+       {
+               MSAPI_DBG_ERR("invalid query");
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       MSAPI_DBG("REQUEST DIRECTORY SCANNING");
+
+       request_msg_size = strlen(request_msg);
+       if(request_msg_size >= MAX_MSG_SIZE)
+       {
+               MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE);
+               return MS_MEDIA_ERR_INVALID_PARAMETER;
+       }
+
+       MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg);
+
+       memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s));
+       send_msg.msg_type = msg_type;
+       send_msg.pid = syscall(__NR_getpid);
+       send_msg.msg_size = request_msg_size;
+       strncpy(send_msg.msg, request_msg, request_msg_size);
+
+       /*Create Socket*/
+       ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd);
+       MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret);
+
+       ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, NULL);
+       if (ret != MS_MEDIA_ERR_NONE) {
+               MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret);
+               close(sockfd);
+               return ret;
+       }
+
+       ret = _attach_callback(&sockfd, user_callback ,user_data);
+       if(ret != MS_MEDIA_ERR_NONE)
+               return ret;
+
+       return ret;
+}
+
+
+int media_directory_scanning_async(const char *directory_path, bool recusive_on, scan_complete_cb user_callback, void *user_data)
+{
+       int ret;
+
+       ret = _check_dir_path(directory_path);
+       if(ret != MS_MEDIA_ERR_NONE)
+               return ret;
+
+       if (recusive_on == TRUE)
+               ret = __media_db_request_update_async(MS_MSG_DIRECTORY_SCANNING, directory_path, user_callback, user_data);
+       else
+               ret = __media_db_request_update_async(MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE, directory_path, user_callback, user_data);
+
+       return ret;
+}
+
+static int _check_file_path(const char *file_path)
+{
+       int exist;
+       struct stat file_st;
+
+       /* check location of file */
+       /* file must exists under "/opt/usr/media" or "/opt/storage/sdcard" */
+       if(!_is_valid_path(file_path)) {
+               MSAPI_DBG("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) {
+               MSAPI_DBG("Not exist path : %s", file_path);
+               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 */
+                       MSAPI_DBG("this path is not a file");
+                       return MS_MEDIA_ERR_INVALID_PATH;
+               }
+       } else {
+               MSAPI_DBG("stat failed [%s]", strerror(errno));
+               return MS_MEDIA_ERR_INTERNAL;
+       }
+
+       return MS_MEDIA_ERR_NONE;
+}
+
+int media_file_register(const char *file_full_path)
+{
+       int ret;
+
+       ret = _check_file_path(file_full_path);
+       if(ret != MS_MEDIA_ERR_NONE)
+               return ret;
+
+       ret = __media_db_request_update_sync(MS_MSG_DB_UPDATE, file_full_path);
+
+       MSAPI_DBG("client receive: %d", ret);
+
+       return ret;
+}
+
+int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data)
+{
+       int ret;
+
+       ret = __media_db_request_update_async(MS_MSG_BULK_INSERT, list_path, user_callback, user_data);
+
+       MSAPI_DBG("client receive: %d", ret);
+
+       return ret;
+}
+
diff --git a/libmedia-utils.manifest b/libmedia-utils.manifest
new file mode 100644 (file)
index 0000000..ca37499
--- /dev/null
@@ -0,0 +1,6 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
+
diff --git a/libmedia-utils.pc.in b/libmedia-utils.pc.in
new file mode 100755 (executable)
index 0000000..886d52d
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: media contents managing service
+Description: media contents managing service API
+Requires:
+Version: @VERSION@
+Libs: -L${libdir} -lmedia-utils
+Cflags: -I${includedir}/media-utils
diff --git a/media-server.manifest b/media-server.manifest
new file mode 100644 (file)
index 0000000..387fd9f
--- /dev/null
@@ -0,0 +1,17 @@
+<manifest>
+       <define>
+               <domain name="media-server"/>
+       </define>
+       <request>
+               <domain name="_"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/media-server" label="media-server" exec_label="media-server"/>
+                <filesystem path="/usr/bin/media-scanner" label="media-server" exec_label="media-server" />
+                <filesystem path="/usr/bin/mediadb-update" label="media-server" exec_label="media-server" />
+                <filesystem path="/etc/rc.d/init.d/mediasvr" label="_" exec_label="none" />
+                <filesystem path="/etc/rc.d/rc3.d/S99mediasvr" label="_" exec_label="none" />
+                <filesystem path="/etc/rc.d/rc5.d/S99mediasvr" label="_" exec_label="none" />
+       </assign>
+</manifest>
+
diff --git a/packaging/media-server.service b/packaging/media-server.service
new file mode 100644 (file)
index 0000000..e243d10
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Media server
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/media-server
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/media-server.spec b/packaging/media-server.spec
new file mode 100755 (executable)
index 0000000..ef40e86
--- /dev/null
@@ -0,0 +1,124 @@
+Name:       media-server
+Summary:    File manager service server.
+Version: 0.2.26
+Release:    1
+Group:      utils
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1:    media-server.service
+
+Requires(post): /usr/bin/vconftool
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(drm-client)
+BuildRequires:  pkgconfig(aul)
+BuildRequires:  pkgconfig(pmapi)
+BuildRequires:  pkgconfig(heynoti)
+BuildRequires:  pkgconfig(dbus-glib-1)
+BuildRequires:  pkgconfig(sqlite3)
+BuildRequires:  pkgconfig(db-util)
+BuildRequires:  pkgconfig(notification)
+
+%description
+Description: File manager service server
+
+
+%package -n libmedia-utils
+Summary:   media server runtime library.
+Group:     TO_BE/FILLED_IN
+
+%description -n libmedia-utils
+Description : media server runtime library.
+
+
+%package -n libmedia-utils-devel
+Summary:   media server development library.
+Group:     Development/Libraries
+Requires:  libmedia-utils = %{version}-%{release}
+
+%description -n libmedia-utils-devel
+Description: media server development library.
+
+%prep
+%setup -q
+
+%build
+
+%autogen
+%configure --prefix=%{_prefix} --disable-static
+
+make %{?jobs:-j%jobs}
+
+%install
+%make_install
+
+mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
+install -m 644 %{SOURCE1} %{buildroot}/usr/lib/systemd/system/media-server.service
+ln -s ../media-server.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/media-server.service
+
+#License
+mkdir -p %{buildroot}/%{_datadir}/license
+cp -rf %{_builddir}/%{name}-%{version}/LICENSE.APLv2.0 %{buildroot}/%{_datadir}/license/%{name}
+
+%post
+vconftool set -t int db/filemanager/dbupdate "1" -f
+vconftool set -t int memory/filemanager/Mmc "0" -i -f
+vconftool set -t string db/private/mediaserver/mmc_info "" -f
+vconftool set -t int file/private/mediaserver/scan_internal "1" -f
+vconftool set -t int file/private/mediaserver/scan_directory "1" -f
+
+%files
+%manifest media-server.manifest
+%defattr(-,root,root,-)
+%{_bindir}/media-server
+%{_bindir}/media-scanner
+%{_bindir}/mediadb-update
+%attr(755,-,-) %{_sysconfdir}/rc.d/init.d/mediasvr
+/etc/rc.d/rc3.d/S99mediasvr
+/etc/rc.d/rc5.d/S99mediasvr
+/usr/local/bin/reset_mediadb.sh
+/usr/lib/systemd/system/media-server.service
+/usr/lib/systemd/system/multi-user.target.wants/media-server.service
+#License
+%{_datadir}/license/%{name}
+
+%files -n libmedia-utils
+%manifest libmedia-utils.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libmedia-utils.so
+%{_libdir}/libmedia-utils.so.0
+%{_libdir}/libmedia-utils.so.0.0.0
+
+%files -n libmedia-utils-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/libmedia-utils.pc
+%{_includedir}/media-utils/*.h
+
+%changelog
+* Mon Oct 15 2012 Hyunjun Ko <zzoon.ko@samsnug.com> - 0.1.97
+- Fix a bug in db thread
+
+* Wed Oct 10 2012 Hyunjun Ko <zzoon.ko@samsnug.com> - 0.1.96
+- Some apis are added : media_db_request_update_db_batch / start / end
+
+* Mon Sep 10 2012 Haejeong Kim <backto.kim@samsnug.com> - 0.1.86
+- Make new thread for DB write. Only Media server can update db
+
+* Mon Aug 06 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.86
+- add notification subscribe function for application
+- fix bug : once validity checking time, call insert_item_batch two times.
+- add MS_SAFE_FREE Macro, modify check value after using snprintf by secure coding guide
+- change macro name MS_PHONE_ROOT_PATH, MS_MMC_ROOT_PATH
+- make reference directory list by each thread
+
+* Tue Jul 03 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.80
+- manage db handle by plug-in
+
+* Wed Jun 27 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.79
+- If item exists in media db, return directly
+
+* Tue Jun 26 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.78
+- change modified file updating routine (delete & insert -> refresh)
+- modify return error type of media_file_register
+
diff --git a/reset_mediadb.sh b/reset_mediadb.sh
new file mode 100755 (executable)
index 0000000..1061599
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]
+then
+       echo 'Usage : reset_mediadb.sh [phone|sd|all]'
+       exit
+fi
+
+if [ $1 = "phone" ]
+then
+       vconftool set -f -t int db/filemanager/dbupdate "0"
+       killall media-server
+fi
+
+if [ $1 = "sd" ]
+then
+       vconftool set -f -t string db/private/mediaserver/mmc_info ""
+       killall media-server
+fi
+
+if [ $1 = "all" ]
+then
+       vconftool set -f -t int db/filemanager/dbupdate "0"
+       vconftool set -f -t string db/private/mediaserver/mmc_info ""
+       killall media-server
+fi
+
+