--- /dev/null
+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>
--- /dev/null
+
+ 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.
+
+
+
--- /dev/null
+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
--- /dev/null
+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.
--- /dev/null
+#!/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."
--- /dev/null
+#! /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:
--- /dev/null
+#!/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:
--- /dev/null
+#! /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:
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
+
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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__*/
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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, ¬i_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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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__*/
+
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/* 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
--- /dev/null
+# -*- 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
--- /dev/null
+#!/bin/sh
+/usr/bin/media-server&
+
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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_*/
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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, ¬i_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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
+
--- /dev/null
+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
--- /dev/null
+<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>
+
--- /dev/null
+[Unit]
+Description=Media server
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/media-server
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+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
+
--- /dev/null
+#!/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
+
+