diff options
73 files changed, 9032 insertions, 6234 deletions
@@ -0,0 +1,3 @@ +Yong Yeon Kim <yy9875.kim at samsung dot com> +Hyunjun Ko <zzoon.ko at samsung dot com> +Haejeong Kim <backto.kim at samsung dot com> diff --git a/LICENSE b/LICENSE.APLv2.0 index f94008a..f94008a 100644 --- a/LICENSE +++ b/LICENSE.APLv2.0 diff --git a/Makefile.am b/Makefile.am index ff14a29..4cbb428 100755 --- a/Makefile.am +++ b/Makefile.am @@ -10,82 +10,140 @@ AM_LDFLAGS=-Wl,--as-needed -Wl,--hash-style=both 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) + $(DBUS_CFLAGS) \ + $(SQLITE3_CFLAGS) \ + $(DB_UTIL_CFLAGS) \ + $(PHONESTATUS_CFLAGS) libmedia_utils_la_LIBADD = $(GLIB_LIBS) \ $(DLOG_LIBS) \ - $(DBUS_LIBS) + $(DBUS_LIBS) \ + $(SQLITE3_LIBS) \ + $(DB_UTIL_LIBS) \ + $(PHONESTATUS_LIBS) ### file-manager-server ### -bin_PROGRAMS = media-server - -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-scan-internal.c \ - common/media-server-scan.c \ - common/media-server-socket.c \ - common/media-server-main.c - -media_server_CFLAGS = -I${srcdir}/common/include \ +bin_PROGRAMS = media-server \ + media-scanner \ + mediadb-update + +media_server_SOURCES = src/common/media-common-utils.c \ + src/common/media-common-external-storage.c \ + src/server/media-server-db-svc.c \ + src/server/media-server-db.c \ + src/server/media-server-socket.c \ + src/server/media-server-thumb.c \ + src/server/media-server-scanner.c \ + src/server/media-server-main.c + +media_server_CFLAGS = -I${srcdir}/src/common/include \ + -I${srcdir}/src/server/include \ -I${srcdir}/lib/include \ $(GTHREAD_CFLAGS) \ $(GLIB_CFLAGS) \ - $(PHONESTATUS_CFLAGS) \ $(DLOG_CFLAGS) \ - $(DRM_SERVICE_CFLAGS) \ - $(AUL_CFLAG)\ - $(LIBPMCONTROL_CFLAGS) \ - $(HEYNOTI_CFLAGS) \ + $(PHONESTATUS_CFLAGS) \ $(DBUS_CFLAGS) -# $(LIBQUICKPANEL_CFLAGS) +if USE_NOTIFICATION +media_server_CFLAGS += $(STATUS_CFLAGS) +endif + +media_server_CFLAGS += $(LIBPMCONTROL_CFLAGS) + +media_server_CFLAGS += $(SECURITY_CFLAGS) + +media_server_CFLAGS += -fPIE + +media_server_LDFLAGS = -pie media_server_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 -# $(LIBQUICKPANEL_LIBS) + -ldl +if USE_NOTIFICATION +media_server_LDADD += $(STATUS_LIBS) +endif + +media_server_LDADD += $(LIBPMCONTROL_LIBS) + +media_server_LDADD += $(SECURITY_LIBS) + + + +media_scanner_SOURCES = src/common/media-common-utils.c \ + src/common/media-common-external-storage.c \ + src/scanner/media-scanner-db-svc.c \ + src/scanner/media-scanner-scan.c \ + src/scanner/media-scanner-socket.c \ + src/scanner/media-scanner.c + +media_scanner_CFLAGS = -I${srcdir}/lib/include \ + -I${srcdir}/src/common/include \ + -I${srcdir}/src/scanner/include \ + $(GTHREAD_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(PHONESTATUS_CFLAGS) \ + $(DLOG_CFLAGS) \ + $(DBUS_CFLAGS) +if USE_NOTIFICATION +media_scanner_CFLAGS += $(STATUS_CFLAGS) +endif + +media_scanner_CFLAGS += $(LIBPMCONTROL_CFLAGS) + +media_scanner_CFLAGS += -fPIE + +media_scanner_LDFLAGS = -pie + +media_scanner_LDADD = libmedia-utils.la \ + $(GLIB_LIBS) \ + $(GTHREAD_LIBS) \ + $(PHONESTATUS_LIBS) \ + $(DLOG_LIBS) \ + $(DBUS_LIBS) \ + -ldl +if USE_NOTIFICATION +media_scanner_LDADD += $(STATUS_LIBS) +endif + +media_scanner_LDADD += $(LIBPMCONTROL_LIBS) + +mediadb_update_SOURCES = src/mediadb-update.c + +mediadb_update_CFLAGS = -I${srcdir}/lib/include \ + $(GTHREAD_CFLAGS) \ + $(GLIB_CFLAGS) + +mediadb_update_CFLAGS += -fPIE + +mediadb_update_LDFLAGS = -pie + +mediadb_update_LDADD = libmedia-utils.la \ + $(GLIB_LIBS) \ + $(GTHREAD_LIBS) ### includeheaders ### includeheadersdir = $(includedir)/media-utils -includeheaders_HEADERS = lib/include/media-util-noti.h \ +includeheaders_HEADERS = lib/include/media-util-noti-common.h \ + lib/include/media-util-noti.h \ lib/include/media-util-register.h \ - lib/include/media-util-err.h + lib/include/media-util-err.h \ + lib/include/media-util-db.h \ + lib/include/media-util-ipc.h \ + lib/include/media-util.h \ + lib/include/media-server-ipc.h diff --git a/build-aux/depcomp b/build-aux/depcomp deleted file mode 100755 index df8eea7..0000000 --- a/build-aux/depcomp +++ /dev/null @@ -1,630 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2009-04-28.21; # UTC - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to <bug-automake@gnu.org>. -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" - depmode=msvisualcpp -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" - echo >> "$depfile" - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/build-aux/install-sh b/build-aux/install-sh deleted file mode 100755 index 6781b98..0000000 --- a/build-aux/install-sh +++ /dev/null @@ -1,520 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2009-04-28.21; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/build-aux/missing b/build-aux/missing deleted file mode 100755 index 28055d2..0000000 --- a/build-aux/missing +++ /dev/null @@ -1,376 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2009-04-28.21; # UTC - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. - -Send bug reports to <bug-automake@gnu.org>." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/common/include/media-server-db-svc.h b/common/include/media-server-db-svc.h deleted file mode 100755 index 85aa483..0000000 --- a/common/include/media-server-db-svc.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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-global.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 (*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 table_id); - -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); - -#endif /*_MEDIA_SERVER_DB_SVC_H_*/
\ No newline at end of file diff --git a/common/include/media-server-error.h b/common/include/media-server-error.h deleted file mode 100755 index f4bf8e7..0000000 --- a/common/include/media-server-error.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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-error.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - -#ifndef _MEDIA_SERVER_ERROR_H_ -#define _MEDIA_SERVER_ERROR_H_ - -#define ERROR_MASKL16 0xFFFF -#define ERROR(X) (X & ERROR_MASKL16) - -#define MID_CONTENTS_MGR_ERROR 0 /*MID_CONTENTS_MGR_SERVICE */ - -#define MS_ERR_NONE 0 - -/*internal operation error*/ -#define MS_ERR_ARG_INVALID (MID_CONTENTS_MGR_ERROR - ERROR(0x01)) /**< invalid argument */ -#define MS_ERR_ALLOCATE_MEMORY_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x02)) /**< exception of memory allocation */ -#define MS_ERR_OUT_OF_RANGE (MID_CONTENTS_MGR_ERROR - ERROR(0x03)) -#define MS_ERR_INVALID_DIR_PATH (MID_CONTENTS_MGR_ERROR - ERROR(0x04)) /**< exception of invalid dir path */ -#define MS_ERR_INVALID_FILE_PATH (MID_CONTENTS_MGR_ERROR - ERROR(0x05)) /**< exception of invalid file path */ -#define MS_ERR_NOW_REGISTER_FILE (MID_CONTENTS_MGR_ERROR - ERROR(0x06)) /**< exception of invalid file path */ - -/*directory operation error*/ -#define MS_ERR_DIR_OPEN_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x10)) /**< exception of dir open*/ -#define MS_ERR_DIR_NOT_FOUND (MID_CONTENTS_MGR_ERROR - ERROR(0x11)) /**< exception of dir doesn't exist*/ -#define MS_ERR_DIR_READ_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x13)) /**< exception of dir read*/ - -/*file operation error*/ -#define MS_ERR_FILE_NOT_FOUND (MID_CONTENTS_MGR_ERROR - ERROR(0x20)) /**< exception of file doesn't exist*/ -#define MS_ERR_FILE_OPEN_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x21)) /**< exception of file doesn't exist*/ - -/*db operation error*/ -#define MS_ERR_DB_TRUNCATE_TABLE_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x30)) /**< truncating table fails */ -#define MS_ERR_DB_INSERT_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x31)) /**< inserting record fails */ -#define MS_ERR_DB_DELETE_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x32)) /**< deleting record fails */ -#define MS_ERR_DB_UPDATE_RECORD_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x33)) /**< updating record fails */ -#define MS_ERR_DB_CONNECT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x34)) /**< connecting database fails */ -#define MS_ERR_DB_DISCONNECT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x35)) /**< disconnecting database fails */ -#define MS_ERR_DB_EXIST_ITEM_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x36)) /**< item does not exist */ - -/*drm operation error*/ -#define MS_ERR_DRM_GET_TYPE_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x40)) -#define MS_ERR_DRM_MOVE_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x41)) /**< can't copy/move drm file because of permission */ -#define MS_ERR_DRM_REGISTER_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x42)) -#define MS_ERR_DRM_EXTRACT_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x43)) -#define MS_ERR_DRM_GET_INFO_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x40)) - -/*IPC operation error*/ -#define MS_ERR_SOCKET_CONN (MID_CONTENTS_MGR_ERROR - ERROR(0x50)) /**< Socket connect error */ -#define MS_ERR_SOCKET_BIND (MID_CONTENTS_MGR_ERROR - ERROR(0x51)) /**< Socket connect error */ -#define MS_ERR_SOCKET_MSG (MID_CONTENTS_MGR_ERROR - ERROR(0x52)) /**< Socket message error */ -#define MS_ERR_SOCKET_SEND (MID_CONTENTS_MGR_ERROR - ERROR(0x53)) /**< Socket send error */ -#define MS_ERR_SOCKET_RECEIVE (MID_CONTENTS_MGR_ERROR - ERROR(0x54)) /**< Socket receive error */ - -/*ETC*/ -#define MS_ERR_LOW_MEMORY (MID_CONTENTS_MGR_ERROR - ERROR(0x60)) /**< low memory*/ -#define MS_ERR_UNKNOWN_ERROR (MID_CONTENTS_MGR_ERROR - ERROR(0x61)) /**< unknow error*/ -#define MS_ERR_VCONF_SET_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x62)) /**< vconf set fail*/ -#define MS_ERR_VCONF_GET_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x63)) /**< vconf get fail*/ -#define MS_ERR_MIME_GET_FAIL (MID_CONTENTS_MGR_ERROR - ERROR(0x64)) /**< not media file*/ - -#define MS_ERR_MAX (MID_CONTENTS_MGR_ERROR - ERROR(0xff)) /**< not media file*/ -#endif/* _MEDIA_SERVER_ERROR_H_ */ -/** - * @} - */ diff --git a/common/include/media-server-global.h b/common/include/media-server-global.h deleted file mode 100755 index 183df43..0000000 --- a/common/include/media-server-global.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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-global.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - -#ifndef _MEDIA_SERVER_GLOBAL_H_ -#define _MEDIA_SERVER_GLOBAL_H_ -#include <malloc.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <time.h> -#include <stdbool.h> -#include <unistd.h> -#include <glib.h> -#include <fcntl.h> -#include <dirent.h> -#include <sys/file.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/vfs.h> -#include <sys/syscall.h> -#include <dlfcn.h> -#include <errno.h> - -#include <dlog.h> - -#include "media-server-error.h" -#include "media-server-types.h" - -#define FMS_PERF - -/* To enable progress bar in quickpanel */ -/*#define PROGRESS*/ - -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "MEDIA-SERVER" -#define MS_DBG_FUNC_LINE() LOGD("[%s-%d] debug\n" , __func__ , __LINE__); -#define MS_DBG(fmt, args...) LOGD("[%d, %s-%d] " fmt "\n" , syscall(__NR_gettid), __func__ , __LINE__ , ##args); - -#define MS_DBG_INFO(fmt, args...) do{ if (true) { \ - LOGE("[%s-%d]" fmt "\n", __func__ , __LINE__, ##args); \ - }} while(false) - -#define MS_DBG_WARN(fmt, args...) do{ if (true) { \ - LOGW("[%s-%d]" fmt "\n", __func__ , __LINE__, ##args); \ - }} while(false) - -#define MS_DBG_ERR(fmt, args...) do{ if (true) { \ - LOGE("[%d, %s-%d]" fmt "\n", syscall(__NR_gettid), __func__ , __LINE__, ##args); \ - }} while(false) - -#define MALLOC(a) malloc(a) -#define FREE(a) free(a) - -#define MS_ROOT_PATH_INTERNAL "/opt/media" -#define MS_ROOT_PATH_EXTERNAL "/opt/storage/sdcard" -#define MS_DB_UPDATE_NOTI_PATH "/opt/data/file-manager-service" - -/*This macro is used to save and check information of inserted memory card*/ -#define MS_MMC_INFO_KEY "db/private/mediaserver/mmc_info" - - -/*Use for Poweroff sequence*/ -#define POWEROFF_NOTI_NAME "power_off_start" /*poeroff noti from system-server*/ -#define POWEROFF_DIR_PATH "/opt/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 10000 /*This number uses for stopping Scannig thread*/ - -/** - * @} - */ - -#endif /*_MEDIA_SERVER_GLOBAL_H_*/ diff --git a/common/include/media-server-inotify-internal.h b/common/include/media-server-inotify-internal.h deleted file mode 100755 index 78061de..0000000 --- a/common/include/media-server-inotify-internal.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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> - -#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 /*_MEDIA_SERVER_INOTIFY_INTERNAL_H_*/ diff --git a/common/include/media-server-inotify.h b/common/include/media-server-inotify.h deleted file mode 100755 index 34236b6..0000000 --- a/common/include/media-server-inotify.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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-global.h" - -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/* _MEDIA_SERVER_INOTI_H_ */ diff --git a/common/media-server-db-svc.c b/common/media-server-db-svc.c deleted file mode 100755 index 2b8bf5e..0000000 --- a/common/media-server-db-svc.c +++ /dev/null @@ -1,873 +0,0 @@ -/* - * 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-server-utils.h" -#include "media-server-inotify.h" -#include "media-server-drm.h" -#include "media-server-db-svc.h" - -GMutex * db_mutex; -extern GMutex *queue_mutex; - -GAsyncQueue* soc_queue; -GArray *reg_list; -GMutex *list_mutex; -GMutex *queue_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_ERR_ARG_INVALID; - - /*get content type and mime type from file. */ - /*in case of drm file. */ - if (ms_is_drm_file(path)) { - - ms_inoti_add_ignore_file(path); - - ret = ms_get_mime_in_drm_info(path, mimetype); - if (ret != MS_ERR_NONE) { - MS_DBG_ERR("Fail to get mime"); - return MS_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_ERR_MIME_GET_FAIL; - } - } - - return MS_ERR_NONE; -} - -#define CONFIG_PATH "/opt/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() -{ - char *cret; - 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_ERR_FILE_OPEN_FAIL; - } - while(1) { - cret = fgets(buf, 256, fp); - if (cret == NULL) - 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_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 -1; - } - - /*the number of functions*/ - lib_num = so_array->len; - - MS_DBG("The number of information of so : %d", lib_num); - func_handle = malloc(sizeof(void*) * lib_num); - - 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()); - return -1; - } - lib_index++; - } - - dlerror(); /* Clear any existing error */ - - /*allocate for array of functions*/ - func_array = malloc(sizeof(void*) * lib_num); - for(lib_index = 0 ; lib_index < lib_num; lib_index ++) { - func_array[lib_index] = malloc(sizeof(void*) * eFUNC_MAX); - } - - /*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]); - } - } - - return MS_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); - - *handle = malloc (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_ERR_DB_CONNECT_FAIL; - } - } - - MS_DBG("connect Media DB"); - - g_mutex_unlock(db_mutex); - - return MS_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_ERR_DB_DISCONNECT_FAIL; - } - } - - MS_SAFE_FREE(*handle); - - MS_DBG("Disconnect Media DB"); - - return MS_ERR_NONE; -} - -int -ms_validate_item(void **handle, char *path) -{ - int lib_index; - int res = MS_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_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_ERR_DB_INSERT_RECORD_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_ERR_DB_UPDATE_RECORD_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_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_ERR_DB_UPDATE_RECORD_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_ERR_NONE; - int ret; - - if (path == NULL) { - return MS_ERR_ARG_INVALID; - } - - /*check item in DB. If it exist in DB, return directly.*/ - ret = ms_check_exist(handle, path); - if (ret == MS_ERR_NONE) { - MS_DBG("Already exist"); - return MS_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_ERR_NOW_REGISTER_FILE; - } - g_mutex_unlock(queue_mutex); - - ret = ms_insert_item(handle, path); - if (ret != MS_ERR_NONE) { - int lib_index; - char mimetype[255]; - ms_storage_type_t storage_type; - - ret = _ms_get_mime(path, mimetype); - if (ret != MS_ERR_NONE) { - MS_DBG_ERR("err : _ms_get_mime [%d]", ret); - res = MS_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_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_ERR_DB_INSERT_RECORD_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_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_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_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_ERR_DB_INSERT_RECORD_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_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_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_ERR_DB_INSERT_RECORD_FAIL; - } - } - } - - return res; -} - -int -ms_delete_item(void **handle, const char *path) -{ - int lib_index; - int res = MS_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_ERR_DB_DELETE_RECORD_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_ERR_DB_DELETE_RECORD_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_ERR_NONE; - int ret; - char mimetype[255]; - char *err_msg = NULL; - - ret = _ms_get_mime(dst_path, mimetype); - if (ret != MS_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_ERR_DB_UPDATE_RECORD_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_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_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_ERR_DB_UPDATE_RECORD_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_ERR_DB_EXIST_ITEM_FAIL; - } - } - - return MS_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); - } - } -} diff --git a/common/media-server-dbus.c b/common/media-server-dbus.c deleted file mode 100755 index 9b50e03..0000000 --- a/common/media-server-dbus.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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-global.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 diff --git a/common/media-server-drm.c b/common/media-server-drm.c deleted file mode 100755 index 68609f8..0000000 --- a/common/media-server-drm.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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-server-global.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_ERR_ARG_INVALID; - - 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_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_ERR_NONE; -} - -int -ms_drm_register(const char* path) -{ - MS_DBG("THIS IS DRM FILE"); - int res = MS_ERR_NONE; - int ret; - -// ms_inoti_add_ignore_file(path); - 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_ERR_DRM_REGISTER_FAIL; - } - - return res; -} - -void -ms_drm_unregister(const char* path) -{ - int ret; - ms_ignore_file_info *ignore_file; - - 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); - - ignore_file = ms_inoti_find_ignore_file(path); - if (ignore_file != NULL) - ms_inoti_delete_ignore_file(ignore_file); -} - -void -ms_drm_unregister_all(void) -{ - if (drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_ALL_FILES , NULL, NULL) == DRM_RETURN_SUCCESS) - MS_DBG("drm_svc_unregister_all_contents OK"); -} - -bool -ms_drm_insert_ext_memory(void) -{ - MS_DBG(""); - if (drm_process_request(DRM_REQUEST_TYPE_INSERT_EXT_MEMORY, NULL, NULL) != DRM_RETURN_SUCCESS) - return false; - - return true; -} - -bool -ms_drm_extract_ext_memory(void) -{ - MS_DBG(""); - if (drm_process_request(DRM_REQUEST_TYPE_EXTRACT_EXT_MEMORY , NULL, NULL) != DRM_RETURN_SUCCESS) - return false; - - return true; -} - diff --git a/common/media-server-external-storage.c b/common/media-server-external-storage.c deleted file mode 100755 index 688807f..0000000 --- a/common/media-server-external-storage.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Media Server - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */
-
-#include <vconf.h>
-
-#include "media-server-utils.h"
-#include "media-server-inotify.h"
-#include "media-server-external-storage.h"
-#include "media-server-drm.h"
-
-#define MMC_INFO_SIZE 256
-
-int mmc_state = 0;
-extern GAsyncQueue *scan_queue;
-
-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 { - ms_inoti_add_watch(default_path[i]); - } - } else { - closedir(dp); - } - } -}
-
-int
-_ms_update_mmc_info(const char *cid) -{ - bool res;
- - if (cid == NULL) { - MS_DBG_ERR("Parameters are invalid");
- return MS_ERR_ARG_INVALID; - } - - res = ms_config_set_str(MS_MMC_INFO_KEY, cid); - if (!res) { - MS_DBG_ERR("fail to get MS_MMC_INFO_KEY");
- return MS_ERR_VCONF_SET_FAIL; - } - - return MS_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_ERR_FILE_OPEN_FAIL; - } - fgets(buf, 255, fp); - - fclose(fp); - - return MS_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_ERR_UNKNOWN_ERROR; - } - else { - mmcpath[len] = '\0'; - } - - dp = opendir(mmcpath);
- if (dp == NULL) { - MS_DBG_ERR("dp is NULL");
- return MS_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_ERR_NONE) - break; - else - getdata = true; - }
- } - } - closedir(dp); - - if (getdata == true) { - break; - } - } -
- return MS_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; -}
-
-void
-ms_mmc_removed_handler(void) -{ - ms_scan_data_t *mmc_scan_data; - - mmc_scan_data = malloc(sizeof(ms_scan_data_t)); -
- mmc_scan_data->path = strdup(MS_ROOT_PATH_EXTERNAL);
- mmc_scan_data->scan_type = MS_SCAN_INVALID;
- mmc_scan_data->storage_type = MS_STORATE_EXTERNAL;
- - g_async_queue_push(scan_queue, GINT_TO_POINTER(mmc_scan_data)); - - /*remove added watch descriptors */ - ms_inoti_remove_watch_recursive(MS_ROOT_PATH_EXTERNAL);
- - ms_inoti_delete_mmc_ignore_file(); - - if (!ms_drm_extract_ext_memory())
- MS_DBG_ERR("ms_drm_extract_ext_memory failed");
-} -
-void
-ms_mmc_vconf_cb(void *data) -{ - int status = 0;
- ms_scan_data_t *scan_data; -
- 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 (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED ||
- mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) { - ms_mmc_removed_handler(); - }
- else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { - scan_data = malloc(sizeof(ms_scan_data_t)); - - if (!ms_drm_insert_ext_memory())
- MS_DBG_ERR("ms_drm_insert_ext_memory failed");
- - ms_make_default_path_mmc();
-
- ms_inoti_add_watch_all_directory(MS_STORATE_EXTERNAL);
-
- scan_data->path = strdup(MS_ROOT_PATH_EXTERNAL);
- scan_data->scan_type = ms_get_mmc_state(); - scan_data->storage_type = MS_STORATE_EXTERNAL;
- - MS_DBG("ms_get_mmc_state is %d", scan_data->scan_type); - - g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); - } -
- return; -} -
diff --git a/common/media-server-inotify-internal.c b/common/media-server-inotify-internal.c deleted file mode 100755 index 6048634..0000000 --- a/common/media-server-inotify-internal.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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-server-utils.h" -#include "media-server-inotify-internal.h" - -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_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_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_ERR_NONE) { - MS_DBG_ERR("ms_strappend error : %d", err); - return false; - } - MS_DBG("full path : %s", path); - return true; -} diff --git a/common/media-server-inotify.c b/common/media-server-inotify.c deleted file mode 100755 index 531d1a8..0000000 --- a/common/media-server-inotify.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * 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 <vconf.h> - -#include "media-server-utils.h" -#include "media-server-db-svc.h" -#include "media-server-inotify-internal.h" -#include "media-server-inotify.h" - -extern 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_ERR_INVALID_DIR_PATH; - - dp = opendir(dir_path); - if (dp == NULL) { - MS_DBG_ERR("Fail to open dir %s", dir_path); - return MS_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_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_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_ERR_ARG_INVALID; - } - - dp = opendir(chg_path); - if (dp == NULL) { - MS_DBG_ERR("Fail to open dir %s", chg_path); - return MS_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_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_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_ERR_INVALID_FILE_PATH) - && (des_storage != MS_ERR_INVALID_FILE_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_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_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_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, MS_ROOT_PATH_EXTERNAL) != 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_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_ERR_NONE) - return MS_ERR_INVALID_DIR_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_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_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); - } -} - -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_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 POWER_OFF; - } - - /*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 POWER_OFF; - } else if(strcmp(event->name, "_FILEOPERATION_END") == 0) { - /*file operation is end*/ - /* announce db is updated*/ - ms_set_db_status(MS_DB_UPDATED); - rmdir("/opt/data/file-manager-service/_FILEOPERATION_END"); - goto NEXT_INOTI_EVENT; - } 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)) { - /*Add for fixing prevent defect 2011-02-15 */ - err = ms_strcopy(name, sizeof(name), "%s", event->name); - if (err != MS_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_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_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_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_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_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_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); - } -POWER_OFF: - ms_inoti_remove_watch(MS_DB_UPDATE_NOTI_PATH); - - ms_inoti_remove_watch_recursive(MS_ROOT_PATH_INTERNAL); - ms_inoti_remove_watch_recursive(MS_ROOT_PATH_EXTERNAL); - - 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_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_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_ERR_NONE) - return MS_ERR_INVALID_DIR_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(MS_ROOT_PATH_INTERNAL); - else - root->name = strdup(MS_ROOT_PATH_EXTERNAL); - if (root->name == NULL) { - MS_DBG_ERR("strdup fail"); - 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_ERR_NONE) { - 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_STORATE_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_STORATE_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_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); - if (path) free(path); - dp = NULL; - path = NULL; - - err = _ms_get_path_from_current_node(find_folder, &tmp_root, &root, &path, &depth); - if (err != MS_ERR_NONE) - break; - - if (tmp_root == NULL) - break; - - find_folder = 0; - } - -FREE_RESOURCES: - /*free allocated memory */ - if (path) free(path); - if (dp) closedir(dp); - - cur_node = root; - while (cur_node != NULL) { - next_node = cur_node->next; - free(cur_node->name); - free(cur_node); - cur_node = next_node; - } -}
\ No newline at end of file diff --git a/common/media-server-main.c b/common/media-server-main.c deleted file mode 100755 index 14131ff..0000000 --- a/common/media-server-main.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 <vconf.h> -#include <heynoti.h> -#include <media-util-register.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-scan.h" -#include "media-server-socket.h" -#include "media-server-drm.h" -#include "media-server-dbus.h" - -#define APP_NAME "media-server" - -static int heynoti_id; - -extern GAsyncQueue *scan_queue; -extern GAsyncQueue* ret_queue; -extern GMutex *db_mutex; -extern GMutex *list_mutex; -extern GMutex *queue_mutex; -extern GArray *reg_list; -extern int mmc_state; -extern bool power_off; /*If this is TRUE, poweroff notification received*/ -static GMainLoop *mainloop = NULL; - -bool check_process(pid_t current_pid) -{ - DIR *pdir; - struct dirent pinfo; - struct dirent *result = NULL; - bool ret = false; - int find_pid = 0; - - 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) { - fgets(buff, 128, fp); - 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_scan_data_t *scan_data; - - MS_DBG("++++++++++++++++++++++++++++++++++++++"); - MS_DBG("POWER OFF"); - MS_DBG("++++++++++++++++++++++++++++++++++++++"); - - power_off = true; - - if (scan_queue) { - /*notify to scannig thread*/ - scan_data = malloc(sizeof(ms_scan_data_t)); - scan_data->path = NULL; - scan_data->scan_type = POWEROFF; - g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); - - /*notify to Inotify thread*/ - mkdir(POWEROFF_DIR_PATH, 0777); - rmdir(POWEROFF_DIR_PATH); - } - - if (g_main_loop_is_running(mainloop)) g_main_loop_quit(mainloop); -} - -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_STORATE_EXTERNAL); - if (err != MS_ERR_NONE) - MS_DBG_ERR("ms_change_valid_type fail"); - - ms_config_get_int(VCONFKEY_FILEMANAGER_DB_STATUS, &db_status); - MS_DBG("finish_phone_init_data db = %d", db_status); - - if (db_status == VCONFKEY_FILEMANAGER_DB_UPDATING) { - need_db_create = true; - - err = ms_invalidate_all_items(handle, MS_STORAGE_INTERNAL); - if (err != MS_ERR_NONE) - MS_DBG_ERR("ms_change_valid_type fail"); - } - - ms_set_db_status(MS_DB_UPDATED); - - return need_db_create; -} - -int main(int argc, char **argv) -{ - GThread *inoti_tid = NULL; - GThread *scan_tid = NULL; - GSource *source = NULL; - GIOChannel *channel = NULL; - GMainContext *context = NULL; - - pid_t current_pid = 0; - int sockfd = -1; - int err; - bool check_result = false; - bool need_db_create; - void **handle = NULL; - - ms_scan_data_t *phone_scan_data; - ms_scan_data_t *mmc_scan_data; - - current_pid = getpid(); - check_result = check_process(current_pid); - if (check_result == false) - exit(0); - - if (!g_thread_supported()) { - g_thread_init(NULL); - } - - /*Init main loop*/ - mainloop = g_main_loop_new(NULL, FALSE); - - /*inotify setup */ - ms_inoti_init(); - - /*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)*/ - ms_load_functions(); - - /*Init db mutex variable*/ - if (!db_mutex) db_mutex = g_mutex_new(); - - /*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*)); - - /*connect to media db, if conneting is failed, db updating is stopped*/ - ms_connect_db(&handle); - - /*clear previous data of sdcard on media database and check db status for updating*/ - need_db_create = _db_clear(handle); - - ms_dbus_init(); - - ms_inoti_add_watch(MS_DB_UPDATE_NOTI_PATH); - ms_inoti_add_watch_all_directory(MS_STORAGE_INTERNAL); - - /*These are a communicator for thread*/ - if (!scan_queue) scan_queue = g_async_queue_new(); - if (!ret_queue) ret_queue = g_async_queue_new(); - - /*prepare socket*/ - /* Create and bind new UDP socket */ - if (!ms_prepare_socket(&sockfd)) { - MS_DBG_ERR("Failed to create socket\n"); - } 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); - } - - /*create each threads*/ - inoti_tid = g_thread_create((GThreadFunc) ms_inoti_thread, NULL, TRUE, NULL); - scan_tid = g_thread_create((GThreadFunc) ms_scan_thread, NULL, TRUE, 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); - - phone_scan_data = malloc(sizeof(ms_scan_data_t)); - mmc_scan_data = malloc(sizeof(ms_scan_data_t)); - MS_DBG("*********************************************************"); - MS_DBG("*** Begin to check tables of file manager in database ***"); - MS_DBG("*********************************************************"); - - if (need_db_create) { - /*insert records*/ - phone_scan_data->path = strdup(MS_ROOT_PATH_INTERNAL); - phone_scan_data->storage_type = MS_STORAGE_INTERNAL; - phone_scan_data->scan_type = MS_SCAN_ALL; - /*push data to fex_dir_scan_cb */ - g_async_queue_push(scan_queue, GINT_TO_POINTER(phone_scan_data)); - } - - 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(); - ms_inoti_add_watch_all_directory(MS_STORATE_EXTERNAL); - - mmc_scan_data->path = strdup(MS_ROOT_PATH_EXTERNAL); - mmc_scan_data->scan_type = ms_get_mmc_state(); - mmc_scan_data->storage_type = MS_STORATE_EXTERNAL; - - g_async_queue_push(scan_queue, GINT_TO_POINTER(mmc_scan_data)); - } - - /*Active flush */ - malloc_trim(0); - - MS_DBG("*****************************************"); - MS_DBG("*** Server of File Manager is running ***"); - MS_DBG("*****************************************"); - - g_main_loop_run(mainloop); - - g_thread_join(inoti_tid); - g_thread_join(scan_tid); - - /*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); - - if (scan_queue) g_async_queue_unref(scan_queue); - if (ret_queue) g_async_queue_unref(ret_queue); - if (reg_list) g_array_free(reg_list, true); - - /*********** - **remove call back functions - ************/ - vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, - (vconf_callback_fn) ms_mmc_vconf_cb); - - /*Clear db mutex variable*/ - if (db_mutex) g_mutex_free (db_mutex); - - /*disconnect form media db*/ - if (handle) ms_disconnect_db(&handle); - - /*close socket*/ - close(sockfd); - - /*unload functions*/ - ms_unload_functions(); - - exit(0); -} diff --git a/common/media-server-scan-internal.c b/common/media-server-scan-internal.c deleted file mode 100755 index 5f027c5..0000000 --- a/common/media-server-scan-internal.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * 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-internal.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ -#include <vconf.h> - -#include "media-server-utils.h" -#include "media-server-db-svc.h" -#include "media-server-inotify.h" -#include "media-server-scan-internal.h" - -extern int mmc_state; -bool power_off; - -typedef struct ms_scan_data { - char *name; - struct ms_scan_data *next; -} ms_scan_data; - -ms_scan_data *first_scan_node; - -static int _ms_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_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_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_ERR_NONE) - return MS_ERR_INVALID_DIR_PATH; - - *path = strdup(get_path); - - return err; -} - -static int _ms_scan_add_node(ms_dir_scan_info * const node, int depth) -{ - int err; - char full_path[MS_FILE_PATH_LEN_MAX] = { 0 }; - ms_scan_data *current_dir = NULL; - ms_scan_data *prv_node = NULL; - ms_scan_data *last_node = NULL; - - err = ms_get_full_path_from_node(node, full_path, depth); - if (err != MS_ERR_NONE) - return MS_ERR_INVALID_DIR_PATH; - - last_node = first_scan_node; - while (last_node != NULL) { - last_node = last_node->next; - } - - /*find same folder */ - if (first_scan_node != NULL) { - last_node = first_scan_node; - while (last_node != NULL) { - if (strcmp(full_path, last_node->name) == 0) { - return MS_ERR_NONE; - } - prv_node = last_node; - last_node = last_node->next; - } - } - - current_dir = malloc(sizeof(ms_scan_data)); - current_dir->name = strdup(full_path); - current_dir->next = NULL; - - if (first_scan_node == NULL) { - first_scan_node = current_dir; - } else { - /*if next node of current node is NULL, it is the lastest node. */ - prv_node->next = current_dir; - } - MS_DBG("scan path : %s", full_path); - - return MS_ERR_NONE; -} - -static void _ms_dir_check(ms_scan_data_t * 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 = scan_data->storage_type; - - 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; - } - - root->name = strdup(scan_data->path); - 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_ERR_NONE) { - return; - } - - _ms_scan_add_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_STORATE_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_STORATE_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_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); - 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_scan_add_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 = _ms_scan_get_next_path_from_current_node(find_folder, &tmp_root, &root, &path, &depth); - if (err != MS_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; - } -} - -void _ms_dir_scan(void **handle, ms_scan_data_t * scan_data) -{ - int err = 0; - char path[MS_FILE_PATH_LEN_MAX] = { 0 }; - ms_scan_data *node; - DIR *dp = NULL; - ms_storage_type_t storage_type = scan_data->storage_type; - ms_dir_scan_type_t scan_type = scan_data->scan_type; - - err = ms_strcopy(path, sizeof(path), "%s", scan_data->path); - if (err != MS_ERR_NONE) { - MS_DBG_ERR("error : %d", err ); - } - - /*Add inotify watch */ - if (scan_type != MS_SCAN_INVALID) - _ms_dir_check(scan_data); - - /*if scan type is not MS_SCAN_NONE, check data in db. */ - if (scan_type == MS_SCAN_ALL || scan_type == MS_SCAN_PART) { - struct dirent entry; - struct dirent *result = NULL; - - node = first_scan_node; - - while (node != NULL) { - /*check poweroff status*/ - if (power_off) { - MS_DBG("Power off"); - goto STOP_SCAN; - } - - /*check SD card in out */ - if ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (storage_type == MS_STORATE_EXTERNAL)) { - MS_DBG("Directory scanning is stopped"); - goto STOP_SCAN; - } - - dp = opendir(node->name); - if (dp != NULL) { - while (!readdir_r(dp, &entry, &result)) { - /*check poweroff status*/ - if (power_off) { - MS_DBG("Power off"); - goto STOP_SCAN; - } - - 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_STORATE_EXTERNAL)) { - MS_DBG("Directory scanning is stopped"); - goto STOP_SCAN; - } - - if (entry.d_type & DT_REG) { - err = ms_strappend(path, sizeof(path), "%s/%s", node->name, entry.d_name); - if (err < 0) { - MS_DBG_ERR("error : %d", err); - continue; - } - - if (scan_type == MS_SCAN_PART) - err = ms_validate_item(handle,path); - else - err = ms_insert_item_batch(handle, path); - - if (err < 0) { - MS_DBG_ERR("failed to update db : %d , %d\n", err, scan_type); - continue; - } - } - } - } else { - MS_DBG_ERR("%s folder opendir fails", node->name); - } - if (dp) closedir(dp); - dp = NULL; - - if (node == NULL) { - MS_DBG_ERR("DB updating is done"); - break; - } - node = node->next; - } /*db update while */ - } else if ( scan_type == MS_SCAN_INVALID) { - /*In this case, update just validation record*/ - /*update just valid type*/ - err = ms_invalidate_all_items(handle, storage_type); - if (err != MS_ERR_NONE) - MS_DBG_ERR("error : %d", err); - } -STOP_SCAN: - if (dp) closedir(dp); - - /*delete all node*/ - node = first_scan_node; - - while (node != NULL) { - if (node->name) free(node->name); - MS_SAFE_FREE(node); - } - - first_scan_node = NULL; - - sync(); - - return; -} diff --git a/common/media-server-scan.c b/common/media-server-scan.c deleted file mode 100755 index 6d41de7..0000000 --- a/common/media-server-scan.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 <vconf.h> - -#include "media-server-utils.h" -#include "media-server-db-svc.h" -#include "media-server-external-storage.h" -#include "media-server-scan-internal.h" -#include "media-server-scan.h" - -extern bool power_off; - -GAsyncQueue *scan_queue; -extern int mmc_state; - -#ifdef FMS_PERF -extern struct timeval g_mmc_start_time; -extern struct timeval g_mmc_end_time; -#endif - -static void _insert_array(GArray *garray, ms_scan_data_t *insert_data) -{ - ms_scan_data_t *data; - bool insert_ok = false; - int len = garray->len; - int i; - - MS_DBG("the length of array : %d", len); - MS_DBG("path : %s", insert_data->path); - MS_DBG("scan_type : %d", insert_data->scan_type); - - if (insert_data->scan_type == 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->scan_type != 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); - } -} - -gboolean ms_scan_thread(void *data) -{ - ms_scan_data_t *scan_data = NULL; - ms_scan_data_t *insert_data; - GArray *garray = NULL; - bool res; - int length; - int err; - void **handle = NULL; - ms_storage_type_t storage_type; - ms_dir_scan_type_t scan_type; - - /*create array for processing overlay data*/ - garray = g_array_new (FALSE, FALSE, sizeof (ms_scan_data_t *)); - if (garray == NULL) { - MS_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_scan_data_t*, 0); - g_array_remove_index (garray, 0); - if (scan_data->scan_type == POWEROFF) { - MS_DBG("power off"); - goto POWER_OFF; - } - } else if (length != 0) { - insert_data = g_async_queue_pop(scan_queue); - _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); - _insert_array(garray, insert_data); - continue; - } - - storage_type = scan_data->storage_type; - scan_type = scan_data->scan_type; - - /*connect to media db, if conneting is failed, db updating is stopped*/ - err = ms_connect_db(&handle); - if (err != MS_ERR_NONE) - continue; - - /*start db updating */ - ms_set_db_status(MS_DB_UPDATING); - - /*Delete all data before full scanning*/ - if (scan_type == MS_SCAN_ALL) { - res = ms_delete_all_items(handle, storage_type); - if (res != true) { - MS_DBG_ERR("ms_delete_all_record fails"); - } - } - -#ifdef FMS_PERF - if (storage_type == MS_STORATE_EXTERNAL) { - ms_check_start_time(&g_mmc_start_time); - } -#endif - /*call for bundle commit*/ - ms_register_start(handle); - if (scan_type == MS_SCAN_PART) { - /*enable bundle commit*/ - ms_validate_start(handle); - } - - /*add inotify watch and insert data into media db */ - _ms_dir_scan(handle, scan_data); - - if (power_off) { - MS_DBG("power off"); - goto POWER_OFF; - } - - /*call for bundle commit*/ - ms_register_end(handle); - if (scan_type == MS_SCAN_PART) { - /*disable bundle commit*/ - ms_validate_end(handle); - ms_delete_invalid_items(handle, storage_type); - } - -#ifdef FMS_PERF - if (storage_type == MS_STORATE_EXTERNAL) { - ms_check_end_time(&g_mmc_end_time); - ms_check_time_diff(&g_mmc_start_time, &g_mmc_end_time); - } -#endif - - /*set vconf key mmc loading for indicator */ - ms_set_db_status(MS_DB_UPDATED); - - /*disconnect form media db*/ - if (handle) ms_disconnect_db(&handle); - - /*Active flush */ - malloc_trim(0); - - if (storage_type == MS_STORATE_EXTERNAL && scan_type == MS_SCAN_ALL) { - ms_update_mmc_info(); - } - - MS_SAFE_FREE(scan_data->path); - MS_SAFE_FREE(scan_data); - } /*thread while*/ - -POWER_OFF: - MS_SAFE_FREE(scan_data->path); - MS_SAFE_FREE(scan_data); - if (garray) g_array_free (garray, TRUE); - if (handle) ms_disconnect_db(&handle); - - return false; -} diff --git a/common/media-server-socket.c b/common/media-server-socket.c deleted file mode 100755 index 816c6f5..0000000 --- a/common/media-server-socket.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 <media-util-err.h> - -#include "media-server-global.h" -#include "media-server-db-svc.h" -#include "media-server-socket.h" - -#define MS_REGISTER_PORT 1001 - -GAsyncQueue* ret_queue; - -gboolean ms_read_socket(GIOChannel *src, - GIOCondition condition, - gpointer data) -{ - struct sockaddr_in client_addr; - unsigned int client_addr_len; - - char recv_buff[MS_FILE_PATH_LEN_MAX] = {0}; - int send_msg = MS_MEDIA_ERR_NONE; - int recv_msg_size; - int sock = -1; - int ret; - void **handle = data; - - memset(recv_buff, 0, sizeof(recv_buff)); - - sock = g_io_channel_unix_get_fd(src); - if (sock < 0) { - MS_DBG_ERR("sock fd is invalid!"); - return TRUE; - } - - /* Socket is readable */ - client_addr_len = sizeof(client_addr); - if ((recv_msg_size = recvfrom(sock, &recv_buff, sizeof(recv_buff), 0, (struct sockaddr *)&client_addr, &client_addr_len)) < 0) { - MS_DBG_ERR("recvfrom failed"); - return TRUE; - } - ret = ms_register_file(handle, recv_buff, ret_queue); - if (ret == MS_ERR_NOW_REGISTER_FILE) { - ret= GPOINTER_TO_INT(g_async_queue_pop(ret_queue)) - MS_ERR_MAX; - } - - if (ret != MS_ERR_NONE) { - MS_DBG_ERR("ms_register_file error : %d", ret); - - if(ret == MS_ERR_ARG_INVALID) { - send_msg = MS_MEDIA_ERR_INVALID_PARAMETER; - } else if (ret == MS_ERR_MIME_GET_FAIL) { - send_msg = MS_MEDIA_ERR_INVALID_MEDIA; - } else if (ret == MS_ERR_DB_INSERT_RECORD_FAIL) { - send_msg = MS_MEDIA_ERR_INSERT_FAIL; - } else if (ret == MS_ERR_DRM_REGISTER_FAIL) { - send_msg = MS_MEDIA_ERR_DRM_INSERT_FAIL; - } - } else { - MS_DBG("SOCKET INSERT SECCESS : %s", recv_buff); - send_msg = MS_MEDIA_ERR_NONE; - } - - if (sendto(sock, &send_msg, sizeof(send_msg), 0, (struct sockaddr *)&client_addr, sizeof(client_addr)) != sizeof(send_msg)) { - MS_DBG_ERR("sendto failed"); - } else { - MS_DBG("Sent %d", send_msg); - } - - /*Active flush */ - malloc_trim(0); - - return TRUE; -} - -gboolean ms_prepare_socket(int *sock_fd) -{ - int sock; - struct sockaddr_in serv_addr; - unsigned short serv_port; - - serv_port = MS_REGISTER_PORT; - - /* Creaete a datagram/UDP socket */ - if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - MS_DBG_ERR("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"); - - *sock_fd = sock; - - return TRUE; -} - diff --git a/common/media-server-utils.c b/common/media-server-utils.c deleted file mode 100755 index 76b7db9..0000000 --- a/common/media-server-utils.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * 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 <pmapi.h> -#include <vconf.h> - -#include "media-server-inotify.h" -#include "media-server-utils.h" -#include "media-server-drm.h" -#include "media-server-dbus.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 - -int ums_mode = 0; -extern int mmc_state; - -static int -_ms_set_power_mode(ms_db_status_type_t status) -{ - int res = MS_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_ERR_UNKNOWN_ERROR; - break; - case MS_DB_UPDATED: - err = pm_unlock_state(LCD_OFF, STAY_CUR_STATE); - if (err != 0) - res = MS_ERR_UNKNOWN_ERROR; - 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_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_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_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_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_ERR_INVALID_DIR_PATH; - } - - path_array = malloc(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); - return MS_ERR_INVALID_DIR_PATH; - } - - strncpy(ret_path+path_length, path_array[i], length); - path_length += length; - - ret_path[path_length] = '/'; - path_length ++; - } - - ret_path[-- path_length] = '\0'; - - free(path_array); - - return MS_ERR_NONE; -} - -ms_storage_type_t -ms_get_storage_type_by_full(const char *path) -{ - if (strncmp(path, MS_ROOT_PATH_INTERNAL, strlen(MS_ROOT_PATH_INTERNAL)) == 0) { - return MS_STORAGE_INTERNAL; - } else if (strncmp(path, MS_ROOT_PATH_EXTERNAL, strlen(MS_ROOT_PATH_EXTERNAL)) == 0) { - return MS_STORATE_EXTERNAL; - } else - return MS_ERR_INVALID_FILE_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_ERR_ARG_INVALID; - - if (real_size < (strlen(str1) + strlen(str2))) - return MS_ERR_OUT_OF_RANGE; - - len = snprintf(res, real_size, pattern, str1, str2); - if (len < 0) { - return MS_ERR_ARG_INVALID; - } - - res[len] = '\0'; - - return MS_ERR_NONE; -} - -int -ms_strcopy(char *res, const int size, const char *pattern, const char *str1) -{ - int len = 0; - int real_size = size - 1; - - if (!res || !pattern || !str1) - return MS_ERR_ARG_INVALID; - - if (real_size < strlen(str1)) - return MS_ERR_OUT_OF_RANGE; - - len = snprintf(res, real_size, pattern, str1); - if (len < 0) { - return MS_ERR_ARG_INVALID; - } - - res[len] = '\0'; - - return MS_ERR_NONE; -} - -bool -ms_config_get_int(const char *key, int *value) -{ - int err; - - if (!key || !value) { - MS_DBG_ERR("Arguments key or value is NULL"); - return false; - } - - err = vconf_get_int(key, value); - if (err == 0) - return true; - else if (err == -1) - return false; - else - MS_DBG_ERR("Unexpected error code: %d", err); - - return false; -} - -bool -ms_config_set_int(const char *key, int value) -{ - int err; - - if (!key) { - MS_DBG_ERR("Arguments key is NULL"); - return false; - } - - err = vconf_set_int(key, value); - if (err == 0) - return true; - else if (err == -1) - return false; - else - MS_DBG_ERR("Unexpected error code: %d", err); - - return false; -} - -bool -ms_config_get_str(const char *key, char *value) -{ - char *res; - if (!key || !value) { - MS_DBG_ERR("Arguments key or value is NULL"); - return false; - } - - res = vconf_get_str(key); - if (res) { - strncpy(value, res, strlen(res) + 1); - return true; - } - - return false; -} - -bool -ms_config_set_str(const char *key, const char *value) -{ - int err; - - if (!key || !value) { - MS_DBG_ERR("Arguments key or value is NULL"); - return false; - } - - err = vconf_set_str(key, value); - if (err == 0) - return true; - else - MS_DBG_ERR("fail to vconf_set_str %d", err); - - return false; -} - diff --git a/configure.ac b/configure.ac index 79a1553..edcd8bf 100755 --- a/configure.ac +++ b/configure.ac @@ -12,7 +12,9 @@ AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_CC +AM_PROG_CC_C_O AC_PROG_INSTALL AC_PROG_MAKE_SET AC_PROG_LIBTOOL @@ -33,6 +35,9 @@ fi CPPFLAGS="${CPPFLAGS} -DRND_LINUX" +#For supporting Large file +CPPFLAGS="${CPPFLAGS} -D_FILE_OFFSET_BITS=64" + # FMS_DEBUG - File Manager Service debug options # To open debug options: # export FMS_DEBUG=1 or configure --enable-debug @@ -64,34 +69,72 @@ 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) -# quickpanel library -#PKG_CHECK_MODULES(LIBQUICKPANEL, quickpanel) -#AC_SUBST(LIBQUICKPANEL_CFLAGS) -#AC_SUBST(LIBQUICKPANEL_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) + +dnl use notification -------------------------------------------------------------------------- +AC_ARG_ENABLE(notification, AC_HELP_STRING([--enable-notification], [using notification]), +[ + case "${enableval}" in + yes) USE_NOTIFICATION=yes ;; + no) USE_NOTIFICATION=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-notification) ;; + esac +],[USE_NOTIFICATION=yes]) +if test "x$USE_NOTIFICATION" = "xyes"; then + #ticker noti library + PKG_CHECK_MODULES(STATUS, notification) + AC_SUBST(STATUS_CFLAGS) + AC_SUBST(STATUS_LIBS) +fi +AM_CONDITIONAL(USE_NOTIFICATION, test "x$USE_NOTIFICATION" = "xyes") + + +dnl use deviced -------------------------------------------------------------------------- +AC_ARG_ENABLE(deviced, AC_HELP_STRING([--enable-deviced], [using deviced]), +[ + case "${enableval}" in + yes) USE_DEVICED=yes ;; + no) USE_DEVICED=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-deviced) ;; + esac +],[USE_DEVICED=yes]) +if test "x$USE_DEVICED" = "xyes"; then + PKG_CHECK_MODULES(LIBPMCONTROL, deviced) + AC_SUBST(LIBPMCONTROL_CFLAGS) + AC_SUBST(LIBPMCONTROL_LIBS) +fi +AM_CONDITIONAL(USE_DEVICED, test "x$USE_DEVICED" = "xyes") + +dnl use security server -------------------------------------------------------------------------- +AC_ARG_ENABLE(security-server, AC_HELP_STRING([--enable-security-server], [using security-server]), +[ + case "${enableval}" in + yes) USE_SECURITY=yes ;; + no) USE_SECURITY=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-security-security) ;; + esac +],[USE_SECURITY=yes]) +if test "x$USE_SECURITY" = "xyes"; then + #sercurity server + PKG_CHECK_MODULES(SECURITY, security-server) + AC_SUBST(SECURITY_CFLAGS) + AC_SUBST(SECURITY_LIBS) +fi +AM_CONDITIONAL(USE_SECURITY, test "x$USE_SECURITY" = "xyes") #Checks for header files. AC_HEADER_DIRENT diff --git a/data/mediasvr b/data/mediasvr deleted file mode 100755 index d109017..0000000 --- a/data/mediasvr +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -/usr/bin/media-server& - diff --git a/lib/include/media-server-ipc.h b/lib/include/media-server-ipc.h new file mode 100755 index 0000000..36f667f --- /dev/null +++ b/lib/include/media-server-ipc.h @@ -0,0 +1,122 @@ +/* + * 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 */ + +typedef enum{ + MS_DB_BATCH_UPDATE_PORT = 0, /**< Media DB batch update */ + MS_SCAN_DAEMON_PORT, /**< Port of communication between scanner and server */ + MS_SCANNER_PORT, /**< Directory Scanner */ + MS_DB_UPDATE_PORT, /**< Media DB Update */ + MS_THUMB_CREATOR_PORT, /**< Create thumbnail */ + MS_THUMB_COMM_PORT, /**< Port of communication between creator and server */ + MS_THUMB_DAEMON_PORT, /**< Port of Thumbnail server */ + MS_PORT_MAX, +}ms_msg_port_type_e; + +#define MAX_MSG_SIZE 4096*2 +#define MAX_FILEPATH_LEN 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_BURSTSHOT_INSERT, + 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_STORAGE_META, /**< Request updating meta data */ + MS_MSG_MAX /**< Invalid msg type */ +}ms_msg_type_e; + +#define MS_SCANNER_FIFO_PATH_REQ "/tmp/media-scanner-fifo-req" +#define MS_SCANNER_FIFO_PATH_RES "/tmp/media-scanner-fifo-res" +#define MS_SCANNER_FIFO_MODE 0666 + +typedef struct +{ + int sock_fd; + char *sock_path; +}ms_sock_info_s; + +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_FILEPATH_LEN]; + char dst_path[MAX_FILEPATH_LEN]; +} thumbMsg; + + +#endif /*_MEDIA_SERVER_IPC_H_*/ diff --git a/common/include/media-server-scan-internal.h b/lib/include/media-util-db.h index 5f34fee..efbea0f 100755 --- a/common/include/media-server-scan-internal.h +++ b/lib/include/media-util-db.h @@ -1,5 +1,5 @@ /* - * Media Server + * Media Utility * * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. * @@ -22,17 +22,40 @@ /** * This file defines api utilities of contents manager engines. * - * @file media-server-scan-internal.h + * @file media-util-noti.h * @author Yong Yeon Kim(yy9875.kim@samsung.com) * @version 1.0 * @brief */ -#ifndef _MEDIA_SERVER_SCAN_INTERNAL_H_ -#define _MEDIA_SERVER_SCAN_INTERNAL_H_ + #ifndef _MEDIA_UTIL_DB_H_ +#define _MEDIA_UTIL_DB_H_ -#include "media-server-global.h" -#include "media-server-types.h" +#ifdef __cplusplus +extern "C" { +#endif -void _ms_dir_scan(void **handle, ms_scan_data_t * scan_data); +typedef void MediaDBHandle; /**< Handle */ -#endif /*_MEDIA_SERVER_SCAN_INTERNAL_H_*/ +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_update_db_batch_clear(void); + +/** +* @} +*/ + +#ifdef __cplusplus +} +#endif + +#endif /*_MEDIA_UTIL_DB_H_*/ diff --git a/lib/include/media-util-dbg.h b/lib/include/media-util-dbg.h index 10b72b9..d5e06a3 100755 --- a/lib/include/media-util-dbg.h +++ b/lib/include/media-util-dbg.h @@ -33,13 +33,62 @@ #include <stdio.h> #include <stdlib.h> #include <dlog.h> +#include <error.h> #ifdef LOG_TAG #undef LOG_TAG #endif -#define LOG_TAG "MEDIA-UTIL" +#define LOG_TAG "MEDIA_UTIL" +#define BUF_LENGTH 256 -#define MSAPI_DBG(fmt, arg...) LOGD("[%s : %d] [%s] " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ##arg) +#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_STRERROR(fmt) do { \ + char buf[BUF_LENGTH] = {0,}; \ + strerror_r(errno, buf, BUF_LENGTH); \ + LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + } while (0) + +#define MSAPI_DBG_SLOG(fmt, args...) do { \ + SECURE_LOGD(fmt "\n", ##args); \ + } while (0) + +#define MSAPI_DBG(fmt, arg...) do { \ + LOGD(FONT_COLOR_RESET fmt, ##arg); \ + } while (0) + +#define MSAPI_DBG_INFO(fmt, arg...) do { \ + LOGI(FONT_COLOR_GREEN fmt, ##arg); \ + } while (0) + +#define MSAPI_DBG_ERR(fmt, arg...) do { \ + LOGE(FONT_COLOR_RED fmt, ##arg); \ + } while (0) + +#define MSAPI_DBG_FUNC() do { \ + LOGD(FONT_COLOR_RESET); \ + } while (0) + +#define MSAPI_RETV_IF(expr, val) do { \ + if(expr) { \ + LOGE(FONT_COLOR_RED); \ + return (val); \ + } \ + } while (0) + +#define MSAPI_RETVM_IF(expr, val, fmt, arg...) do { \ + if(expr) { \ + LOGE(FONT_COLOR_RED fmt, ##arg); \ + return (val); \ + } \ + } while (0) #endif /*_MEDIA_UTIL_DBG_H_*/ diff --git a/lib/include/media-util-err.h b/lib/include/media-util-err.h index 241742f..c39e7c4 100755 --- a/lib/include/media-util-err.h +++ b/lib/include/media-util-err.h @@ -30,27 +30,64 @@ #ifndef _MEDIA_UTIL_ERR_H_ #define _MEDIA_UTIL_ERR_H_ -#define MS_ERROR_MASKL16 0xFFFF -#define MS_ERROR(X) (X & MS_ERROR_MASKL16) - #define MS_MEDIA_ERR_NONE 0 -#define MS_MEDIA_ERR_OCCURRED (MS_MEDIA_ERR_NONE - MS_ERROR(0x01)) -#define MS_MEDIA_ERR_INVALID_PARAMETER (MS_MEDIA_ERR_NONE - MS_ERROR(0x01)) /**< invalid parameter(s) */ -#define MS_MEDIA_ERR_INVALID_PATH (MS_MEDIA_ERR_NONE - MS_ERROR(0x02)) /**< Invalid file path */ -#define MS_MEDIA_ERR_SOCKET_CONN (MS_MEDIA_ERR_NONE - MS_ERROR(0x03))/**< Socket connect error */ -#define MS_MEDIA_ERR_SOCKET_MSG (MS_MEDIA_ERR_NONE - MS_ERROR(0x04))/**< Socket message error */ -#define MS_MEDIA_ERR_SOCKET_SEND (MS_MEDIA_ERR_NONE - MS_ERROR(0x05))/**< Socket send error */ -#define MS_MEDIA_ERR_SOCKET_RECEIVE (MS_MEDIA_ERR_NONE - MS_ERROR(0x06))/**< Socket receive error */ -#define MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT (MS_MEDIA_ERR_NONE - MS_ERROR(0x07))/**< Socket time out */ +/* internal operation error*/ +#define MS_MEDIA_ERR_INTERNAL -1 +#define MS_MEDIA_ERR_INVALID_PARAMETER -2 /* invalid parameter(s) */ +#define MS_MEDIA_ERR_INVALID_PATH -3 /* Invalid path */ +#define MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL -4 /* exception of memory allocation */ +#define MS_MEDIA_ERR_NOT_ENOUGH_SPACE -5 /* not enough space in storage */ + +/* 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_BUSY_FAIL -16 /* DB Busy */ +#define MS_MEDIA_ERR_DB_CONSTRAINT_FAIL -17 /* DB CONSTRAINT fails - In case of insert, the record already exists */ +#define MS_MEDIA_ERR_DB_BATCH_UPDATE_BUSY -18 /* Batch update thread is full */ + +/* IPC operation error*/ +#define MS_MEDIA_ERR_SOCKET_INTERNAL -21 /* receive error from socket API */ +#define MS_MEDIA_ERR_SOCKET_CONN -22 /* socket connect error */ +#define MS_MEDIA_ERR_SOCKET_BIND -23 /* socket binding fails */ +#define MS_MEDIA_ERR_SOCKET_SEND -24 /* socket sending fails */ +#define MS_MEDIA_ERR_SOCKET_RECEIVE -25 /* socket receiving fails */ +#define MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT -26 /* socket receive timeout error */ +#define MS_MEDIA_ERR_SOCKET_ACCEPT -27 /* socket accept fails */ + +#define MS_MEDIA_ERR_DBUS_ADD_FILTER -31 /* DBUS add filter fails*/ +#define MS_MEDIA_ERR_DBUS_GET -32 /* DBUS get fails */ + +#define MS_MEDIA_ERR_FIFO_MAKE_FAIL -41 /* FIFO making fails */ + +/* DIRECTORY error*/ +#define MS_MEDIA_ERR_DIR_OPEN_FAIL -51 /* direcotry opennig fails */ +#define MS_MEDIA_ERR_DIR_CLOSE_FAIL -53 /* directory closing fails */ +#define MS_MEDIA_ERR_DIR_READ_FAIL -52 /* directory reading fails */ + +/* FILE error*/ +#define MS_MEDIA_ERR_FILE_OPEN_FAIL -61 /* file opennig fails */ +#define MS_MEDIA_ERR_FILE_CLOSE_FAIL -62 /* file closing fails */ +#define MS_MEDIA_ERR_FILE_READ_FAIL -63 /* file reading fails */ +#define MS_MEDIA_ERR_FILE_WRITE_FAIL -64 /* file writing fails */ -#define MS_MEDIA_ERR_INVALID_MEDIA (MS_MEDIA_ERR_NONE - MS_ERROR(0x08))/**< Invalid media content */ -#define MS_MEDIA_ERR_INSERT_FAIL (MS_MEDIA_ERR_NONE - MS_ERROR(0x09))/**< DB insert fail */ -#define MS_MEDIA_ERR_DRM_INSERT_FAIL (MS_MEDIA_ERR_NONE - MS_ERROR(0x0a))/**< DRM file insert fail */ +/* MEDIA SERVER error*/ +#define MS_MEDIA_ERR_DB_SERVER_BUSY_FAIL -101 /* DB server busy */ +#define MS_MEDIA_ERR_SCANNER_FORCE_STOP -102 /* scanning is stopped forcely */ +#define MS_MEDIA_ERR_PERMISSION_DENIED -103 /* Do have permission of request */ -#define MS_MEDIA_ERR_DBUS_ADD_FILTER (MS_MEDIA_ERR_NONE - MS_ERROR(0x0b)) -#define MS_MEDIA_ERR_DBUS_GET (MS_MEDIA_ERR_NONE - MS_ERROR(0x0c)) +/*ETC*/ +#define MS_MEDIA_ERR_VCONF_SET_FAIL -201 /* vconf setting fails*/ +#define MS_MEDIA_ERR_VCONF_GET_FAIL -202 /* vconf getting fails*/ +#define MS_MEDIA_ERR_SCANNER_NOT_READY -203 /* scanner is not ready */ +#define MS_MEDIA_ERR_DYNAMIC_LINK -204 /* fail to dynamic link */ +#define MS_MEDIA_ERR_INVALID_IPC_MESSAGE -205 /* received message is not valid */ +#define MS_MEDIA_ERR_DATA_TAINTED -206 /* received data is tainted */ +#define MS_MEDIA_ERR_SEND_NOTI_FAIL -207 /* sending notification is failed */ -#define MS_MEDIA_ERR_UNKNOWN (MS_MEDIA_ERR_NONE - MS_ERROR(0x10)) /**<Unknown error*/ +#define MS_MEDIA_ERR_MAX -999 #endif /*_MEDIA_UTIL_ERR_H_*/ diff --git a/lib/include/media-util-internal.h b/lib/include/media-util-internal.h index f1922dd..7cf8396 100755 --- a/lib/include/media-util-internal.h +++ b/lib/include/media-util-internal.h @@ -22,29 +22,34 @@ /** * This file defines api utilities of contents manager engines. * - * @file media-util-global.h + * @file media-util-internal.h * @author Yong Yeon Kim(yy9875.kim@samsung.com) * @version 1.0 * @brief */ -#ifndef _MEDIA_UTIL_GLOBAL_H_ -#define _MEDIA_UTIL_GLOBAL_H_ +#ifndef _MEDIA_UTIL_INTERNAL_H_ +#define _MEDIA_UTIL_INTERNAL_H_ -#define MS_SAFE_FREE(src) { if(src) {free(src); src = NULL;} } - -#define MS_MEDIA_TIMEOUT_SEC 10 /*timeout of waiting reponse for IPC*/ +#include "media-util-db.h" -#define MS_MEDIA_UPDATE_NOTI_PATH "/opt/data/file-manager-service/_FILEOPERATION_END" +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif -#define MS_MEDIA_REGISTER_PORT 1001 +#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);} } +#define MS_STRING_VALID(str) \ + ((str != NULL && strlen(str) > 0) ? TRUE : FALSE) -#define MS_MEDIA_PHONE_ROOT_PATH "/opt/media" -#define MS_MEDIA_MMC_ROOT_PATH "/opt/storage/sdcard" +int media_db_update_db(MediaDBHandle *handle, const char *query_str); -#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'" +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_GLOBAL_H_*/ +#endif /*_MEDIA_UTIL_INTERNAL_H_*/ diff --git a/lib/include/media-util-ipc.h b/lib/include/media-util-ipc.h new file mode 100755 index 0000000..aa4d8c5 --- /dev/null +++ b/lib/include/media-util-ipc.h @@ -0,0 +1,66 @@ +/* + * 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/un.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, ms_sock_info_s* sock_info); +int ms_ipc_create_server_socket(ms_protocol_e protocol, ms_msg_port_type_e port, int *sock_fd); +int ms_ipc_send_msg_to_server(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr); +int ms_ipc_send_msg_to_server_tcp(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr); +int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr); +int ms_ipc_send_msg_to_client_tcp(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr); +int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *client_addr, unsigned int *size); +int ms_ipc_receive_message_tcp(int client_sock, ms_comm_msg_s *recv_msg); +int ms_ipc_wait_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *recv_addr, unsigned int *size); +int ms_ipc_delete_client_socket(ms_sock_info_s* sock_info); +int ms_ipc_accept_client_tcp(int serv_sock, int* client_sock); + +#ifdef __cplusplus +} +#endif + +#endif /*_MEDIA_UTIL_IPC_H_*/ diff --git a/lib/include/media-util-noti-common.h b/lib/include/media-util-noti-common.h new file mode 100755 index 0000000..60e8cf4 --- /dev/null +++ b/lib/include/media-util-noti-common.h @@ -0,0 +1,82 @@ +/* + * 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-not-commoni.h + * @author Yong Yeon Kim(yy9875.kim@samsung.com) + * @version 1.0 + * @brief + */ + #ifndef _MEDIA_UTIL_NOTI_COMMON_H_ +#define _MEDIA_UTIL_NOTI_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MS_MEDIA_ITEM_FILE = 0, + MS_MEDIA_ITEM_DIRECTORY = 1, +}media_item_type_e; + +typedef enum { + MS_MEDIA_ITEM_INSERT = 0, + MS_MEDIA_ITEM_DELETE = 1, + MS_MEDIA_ITEM_UPDATE = 2, +}media_item_update_type_e; + +typedef enum { + MS_MEDIA_UNKNOWN = -1, /**< Unknown Conntent*/ + MS_MEDIA_IMAGE = 0, /**< Image Content*/ + MS_MEDIA_VIDEO = 1, /**< Video Content*/ + MS_MEDIA_SOUND = 2, /**< Sound Content like Ringtone*/ + MS_MEDIA_MUSIC = 3, /**< Music Content like mp3*/ + MS_MEDIA_OTHER = 4, /**< Invalid Content*/ +}media_type_e; + +typedef void (*db_update_cb)(int pid, /* mandatory */ + media_item_type_e item, /* mandatory */ + media_item_update_type_e update_type, /* mandatory */ + char* path, /* mandatory */ + char* uuid, /* optional */ + media_type_e media_type, /* optional */ + char *mime_type, /* optional */ + void *user_data); + +typedef void (*clear_user_data_cb)(void * user_data); + +typedef void *MediaNotiHandle; /**< Handle */ + +#define MS_MEDIA_DBUS_PATH "/com/mediaserver/dbus/notify" +#define MS_MEDIA_DBUS_INTERFACE "com.mediaserver.dbus.Signal" +#define MS_MEDIA_DBUS_MATCH_RULE "type='signal',interface='com.mediaserver.dbus.Signal'" + +/** +* @} +*/ + +#ifdef __cplusplus +} +#endif + +#endif /*_MEDIA_UTIL_NOTI_COMMON_H_*/ diff --git a/lib/include/media-util-noti.h b/lib/include/media-util-noti.h index 3ebb97b..c7e8b28 100755 --- a/lib/include/media-util-noti.h +++ b/lib/include/media-util-noti.h @@ -34,48 +34,10 @@ extern "C" { #endif -/** -* @fn int ms_noti_db_update_complete(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 <string.h> -#include <media-service-noti.h> - - int main() - { - int result; - - .... - file operation (copy/move/delete) - .... - - result = ms_noti_db_update_complete(); - if( result < 0 ) - { - printf("FAIL to ms_noti_db_update_complete\n"); - return 0; - } - else - { - printf("SUCCESS to ms_noti_db_update_complete\n"); - } - - return 0; - } - -* @endcode -*/ - -int ms_noti_update_complete(void); +#include "media-util-noti-common.h" /** -* @fn int ms_noti_db_update_complete(void); +* @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 @@ -108,10 +70,18 @@ main (int argc, char **argv) */ -typedef void (*db_update_cb)(void); +int media_db_update_subscribe(db_update_cb user_cb, void *user_data); -int media_db_update_subscribe(db_update_cb user_cb); +int media_db_update_unsubscribe(void); +int media_db_update_send(int pid, /* mandatory */ + media_item_type_e item, /* mandatory */ + media_item_update_type_e update_type, /* mandatory */ + char* path, /* mandatory */ + char* uuid, /* optional */ + media_type_e media_type, /* optional */ + char *mime_type /* optional */ + ); /** * @} diff --git a/lib/include/media-util-register.h b/lib/include/media-util-register.h index e61d19d..cc6e16e 100755 --- a/lib/include/media-util-register.h +++ b/lib/include/media-util-register.h @@ -31,62 +31,34 @@ #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/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() +typedef enum { - int result = -1; - - result = ms_media_file_register("/opt/media/test.mp3"); - if( result < 0 ) - { - printf("FAIL to mediainfo_register_file\n"); - return 0; - } - else - { - printf("SUCCESS to register file\n"); - } + MEDIA_DIRECTORY_SCAN = 0, + MEDIA_FILES_REGISTER, +} media_request_type_e; - return 0; -} - - * @endcode - */ -int media_file_register(const char *file_full_path); - - typedef GArray* media_list; +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; -int media_list_new(media_list *list); +typedef void (*scan_complete_cb)(media_request_result_s *, void *); +typedef void (*insert_complete_cb)(media_request_result_s *, void *); -int media_list_add(media_list list, const char* file_full_path); +int media_directory_scanning_async(const char *directory_path, bool recursive_on, scan_complete_cb user_callback, void *user_data); -int media_list_free(media_list list); +int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data); -int media_files_register(const media_list list); +int media_burstshot_register(const char *list_path, insert_complete_cb user_callback, void *user_data); /** * @} diff --git a/lib/include/media-util.h b/lib/include/media-util.h new file mode 100755 index 0000000..f7e6948 --- /dev/null +++ b/lib/include/media-util.h @@ -0,0 +1,41 @@ +/* + * 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 STORAGE_PATH "/opt/storage" + +#define MEDIA_ROOT_PATH_INTERNAL MOUNT_PATH"/media" +#define MEDIA_ROOT_PATH_SDCARD STORAGE_PATH"/sdcard" + +#define MEDIA_THUMB_ROOT_PATH MOUNT_PATH"/share/media" +#define MEDIA_DB_NAME MOUNT_PATH"/dbspace/.media.db" /**< media db name*/ +#define MEDIA_DATA_PATH MOUNT_PATH"/data/file-manager-service" + +#endif /*_MEDIA_UTIL_H_*/ diff --git a/lib/media-util-db.c b/lib/media-util-db.c new file mode 100755 index 0000000..a094eee --- /dev/null +++ b/lib/media-util-db.c @@ -0,0 +1,567 @@ +/* + * 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 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; +} + +extern char MEDIA_IPC_PATH[][50]; +#define MAX_RETRY_COUNT 3 + +static int __media_db_request_update_tcp(ms_msg_type_e msg_type, const char *request_msg) +{ + int ret = MS_MEDIA_ERR_NONE; + int request_msg_size = 0; + int sockfd = -1; + ms_sock_info_s sock_info; + struct sockaddr_un serv_addr; + int port = MS_DB_UPDATE_PORT; + int retry_count = 0; + + 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_TCP, MS_TIMEOUT_SEC_10, &sock_info); + sockfd = sock_info.sock_fd; + MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); + + /*Set server Address*/ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; +// MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[port]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); + + /* Connecting to the media db server */ + if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + MSAPI_DBG_STRERROR("connect error"); + close(sockfd); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + /* Send request */ + if (send(sockfd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { + MSAPI_DBG_STRERROR("send failed"); + close(sockfd); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + /*Receive Response*/ + int recv_msg_size = -1; + int recv_msg = -1; +RETRY: + if ((recv_msg_size = recv(sockfd, &recv_msg, sizeof(recv_msg), 0)) < 0) { + MSAPI_DBG_ERR("recv failed : [%d]", sockfd); + + if (errno == EINTR) { + MSAPI_DBG_STRERROR("catch interrupt"); + goto RETRY; + } + + if (errno == EWOULDBLOCK) { + if(retry_count < MAX_RETRY_COUNT) { + MSAPI_DBG_ERR("TIME OUT[%d]", retry_count); + retry_count ++; + goto RETRY; + } + + close(sockfd); + MSAPI_DBG_ERR("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recv failed"); + + close(sockfd); + + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + + MSAPI_DBG("RECEIVE OK [%d]", recv_msg); + ret = recv_msg; + + close(sockfd); + + return ret; +} + +static __thread 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; + ms_sock_info_s sock_info; + struct sockaddr_un serv_addr; + int port = MS_DB_BATCH_UPDATE_PORT; + + /*Create TCP Socket*/ + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info); + sockfd = sock_info.sock_fd; + MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); + + /*Set server Address*/ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; +// MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[port]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); + + /* Connecting to the media db server */ + if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + MSAPI_DBG_STRERROR("connect error"); + 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() +{ + int ret = MS_MEDIA_ERR_NONE; + + if (g_tcp_client_sock != -1) { + if (close(g_tcp_client_sock)<0) { + MSAPI_DBG_ERR("sock(%d) close failed", g_tcp_client_sock); + MSAPI_DBG_STRERROR("socket close failed"); + ret = MS_MEDIA_ERR_SOCKET_INTERNAL; + } + g_tcp_client_sock = -1; + } + + return ret; +} + +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_SLOG("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_STRERROR("send failed"); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + /*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 : [%d]", sockfd); + if (errno == EWOULDBLOCK) { + MSAPI_DBG_ERR("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recv failed"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + + MSAPI_DBG("RECEIVE OK [%d]", recv_msg); + ret = recv_msg; + + if (ret != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("batch updated[%d] failed, error [%d]", msg_type, ret); + } + + 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_SLOG("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", sql_str); + MSAPI_DBG_ERR("ERROR [%s]", zErrMsg); + if (ret == SQLITE_BUSY) + ret = MS_MEDIA_ERR_DB_BUSY_FAIL; + else if (ret == SQLITE_CONSTRAINT) + ret = MS_MEDIA_ERR_DB_CONSTRAINT_FAIL; + else + ret = MS_MEDIA_ERR_DB_UPDATE_FAIL; + } + + 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_tcp(MS_MSG_DB_UPDATE, query_str); + if (ret != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("__media_db_request_update_tcp failed : %d", ret); + } + + 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); + if (ret != MS_MEDIA_ERR_NONE) { + __media_db_close_tcp_client_socket(); + } + + 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); + if (ret != MS_MEDIA_ERR_NONE) { + __media_db_close_tcp_client_socket(); + } + + 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_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; +} + +int media_db_request_update_db_batch_clear(void) +{ + int ret = MS_MEDIA_ERR_NONE; + + __media_db_destroy_sql_list(); + + return ret; +} diff --git a/lib/media-util-ipc.c b/lib/media-util-ipc.c new file mode 100755 index 0000000..e1c67c0 --- /dev/null +++ b/lib/media-util-ipc.c @@ -0,0 +1,433 @@ +/* + * 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 <sys/stat.h> + +#include "media-util-dbg.h" +#include "media-util.h" + +char MEDIA_IPC_PATH[][50] ={ + {"/tmp/.media_ipc_dbbatchupdate"}, + {"/tmp/.media_ipc_scandaemon"}, + {"/tmp/.media_ipc_scanner"}, + {"/tmp/.media_ipc_dbupdate"}, + {"/tmp/.media_ipc_thumbcreator"}, + {"/tmp/.media_ipc_thumbcomm"}, + {"/tmp/.media_ipc_thumbdaemon"}, +}; + +#define MS_SOCK_PATH_PRFX "/tmp/.media_ipc_client" +#define MS_SOCK_PATH_TEMPLATE "XXXXXX" +#define MS_SOCK_PATH MS_SOCK_PATH_PRFX MS_SOCK_PATH_TEMPLATE + +static const char abc[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +static int __make_rand_sock_and_bind(int sockfd, struct sockaddr_un *serv_addr, char *sock_path) +{ + int count; + char *rand_str = NULL; + int len = 0; + int ret = MS_MEDIA_ERR_NONE; + unsigned int seed = time(NULL); + + len = strlen(sock_path); + + rand_str = &sock_path[len -strlen(MS_SOCK_PATH_TEMPLATE)]; + + for (count = 0; count < TMP_MAX; count++) { + + srand((unsigned int) time(0) + getpid()); + + rand_str[0] = abc[rand_r(&seed) % 62]; + rand_str[1] = abc[rand_r(&seed) % 62]; + rand_str[2] = abc[rand_r(&seed) % 62]; + rand_str[3] = abc[rand_r(&seed) % 62]; + rand_str[4] = abc[rand_r(&seed) % 62]; + rand_str[5] = abc[rand_r(&seed) % 62]; + + strncpy(serv_addr->sun_path, sock_path, strlen(sock_path)); + + /* Bind to the local address */ + if (bind(sockfd, (struct sockaddr *)serv_addr, sizeof(struct sockaddr_un)) < 0) { + MSAPI_DBG_STRERROR("bind failed"); + if(errno == EADDRINUSE) { + if (count == TMP_MAX -1) { + MSAPI_DBG_ERR("bind failed : arrive max count %d", TMP_MAX); + ret = MS_MEDIA_ERR_SOCKET_BIND; + break; + } + MSAPI_DBG_ERR("retry bind %d", count); + continue; + } else { + MSAPI_DBG_ERR("socket bind failed"); + close(sockfd); + ret= MS_MEDIA_ERR_SOCKET_BIND; + break; + } + } else { + ret = MS_MEDIA_ERR_NONE; + break; + } + } + + return ret; +} + +int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, ms_sock_info_s* sock_info) +{ + int sock = -1; + int err = MS_MEDIA_ERR_NONE; + struct sockaddr_un serv_addr; + char sock_path_temp[] = MS_SOCK_PATH; + + struct timeval tv_timeout = { timeout_sec, 0 }; + + if(protocol == MS_PROTOCOL_UDP) + { + /* Create a datagram/UDP socket */ + if ((sock = socket(PF_FILE, SOCK_DGRAM, 0)) < 0) { + MSAPI_DBG_STRERROR("socket failed"); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; + /* make temp file for socket*/ + err = __make_rand_sock_and_bind(sock, &serv_addr, sock_path_temp); + if (err != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("__make_rand_sock_and_bind failed"); + return err; + } + } + else + { + /*Create TCP Socket*/ + if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + MSAPI_DBG_STRERROR("socket failed"); + 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_STRERROR("setsockopt failed"); + close(sock); + return MS_MEDIA_ERR_SOCKET_CONN; + } + } + + sock_info->sock_fd = sock; + if(protocol == MS_PROTOCOL_UDP) + sock_info->sock_path = strdup(sock_path_temp); + else + sock_info->sock_path = NULL; + + return MS_MEDIA_ERR_NONE; +} + +int ms_ipc_delete_client_socket(ms_sock_info_s* sock_info) +{ + int err = 0; + + close(sock_info->sock_fd); + MSAPI_DBG("sockfd %d close", sock_info->sock_fd); + if (sock_info->sock_path != NULL) { + err = unlink(sock_info->sock_path); + if (err< 0) { + MSAPI_DBG_STRERROR("unlink failed"); + } + free(sock_info->sock_path); + } + + return 0; +} + +int ms_ipc_create_server_socket(ms_protocol_e protocol, ms_msg_port_type_e port, int *sock_fd) +{ + int i; + bool bind_success = false; + int sock = -1; + struct sockaddr_un serv_addr; + unsigned short serv_port; + + serv_port = port; + + if(protocol == MS_PROTOCOL_UDP) + { + /* Create a datagram/UDP socket */ + if ((sock = socket(PF_FILE, SOCK_DGRAM, 0)) < 0) { + MSAPI_DBG_STRERROR("socket failed"); + return MS_MEDIA_ERR_SOCKET_CONN; + } + } + else + { + /* Create a TCP socket */ + if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + MSAPI_DBG_STRERROR("socket failed"); + return MS_MEDIA_ERR_SOCKET_CONN; + } + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + + serv_addr.sun_family = AF_UNIX; +// MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[serv_port]); + unlink(MEDIA_IPC_PATH[serv_port]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[serv_port], strlen(MEDIA_IPC_PATH[serv_port])); + + /* Bind to the local address */ + for (i = 0; i < 20; i ++) { + if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) { + bind_success = true; + break; + } + MSAPI_DBG("%d",i); + usleep(250000); + } + + if (bind_success == false) { + MSAPI_DBG_STRERROR("bind failed"); + 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"); + close(sock); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + MSAPI_DBG("Listening..."); + } + + /*change permission of sock file*/ + if (chmod(MEDIA_IPC_PATH[serv_port], 0660) < 0) { + MSAPI_DBG_STRERROR("chmod failed"); + } + + if (chown(MEDIA_IPC_PATH[serv_port], 0, 5000) < 0) { + MSAPI_DBG_STRERROR("chown failed"); + } + *sock_fd = sock; + + return MS_MEDIA_ERR_NONE; +} + +int ms_ipc_send_msg_to_server(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr) +{ + int res = MS_MEDIA_ERR_NONE; + struct sockaddr_un addr; + + /* Set server Address */ + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); +// MSAPI_DBG_SLOG("%s", addr.sun_path); + + if (sendto(sockfd, send_msg, sizeof(*(send_msg)), 0, (struct sockaddr *)&addr, sizeof(addr)) != sizeof(*(send_msg))) { + MSAPI_DBG_STRERROR("sendto failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%s]", send_msg->msg); + if (serv_addr != NULL) + *serv_addr = addr; + } + + return res; +} + +int ms_ipc_send_msg_to_server_tcp(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr) +{ + int res = MS_MEDIA_ERR_NONE; + struct sockaddr_un addr; + + /* Set server Address */ + memset(&addr, 0, sizeof(addr)); + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); +// MSAPI_DBG("%s", addr.sun_path); + + /* Connecting to the media db server */ + if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + MSAPI_DBG_STRERROR("connect error"); + close(sockfd); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + if (write(sockfd, send_msg, sizeof(*(send_msg))) != sizeof(*(send_msg))) { + MSAPI_DBG_STRERROR("write failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%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_un *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_STRERROR("sendto failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%s]", send_msg->msg); + } + + return res; +} + +int ms_ipc_send_msg_to_client_tcp(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr) +{ + int res = MS_MEDIA_ERR_NONE; + + if (write(sockfd, send_msg, sizeof(*(send_msg))) != sizeof(*(send_msg))) { + MSAPI_DBG_STRERROR("sendto failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%s]", send_msg->msg); + } + + return res; +} + +int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *recv_addr, unsigned int *addr_size) +{ + int recv_msg_size; + struct sockaddr_un addr; + socklen_t addr_len; + + if (!recv_msg) + return MS_MEDIA_ERR_INVALID_PARAMETER; + + addr_len = sizeof(addr); + if ((recv_msg_size = recvfrom(sockfd, recv_msg, msg_size, 0, (struct sockaddr *)&addr, &addr_len)) < 0) { + MSAPI_DBG_STRERROR("recvfrom failed"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + + MSAPI_DBG_SLOG("the path of received client address : %s", addr.sun_path); + + 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_un *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_un); + if ((recv_msg_size = recvfrom(sockfd, recv_msg, msg_size, 0, (struct sockaddr *)recv_addr, &addr_len)) < 0) { + MSAPI_DBG_STRERROR("recvfrom failed"); + if (errno == EWOULDBLOCK) { + MSAPI_DBG_ERR("recvfrom Timeout."); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recvfrom error"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + + if (addr_size != NULL) + *addr_size = addr_len; + + return MS_MEDIA_ERR_NONE; +} + +int ms_ipc_accept_client_tcp(int serv_sock, int* client_sock) +{ + int sockfd = -1; + struct sockaddr_un client_addr; + socklen_t client_addr_len; + + if (client_sock == NULL) + return MS_MEDIA_ERR_INVALID_PARAMETER; + + client_addr_len = sizeof(client_addr); + if ((sockfd = accept(serv_sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { + MSAPI_DBG_STRERROR("accept failed"); + *client_sock = -1; + return MS_MEDIA_ERR_SOCKET_ACCEPT; + } + + *client_sock = sockfd; + + return MS_MEDIA_ERR_NONE; +} + +int ms_ipc_receive_message_tcp(int client_sock, ms_comm_msg_s *recv_msg) +{ + int recv_msg_size = 0; + + if ((recv_msg_size = read(client_sock, recv_msg, sizeof(ms_comm_msg_s))) < 0) { + if (errno == EWOULDBLOCK) { + MSAPI_DBG_ERR("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recv failed"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + + MSAPI_DBG_SLOG("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 < MAX_FILEPATH_LEN)) { + MSAPI_DBG_ERR("IPC message is wrong. message size is %d", recv_msg->msg_size); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + return MS_MEDIA_ERR_NONE; +} + diff --git a/lib/media-util-noti.c b/lib/media-util-noti.c index cdda750..46cddf1 100755 --- a/lib/media-util-noti.c +++ b/lib/media-util-noti.c @@ -37,71 +37,285 @@ #include <dbus/dbus.h> #include <dbus/dbus-glib-lowlevel.h> -#include "media-util-dbg.h" -#include "media-util-err.h" #include "media-util-internal.h" +#include "media-util-dbg.h" +#include "media-util.h" #include "media-util-noti.h" -static DBusHandlerResult -__message_filter (DBusConnection *connection, DBusMessage *message, void *user_data) +DBusConnection *g_bus; +void *g_data_store; +GArray *handle_list; +static GStaticMutex noti_mutex = G_STATIC_MUTEX_INIT; +int ref_count; + +#define MS_MEDIA_DBUS_NAME "ms_db_updated" + +typedef struct noti_callback_data{ + db_update_cb user_callback; + void *user_data; +} noti_callback_data; + +static void +__free_data_fuction(void *memory) { - db_update_cb user_cb = user_data; + MS_SAFE_FREE(memory); + g_data_store = NULL; +} +DBusHandlerResult +__get_message(DBusMessage *message, db_update_cb user_cb, void *userdata) +{ /* A Ping signal on the com.burtonini.dbus.Signal interface */ if (dbus_message_is_signal (message, MS_MEDIA_DBUS_INTERFACE, MS_MEDIA_DBUS_NAME)) { + int i = 0; + int current_type = DBUS_TYPE_INVALID; DBusError error; - dbus_uint16_t noti_type; + DBusMessageIter read_iter; + DBusBasicValue value[6]; + + dbus_int32_t item = -1; + dbus_int32_t pid = 0; + dbus_int32_t update_type = MS_MEDIA_UNKNOWN; + dbus_int32_t content_type = -1; + char *update_path = NULL; + char *uuid = NULL; + char *mime_type = NULL; + void *recevie_path = NULL; + int path_len = 0; 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); + MSAPI_DBG("size [%d]", sizeof(value)); + memset(value, 0x0, sizeof(value)); + + /* get data from dbus message */ + dbus_message_iter_init (message, &read_iter); + while ((current_type = dbus_message_iter_get_arg_type (&read_iter)) != DBUS_TYPE_INVALID){ + if (current_type == DBUS_TYPE_ARRAY) { + DBusMessageIter sub; + dbus_message_iter_recurse(&read_iter, &sub); + dbus_message_iter_get_fixed_array(&sub, &recevie_path, &path_len); + } else { + dbus_message_iter_get_basic (&read_iter, &value[i]); + i ++; + } + dbus_message_iter_next (&read_iter); } + + item = value[0].i32; + pid = value[1].i32; + update_type = value[2].i32; + update_path = strndup(recevie_path, path_len); + if (value[3].str != NULL) uuid = strdup(value[3].str); + content_type = value[4].i32; + if (value[5].str != NULL) mime_type = strdup(value[5].str); + + if (item == MS_MEDIA_ITEM_DIRECTORY) + content_type = MS_MEDIA_UNKNOWN; + + /* getting data complete */ + user_cb(pid, + item, + update_type, + update_path, + uuid, + content_type, + mime_type, + userdata); + + MS_SAFE_FREE(update_path); + MS_SAFE_FREE(uuid); + MS_SAFE_FREE(mime_type); + return DBUS_HANDLER_RESULT_HANDLED; } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - int ms_noti_update_complete(void) +static DBusHandlerResult +__message_filter (DBusConnection *connection, DBusMessage *message, void *user_data) { - int ret; - int err = MS_MEDIA_ERR_NONE; + db_update_cb user_cb = ((noti_callback_data*)user_data)->user_callback; + void *userdata = ((noti_callback_data*)user_data)->user_data; + DBusHandlerResult ret; - ret = mkdir(MS_MEDIA_UPDATE_NOTI_PATH, 0777); - if (ret != 0) { - MSAPI_DBG("%s", strerror(errno)); - err = MS_MEDIA_ERR_OCCURRED; - } + ret = __get_message(message, user_cb, userdata); - return err; + return ret; } -int media_db_update_subscribe(db_update_cb user_cb) + +int media_db_update_subscribe(db_update_cb user_cb, void *user_data) { - DBusConnection *bus; + int ret = MS_MEDIA_ERR_NONE; DBusError error; + noti_callback_data *callback_data = NULL; - dbus_g_thread_init(); + g_static_mutex_lock(¬i_mutex); - dbus_error_init (&error); + if (g_bus == NULL) { + dbus_g_thread_init(); + + dbus_error_init (&error); + + g_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (!g_bus) { + MSAPI_DBG ("Failed to connect to the D-BUS daemon: %s", error.message); + dbus_error_free (&error); + ret = MS_MEDIA_ERR_DBUS_GET; + goto ERROR; + } + + dbus_connection_setup_with_g_main (g_bus, NULL); + + MS_MALLOC(callback_data, sizeof(noti_callback_data)); + if (callback_data == NULL) { + MSAPI_DBG_ERR("MS_MALLOC failed"); + ret = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + goto ERROR; + } + callback_data->user_callback = user_cb; + callback_data->user_data = user_data; + + /* listening to messages from all objects as no path is specified */ + dbus_bus_add_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, &error); + if( !dbus_connection_add_filter (g_bus, __message_filter, callback_data, __free_data_fuction)) { + dbus_bus_remove_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, NULL); + ret = MS_MEDIA_ERR_DBUS_ADD_FILTER; + goto ERROR; + } + g_data_store = (void *)callback_data; + } - bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + ref_count ++; + + g_static_mutex_unlock(¬i_mutex); + + return MS_MEDIA_ERR_NONE; + +ERROR: + + if (g_bus != NULL) { + dbus_connection_unref(g_bus); + g_bus = NULL; + } + MS_SAFE_FREE(callback_data); + + g_static_mutex_unlock(¬i_mutex); + + return ret; +} + +int media_db_update_unsubscribe(void) +{ + if (g_bus == NULL) { + return MS_MEDIA_ERR_NONE; + } + + g_static_mutex_lock(¬i_mutex); + + if (ref_count == 1) { + dbus_connection_remove_filter(g_bus, __message_filter, g_data_store); + dbus_bus_remove_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, NULL); + dbus_connection_unref(g_bus); + + g_bus = NULL; + } + + ref_count --; + + g_static_mutex_unlock(¬i_mutex); + + return MS_MEDIA_ERR_NONE; +} + +int media_db_update_send(int pid, /* mandatory */ + media_item_type_e item, /* mandatory */ + media_item_update_type_e update_type, /* mandatory */ + char* path, /* mandatory */ + char* uuid, /* optional */ + media_type_e media_type, /* optional */ + char *mime_type /* optional */ + ) +{ + DBusMessage *message = NULL; + DBusConnection *bus = NULL; + DBusError error; + unsigned char *path_array = NULL; + int path_length = strlen(path) + 1; + + /* Get a connection to the session bus */ + dbus_error_init (&error); + bus = dbus_bus_get (DBUS_BUS_SYSTEM, &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); + message = dbus_message_new_signal (MS_MEDIA_DBUS_PATH, MS_MEDIA_DBUS_INTERFACE, MS_MEDIA_DBUS_NAME); + if (message != NULL) { + path_array = malloc(sizeof(unsigned char) * path_length); + memcpy(path_array, path, path_length); + + if (item == MS_MEDIA_ITEM_FILE) { + MSAPI_DBG("FILE CHANGED"); + if (uuid != NULL && mime_type != NULL) { + /* fill all datas */ + dbus_message_append_args (message, + DBUS_TYPE_INT32, &item, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &update_type, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INT32, &media_type, + DBUS_TYPE_STRING, &mime_type, + DBUS_TYPE_INVALID); + } else { + MSAPI_DBG_ERR("uuid or mime_type is NULL"); + MS_SAFE_FREE(path_array); + dbus_message_unref (message); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + } else if (item == MS_MEDIA_ITEM_DIRECTORY) { + MSAPI_DBG("DIRECTORY CHANGED"); + /* fill all datas */ + if(uuid != NULL) { + dbus_message_append_args (message, + DBUS_TYPE_INT32, &item, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &update_type, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + } else { + dbus_message_append_args (message, + DBUS_TYPE_INT32, &item, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &update_type, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, + DBUS_TYPE_INVALID); + } + } else { + MSAPI_DBG("this request is wrong"); + } + + MS_SAFE_FREE(path_array); + + /* Send the signal */ + dbus_connection_send (bus, message, NULL); + + /* Free the signal now we have finished with it */ + dbus_message_unref (message); + + MSAPI_DBG("success send notification"); + } else { + MSAPI_DBG_ERR("dbus_message_new_signal failed"); + } - /* 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; + dbus_connection_unref(bus); + /* Return TRUE to tell the event loop we want to be called again */ return MS_MEDIA_ERR_NONE; } diff --git a/lib/media-util-register.c b/lib/media-util-register.c index 1d3a946..9254209 100755 --- a/lib/media-util-register.c +++ b/lib/media-util-register.c @@ -33,23 +33,33 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -#include <sys/socket.h> +#include <sys/un.h> +#include <sys/syscall.h> #include <string.h> #include <stdbool.h> +#include <dirent.h> +#include <vconf.h> -#include "media-util-dbg.h" -#include "media-util-err.h" +#include "media-server-ipc.h" #include "media-util-internal.h" -#include "media-util-register.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; + char *sock_path; +} media_callback_data; static bool _is_valid_path(const char *path) { if (path == NULL) return false; - if (strncmp(path, MS_MEDIA_PHONE_ROOT_PATH, strlen(MS_MEDIA_PHONE_ROOT_PATH)) == 0) { + if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) { return true; - } else if (strncmp(path, MS_MEDIA_MMC_ROOT_PATH, strlen(MS_MEDIA_MMC_ROOT_PATH)) == 0) { + } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) { return true; } else return false; @@ -57,153 +67,232 @@ static bool _is_valid_path(const char *path) return true; } -int media_file_register(const char *file_full_path) +static int _check_dir_path(const char *dir_path) { - int exist; - int err; - int sockfd; - int recv_msg = MS_MEDIA_ERR_NONE; - int server_addr_size; - struct sockaddr_in server_addr; - struct timeval tv_timeout = { MS_MEDIA_TIMEOUT_SEC, 0 }; - - if(!_is_valid_path(file_full_path)) { - MSAPI_DBG("Invalid path : %s", file_full_path); - return MS_MEDIA_ERR_INVALID_PATH; - } + struct stat sb; + DIR *dp = NULL; - exist = open(file_full_path, O_RDONLY); - if(exist < 0) { - MSAPI_DBG("Not exist path : %s", file_full_path); + if (!_is_valid_path(dir_path)) { + MSAPI_DBG("Invalid path : %s", dir_path); return MS_MEDIA_ERR_INVALID_PATH; } - close(exist); - sockfd = socket(PF_INET, SOCK_DGRAM, 0); - if(sockfd < 0) - { - MSAPI_DBG("socket create fail"); - return MS_MEDIA_ERR_SOCKET_CONN; + 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; + } } - /*add timeout : timeout is 10 sec.*/ - if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) { - MSAPI_DBG("setsockopt failed"); - return MS_MEDIA_ERR_SOCKET_CONN; + 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 sockfd = -1; + char *sock_path = NULL; + int recv_msg_size = 0; + + sockfd = g_io_channel_unix_get_fd(src); + if (sockfd < 0) { + MSAPI_DBG("sock fd is invalid!"); + return TRUE; } - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(MS_MEDIA_REGISTER_PORT); - server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s)); + memset(&req_result, 0x0, sizeof(media_request_result_s)); - err = sendto(sockfd, file_full_path, strlen(file_full_path), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)); - if (err < 0) { - MSAPI_DBG("sendto error"); - perror("sendto error : "); - return MS_MEDIA_ERR_SOCKET_SEND; - } else { - MSAPI_DBG("SEND OK"); + if ((recv_msg_size = read(sockfd, &recv_msg, sizeof(ms_comm_msg_s))) < 0) { + MSAPI_DBG_STRERROR("recv failed"); + req_result.pid = -1; + req_result.result = MS_MEDIA_ERR_SOCKET_RECEIVE; + req_result.complete_path = NULL; + req_result.request_type = -1; + goto ERROR; } - server_addr_size = sizeof(server_addr); - err = recvfrom(sockfd, &recv_msg, sizeof(recv_msg), 0 , (struct sockaddr*)&server_addr, (socklen_t *)&server_addr_size); - if (err < 0) { - if (errno == EWOULDBLOCK) { - MSAPI_DBG("recvfrom timeout"); - return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; - } else { - MSAPI_DBG("recvfrom error"); - perror("recvfrom error : "); - return MS_MEDIA_ERR_SOCKET_RECEIVE; - } - } else { - MSAPI_DBG("RECEIVE OK"); - MSAPI_DBG("client receive: %d", recv_msg); + 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 = strndup(recv_msg.msg, MAX_FILEPATH_LEN); + 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 = strndup(recv_msg.msg, MAX_FILEPATH_LEN); + 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); + +ERROR: + source = ((media_callback_data *)data)->source; + user_callback = ((media_callback_data *)data)->user_callback; + user_data = ((media_callback_data *)data)->user_data; + sock_path = ((media_callback_data *)data)->sock_path; + + /*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); + if (sock_path != NULL) { + MSAPI_DBG("delete path :%s", sock_path); + unlink(sock_path); + MS_SAFE_FREE(sock_path); + } + MS_SAFE_FREE(data); - return recv_msg; + return TRUE; } -int media_list_new(media_list *list) +static int _attach_callback(int *sockfd, char* sock_path, scan_complete_cb user_callback, void *user_data) { - *list = g_array_new(TRUE, TRUE, sizeof(char*)); + 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; + cb_data->sock_path = sock_path; + + /* 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; } -int media_list_add(media_list list, const char* file_full_path) +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) { - MSAPI_DBG(""); - - if (!list) { - MSAPI_DBG("list == NULL"); + 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; + char *sock_path = NULL; + ms_sock_info_s sock_info; + + if(!MS_STRING_VALID(request_msg)) + { + MSAPI_DBG_ERR("invalid query"); return MS_MEDIA_ERR_INVALID_PARAMETER; } - if (!file_full_path) { - MSAPI_DBG("file_full_path == NULL"); + 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; } - media_list ret_list = NULL; - char *path = strdup(file_full_path); + MSAPI_DBG("querysize[%d] query[%s]", request_msg_size, request_msg); - int len = list->len + 1; - int i; - char *data = NULL; + 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); - ret_list = g_array_append_val(list, path); - if(ret_list == NULL) { - MSAPI_DBG("g_array_append_val fails"); - return MS_MEDIA_ERR_UNKNOWN; - } + /*Create Socket*/ + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, 0, &sock_info); + sockfd = sock_info.sock_fd; + if (sock_info.sock_path != NULL) + sock_path = sock_info.sock_path; - list = ret_list; + MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); - for(i = 0; i < len; i++) { - data = g_array_index(list, char*, i); - MSAPI_DBG("%d, %s", i, data); + ret = ms_ipc_send_msg_to_server_tcp(sockfd, port, &send_msg, NULL); + if (ret != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret); + ms_ipc_delete_client_socket(&sock_info); + return ret; } - return MS_MEDIA_ERR_NONE; + ret = _attach_callback(&sockfd, sock_path, user_callback ,user_data); + if(ret != MS_MEDIA_ERR_NONE) + return ret; + + return ret; } -int media_list_free(media_list list) + +int media_directory_scanning_async(const char *directory_path, bool recursive_on, scan_complete_cb user_callback, void *user_data) { - if (!list) - return MS_MEDIA_ERR_INVALID_PARAMETER; + int ret = MS_MEDIA_ERR_NONE; - int len = list->len + 1; - int i; - char *data = NULL; + ret = _check_dir_path(directory_path); + if(ret != MS_MEDIA_ERR_NONE) + return ret; - for(i = 0; i < len; i++) { - data = g_array_index(list, char*, i); - MS_SAFE_FREE(data); - } + if (recursive_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; +} - g_array_free(list, TRUE); +int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data) +{ + int ret = MS_MEDIA_ERR_NONE; - return MS_MEDIA_ERR_NONE; + ret = __media_db_request_update_async(MS_MSG_BULK_INSERT, list_path, user_callback, user_data); + + MSAPI_DBG("client receive: %d", ret); + + return ret; } -int media_files_register(const media_list list) +int media_burstshot_register(const char *list_path, insert_complete_cb user_callback, void *user_data) { - if (!list) - return MS_MEDIA_ERR_INVALID_PARAMETER; + int ret = MS_MEDIA_ERR_NONE; - int len = list->len + 1; - int i; - char *data; + ret = __media_db_request_update_async(MS_MSG_BURSTSHOT_INSERT, list_path, user_callback, user_data); - for(i = 0; i < len; i++) { - data = g_array_index(list, char*, i); - media_file_register(data); - } + MSAPI_DBG("client receive: %d", ret); + + return ret; - return MS_MEDIA_ERR_NONE; } diff --git a/libmedia-utils.manifest b/libmedia-utils.manifest new file mode 100644 index 0000000..ca37499 --- /dev/null +++ b/libmedia-utils.manifest @@ -0,0 +1,6 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> + diff --git a/media-server-plugin b/media-server-plugin new file mode 100644 index 0000000..aa0a393 --- /dev/null +++ b/media-server-plugin @@ -0,0 +1 @@ +libmedia-content-plugin.so diff --git a/media-server.manifest b/media-server.manifest new file mode 100644 index 0000000..f447e3b --- /dev/null +++ b/media-server.manifest @@ -0,0 +1,28 @@ +<manifest> + <define> + <domain name="media-server" policy="restricted" plist="media-thumbnail-server, media-data, media-data-sdk"/> + <provide> + <label name="media-server::vconf"/> + </provide> + <request> + <smack request="system::media" type="rwxat"/> + <smack request="system::media::root" type="rwxat"/> + <smack request="system::ext_storage" type="rwxat"/> + <smack request="system::vconf" type="rwxat"/> + <smack request="system::vconf_system" type="r"/> + <smack request="deviced" type="rwx"/> + <smack request="deviced::display" type="rw"/> + <smack request="security-server::api-privilege-by-pid" type="w"/> + <smack request="aul::lunch" type="x"/> + </request> + </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" /> + </assign> +</manifest> + diff --git a/packaging/media-scanner.service.wearable b/packaging/media-scanner.service.wearable new file mode 100644 index 0000000..d040e02 --- /dev/null +++ b/packaging/media-scanner.service.wearable @@ -0,0 +1,10 @@ +[Unit] +Description=Media scanner + +[Service] +Type=simple +ExecStart=/usr/bin/media-scanner +MemoryLimit=100M + +[Install] +WantedBy=multi-user.target diff --git a/packaging/media-server.service.mobile b/packaging/media-server.service.mobile new file mode 100644 index 0000000..7ad7b53 --- /dev/null +++ b/packaging/media-server.service.mobile @@ -0,0 +1,13 @@ +[Unit] +Description=Media server +After=vconf-setup.service + +[Service] +Type=simple +ExecStart=/usr/bin/media-server +Restart=always +RestartSec=0 + + +[Install] +WantedBy=multi-user.target diff --git a/packaging/media-server.service.wearable b/packaging/media-server.service.wearable new file mode 100644 index 0000000..c4326fe --- /dev/null +++ b/packaging/media-server.service.wearable @@ -0,0 +1,14 @@ +[Unit] +Description=Media server +Requires=icd.service +After=icd.service + +[Service] +Type=simple +ExecStart=/usr/bin/media-server +Restart=always +RestartSec=0 +MemoryLimit=100M + +[Install] +WantedBy=multi-user.target diff --git a/packaging/media-server.spec b/packaging/media-server.spec index e27e717..dced0a0 100644..100755 --- a/packaging/media-server.spec +++ b/packaging/media-server.spec @@ -1,29 +1,34 @@ Name: media-server Summary: File manager service server. -Version: 0.1.90 +Version: 0.2.89 Release: 1 Group: utils -License: Samsung +License: Apache-2.0 Source0: %{name}-%{version}.tar.gz +Source1: media-server.service.wearable +Source2: media-scanner.service.wearable +Source3: media-server.service.mobile Requires(post): /usr/bin/vconftool +Requires: deviced + 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(deviced) +BuildRequires: pkgconfig(security-server) +BuildRequires: pkgconfig(notification) + %description Description: File manager service server - %package -n libmedia-utils Summary: media server runtime library. Group: TO_BE/FILLED_IN -Requires: %{name} = %{version}-%{release} %description -n libmedia-utils Description : media server runtime library. @@ -42,31 +47,62 @@ Description: media server development library. %build +export GC_SECTIONS_FLAGS="-fdata-sections -ffunction-sections -Wl,--gc-sections" +export CFLAGS+=" ${GC_SECTIONS_FLAGS}" +export CXXFLAGS+=" ${GC_SECTIONS_FLAGS}" + +%if 0%{?sec_build_binary_debug_enable} +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif + %autogen + %configure --prefix=%{_prefix} --disable-static make %{?jobs:-j%jobs} %install -rm -rf %{buildroot} %make_install -%post -vconftool set -t int db/filemanager/dbupdate "1" -vconftool set -t int memory/filemanager/Mmc "0" -i +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 -vconftool set -t string db/private/mediaserver/mmc_info "" +install -m 644 %{SOURCE2} %{buildroot}/usr/lib/systemd/system/media-scanner.service +#ln -s ../media-scanner.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/media-scanner.service +mkdir -p %{buildroot}/usr/etc +cp -rf %{_builddir}/%{name}-%{version}/media-server-plugin %{buildroot}/usr/etc/media-server-plugin + +#License +mkdir -p %{buildroot}/%{_datadir}/license +cp -rf %{_builddir}/%{name}-%{version}/LICENSE.APLv2.0 %{buildroot}/%{_datadir}/license/%{name} +cp -rf %{_builddir}/%{name}-%{version}/LICENSE.APLv2.0 %{buildroot}/%{_datadir}/license/libmedia-utils + +%post +vconftool set -t int db/filemanager/dbupdate "1" -f -s system::vconf_inhouse +vconftool set -t int memory/filemanager/Mmc "0" -i -f -s system::vconf_inhouse +vconftool set -t string db/private/mediaserver/mmc_info "" -f -s media-server::vconf %files +%manifest media-server.manifest %defattr(-,root,root,-) %{_bindir}/media-server -%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 +%{_bindir}/media-scanner +%{_bindir}/mediadb-update +/usr/lib/systemd/system/media-server.service +/usr/lib/systemd/system/multi-user.target.wants/media-server.service +/usr/lib/systemd/system/media-scanner.service +#/usr/lib/systemd/system/multi-user.target.wants/media-scanner.service +/usr/etc/media-server-plugin +#License +%{_datadir}/license/%{name} +%{_datadir}/license/libmedia-utils %files -n libmedia-utils +%manifest libmedia-utils.manifest %defattr(-,root,root,-) %{_libdir}/libmedia-utils.so %{_libdir}/libmedia-utils.so.0 @@ -77,21 +113,3 @@ vconftool set -t string db/private/mediaserver/mmc_info "" %{_libdir}/pkgconfig/libmedia-utils.pc %{_includedir}/media-utils/*.h -%changelog -* Mon Aug 06 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.86 -- add notification subscribe function for application -- fix bug : once validity checking time, call insert_item_batch two times. -- add MS_SAFE_FREE Macro, modify check value after using snprintf by secure coding guide -- change macro name MS_PHONE_ROOT_PATH, MS_MMC_ROOT_PATH -- make reference directory list by each thread - -* Tue Jul 03 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.80 -- manage db handle by plug-in - -* Wed Jun 27 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.79 -- If item exists in media db, return directly - -* Tue Jun 26 2012 Yong Yeon Kim <yy9875.kim@samsnug.com> - 0.1.78 -- change modified file updating routine (delete & insert -> refresh) -- modify return error type of media_file_register - diff --git a/reset_mediadb.sh b/reset_mediadb.sh deleted file mode 100755 index 1061599..0000000 --- a/reset_mediadb.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/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 - - diff --git a/src/common/include/media-common-dbg.h b/src/common/include/media-common-dbg.h new file mode 100755 index 0000000..af9e42f --- /dev/null +++ b/src/common/include/media-common-dbg.h @@ -0,0 +1,67 @@ +/* + * 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> +#include <errno.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "MEDIA_COMMON" +#define BUF_LENGTH 256 + +#define MS_DBG_STRERROR(fmt) do { \ + char buf[BUF_LENGTH] = {0,}; \ + strerror_r(errno, buf, BUF_LENGTH); \ + LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + } while (0) + + +#define MS_DBG_SLOG(fmt, args...) SECURE_LOGD(fmt "\n", ##args); + +#define MS_DBG(fmt, args...) LOGD(fmt "\n", ##args); + +#define MS_DBG_INFO(fmt, args...) do{ if (true) { \ + LOGI(fmt "\n" , ##args); \ + }} while(false) + +#define MS_DBG_WARN(fmt, args...) do{ if (true) { \ + LOGW(fmt "\n", ##args); \ + }} while(false) + +#define MS_DBG_ERR(fmt, args...) do{ if (true) { \ + LOGE(fmt "\n", ##args); \ + }} while(false) + +#endif /*_MEDIA_SERVER_DBG_H_*/ diff --git a/common/include/media-server-external-storage.h b/src/common/include/media-common-external-storage.h index 1d3994e..a6cf430 100755 --- a/common/include/media-server-external-storage.h +++ b/src/common/include/media-common-external-storage.h @@ -17,23 +17,30 @@ * 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_
-
-void
-ms_make_default_path_mmc(void);
-
-int
+ */ +#ifndef _MEDIA_SERVER_EXTERNAL_STORAGE_H_ +#define _MEDIA_SERVER_EXTERNAL_STORAGE_H_ + +#include "media-common-types.h" + +void +ms_make_default_path_mmc(void); + +int ms_update_mmc_info(void); void ms_mmc_removed_handler(void); +#ifndef DISABLE_NOTIFICATION +int +ms_present_mmc_status(ms_sdcard_status_type_t status); +#endif + void -ms_mmc_vconf_cb(void *data);
-
+ms_mmc_vconf_cb(void *data); + ms_dir_scan_type_t -ms_get_mmc_state(void);
-
-#endif /*_MEDIA_SERVER_EXTERNAL_STORAGE_H_*/
+ms_get_mmc_state(void); + +#endif /*_MEDIA_SERVER_EXTERNAL_STORAGE_H_*/ diff --git a/common/include/media-server-types.h b/src/common/include/media-common-types.h index 01f128c..dfe0b75 100755 --- a/common/include/media-server-types.h +++ b/src/common/include/media-common-types.h @@ -22,7 +22,7 @@ /** * This file defines api utilities of contents manager engines. * - * @file media-server-types.h + * @file media-common-types.h * @author Yong Yeon Kim(yy9875.kim@samsung.com) * @version 1.0 * @brief @@ -31,33 +31,53 @@ #ifndef _MEDIA_SERVER_TYPES_H_ #define _MEDIA_SERVER_TYPES_H_ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> #include <stdbool.h> -#include <glib.h> +#include <unistd.h> -#if !defined(__TYPEDEF_INT64__) -#define __TYPEDEF_INT64__ -typedef long long int64; -#endif +#define FMS_PERF + +#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" + +/*Use for Poweroff sequence*/ +#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 */ -#define FAT_DIRECTORY_LEN_MAX 244 /* 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_STORATE_EXTERNAL, /**< Stored only in MMC */ + MS_STORAGE_EXTERNAL, /**< Stored only in MMC */ } ms_storage_type_t; typedef enum { + MS_SDCARD_INSERTED, /**< Stored only in phone */ + MS_SDCARD_REMOVED, /**< Stored only in MMC */ +} ms_sdcard_status_type_t; + +typedef enum { MS_SCAN_INVALID, MS_SCAN_PART, + MS_SCAN_META, MS_SCAN_ALL, } ms_dir_scan_type_t; @@ -77,8 +97,15 @@ 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; + /** * @} */ diff --git a/common/include/media-server-utils.h b/src/common/include/media-common-utils.h index 9b42318..3f01b7e 100755 --- a/common/include/media-server-utils.h +++ b/src/common/include/media-common-utils.h @@ -22,7 +22,7 @@ /** * This file defines api utilities of contents manager engines. * - * @file media-server-utils.h + * @file media-common-utils.h * @author Yong Yeon Kim(yy9875.kim@samsung.com) * @version 1.0 * @brief @@ -31,10 +31,7 @@ #ifndef _MEDIA_SERVER_UTILS_H__ #define _MEDIA_SERVER_UTILS_H__ -#include "media-server-global.h" - -int -ms_set_db_status(ms_db_status_type_t status); +#include "media-common-types.h" int ms_db_init(bool need_db_create); @@ -51,9 +48,6 @@ 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); @@ -77,6 +71,9 @@ ms_config_get_str(const char *key, char *value); bool ms_config_set_str(const char *key, const char *value); +bool +ms_config_get_bool(const char *key, int *value); + #ifdef FMS_PERF void ms_check_start_time(struct timeval *start_time); @@ -88,6 +85,9 @@ void ms_check_time_diff(struct timeval *start_time, struct timeval *end_time); #endif/*FMS_PERF */ +typedef void (*power_off_cb)(void *user_data); + +int ms_add_poweoff_event_receiver(power_off_cb user_callback, void *user_data); /** * @} */ diff --git a/src/common/media-common-external-storage.c b/src/common/media-common-external-storage.c new file mode 100755 index 0000000..279de76 --- /dev/null +++ b/src/common/media-common-external-storage.c @@ -0,0 +1,224 @@ +/* + * 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 <errno.h> +#include <notification.h> + +#include "media-util.h" +#include "media-server-ipc.h" +#include "media-common-dbg.h" +#include "media-common-utils.h" +#include "media-common-external-storage.h" + +#define MMC_INFO_SIZE 256 + +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"}, +}; + +#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_ERR("make fail"); + } + /*this fuction for emulator*/ + /*at the first time, the directroies are made permission 755*/ + ret = chmod(default_path[i], 0777); + if (ret != 0) { + MS_DBG_STRERROR("chmod failed"); + } + ret = chown(default_path[i], 5000, 5000); + if (ret != 0) { + MS_DBG_STRERROR("chown failed"); + } + } 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) +{ + char *path = "/sys/block/mmcblk1/device/cid"; + + if (_get_contents(path, cid) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("_get_contents failed"); + } + + 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 = NULL; + char *r = NULL; + + 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", r); + } + free(lang); + } +} + +int +ms_present_mmc_status(ms_sdcard_status_type_t status) +{ + int ret = NOTIFICATION_ERROR_NONE; + + update_lang(); + + if (status == MS_SDCARD_INSERTED) + ret = notification_status_message_post(_GETSYSTEMSTR("IDS_COM_BODY_PREPARING_SD_CARD")); + else if (status == MS_SDCARD_REMOVED) + ret = notification_status_message_post(_GETSYSTEMSTR("IDS_COM_BODY_SD_CARD_UNEXPECTEDLY_REMOVED")); + + if(ret != NOTIFICATION_ERROR_NONE) + return MS_MEDIA_ERR_INTERNAL; + return MS_MEDIA_ERR_NONE; +} + diff --git a/src/common/media-common-utils.c b/src/common/media-common-utils.c new file mode 100755 index 0000000..bdf86be --- /dev/null +++ b/src/common/media-common-utils.c @@ -0,0 +1,353 @@ +/* + * 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 <vconf.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include "media-util.h" +#include "media-server-ipc.h" +#include "media-common-dbg.h" +#include "media-common-utils.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 + +#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; + } +} + +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 = NULL; + if (!key || !value) { + MS_DBG_ERR("Arguments key or value is NULL"); + return false; + } + + res = vconf_get_str(key); + if ((res!= NULL) && (strlen(res) > 0)) { + strncpy(value, res, strlen(res) + 1); + free(res); + 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; +} + +bool +ms_config_get_bool(const char *key, int *value) +{ + int err; + + if (!key || !value) { + MS_DBG_ERR("Arguments key or value is NULL"); + return false; + } + + err = vconf_get_bool(key, value); + if (err == 0) + return true; + else if (err == -1) + return false; + else + MS_DBG_ERR("Unexpected error code: %d", err); + + return false; +} + +#define SYS_DBUS_NAME "ChangeState" +#define SYS_DBUS_PATH "/Org/Tizen/System/DeviceD/PowerOff" +#define SYS_DBUS_INTERFACE "org.tizen.system.deviced.PowerOff" +#define SYS_DBUS_MATCH_RULE "type='signal',interface='org.tizen.system.deviced.PowerOff'" + +typedef struct pwoff_callback_data{ + power_off_cb user_callback; + void *user_data; +} pwoff_callback_data; + +DBusHandlerResult +__get_dbus_message(DBusMessage *message, void *user_cb, void *userdata) +{ + MS_DBG(""); + + /* A Ping signal on the com.burtonini.dbus.Signal interface */ + if (dbus_message_is_signal (message, SYS_DBUS_INTERFACE, SYS_DBUS_NAME)) { + int current_type = DBUS_TYPE_INVALID; + DBusError error; + DBusMessageIter read_iter; + DBusBasicValue value; + power_off_cb cb_func = (power_off_cb)user_cb; + + dbus_error_init (&error); + + /* get data from dbus message */ + dbus_message_iter_init (message, &read_iter); + while ((current_type = dbus_message_iter_get_arg_type (&read_iter)) != DBUS_TYPE_INVALID){ + dbus_message_iter_get_basic (&read_iter, &value); + switch(current_type) { + case DBUS_TYPE_INT32: + MS_DBG_WARN("value[%d]", value.i32); + break; + default: + MS_DBG_ERR("current type : %d", current_type); + break; + } + + if (value.i32 == 2 || value.i32 == 3) { + MS_DBG_WARN("PREPARE POWER OFF"); + break; + } + + dbus_message_iter_next (&read_iter); + } + + if (value.i32 == 2 || value.i32 == 3) + cb_func(userdata); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult +__sysman_message_filter (DBusConnection *connection, DBusMessage *message, void *user_data) +{ + DBusHandlerResult ret; + + pwoff_callback_data *cb_data = (pwoff_callback_data *)user_data; + + MS_DBG(""); + + ret = __get_dbus_message(message, cb_data->user_callback, cb_data->user_data); + + MS_DBG(""); + + return ret; +} + +int ms_add_poweoff_event_receiver(power_off_cb user_callback, void *user_data) +{ + DBusConnection *dbus; + DBusError error; + pwoff_callback_data *cb_data = NULL; + + /*add noti receiver for power off*/ + dbus_error_init (&error); + + dbus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (!dbus) { + MS_DBG_ERR ("Failed to connect to the D-BUS daemon: %s", error.message); + return MS_MEDIA_ERR_DBUS_GET; + } + + dbus_connection_setup_with_g_main (dbus, NULL); + + cb_data = malloc(sizeof(pwoff_callback_data)); + cb_data->user_callback = user_callback; + cb_data->user_data = user_data; + + /* listening to messages from all objects as no path is specified */ + dbus_bus_add_match (dbus, SYS_DBUS_MATCH_RULE, &error); + if( !dbus_connection_add_filter (dbus, __sysman_message_filter, cb_data, NULL)) { + dbus_bus_remove_match (dbus, SYS_DBUS_MATCH_RULE, NULL); + return MS_MEDIA_ERR_DBUS_ADD_FILTER; + MS_DBG_ERR(""); + } + + return MS_MEDIA_ERR_NONE; +}
\ No newline at end of file diff --git a/src/mediadb-update.c b/src/mediadb-update.c new file mode 100644 index 0000000..20552e2 --- /dev/null +++ b/src/mediadb-update.c @@ -0,0 +1,163 @@ +/* + * 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("db-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("db-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"); +} + +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); + } + print_help(); + return NOT_OK; + } + } else { + printf("stat error"); + } + + return NOT_OK; +} + +int main(int argc, char **argv) +{ + int ret; + char *argv1 = NULL; + char *argv2 = NULL; + + if (argc > 3 ||argc < 2) { + print_help(); + exit(1); + } + + argv1 = strdup(argv[1]); + + mainloop = g_main_loop_new(NULL, FALSE); + + if (argc == 2) { + if (strcmp(argv1 , "--help") == 0) { + print_help(); + exit(1); + } + + if (check_path(argv1) == DIRECTORY_OK) { + ret = dir_scan_non_recursive(argv1); + if (ret != 0) { + printf("error : %d\n", ret); + exit(1); + } + } else { + printf("[%d]invalid path\n", __LINE__); + print_help(); + exit(1); + } + } 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 { + printf("[%d]invalid path\n", __LINE__); + print_help(); + exit(1); + } + } else { + printf("[%d] invalide option\n", __LINE__); + print_help(); + exit(1); + } + } + + g_main_loop_run(mainloop); + + exit(0); +} diff --git a/src/scanner/include/media-scanner-db-svc.h b/src/scanner/include/media-scanner-db-svc.h new file mode 100755 index 0000000..f9bffaf --- /dev/null +++ b/src/scanner/include/media-scanner-db-svc.h @@ -0,0 +1,148 @@ +/* + * 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-common-types.h" + +typedef int (*CONNECT)(void**, char **); +typedef int (*DISCONNECT)(void*, char **); +typedef int (*CHECK_ITEM_EXIST)(void*, const char*, bool*, char **); +typedef int (*INSERT_ITEM_BEGIN)(void*, int, int, int, char **); +typedef int (*INSERT_ITEM_END)(void*, char **); +typedef int (*INSERT_ITEM)(void*, const char*, int, char **); +typedef int (*INSERT_ITEM_IMMEDIATELY)(void*, const char*, int, 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, 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**); +typedef int (*INSERT_BURST_ITEM)(void *, const char *, int , char **); +typedef int (*SEND_DIR_UPDATE_NOTI)(void *, const char *, char **); +typedef int (*COUNT_DELETE_ITEMS_IN_FOLDER)(void *, const char *, int *, char **); +typedef int (*DELETE_ITEM)(void *, const char *, char **); +typedef int (*GET_FOLDER_LIST)(void *, char*, char ***, int **, int **, int *, char **); +typedef int (*UPDATE_FOLDER_TIME)(void *, const char *, char **); +typedef int (*UPDATE_ITEM_META)(void *, const char *, int, char **); +typedef int (*UPDATE_ITEM_BEGIN)(void *, int, char **); +typedef int (*UPDATE_ITEM_END)(void *, 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, const char *path); + +int +msc_insert_item_batch(void **handle, const char *path); + +int +msc_insert_burst_item(void **handle, const char *path); + +bool +msc_delete_all_items(void **handle, ms_storage_type_t store_type); + +int +msc_validaty_change_all_items(void **handle, ms_storage_type_t store_type, bool validity); + +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); + +int +msc_send_dir_update_noti(void **handle, const char*path); + +int +msc_count_delete_items_in_folder(void **handle, const char*path, int *count); + +typedef struct msc_dir_info_s { + char *dir_path; + int modified_time; + int item_num; +} msc_dir_info_s; + +int +msc_get_folder_list(void **handle, char* start_path, GArray **dir_array); + +int +msc_update_folder_time(void **handle, char *folder_path); + +int +msc_insert_item_immediately(void **handle, const char *path); + +int +msc_update_meta_batch(void **handle, const char *path); + +/**************************************************************************************************** +FOR BULK COMMIT +*****************************************************************************************************/ +typedef enum { + MS_NOTI_DISABLE = 0, /**< Stored only in phone */ + MS_NOTI_ENABLE = 1, /**< Stored only in MMC */ +} ms_noti_status_e; + +void +msc_register_start(void **handle, ms_noti_status_e noti_status, int pid); + +void +msc_register_end(void **handle); + +void +msc_validate_start(void **handle); + +void +msc_validate_end(void **handle); + +void +msc_update_start(void **handle); + +void +msc_update_end(void **handle); + +#endif /*_MEDIA_SCANNER_DB_SVC_H_*/ diff --git a/src/scanner/include/media-scanner-dbg.h b/src/scanner/include/media-scanner-dbg.h new file mode 100755 index 0000000..735e4c1 --- /dev/null +++ b/src/scanner/include/media-scanner-dbg.h @@ -0,0 +1,73 @@ +/* + * 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> +#include <errno.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "MEDIA_SCANNER" +#define BUF_LENGTH 256 + +#define MSC_DBG_STRERROR(fmt) do { \ + char buf[BUF_LENGTH] = {0,}; \ + strerror_r(errno, buf, BUF_LENGTH); \ + LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + } while (0) + +#define MSC_DBG_SLOG(fmt, args...) do{ if (true) { \ + SECURE_LOGD(fmt "\n", ##args); \ + }} while(false) + +#define MSC_DBG(fmt, args...) do{ if (true) { \ + LOGD(fmt "\n", ##args); \ + }} while(false) + +#define MSC_DBG_INFO(fmt, args...) do{ if (true) { \ + LOGI(fmt "\n", ##args); \ + }} while(false) + +#define MSC_DBG_ERR(fmt, args...) do{ if (true) { \ + LOGE(fmt "\n", ##args); \ + }} while(false) + +#define MSC_DBG_WAN(fmt, args...) do{ if (true) { \ + LOGW(fmt "\n", ##args); \ + }} while(false) + +/** + * @} + */ +#endif /*_MEDIA_SCANNER_DBG_H_*/ + diff --git a/common/include/media-server-scan.h b/src/scanner/include/media-scanner-scan.h index 113b39a..49e32c9 100755 --- a/common/include/media-server-scan.h +++ b/src/scanner/include/media-scanner-scan.h @@ -27,9 +27,17 @@ * @version 1.0 * @brief */ -#ifndef _MEDIA_SERVER_SCAN_H_ -#define _MEDIA_SERVER_SCAN_H_ +#ifndef _MEDIA_SCANNER_SCAN_H_ +#define _MEDIA_SCANNER_SCAN_H_ -gboolean ms_scan_thread(void *data); +gboolean msc_directory_scan_thread(void *data); -#endif /*_MEDIA_SERVER_SCAN_H_*/
\ No newline at end of file +gboolean msc_register_thread(void *data); + +gboolean msc_storage_scan_thread(void *data); + +int msc_check_remain_task(void); + +ms_db_status_type_t msc_check_scanning_status(void); + +#endif /*_MEDIA_SCANNER_SCAN_H_*/
\ No newline at end of file diff --git a/common/include/media-server-socket.h b/src/scanner/include/media-scanner-socket.h index de29dc3..4d026b3 100755 --- a/common/include/media-server-socket.h +++ b/src/scanner/include/media-scanner-socket.h @@ -27,16 +27,16 @@ * @version 1.0 * @brief */ -#ifndef _MEDIA_SERVER_SOCKET_H_ -#define _MEDIA_SERVER_SOCKET_H_ +#ifndef _MEDIA_SCANNER_SOCKET_H_ +#define _MEDIA_SCANNER_SOCKET_H_ -#include "media-server-global.h" -#include "media-server-types.h" +#include "media-common-types.h" +#include "media-server-ipc.h" -gboolean ms_read_socket(GIOChannel *src, - GIOCondition condition, - gpointer data); +gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer data); -gboolean ms_prepare_socket(int *sock_fd); +int msc_send_ready(void); -#endif /*_MEDIA_SERVER_SOCKET_H_*/ +int msc_send_result(int result, ms_comm_msg_s *scan_data); + +#endif /*_MEDIA_SCANNER_SOCKET_H_*/ diff --git a/src/scanner/media-scanner-db-svc.c b/src/scanner/media-scanner-db-svc.c new file mode 100755 index 0000000..c1842f1 --- /dev/null +++ b/src/scanner/media-scanner-db-svc.c @@ -0,0 +1,769 @@ +/* + * 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 "media-util.h" + +#include "media-common-utils.h" +#include "media-scanner-dbg.h" +#include "media-scanner-db-svc.h" + +#define CONFIG_PATH "/usr/etc/media-server-plugin" +#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*/ +extern int insert_count; + +enum func_list { + eCONNECT, + eDISCONNECT, + eEXIST, + eINSERT_BEGIN, + eINSERT_END, + eINSERT_BATCH, + eINSERT_ITEM_IMMEDIATELY, + 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, + eINSERT_BURST, + eSEND_DIR_UPDATE_NOTI, + eCOUNT_DELETE_ITEMS_IN_FOLDER, + eDELETE_ITEM, + eGET_FOLDER_LIST, + eUPDATE_FOLDER_TIME, + eUPDATE_ITEM_META, + eUPDATE_ITEM_BEGIN, + eUPDATE_ITEM_END, + eFUNC_MAX +}; + +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); + } + + 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] = { + "connect_db", + "disconnect_db", + "check_item_exist", + "insert_item_begin", + "insert_item_end", + "insert_item", + "insert_item_immediately", + "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", + "insert_burst_item", + "send_dir_update_noti", + "count_delete_items_in_folder", + "delete_item", + "get_folder_list", + "update_folder_time", + "update_item_meta", + "update_item_begin", + "update_item_end", + }; + /*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_ERR("There is no information for functions"); + return MS_MEDIA_ERR_DYNAMIC_LINK; + } + + /*the number of functions*/ + lib_num = so_array->len; + + MSC_DBG_SLOG("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_SLOG("[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 [%s]", func_list[func_index]); + 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, const char *path) +{ + int lib_index; + int res = MS_MEDIA_ERR_NONE; + int ret; + char *err_msg = NULL; + bool modified = FALSE; + + for (lib_index = 0; lib_index < lib_num; 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, &modified, &err_msg); /*dlopen*/ + if (ret != 0) { + MS_SAFE_FREE(err_msg); + ret = msc_insert_item_batch(handle, path); + if (ret != 0) { + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } else { + insert_count++; + } + } else { + if (modified == FALSE) { + /*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, 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); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_UPDATE_FAIL; + } + } else { + /* the file has same name but it is changed, so we have to update DB */ + MSC_DBG_WAN("DELETE ITEM [%s]", path); + ret = ((DELETE_ITEM)func_array[lib_index][eDELETE_ITEM])(handle[lib_index], path, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_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_DELETE_FAIL; + } else { + ret = msc_insert_item_batch(handle, path); + if (ret != 0) { + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } else { + insert_count++; + } + } + } + } + } + + return res; +} + +int +msc_validaty_change_all_items(void **handle, ms_storage_type_t store_type, bool validity) +{ + 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, validity, &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 *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 = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_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; + } + } + + return res; +} + +int +msc_insert_item_immediately(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 = ((INSERT_ITEM_IMMEDIATELY)func_array[lib_index][eINSERT_ITEM_IMMEDIATELY])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_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; + } + } + + return res; +} + +int +msc_insert_burst_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 = ((INSERT_BURST_ITEM)func_array[lib_index][eINSERT_BURST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_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; + } + } + + 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; +} + +int +msc_send_dir_update_noti(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 = ((SEND_DIR_UPDATE_NOTI)func_array[lib_index][eSEND_DIR_UPDATE_NOTI])(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_SEND_NOTI_FAIL; + } + } + + return MS_MEDIA_ERR_NONE; +} + +int +msc_count_delete_items_in_folder(void **handle, const char*path, int *count) +{ + int lib_index; + int ret; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((COUNT_DELETE_ITEMS_IN_FOLDER)func_array[lib_index][eCOUNT_DELETE_ITEMS_IN_FOLDER])(handle[lib_index], path, 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); + return MS_MEDIA_ERR_INTERNAL; + } + } + + return MS_MEDIA_ERR_NONE; +} + +int +msc_get_folder_list(void **handle, char* start_path, GArray **dir_array) +{ + int lib_index; + int ret; + char *err_msg = NULL; + + char **folder_list = NULL; + int *modified_time_list = NULL; + int *item_num_list = NULL; + int count = 0; + int i = 0; + + msc_dir_info_s* dir_info = NULL; + MSC_DBG_ERR("start path: %s", start_path); + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((GET_FOLDER_LIST)func_array[lib_index][eGET_FOLDER_LIST])(handle[lib_index], start_path, &folder_list, &modified_time_list, &item_num_list, &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); + return MS_MEDIA_ERR_INTERNAL; + } + } + + MSC_DBG_ERR("OK"); + + *dir_array = g_array_new(FALSE, FALSE, sizeof(msc_dir_info_s*)); + if (count != 0) { + for(i = 0; i < count; i ++) { + dir_info = malloc(sizeof(msc_dir_info_s)); + dir_info->dir_path = strdup(folder_list[i]); + dir_info->modified_time = modified_time_list[i]; + dir_info->item_num = item_num_list[i]; + g_array_append_val(*dir_array, dir_info); + MS_SAFE_FREE(folder_list[i]); +// MSC_DBG("%d get path : %s, %d", i, dir_info->dir_path, dir_info->modified_time); + } + } + + MS_SAFE_FREE(folder_list); + MS_SAFE_FREE(modified_time_list); + + return MS_MEDIA_ERR_NONE; +} + +int +msc_update_folder_time(void **handle, char *folder_path) +{ + int lib_index; + int ret; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_FOLDER_TIME)func_array[lib_index][eUPDATE_FOLDER_TIME])(handle[lib_index], folder_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_INTERNAL; + } + } + + return MS_MEDIA_ERR_NONE; +} + +int +msc_update_meta_batch(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); + + MSC_DBG_ERR(""); + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_META)func_array[lib_index][eUPDATE_ITEM_META])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_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; + } + } + + return res; +} + +/**************************************************************************************************** +FOR BULK COMMIT +*****************************************************************************************************/ + +void +msc_register_start(void **handle, ms_noti_status_e noti_status, int pid) +{ + 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, noti_status, pid, &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); + } + } +} + +void +msc_update_start(void **handle) +{ + int lib_index; + int ret = 0; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_BEGIN)func_array[lib_index][eUPDATE_ITEM_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_update_end(void **handle) +{ + int lib_index; + int ret = 0; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_END)func_array[lib_index][eUPDATE_ITEM_END])(handle[lib_index], &err_msg);/*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + } + } +} + diff --git a/src/scanner/media-scanner-scan.c b/src/scanner/media-scanner-scan.c new file mode 100755 index 0000000..c403ab4 --- /dev/null +++ b/src/scanner/media-scanner-scan.c @@ -0,0 +1,1282 @@ +/* + * 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 <dd-display.h> +#include <vconf.h> + +#include "media-util.h" +#include "media-server-ipc.h" +#include "media-common-utils.h" +#include "media-common-external-storage.h" +#include "media-scanner-dbg.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 = 0; +bool power_off; +GAsyncQueue * storage_queue; +GAsyncQueue *scan_queue; +GAsyncQueue *reg_queue; +int insert_count; + +#ifdef FMS_PERF +extern struct timeval g_mmc_start_time; +extern struct timeval g_mmc_end_time; +#endif + +static int __msc_set_power_mode(ms_db_status_type_t status); +static int __msc_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type); +static int __msc_check_stop_status(ms_storage_type_t storage_type); +static int __msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t storage_type, int scan_type); +static int __msc_db_update(void **handle, const ms_comm_msg_s * scan_data); +static int __msc_check_file_path(const char *file_path); +static int __msc_make_file_list(char *file_path, GArray **path_array); +static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array); +static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data); +static int __msc_clear_file_list(GArray *path_array); +static bool __msc_check_scan_ignore(char * path); +static bool __msc_is_valid_path(const char *path); +static void __msc_check_dir_path(char *dir_path); +static void __msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data); +static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid); +static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status); + +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 = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0); + if (err != 0) + res = MS_MEDIA_ERR_INTERNAL; + break; + case MS_DB_UPDATED: + err = display_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_db_status_type_t status, ms_storage_type_t storage_type) +{ + int res = MS_MEDIA_ERR_NONE; + int err = 0; + + if (status == MS_DB_UPDATING) { + if (!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATING)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_config_set_int failed"); + } + + if (storage_type == MS_STORAGE_EXTERNAL) { + if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_config_set_int failed"); + } + } + } else if (status == MS_DB_UPDATED) { + if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_config_set_int failed"); + } + + if (storage_type == MS_STORAGE_EXTERNAL) { + if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_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 bool __msc_check_scan_ignore(char * path) +{ + DIR *dp = NULL; + struct dirent entry; + struct dirent *result; + char *ignore_path = ".scan_ignore"; + + if(strstr(path, "/.")) + { + MSC_DBG_ERR("hidden path"); + return true;; + } + + 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 __msc_check_stop_status(ms_storage_type_t storage_type) +{ + int ret = MS_MEDIA_ERR_NONE; + + /*check poweroff status*/ + if (power_off) { + MSC_DBG_ERR("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_ERR("Directory scanning is stopped"); + ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP; + } + + return ret; +} + +static void __msc_check_dir_path(char *dir_path) +{ + /* need implementation */ + /* if dir_path is not NULL terminated, this function will occure crash */ + int len = strlen(dir_path); + + if (dir_path[len -1] == '/') + dir_path[len -1] = '\0'; +} + +static int __msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t storage_type, int scan_type) +{ + DIR *dp = NULL; + GArray *dir_array = NULL; + struct dirent entry; + struct dirent *result = NULL; + int ret = MS_MEDIA_ERR_NONE; + char *new_path = NULL; + char *current_path = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + int (*scan_function)(void **, const char*) = NULL; + + /* make new array for storing directory */ + dir_array = g_array_new (FALSE, FALSE, sizeof (char*)); + if (dir_array == NULL){ + MSC_DBG_ERR("g_array_new failed"); + return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + } + /* add first direcotiry to directory array */ + g_array_append_val (dir_array, start_path); + + scan_function = (scan_type == MS_MSG_STORAGE_ALL) ? msc_insert_item_batch : msc_validate_item; + + /*start db update. the number of element in the array , db update is complete.*/ + while (dir_array->len != 0) { + /*check poweroff status*/ + ret = __msc_check_stop_status(storage_type); + if (ret != MS_MEDIA_ERR_NONE) { + goto STOP_SCAN; + } + /* get the current path from directory array */ + current_path = g_array_index(dir_array , char*, 0); + g_array_remove_index (dir_array, 0); +// MSC_DBG_SLOG("%d", dir_array->len); + + if (__msc_check_scan_ignore(current_path)) { + MSC_DBG_ERR("%s is ignore", current_path); + MS_SAFE_FREE(current_path); + continue; + } + + dp = opendir(current_path); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + /*check poweroff status*/ + ret = __msc_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) { + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* insert into media DB */ + if (scan_function(handle,path) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("failed to update db : %d", scan_type); + continue; + } + } else if (entry.d_type & DT_DIR) { + if (scan_type != MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) { + /* this request is recursive scanning */ + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* add new directory to dir_array */ + new_path = strdup(path); + g_array_append_val (dir_array, new_path); + } else { + /* this request is recursive scanning */ + /* don't add new directory to dir_array */ + } + } + } + /* update modified time of directory */ + if (scan_type == MS_MSG_STORAGE_PARTIAL + && storage_type == MS_STORAGE_INTERNAL) + msc_update_folder_time(handle, current_path); + } else { + MSC_DBG_ERR("%s folder opendir fails", current_path); + } + if (dp) closedir(dp); + dp = NULL; + MS_SAFE_FREE(current_path); + } /*db update while */ +STOP_SCAN: + if (dp) closedir(dp); + + __msc_clear_file_list(dir_array); + + if (ret != MS_MEDIA_ERR_NONE) MSC_DBG_INFO("ret : %d", ret); + + return ret; +} + +static int __msc_db_update(void **handle, const ms_comm_msg_s * scan_data) +{ + int scan_type; + int err = MS_MEDIA_ERR_NONE; + char *start_path = NULL; + ms_storage_type_t storage_type; + + storage_type = ms_get_storage_type_by_full(scan_data->msg); + scan_type = scan_data->msg_type; + start_path = strndup(scan_data->msg, scan_data->msg_size); + + /*if scan type is not MS_SCAN_NONE, check data in db. */ + if (scan_type != MS_MSG_STORAGE_INVALID) { + MSC_DBG_INFO("INSERT"); + + err = __msc_dir_scan(handle, start_path, storage_type, scan_type); + if (err != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("error : %d", err); + } + } else if (scan_type == MS_MSG_STORAGE_INVALID) { + MSC_DBG_INFO("INVALID"); + + err = msc_set_folder_validity(handle, start_path, false, true); + if (err != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("error : %d", err); + } + + MS_SAFE_FREE(start_path); + } + + sync(); + + return err; +} + +gboolean msc_directory_scan_thread(void *data) +{ + ms_comm_msg_s *scan_data = NULL; + int err; + int ret; + void **handle = NULL; + int scan_type; + char *noti_path = NULL; + + while (1) { + scan_data = g_async_queue_pop(scan_queue); + if (scan_data->pid == POWEROFF) { + MSC_DBG_ERR("power off"); + goto _POWEROFF; + } + + MSC_DBG_INFO("DIRECTORY SCAN START [%s]", scan_data->msg); + + /*connect to media db, if conneting is failed, db updating is stopped*/ + err = msc_connect_db(&handle); + if (err != MS_MEDIA_ERR_NONE) + continue; + + 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; + } + + __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_bacth_commit_enable(handle, TRUE, TRUE, MS_NOTI_DISABLE, 0); + + /*insert data into media db */ + ret = __msc_db_update(handle, scan_data); + + /*call for bundle commit*/ + __msc_bacth_commit_disable(handle, TRUE, TRUE); + + if (ret == MS_MEDIA_ERR_NONE) { + MSC_DBG_INFO("working normally"); + int count = 0; + + noti_path = strndup(scan_data->msg, scan_data->msg_size); + msc_count_delete_items_in_folder(handle, noti_path, &count); + + MSC_DBG_SLOG("delete count %d", count); + MSC_DBG_SLOG("insert count %d", insert_count); + + msc_delete_invalid_items_in_folder(handle, scan_data->msg); + + if ( !(count == 0 && insert_count == 0)) { + msc_send_dir_update_noti(handle, noti_path); + } + MS_SAFE_FREE(noti_path); + } + + insert_count = 0; + + if (power_off) { + MSC_DBG_WAN("power off"); + goto _POWEROFF; + } + + /*disconnect form media db*/ + if (handle) msc_disconnect_db(&handle); +NEXT: + /*Active flush */ + malloc_trim(0); + + msc_send_result(ret, scan_data); + + MS_SAFE_FREE(scan_data); + + MSC_DBG_INFO("DIRECTORY SCAN END [%d]", ret); + } /*thread while*/ + +_POWEROFF: + MS_SAFE_FREE(scan_data); + if (handle) msc_disconnect_db(&handle); + + return false; +} + +/* this thread process only the request of media-server */ +static int _check_folder_from_list(char *folder_path, int item_num, GArray *dir_array) +{ + int i; + int array_len = dir_array->len; + msc_dir_info_s* dir_info = NULL; + struct stat buf; + time_t mtime; + bool find_flag = false; + + if(stat(folder_path, &buf) == 0) { + mtime = buf.st_mtime; + } else { + return MS_MEDIA_ERR_INTERNAL; + } + + for (i = 0; i < array_len; i++) { + dir_info = g_array_index (dir_array, msc_dir_info_s*, i); + if (strcmp(folder_path, dir_info->dir_path) == 0) { + /* if modified time is same, the folder does not need updating */ + if ((mtime == dir_info->modified_time) && (item_num == dir_info->item_num)) { + if (mtime == 0) + continue; + + g_array_remove_index (dir_array, i); + MS_SAFE_FREE(dir_info->dir_path); + MS_SAFE_FREE(dir_info); + } + find_flag = true; + break; + } + } + + /* this folder does not exist in media DB, so this folder has to insert to DB */ + if ((find_flag == false) && + (item_num > 0)) { + dir_info = NULL; + dir_info = malloc(sizeof(msc_dir_info_s)); + dir_info->dir_path = strdup(folder_path); + dir_info->modified_time = -1; + g_array_append_val(dir_array, dir_info); + } + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_compare_with_db(void **handle, const char*update_path, int scan_type, GArray **dir_array) +{ + DIR *dp = NULL; + GArray *read_dir_array = NULL; + struct dirent entry; + struct dirent *result = NULL; + int ret = MS_MEDIA_ERR_NONE; + char *new_path = NULL; + char *current_path = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + char * start_path = strdup(update_path); + int item_num = 0; + + /*get directories list from media db*/ + ret = msc_get_folder_list(handle, start_path, dir_array); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("msc_get_folder_list is failed", ret); + return ret; + } + + MSC_DBG_ERR(" "); + /* make new array for storing directory */ + read_dir_array = g_array_new (FALSE, FALSE, sizeof (char*)); + if (read_dir_array == NULL){ + MSC_DBG_ERR("g_array_new failed"); + return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + } + /* add first direcotiry to directory array */ + g_array_append_val (read_dir_array, start_path); + + /*start db update. the number of element in the array , db update is complete.*/ + while (read_dir_array->len != 0) { + /* get the current path from directory array */ + current_path = g_array_index(read_dir_array , char*, 0); + g_array_remove_index (read_dir_array, 0); +// MSC_DBG_ERR("%s", current_path); + + if (__msc_check_scan_ignore(current_path)) { + MSC_DBG_ERR("%s is ignore", current_path); + MS_SAFE_FREE(current_path); + continue; + } + + dp = opendir(current_path); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + if (result == NULL) + break; + + if (entry.d_name[0] == '.') { + continue; + } + + if (entry.d_type & DT_DIR) { + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* add new directory to dir_array */ + new_path = strdup(path); + g_array_append_val (read_dir_array, new_path); + } else if (entry.d_type & DT_REG) { + item_num++; + } + } + + /* find and compare modified time */ + _check_folder_from_list(current_path, item_num, *dir_array); + item_num = 0; + } else { + MSC_DBG_ERR("%s folder opendir fails", current_path); + } + if (dp) closedir(dp); + dp = NULL; + MS_SAFE_FREE(current_path); + } /*db update while */ + + __msc_clear_file_list(read_dir_array); + + MSC_DBG_INFO("ret : %d", ret); + MSC_DBG_INFO("update count : %d", (*dir_array)->len); + + return ret; +} + +static int _msc_db_update_partial(void **handle, ms_storage_type_t storage_type, GArray *dir_array) +{ + int i; + int err = MS_MEDIA_ERR_NONE; + msc_dir_info_s* dir_info = NULL; + char *update_path = NULL; + + for (i = 0; i < dir_array->len; i ++) { + dir_info = g_array_index (dir_array, msc_dir_info_s*, i); + update_path = strdup(dir_info->dir_path); + +// MSC_DBG_SLOG("update_path : %s, %d", update_path, dir_info->modified_time); + if (dir_info->modified_time != -1) { + err = msc_set_folder_validity(handle, update_path, MS_INVALID, MS_NON_RECURSIVE); + if (err != MS_MEDIA_ERR_NONE) { + MSC_DBG_SLOG("update_path : %s, %d", update_path, dir_info->modified_time); + MSC_DBG_ERR("error : %d", err); + } + } + + __msc_dir_scan(handle, update_path, storage_type, MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE); + +// if (dir_info->modified_time != -1) { +// msc_update_folder_time(handle, tmp_path); +// } + } + + /*delete all node*/ + while(dir_array->len != 0) { + msc_dir_info_s *data = NULL; + data = g_array_index(dir_array , msc_dir_info_s*, 0); + g_array_remove_index (dir_array, 0); + MS_SAFE_FREE(data->dir_path); + MS_SAFE_FREE(data); + } + g_array_free(dir_array, FALSE); + dir_array = NULL; + + return MS_MEDIA_ERR_NONE; +} + +gboolean msc_storage_scan_thread(void *data) +{ + ms_comm_msg_s *scan_data = NULL; + int ret; + int err; + void **handle = NULL; + ms_storage_type_t storage_type = MS_STORAGE_INTERNAL; + int scan_type; + bool valid_status = TRUE; + char *update_path = NULL; + GArray *dir_array = NULL; + + while (1) { + scan_data = g_async_queue_pop(storage_queue); + if (scan_data->pid == POWEROFF) { + MSC_DBG_WAN("power off"); + goto _POWEROFF; + } + + MSC_DBG_INFO("STORAGE SCAN START [%s]", scan_data->msg); + + scan_type = scan_data->msg_type; + if (scan_type != MS_MSG_STORAGE_ALL + && scan_type != MS_MSG_STORAGE_PARTIAL + && scan_type != MS_MSG_STORAGE_INVALID) { + MSC_DBG_ERR("Invalid request"); + ret = MS_MEDIA_ERR_INVALID_PARAMETER; + goto NEXT; + } + + /*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 = ms_get_storage_type_by_full(scan_data->msg); + update_path = strndup(scan_data->msg, scan_data->msg_size); + + /*start db updating */ + __msc_set_db_status(MS_DB_UPDATING, storage_type); + + valid_status = (scan_type == MS_MSG_STORAGE_PARTIAL) ? TRUE : FALSE; + __msc_bacth_commit_enable(handle, TRUE, valid_status, MS_NOTI_DISABLE, 0); + +#ifdef FMS_PERF + ms_check_start_time(&g_mmc_start_time); +#endif + + if (scan_type == MS_MSG_STORAGE_PARTIAL && storage_type == MS_STORAGE_INTERNAL) { + msc_validaty_change_all_items(handle, storage_type, true); + + /* find and compare modified time */ + ret = __msc_compare_with_db(handle, update_path, scan_data->msg_type, &dir_array); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_WAN("__msc_compare_with_db is falied"); + goto NEXT; + } + + if (dir_array->len != 0) { + MSC_DBG_INFO("DB UPDATING IS NEEDED"); + + ret = _msc_db_update_partial(handle, storage_type, dir_array); + } else { + MSC_DBG_INFO("THERE IS NO UPDATE"); + } + } else { + if (scan_type == MS_MSG_STORAGE_ALL) { + /* Delete all data before full scanning */ + if (!msc_delete_invalid_items(handle, storage_type)) { + MSC_DBG_ERR("msc_delete_all_record fails"); + } + + if (storage_type == MS_STORAGE_EXTERNAL) { + ms_update_mmc_info(); + } + } else if (scan_type == MS_MSG_STORAGE_PARTIAL) { + msc_validaty_change_all_items(handle, storage_type, false); + } + + ret = __msc_db_update(handle, scan_data); + } + + /*call for bundle commit*/ + __msc_bacth_commit_disable(handle, TRUE, valid_status); + + if (scan_type == MS_MSG_STORAGE_PARTIAL) { + int del_count = 0; + + /*check delete count*/ + MSC_DBG_INFO("update path : %s", update_path); + msc_count_delete_items_in_folder(handle, update_path, &del_count); + + /*if there is no delete content, do not call delete API*/ + if (del_count != 0) + msc_delete_invalid_items(handle, storage_type); + } + + /* send notification */ + msc_send_dir_update_noti(handle, update_path); + MS_SAFE_FREE(update_path); + +#ifdef FMS_PERF + ms_check_end_time(&g_mmc_end_time); + ms_check_time_diff(&g_mmc_start_time, &g_mmc_end_time); +#endif + +NEXT: + /*set vconf key mmc loading for indicator */ + __msc_set_db_status(MS_DB_UPDATED, storage_type); + + if (power_off) { + MSC_DBG_WAN("power off"); + goto _POWEROFF; + } + + /*disconnect form media db*/ + if (handle) msc_disconnect_db(&handle); + + /*Active flush */ + malloc_trim(0); + + msc_send_result(ret, scan_data); + + MS_SAFE_FREE(scan_data); + + MSC_DBG_INFO("STORAGE SCAN END[%d]", ret); + } /*thread while*/ + +_POWEROFF: + MS_SAFE_FREE(scan_data); + 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_SLOG("path : %s", insert_data->msg); + + if (insert_data->pid == POWEROFF) { + g_array_prepend_val(register_array, insert_data); + } else if (insert_data->msg_type == MS_MSG_BURSTSHOT_INSERT) { + g_array_prepend_val(register_array, insert_data); + } else { + g_array_append_val(register_array, insert_data); + } +} + +static bool __msc_is_valid_path(const char *path) +{ + 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 __msc_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(!__msc_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("error [%s]", file_path); + MSC_DBG_STRERROR("file is not exist"); + 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_STRERROR("stat failed"); + return MS_MEDIA_ERR_INVALID_PATH; + } + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_clear_file_list(GArray *path_array) +{ + if (path_array) { + while(path_array->len != 0) { + char *data = NULL; + data = g_array_index(path_array , char*, 0); + g_array_remove_index (path_array, 0); + MS_SAFE_FREE(data); + } + g_array_free(path_array, FALSE); + path_array = NULL; + } + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_check_ignore_dir(const char *full_path) +{ + int ret = MS_MEDIA_ERR_NONE; + char *dir_path = NULL; + char *leaf_path = NULL; + + ret = __msc_check_file_path(full_path); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("invalid path : %s", full_path); + return MS_MEDIA_ERR_INVALID_PATH; + } + + dir_path = g_path_get_dirname(full_path); + if (strcmp(dir_path, ".") == 0) { + MSC_DBG_ERR("getting directory path is failed : %s", full_path); + MS_SAFE_FREE(dir_path); + return MS_MEDIA_ERR_INVALID_PATH; + } + + while(1) { + if(__msc_check_scan_ignore(dir_path)) { + ret = MS_MEDIA_ERR_INVALID_PATH; + break; + } + + /*If root path, Stop Scanning*/ + if(strcmp(dir_path, MEDIA_ROOT_PATH_INTERNAL) == 0) + break; + else if(strcmp(dir_path, MEDIA_ROOT_PATH_SDCARD) == 0) + break; + + leaf_path = strrchr(dir_path, '/'); + if(leaf_path != NULL) { + int seek_len = leaf_path -dir_path; + dir_path[seek_len] = '\0'; + } else { + MSC_DBG_ERR("Fail to find leaf path"); + ret = MS_MEDIA_ERR_INVALID_PATH; + break; + } + } + + MS_SAFE_FREE(dir_path); + + return ret; +} + +static int __msc_make_file_list(char *file_path, GArray **path_array) +{ + FILE *fp = NULL; + char buf[MS_FILE_PATH_LEN_MAX] = {0,}; + char *path = NULL; + int length; + int res = MS_MEDIA_ERR_NONE; + int ret = MS_MEDIA_ERR_NONE; + + /* load the file list from file */ + fp = fopen(file_path, "rt"); + if (fp == NULL) { + MSC_DBG_STRERROR("fopen failed"); + res = MS_MEDIA_ERR_FILE_OPEN_FAIL; + goto FREE_RESOURCE; + } + + memset(buf, 0x0, MS_FILE_PATH_LEN_MAX); + /* This is an array for storing the path of insert datas*/ + *path_array = g_array_new (FALSE, FALSE, sizeof (char *)); + if (*path_array == NULL) { + MSC_DBG_ERR("g_array_new failed"); + res = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + goto FREE_RESOURCE; + } + + /* read registering file path from stored file */ + while(fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) { + length = strlen(buf); /*the return value of function, strlen(), includes "\n" */ + path = strndup(buf, length - 1); /*copying except "\n" and strndup fuction adds "\0" at the end of the copying string */ + + /* check valid path */ + ret = __msc_check_ignore_dir(path); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("invalide path : %s", path); + MS_SAFE_FREE(path); + continue; + } + /* insert getted path to the list */ + if (g_array_append_val(*path_array, path) == NULL) { + MSC_DBG_ERR("g_array_append_val failed"); + res = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + goto FREE_RESOURCE; + } + } + + if(fp) fclose(fp); + fp = NULL; + + return MS_MEDIA_ERR_NONE; + +FREE_RESOURCE: + + __msc_clear_file_list(*path_array); + + if(fp) fclose(fp); + fp = NULL; + + return res; +} + +static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array) +{ + int err; + int i; + void **handle = NULL; + char *insert_path = NULL; + int (*insert_function)(void **, const char*) = NULL; + + insert_function = (current_msg == MS_MSG_BULK_INSERT) ? msc_insert_item_batch : msc_insert_burst_item; + + /* connect to media db, if conneting is failed, db updating is stopped */ + err = msc_connect_db(&handle); + if (err != MS_MEDIA_ERR_NONE) + return MS_MEDIA_ERR_DB_CONNECT_FAIL; + + /*start db updating */ + /*call for bundle commit*/ + __msc_bacth_commit_enable(handle, TRUE, FALSE, MS_NOTI_ENABLE, pid); + + MSC_DBG_ERR("BULK REGISTER START"); + + /* get the inserting file path from array and insert to db */ + for (i = 0; i < path_array->len; i++) { + + insert_path = g_array_index(path_array, char*, i); + + /* insert to db */ + err = insert_function(handle, insert_path); + + if (power_off) { + MSC_DBG_ERR("power off"); + /*call for bundle commit*/ + msc_register_end(handle); + break; + } + } + + /*call for bundle commit*/ + __msc_bacth_commit_disable(handle, TRUE, FALSE); + + /*disconnect form media db*/ + if (handle) msc_disconnect_db(&handle); + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data) +{ + int remain_request; + ms_comm_msg_s *insert_data = NULL; + + while (1) { + remain_request = g_async_queue_length(reg_queue); + + /*updating requests remain*/ + if (register_array->len != 0 && remain_request == 0) { + *register_data = g_array_index(register_array, ms_comm_msg_s*, 0); + g_array_remove_index (register_array, 0); + break; + } else if (remain_request != 0) { + insert_data = g_async_queue_pop(reg_queue); + __msc_insert_register_request(register_array, insert_data); + continue; + } else if (register_array->len == 0 && remain_request == 0) { + /*Threre is no request, Wait until pushung new request*/ + insert_data = g_async_queue_pop(reg_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); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + return MS_MEDIA_ERR_NONE; + +} + +gboolean msc_register_thread(void *data) +{ + ms_comm_msg_s *register_data = NULL; + GArray *register_array = NULL; + GArray *path_array = NULL; + char *file_path = NULL; + int ret; + int pid = 0; + ms_msg_type_e current_msg = MS_MSG_MAX; + + /*create array for processing overlay data*/ + register_array = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *)); + if (register_array == NULL) { + MSC_DBG_ERR("g_array_new error"); + return false; + } + + while (1) { + ret = __msc_pop_register_request(register_array, ®ister_data); + if (register_data->pid == POWEROFF) { + MSC_DBG_ERR("power off"); + goto _POWEROFF; + } + + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("__msc_pop_register_request failed [%d]", ret); + goto FREE_RESOURCE; + } + + /* check current request */ + current_msg = register_data->msg_type; + pid = register_data->pid; + + if ((current_msg != MS_MSG_BULK_INSERT) && + (current_msg != MS_MSG_BURSTSHOT_INSERT)) { + MSC_DBG_ERR("wrong message type"); + goto FREE_RESOURCE; + } + + file_path = strndup(register_data->msg, register_data->msg_size); + + ret = __msc_make_file_list(file_path, &path_array); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("__msc_make_file_list failed [%d]", ret); + goto FREE_RESOURCE; + } + + ret = __msc_batch_insert(current_msg, pid, path_array); + +FREE_RESOURCE: + /*Active flush */ + malloc_trim(0); + + /* If register_files operation is stopped, there is no necessrty for sending result. */ + msc_send_result(ret, register_data); + + MSC_DBG_ERR("BULK REGISTER END [%d |%s]", ret, register_data->msg); + + __msc_clear_file_list(path_array); + + MS_SAFE_FREE(file_path); + MS_SAFE_FREE(register_data); + } /*thread while*/ + +_POWEROFF: + MS_SAFE_FREE(file_path); + MS_SAFE_FREE(register_data); + if (register_array) { + while(register_array->len != 0) { + ms_comm_msg_s *data = NULL; + data = g_array_index(register_array , ms_comm_msg_s*, 0); + g_array_remove_index (register_array, 0); + MS_SAFE_FREE(data); + } + g_array_free (register_array, FALSE); + register_array = NULL; + } + + __msc_clear_file_list(path_array); + + return false; +} + +static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid) +{ + /*call for bundle commit*/ + if (ins_status) msc_register_start(handle, noti_enable, pid); + if (valid_status) msc_validate_start(handle); + + return; +} + +static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status) +{ + /*call for bundle commit*/ + if (ins_status) msc_register_end(handle); + if (valid_status) msc_validate_end(handle); + + return; +} + +static int __msc_dir_scan_meta_update(void **handle, const char*start_path, ms_storage_type_t storage_type) +{ + DIR *dp = NULL; + GArray *dir_array = NULL; + struct dirent entry; + struct dirent *result = NULL; + int ret = MS_MEDIA_ERR_NONE; + char *new_path = NULL; + char *current_path = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + int (*scan_function)(void **, const char*) = msc_update_meta_batch; + + /* make new array for storing directory */ + dir_array = g_array_new (FALSE, FALSE, sizeof (char*)); + if (dir_array == NULL){ + MSC_DBG_ERR("g_array_new failed"); + return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + } + /* add first direcotiry to directory array */ + g_array_append_val (dir_array, start_path); + + /*start db update. the number of element in the array , db update is complete.*/ + while (dir_array->len != 0) { + /*check poweroff status*/ + ret = __msc_check_stop_status(storage_type); + if (ret != MS_MEDIA_ERR_NONE) { + goto STOP_SCAN; + } + + /* get the current path from directory array */ + current_path = g_array_index(dir_array , char*, 0); + g_array_remove_index (dir_array, 0); +// MSC_DBG_SLOG("%d", dir_array->len); + + if (__msc_check_scan_ignore(current_path)) { + MSC_DBG_ERR("%s is ignore", current_path); + MS_SAFE_FREE(current_path); + continue; + } + + dp = opendir(current_path); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + /*check poweroff status*/ + ret = __msc_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) { + MSC_DBG_ERR(""); + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* insert into media DB */ + MSC_DBG_ERR("%s", path); + if (scan_function(handle,path) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("failed to update db"); + continue; + } + } else if (entry.d_type & DT_DIR) { + /* this request is recursive scanning */ + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* add new directory to dir_array */ + new_path = strdup(path); + g_array_append_val (dir_array, new_path); + } + } + } else { + MSC_DBG_ERR("%s folder opendir fails", current_path); + } + if (dp) closedir(dp); + dp = NULL; + MS_SAFE_FREE(current_path); + } /*db update while */ +STOP_SCAN: + if (dp) closedir(dp); + + __msc_clear_file_list(dir_array); + + if (ret != MS_MEDIA_ERR_NONE) MSC_DBG_INFO("ret : %d", ret); + + return ret; +} + + +gboolean msc_metadata_update(void *data) +{ + ms_comm_msg_s *scan_data = data; + int err; + int ret; + void **handle = NULL; + char *start_path = NULL; + ms_storage_type_t storage_type = MS_STORAGE_INTERNAL; + + MSC_DBG_INFO("META UPDATE START"); + + /*connect to media db, if conneting is failed, db updating is stopped*/ + err = msc_connect_db(&handle); + if (err != MS_MEDIA_ERR_NONE) + return false; + + /*call for bundle commit*/ + msc_update_start(handle); + + /*insert data into media db */ + + start_path = strdup(MEDIA_ROOT_PATH_INTERNAL); + ret = __msc_dir_scan_meta_update(handle, start_path, storage_type); + + /* send notification */ + msc_send_dir_update_noti(handle, MEDIA_ROOT_PATH_INTERNAL); + + if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { + storage_type = MS_STORAGE_EXTERNAL; + start_path = strdup(MEDIA_ROOT_PATH_SDCARD); + ret = __msc_dir_scan_meta_update(handle, start_path, storage_type); + /* send notification */ + msc_send_dir_update_noti(handle, MEDIA_ROOT_PATH_SDCARD); + } + + /*call for bundle commit*/ + msc_update_end(handle); + + if (power_off) { + MSC_DBG_WAN("power off"); + goto _POWEROFF; + } + + /*disconnect form media db*/ + if (handle) msc_disconnect_db(&handle); + + /*Active flush */ + malloc_trim(0); + + msc_send_result(ret, scan_data); + + MS_SAFE_FREE(scan_data); + + MSC_DBG_INFO("META UPDATE END [%d]", ret); + + +_POWEROFF: + MS_SAFE_FREE(scan_data); + if (handle) msc_disconnect_db(&handle); + + return false; +} + + +void msc_metadata_update_thread(ms_comm_msg_s *recv_msg) +{ + g_thread_new("update_thread", (GThreadFunc)msc_metadata_update, recv_msg); +} diff --git a/src/scanner/media-scanner-socket.c b/src/scanner/media-scanner-socket.c new file mode 100755 index 0000000..9ee6060 --- /dev/null +++ b/src/scanner/media-scanner-socket.c @@ -0,0 +1,186 @@ +/* + * 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/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/un.h> +#include <malloc.h> +#include <vconf.h> + +#include "media-util.h" +#include "media-server-ipc.h" +#include "media-common-types.h" +#include "media-common-utils.h" +#include "media-scanner-dbg.h" +#include "media-scanner-db-svc.h" +#include "media-scanner-socket.h" + +extern GAsyncQueue *storage_queue; +extern GAsyncQueue *scan_queue; +extern GAsyncQueue *reg_queue; + +gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer data) +{ + ms_comm_msg_s *recv_msg = NULL; + int sockfd = MS_SOCK_NOT_ALLOCATE; + int req_num = MS_MSG_MAX; + int err = -1; + + sockfd = g_io_channel_unix_get_fd(src); + if (sockfd < 0) { + 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; + } + + /* read() is blocked until media scanner sends message */ + err = read(sockfd, recv_msg, sizeof(ms_comm_msg_s)); + if (err < 0) { + MSC_DBG_STRERROR("fifo read failed"); + MS_SAFE_FREE(recv_msg); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } + + MSC_DBG_SLOG("receive msg from [%d] %d, %s", recv_msg->pid, recv_msg->msg_type, recv_msg->msg); + + /* copy from recived data */ + req_num = recv_msg->msg_type; + + switch(req_num){ + case MS_MSG_BULK_INSERT: + case MS_MSG_BURSTSHOT_INSERT: + { + MSC_DBG_INFO("BULK INSERT"); + /* request bulk insert*/ + g_async_queue_push(reg_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_DIRECTORY_SCANNING: + case MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE: + { + /* this request from another apps */ + /* set the scan data for scanning thread */ + g_async_queue_push(scan_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_STORAGE_ALL: + case MS_MSG_STORAGE_PARTIAL: + case MS_MSG_STORAGE_INVALID: + { + /* this request from media-server */ + g_async_queue_push(storage_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_STORAGE_META: + msc_metadata_update_thread(recv_msg); + break; + default: + { + MSC_DBG_ERR("THIS REQUEST IS INVALID %d", req_num); + MS_SAFE_FREE(recv_msg); + } + break; + } + + /*Active flush */ + malloc_trim(0); + + return TRUE; +} + +int msc_send_ready(void) +{ + int res = MS_MEDIA_ERR_NONE; + ms_comm_msg_s send_msg; + int fd = -1; + int err = -1; + + fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + /* send ready message */ + memset(&send_msg, 0, sizeof(send_msg)); + send_msg.msg_type = MS_MSG_SCANNER_READY; + + /* send ready message */ + err = write(fd, &send_msg, sizeof(send_msg)); + if (err < 0) { + MSC_DBG_STRERROR("fifo write failed"); + res = MS_MEDIA_ERR_FILE_READ_FAIL; + } + + close(fd); + + return res; +} + +int msc_send_result(int result, ms_comm_msg_s *res_data) +{ + int res = MS_MEDIA_ERR_NONE; + ms_comm_msg_s send_msg; + int fd = -1; + int err = -1; + + fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + /* send result message */ + memset(&send_msg, 0x0, sizeof(ms_comm_msg_s)); + send_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT; + send_msg.pid = res_data->pid; + send_msg.result = result; + send_msg.msg_size = res_data->msg_size; + strncpy(send_msg.msg, res_data->msg, send_msg.msg_size); + + /* send ready message */ + err = write(fd, &send_msg, sizeof(send_msg)); + if (err < 0) { + MSC_DBG_STRERROR("fifo write failed"); + res = MS_MEDIA_ERR_FILE_READ_FAIL; + } + + close(fd); + + return res; +} + diff --git a/src/scanner/media-scanner.c b/src/scanner/media-scanner.c new file mode 100755 index 0000000..c62dbbd --- /dev/null +++ b/src/scanner/media-scanner.c @@ -0,0 +1,325 @@ +/* + * 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 <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +#include "media-common-utils.h" +#include "media-common-external-storage.h" + +#include "media-util.h" +#include "media-scanner-dbg.h" +#include "media-scanner-db-svc.h" +#include "media-scanner-scan.h" +#include "media-scanner-socket.h" + +#define APP_NAME "media-scanner" + +extern int mmc_state; + +extern GAsyncQueue *storage_queue; +extern GAsyncQueue *scan_queue; +extern GAsyncQueue *reg_queue; +extern GMutex *db_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]; + + ms_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 (storage_queue) { + /*notify to register thread*/ + MS_MALLOC(reg_data, sizeof(ms_comm_msg_s)); + reg_data->pid = POWEROFF; + g_async_queue_push(storage_queue, GINT_TO_POINTER(reg_data)); + } + + if (g_main_loop_is_running(scanner_mainloop)) g_main_loop_quit(scanner_mainloop); +} + +void +_msc_mmc_vconf_cb(keynode_t *key, void* data) +{ + int status = 0; +/* + ms_comm_msg_s *scan_msg; + ms_dir_scan_type_t scan_type = MS_SCAN_PART; +*/ + if (!ms_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) { + scan_type = MS_SCAN_INVALID; + } else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { + scan_type = ms_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); + ms_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; +} + +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 err = -1; + int fd = -1; + +#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); + + /*set power off callback function*/ + ms_add_poweoff_event_receiver(_power_off_cb, NULL); + + /*load functions from plusin(s)*/ + err = msc_load_functions(); + if (err != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("function load failed[%d]", err); + goto EXIT; + } + + /*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(); + + /* Create pipe */ + err = unlink(MS_SCANNER_FIFO_PATH_REQ); + if (err !=0) { + MSC_DBG_STRERROR("unlink failed"); + } + + err = mkfifo(MS_SCANNER_FIFO_PATH_REQ, MS_SCANNER_FIFO_MODE); + if (err !=0) { + MSC_DBG_STRERROR("mkfifo failed"); + return MS_MEDIA_ERR_FIFO_MAKE_FAIL; + } + + fd = open(MS_SCANNER_FIFO_PATH_REQ, O_RDWR); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + context = g_main_loop_get_context(scanner_mainloop); + + /* Create new channel to watch pipe */ + channel = g_io_channel_unix_new(fd); + source = g_io_create_watch(channel, G_IO_IN); + + /* Set callback to be called when pipe is readable */ + g_source_set_callback(source, (GSourceFunc)msc_receive_request, NULL, NULL); + g_source_attach(source, context); + g_source_unref(source); + + /*create each threads*/ + storage_scan_thread = g_thread_new("storage_scan_thread", (GThreadFunc)msc_storage_scan_thread, NULL); + scan_thread = g_thread_new("scanner_thread", (GThreadFunc)msc_directory_scan_thread, NULL); + register_thread = g_thread_new("register_thread", (GThreadFunc)msc_register_thread, NULL); + + /*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 (ms_is_mmc_inserted()) { + mmc_state = VCONFKEY_SYSMAN_MMC_MOUNTED; + } + + MSC_DBG_INFO("scanner is ready"); + + msc_send_ready(); + + MSC_DBG_ERR("*****************************************"); + MSC_DBG_ERR("*** Scanner is running ***"); + MSC_DBG_ERR("*****************************************"); + + 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); + } + + 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 pipe*/ + close(fd); + + /*unload functions*/ + msc_unload_functions(); + +EXIT: + MSC_DBG_INFO("SCANNER IS END"); + + return 0; +} + diff --git a/common/include/media-server-drm.h b/src/server/include/media-server-db-svc.h index 27f3dc6..010de85 100755 --- a/common/include/media-server-drm.h +++ b/src/server/include/media-server-db-svc.h @@ -22,33 +22,37 @@ /** * This file defines api utilities of contents manager engines. * - * @file media-server-drm.h + * @file media-server-db-svc.h * @author Yong Yeon Kim(yy9875.kim@samsung.com) * @version 1.0 - * @brief This file implements main database operation. + * @brief */ -#ifndef _MEDIA_SERVER_DRM_H_ -#define _MEDIA_SERVER_DRM_H_ +#ifndef _MEDIA_SERVER_DB_SVC_H_ +#define _MEDIA_SERVER_DB_SVC_H_ -bool -ms_is_drm_file(const char *path); +#include "media-common-types.h" -int -ms_get_mime_in_drm_info(const char *path, char *mime); +typedef int (*CONNECT)(void**, char **); +typedef int (*DISCONNECT)(void*, char **); +typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, char **); +typedef int (*CHECK_DB)(void*, char **); int -ms_drm_register(const char* path); +ms_load_functions(void); void -ms_drm_unregister(const char* path); +ms_unload_functions(void); -void -ms_drm_unregister_all(void); +int +ms_connect_db(void ***handle); -bool -ms_drm_insert_ext_memory(void); +int +ms_disconnect_db(void ***handle); -bool -ms_drm_extract_ext_memory(void); +int +ms_invalidate_all_items(void **handle, ms_storage_type_t store_type); + +int +ms_check_db_upgrade(void **handle); -#endif /*_MEDIA_SERVER_DRM_H_*/
\ No newline at end of file +#endif /*_MEDIA_SERVER_DB_SVC_H_*/
\ No newline at end of file diff --git a/common/include/media-server-dbus-type.h b/src/server/include/media-server-db.h index 54c227a..87f0b00 100755 --- a/common/include/media-server-dbus-type.h +++ b/src/server/include/media-server-db.h @@ -18,16 +18,14 @@ * 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'" +#ifndef _MEDIA_SERVER_DB_H_ +#define _MEDIA_SERVER_DB_H_ -typedef enum { - MS_DBUS_DB_UPDATED -} ms_dbus_noti_type_t; +#include <glib.h> -#endif /*_MEDIA_SERVER_DBUS_TYPES_H_*/
\ No newline at end of file +GMainLoop *ms_db_get_mainloop(void); +gboolean ms_db_get_thread_status(void); +gboolean ms_db_thread(void *data); + +#endif/* _MEDIA_SERVER_DB_H_ */ diff --git a/src/server/include/media-server-dbg.h b/src/server/include/media-server-dbg.h new file mode 100755 index 0000000..a4130f9 --- /dev/null +++ b/src/server/include/media-server-dbg.h @@ -0,0 +1,70 @@ +/* + * Media Server + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim <yy9875.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * This file defines api utilities of contents manager engines. + * + * @file media-server-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> +#include <errno.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "MEDIA_SERVER" +#define BUF_LENGTH 256 + +#define MS_DBG_STRERROR(fmt) do { \ + char buf[BUF_LENGTH] = {0,}; \ + strerror_r(errno, buf, BUF_LENGTH); \ + LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + } while (0) + +#define MS_DBG_SLOG(fmt, args...) do{ if (true) { \ + SECURE_LOGD(fmt "\n" , ##args); \ + }} while(false) + +#define MS_DBG(fmt, args...) do{ if (true) { \ + LOGD(fmt "\n" , ##args); \ + }} while(false) + +#define MS_DBG_INFO(fmt, args...) do{ if (true) { \ + LOGI(fmt "\n" , ##args); \ + }} while(false) + +#define MS_DBG_WARN(fmt, args...) do{ if (true) { \ + LOGW(fmt "\n", ##args); \ + }} while(false) + +#define MS_DBG_ERR(fmt, args...) do{ if (true) { \ + LOGE(fmt "\n", ##args); \ + }} while(false) + +#endif /*_MEDIA_SERVER_DBG_H_*/ diff --git a/common/include/media-server-dbus.h b/src/server/include/media-server-scanner.h index 241d543..735a5df 100755 --- a/common/include/media-server-dbus.h +++ b/src/server/include/media-server-scanner.h @@ -18,13 +18,11 @@ * limitations under the License. * */ -#ifndef _MEDIA_SERVER_DBUS_H__ -#define _MEDIA_SERVER_DBUS_H__ -#include "media-server-dbus-type.h" +int ms_scanner_start(void); -void ms_dbus_init(void); +bool ms_get_scanner_status(void); -gboolean ms_dbus_send_noti(ms_dbus_noti_type_t data); +void ms_reset_scanner_status(void); -#endif/*_MEDIA_SERVER_DBUS_H__*/
\ No newline at end of file +int ms_get_scanner_pid(void);
\ No newline at end of file diff --git a/src/server/include/media-server-socket.h b/src/server/include/media-server-socket.h new file mode 100755 index 0000000..a9d3a61 --- /dev/null +++ b/src/server/include/media-server-socket.h @@ -0,0 +1,48 @@ +/* + * 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-common-types.h" +#include "media-server-ipc.h" + +gboolean ms_read_socket(gpointer user_data); + +gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data); + +gboolean ms_read_db_tcp_batch_socket(GIOChannel *src, GIOCondition condition, gpointer data); + +int ms_send_scan_request(ms_comm_msg_s *send_msg, int client_sock); + +int ms_send_storage_scan_request(char *root_path, ms_dir_scan_type_t scan_type); + +gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data); + +#endif /*_MEDIA_SERVER_SOCKET_H_*/ diff --git a/src/server/include/media-server-thumb.h b/src/server/include/media-server-thumb.h new file mode 100755 index 0000000..a8558a9 --- /dev/null +++ b/src/server/include/media-server-thumb.h @@ -0,0 +1,46 @@ +/* + * 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/un.h> +#include <arpa/inet.h> +#include "media-common-types.h" +#include "media-server-ipc.h" + +#ifndef _MEDIA_SERVER_THUMB_H_ +#define _MEDIA_SERVER_THUMB_H_ + +#define MAX_THUMB_REQUEST 100 + +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); + +#endif /*_MEDIA_SERVER_THUMB_H_*/ + diff --git a/src/server/media-server-db-svc.c b/src/server/media-server-db-svc.c new file mode 100755 index 0000000..11dc2b1 --- /dev/null +++ b/src/server/media-server-db-svc.c @@ -0,0 +1,304 @@ +/* + * 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 "media-util.h" + +#include "media-common-utils.h" +#include "media-server-dbg.h" +#include "media-server-db-svc.h" + +#define CONFIG_PATH "/usr/etc/media-server-plugin" +#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 { + eCONNECT, + eDISCONNECT, + eSET_ALL_VALIDITY, + eCHECK_DB, + eFUNC_MAX +}; + +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] = { + "connect_db", + "disconnect_db", + "set_all_storage_items_validity", + "check_db", + }; + /*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; + + 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); + return MS_MEDIA_ERR_DB_CONNECT_FAIL; + } + } + + MS_DBG("connect Media DB"); + + 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_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_check_db_upgrade(void **handle) +{ + 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 = ((CHECK_DB)func_array[lib_index][eCHECK_DB])(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); + res = MS_MEDIA_ERR_DB_UPDATE_FAIL; + } + } + MS_DBG(""); + return res; +} + diff --git a/src/server/media-server-db.c b/src/server/media-server-db.c new file mode 100755 index 0000000..1b1b282 --- /dev/null +++ b/src/server/media-server-db.c @@ -0,0 +1,138 @@ +/* + * 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-ipc.h" +#include "media-common-types.h" + +#include "media-server-dbg.h" +#include "media-server-socket.h" +#include "media-server-db.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"); + return FALSE; + } + + /* Create TCP Socket*/ + ret = ms_ipc_create_server_socket(MS_PROTOCOL_TCP, 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"); + 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); + close(sockfd); + MS_DBG_ERR("Failed to create socket"); + 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_tcp_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_batch_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); + close(tcp_sockfd); + + g_main_loop_unref(g_db_mainloop); + + return FALSE; +} diff --git a/src/server/media-server-main.c b/src/server/media-server-main.c new file mode 100755 index 0000000..3b12d0f --- /dev/null +++ b/src/server/media-server-main.c @@ -0,0 +1,492 @@ +/* + * 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 "media-util.h" +#include "media-common-utils.h" +#include "media-common-external-storage.h" +#include "media-server-dbg.h" +#include "media-server-db-svc.h" +#include "media-server-socket.h" +#include "media-server-db.h" +#include "media-server-thumb.h" +#include "media-server-scanner.h" + +#define APP_NAME "media-server" + +extern GMutex *scanner_mutex; + +GMainLoop *mainloop = NULL; +bool power_off; /*If this is TRUE, poweroff notification received*/ + +static void __ms_check_mediadb(void); +static void __ms_add_signal_handler(void); +static void __ms_remove_event_receiver(void); +static void __ms_add_event_receiver(GIOChannel *channel); +static void __ms_remove_requst_receiver(GIOChannel *channel); +static void __ms_add_requst_receiver(GMainLoop *mainloop, GIOChannel **channel); + +static char *priv_lang = 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"); + 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 _power_off_cb(void* data) +{ + MS_DBG_ERR("POWER OFF"); + + GIOChannel *channel = (GIOChannel *)data; + + power_off = TRUE; + + /*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); + } + + __ms_remove_requst_receiver(channel); + + __ms_remove_event_receiver(); + + return; +} + +static void _db_clear(void) +{ + int err = MS_MEDIA_ERR_NONE; + void **handle = NULL; + + /*load functions from plusin(s)*/ + err = ms_load_functions(); + if (err != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("function load failed [%d]", err); + return; + } + + /*connect to media db, if conneting is failed, db updating is stopped*/ + ms_connect_db(&handle); + + /* check schema of db is chaged and need upgrade */ + MS_DBG_WARN("Check DB upgrade start"); + if (ms_check_db_upgrade(handle) != MS_MEDIA_ERR_NONE) + MS_DBG_ERR("ms_check_db_upgrade fail"); + MS_DBG_WARN("Check DB upgrade end"); + + /*update just valid type*/ + if (ms_invalidate_all_items(handle, MS_STORAGE_EXTERNAL) != MS_MEDIA_ERR_NONE) + MS_DBG_ERR("ms_change_valid_type fail"); + + /*disconnect form media db*/ + if (handle) ms_disconnect_db(&handle); + + /*unload functions*/ + ms_unload_functions(); +} + +void _ms_signal_handler(int n) +{ + int stat, pid, thumb_pid; + int scanner_pid; + + thumb_pid = ms_thumb_get_server_pid(); + scanner_pid = ms_get_scanner_pid(); + + while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) { + /* check pid of child process of thumbnail thread */ + if (pid == thumb_pid) { + MS_DBG_ERR("[%d] Thumbnail server is stopped by media-server", pid); + ms_thumb_reset_server_status(); + } else if (pid == scanner_pid) { + MS_DBG_ERR("[%d] Scanner is stopped by media-server", pid); + ms_reset_scanner_status(); + } else { + MS_DBG_ERR("[%d] is stopped", pid); + } +/* + if (WIFEXITED(stat)) { + MS_DBG_ERR("normal termination , exit status : %d", WEXITSTATUS(stat)); + } else if (WIFSIGNALED(stat)) { + MS_DBG_ERR("abnormal termination , signal number : %d", WTERMSIG(stat)); + } else if (WIFSTOPPED(stat)) { + MS_DBG_ERR("child process is stoped, signal number : %d", WSTOPSIG(stat)); + } +*/ + } + + return; +} + +static void _ms_new_global_variable(void) +{ + /*Init mutex variable*/ + /*media scanner stop/start mutex*/ + if (!scanner_mutex) scanner_mutex = g_mutex_new(); +} + +static void _ms_free_global_variable(void) +{ + /*Clear mutex variable*/ + if (scanner_mutex) g_mutex_free(scanner_mutex); +} + +void +_ms_mmc_vconf_cb(keynode_t *key, 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_ERR("CURRENT STATUS OF SD CARD[%d]", 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 (status == VCONFKEY_SYSMAN_MMC_REMOVED || + status == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) { + + /*remove added watch descriptors */ + ms_present_mmc_status(MS_SDCARD_REMOVED); + + ms_send_storage_scan_request(MEDIA_ROOT_PATH_SDCARD, MS_SCAN_INVALID); + } else if (status == VCONFKEY_SYSMAN_MMC_MOUNTED) { + + ms_make_default_path_mmc(); + + ms_present_mmc_status(MS_SDCARD_INSERTED); + + ms_send_storage_scan_request(MEDIA_ROOT_PATH_SDCARD, ms_get_mmc_state()); + } + + return; +} + +void +_ms_change_lang_vconf_cb(keynode_t *key, void* data) +{ + char lang[100] = {0, }; + char *eng = "en"; + char *chi = "zh"; + char *jpn = "ja"; + char *kor = "ko"; + bool need_update = FALSE; + + if (!ms_config_get_str(VCONFKEY_LANGSET, lang)) { + MS_DBG_ERR("Get VCONFKEY_LANGSET failed."); + return; + } + + MS_DBG("CURRENT LANGUAGE [%s] [%s]", priv_lang, lang); + + if (strcmp(priv_lang, lang) == 0) { + need_update = FALSE; + } else if ((strncmp(lang, eng, strlen(eng)) == 0) || + (strncmp(lang, chi, strlen(chi)) == 0) || + (strncmp(lang, jpn, strlen(jpn)) == 0) || + (strncmp(lang, kor, strlen(kor)) == 0)) { + need_update = TRUE; + } else { + if ((strncmp(priv_lang, eng, strlen(eng)) == 0) || + (strncmp(priv_lang, chi, strlen(chi)) == 0) || + (strncmp(priv_lang, jpn, strlen(jpn)) == 0) || + (strncmp(priv_lang, kor, strlen(kor)) == 0)) { + need_update = TRUE; + } + } + + if (need_update) { + ms_send_storage_scan_request(NULL, MS_SCAN_META); + } else { + MS_DBG_WARN("language is changed but do not update meta data"); + } + + MS_SAFE_FREE(priv_lang); + priv_lang = strdup(lang); + + return; +} + +static void _ms_check_pw_status(void) +{ + int pw_status = 0; + + if (!ms_config_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &pw_status)) { + MS_DBG_ERR("Get VCONFKEY_SYSMAN_POWER_OFF_STATUS failed."); + } + + if (pw_status == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || + pw_status == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { + power_off = TRUE; + + while(1) { + MS_DBG_WARN("wait power off"); + sleep(3); + } + } + + return; +} + +int main(int argc, char **argv) +{ + GThread *db_thread = NULL; + GThread *thumb_thread = NULL; + GIOChannel *channel = NULL; + bool check_result = false; + + power_off = FALSE; + + _ms_check_pw_status(); + + check_result = check_process(); + if (check_result == false) { + goto EXIT; + } + + if (!g_thread_supported()) { + g_thread_init(NULL); + } + + /*Init main loop*/ + mainloop = g_main_loop_new(NULL, FALSE); + + _ms_new_global_variable(); + + __ms_add_requst_receiver(mainloop, &channel); + + /* recevie event from other modules */ + __ms_add_event_receiver(channel); + + __ms_add_signal_handler(); + + /*create each threads*/ + 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); + + /*clear previous data of sdcard on media database and check db status for updating*/ + while(!ms_db_get_thread_status()) { + MS_DBG_ERR("wait db thread"); + sleep(1); + } + + /* update media DB */ + __ms_check_mediadb(); + + /*Active flush */ + malloc_trim(0); + + MS_DBG_ERR("*** Media Server is running ***"); + + g_main_loop_run(mainloop); + + g_thread_join(db_thread); + g_thread_join(thumb_thread); + + _ms_free_global_variable(); + + MS_DBG_ERR("*** Media Server is stopped ***"); + +EXIT: + + return 0; +} + +static void __ms_add_requst_receiver(GMainLoop *mainloop, GIOChannel **channel) +{ + + int sockfd = -1; + GSource *source = NULL; + GMainContext *context = NULL; + + /*prepare socket*/ + /* Create and bind new UDP socket */ + if (ms_ipc_create_server_socket(MS_PROTOCOL_TCP, MS_SCANNER_PORT, &sockfd) + != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("Failed to create socket"); + return; + } 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, *channel, NULL); + g_source_attach(source, context); + g_source_unref(source); + } +} + +static void __ms_remove_requst_receiver(GIOChannel *channel) +{ + int fd = -1; + + /*close an IO channel*/ + fd = g_io_channel_unix_get_fd(channel); + g_io_channel_shutdown(channel, FALSE, NULL); + g_io_channel_unref(channel); + + if (fd > 0) { + if (close(fd) < 0) { + MS_DBG_STRERROR("CLOSE ERROR"); + } + } +} + +static void __ms_add_event_receiver(GIOChannel *channel) +{ + int err; + char lang[100] = {0,}; + + /*set power off callback function*/ + ms_add_poweoff_event_receiver(_power_off_cb,channel); + + /*add noti receiver for SD card event */ + 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); + + if (!ms_config_get_str(VCONFKEY_LANGSET, lang)) { + MS_DBG_ERR("Get VCONFKEY_LANGSET failed."); + return; + } + + priv_lang = strdup(lang); + + err = vconf_notify_key_changed(VCONFKEY_LANGSET, (vconf_callback_fn) _ms_change_lang_vconf_cb, NULL); + if (err == -1) + MS_DBG_ERR("add call back function for event %s fails", VCONFKEY_LANGSET); + +} + +static void __ms_remove_event_receiver(void) +{ + vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + (vconf_callback_fn) _ms_mmc_vconf_cb); +} + +static void __ms_add_signal_handler(void) +{ + struct sigaction sigset; + + /* Add signal handler */ + sigemptyset(&sigset.sa_mask); + sigaddset(&sigset.sa_mask, SIGCHLD); + sigset.sa_flags = SA_RESTART |SA_NODEFER; + sigset.sa_handler = _ms_signal_handler; + + if (sigaction(SIGCHLD, &sigset, NULL) < 0) { + MS_DBG_STRERROR("sigaction failed"); + } + + signal(SIGPIPE,SIG_IGN); +} +static void __ms_check_mediadb(void) +{ + _db_clear(); + + /* update internal storage */ + ms_send_storage_scan_request(MEDIA_ROOT_PATH_INTERNAL, MS_SCAN_PART); + + /* update external storage */ + if (ms_is_mmc_inserted()) { + ms_make_default_path_mmc(); + ms_present_mmc_status(MS_SDCARD_INSERTED); + + ms_send_storage_scan_request(MEDIA_ROOT_PATH_SDCARD, ms_get_mmc_state()); + } +} + diff --git a/src/server/media-server-scanner.c b/src/server/media-server-scanner.c new file mode 100755 index 0000000..21dd923 --- /dev/null +++ b/src/server/media-server-scanner.c @@ -0,0 +1,246 @@ +/* + * 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 <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "media-util.h" +#include "media-server-ipc.h" +#include "media-common-types.h" +#include "media-common-utils.h" +#include "media-server-dbg.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 child_pid; +static int receive_id; + +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 task_num = MS_NO_REMAIN_TASK; + + 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_STRERROR("kill failed"); + g_mutex_unlock(scanner_mutex); + return TRUE; + } + } + MS_DBG("KILL SCANNER"); + + /* close & delete FIFO */ + int res_fd = -1; + GIOChannel *res_channel = user_data; + + res_fd = g_io_channel_unix_get_fd(res_channel); + close(res_fd); + + unlink(MS_SCANNER_FIFO_PATH_RES); + unlink(MS_SCANNER_FIFO_PATH_REQ); + +// ms_reset_scanner_status(); + + 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"); + g_mutex_unlock(scanner_mutex); + } else if (pid > 0) { + /* parent process */ + /* wait until scanner is ready*/ + int ret = MS_MEDIA_ERR_NONE; + int err = -1; + int fd = -1; + ms_comm_msg_s recv_msg; + int scanner_status = -1; + + err = unlink(MS_SCANNER_FIFO_PATH_RES); + if (err !=0) { + MS_DBG_STRERROR("unlink failed"); + } + err = mkfifo(MS_SCANNER_FIFO_PATH_RES, MS_SCANNER_FIFO_MODE); + if (err !=0) { + MS_DBG_STRERROR("mkfifo failed"); + return MS_MEDIA_ERR_FIFO_MAKE_FAIL; + } + + fd = open(MS_SCANNER_FIFO_PATH_RES, O_RDWR); + if (fd < 0) { + MS_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + /* read() is blocked until media scanner sends message */ + err = read(fd, &recv_msg, sizeof(recv_msg)); + if (err < 0) { + MS_DBG_STRERROR("fifo read failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } + + scanner_status = recv_msg.msg_type; + if (scanner_status == MS_MSG_SCANNER_READY) { + GSource *res_source = NULL; + GIOChannel *res_channel = NULL; + GMainContext *res_context = NULL; + + MS_DBG_ERR("SCANNER is ready"); + 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(fd); + 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("SCANNER is not ready"); + ret = MS_MEDIA_ERR_SCANNER_NOT_READY; + close(fd); + } + + 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; + + g_mutex_unlock(scanner_mutex); +} + +int ms_get_scanner_pid(void) +{ + return child_pid; +} diff --git a/src/server/media-server-socket.c b/src/server/media-server-socket.c new file mode 100755 index 0000000..03d1245 --- /dev/null +++ b/src/server/media-server-socket.c @@ -0,0 +1,723 @@ +/* + * 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/stat.h> +#include <fcntl.h> +#include <sys/un.h> +#include <errno.h> +#include <malloc.h> +#include <vconf.h> +#include <security-server.h> + +#include "media-util.h" +#include "media-util-internal.h" +#include "media-server-ipc.h" +#include "media-common-utils.h" +#include "media-server-dbg.h" +#include "media-server-db-svc.h" +#include "media-server-scanner.h" +#include "media-server-socket.h" + +extern GAsyncQueue *scan_queue; +GAsyncQueue* ret_queue; +GArray *owner_list; +extern GMutex *scanner_mutex; +gint cur_running_task; + +extern bool power_off; + +typedef struct ms_req_owner_data +{ + int pid; + int index; + int client_sockfd; +}ms_req_owner_data; + +static int __ms_add_owner(int pid, int client_sock) +{ + if (pid != 0) { + 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"); + return MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + } + } + + /* store pid and client address */ + MS_MALLOC(owner_data, sizeof(ms_req_owner_data)); + owner_data->pid = pid; + owner_data->client_sockfd = client_sock; + // 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); + + owner_data->index = -1; + g_array_append_val(owner_list, owner_data); + } + + return MS_MEDIA_ERR_NONE; +} + +static int __ms_find_owner(int pid, ms_req_owner_data **owner_data) +{ + int i; + int len = owner_list->len; + ms_req_owner_data *data = NULL; + + *owner_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) { + data->index = i; + *owner_data = data; + MS_DBG("FIND OWNER"); + break; + } + } + + return MS_MEDIA_ERR_NONE; +} + +static int __ms_delete_owner(ms_req_owner_data *owner_data) +{ + if (owner_data->index != -1) { + g_array_remove_index(owner_list, owner_data->index); + MS_SAFE_FREE(owner_data); + MS_DBG("DELETE OWNER"); + } + + return MS_MEDIA_ERR_NONE; +} + +static int __ms_send_result_to_client(int pid, ms_comm_msg_s *recv_msg) +{ + 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(pid, &owner_data); + if (owner_data != NULL) { + MS_DBG("PID : %d", owner_data->pid); + /* owner data exists */ + /* send result to the owner of request */ + ms_ipc_send_msg_to_client_tcp(owner_data->client_sockfd, recv_msg, NULL); + close(owner_data->client_sockfd); + + /* free owner data*/ + __ms_delete_owner(owner_data); + } else { + MS_DBG_ERR("Not found Owner"); + return MS_MEDIA_ERR_INTERNAL; + } + } else { + /* owner data does not exist*/ + /* this is result of request of media server*/ + MS_DBG_ERR("There is no request, Owner list is NULL"); + return MS_MEDIA_ERR_INTERNAL; + } + + return MS_MEDIA_ERR_NONE; + +} + +static int __ms_privilege_check(const char *msg, gboolean *privilege) +{ +#define operation_cnt 3 +#define db_table_cnt 5 + + int o_idx = 0; + int t_idx = 0; + gboolean is_privilege = TRUE; + + char *operation[operation_cnt] = { + "INSERT INTO ", + "DELETE FROM ", + "UPDATE " + }; + + char *db_table[db_table_cnt] = { + "playlist_map", + "playlist", + "tag_map", + "tag", + "bookmark" + }; + + if(strlen(msg) < 10) { + MS_DBG_ERR("msg is too short!!"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + for(o_idx = 0; o_idx < operation_cnt; o_idx++) { + if(strncmp(operation[o_idx], msg, strlen(operation[o_idx])) == 0) { + for(t_idx = 0; t_idx < db_table_cnt; t_idx++) { + if(strncmp(db_table[t_idx], msg+strlen(operation[o_idx]), strlen(db_table[t_idx])) == 0) { + MS_DBG("Non privilege [%s][%s]", operation[o_idx], db_table[t_idx]); + is_privilege = FALSE; + break; + } + } + break; + } + } + + *privilege = is_privilege; + + return MS_MEDIA_ERR_NONE; +} + +static int __ms_privilege_ask(int client_sockfd) +{ + int ret = 0; + int res = MS_MEDIA_ERR_NONE; + + ret = security_server_check_privilege_by_sockfd(client_sockfd, "media-data::db", "w"); + if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) { + MS_DBG_ERR("You do not have permission for this operation."); + res = MS_MEDIA_ERR_PERMISSION_DENIED; + } else { + MS_DBG("PERMISSION OK"); + } + + return res; +} +gboolean ms_read_socket(gpointer user_data) +{ + ms_comm_msg_s recv_msg; + int sockfd = MS_SOCK_NOT_ALLOCATE; + int ret; + int res; + int req_num = -1; + int client_sock = -1; + GIOChannel *src = user_data; + + sockfd = g_io_channel_unix_get_fd(src); + if (sockfd < 0) { + MS_DBG_ERR("sock fd is invalid!"); + return TRUE; + } + + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sockfd, &client_sock); + if (ret != MS_MEDIA_ERR_NONE) { + return TRUE; + } + + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + res = ret; + goto ERROR; + } + + ret = __ms_privilege_ask(client_sock); + if (ret == MS_MEDIA_ERR_PERMISSION_DENIED) { + res = MS_MEDIA_ERR_PERMISSION_DENIED; + goto ERROR; + } + + /* copy received data */ + req_num = recv_msg.msg_type; + + /* register file request + * media server inserts the meta data of one file into media db */ + if (req_num == MS_MSG_DIRECTORY_SCANNING + ||req_num == MS_MSG_BULK_INSERT + ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE + || req_num == MS_MSG_BURSTSHOT_INSERT) { + if ((ret = ms_send_scan_request(&recv_msg, client_sock)) != MS_MEDIA_ERR_NONE) { + res = ret; + goto ERROR; + } + } else { + /* NEED IMPLEMENTATION */ + close(client_sock); + } + + /*Active flush */ + malloc_trim(0); + + return TRUE; +ERROR: + { + ms_comm_msg_s res_msg; + + memset(&res_msg, 0x0, sizeof(ms_comm_msg_s)); + + switch(req_num) { + case MS_MSG_DIRECTORY_SCANNING: + case MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE: + res_msg.msg_type = MS_MSG_SCANNER_RESULT; + break; + case MS_MSG_BULK_INSERT: + case MS_MSG_BURSTSHOT_INSERT: + res_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT; + break; + } + + res_msg.result = res; + + ms_ipc_send_msg_to_client_tcp(client_sock, &res_msg, NULL); + close(client_sock); + } + + return TRUE; +} + +static int __ms_send_request(ms_comm_msg_s *send_msg) +{ + int res = MS_MEDIA_ERR_NONE; + int fd = -1; + int err = -1; + + fd = open(MS_SCANNER_FIFO_PATH_REQ, O_WRONLY); + if (fd < 0) { + MS_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + /* send message */ + err = write(fd, send_msg, sizeof(ms_comm_msg_s)); + if (err < 0) { + MS_DBG_STRERROR("fifo write failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } + + close(fd); + + return res; +} + +int ms_send_scan_request(ms_comm_msg_s *send_msg, int client_sock) +{ + int res = MS_MEDIA_ERR_NONE; + int err = MS_MEDIA_ERR_NONE; + int pid = send_msg->pid; + + g_mutex_lock(scanner_mutex); + + if (ms_get_scanner_status()) { + MS_DBG_WARN("Scanner is ready"); + __ms_send_request(send_msg); + + g_mutex_unlock(scanner_mutex); + } else { + MS_DBG_WARN("Scanner starts"); + g_mutex_unlock(scanner_mutex); + + err = ms_scanner_start(); + if(err == MS_MEDIA_ERR_NONE) { + err = __ms_send_request(send_msg); + if(err != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("__ms_send_request failed", err); + } + } else { + MS_DBG_ERR("Scanner starting failed. %d", err); + res = err; + } + } + + if (res == MS_MEDIA_ERR_NONE) { + /* this request process in media scanner */ + if ((err = __ms_add_owner(pid, client_sock)) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("__ms_add_owner failed. %d", err); + res = err; + } + } + + return res; +} + +int ms_send_storage_scan_request(char *root_path, 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; + case MS_SCAN_META: + scan_msg.msg_type = MS_MSG_STORAGE_META; + break; + default : + ret = MS_MEDIA_ERR_INVALID_PARAMETER; + MS_DBG_ERR("ms_send_storage_scan_request invalid parameter"); + goto ERROR; + break; + } + + /* msg_size & msg */ + if (root_path != NULL) { + scan_msg.msg_size = strlen(root_path); + strncpy(scan_msg.msg, root_path, scan_msg.msg_size ); + } + + ret = ms_send_scan_request(&scan_msg, -1); + +ERROR: + + return ret; +} + +gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data) +{ + int sock = -1; + int client_sock = -1; + char * sql_query = NULL; + ms_comm_msg_s recv_msg; + int ret = MS_MEDIA_ERR_NONE; + MediaDBHandle *db_handle = (MediaDBHandle *)data; + int send_msg = MS_MEDIA_ERR_NONE; + gboolean privilege = TRUE; + + if (power_off == TRUE) { + MS_DBG_WARN("in the power off sequence"); + return TRUE; + } + + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { + MS_DBG_ERR("sock fd is invalid!"); + return TRUE; + } + + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sock, &client_sock); + if (ret != MS_MEDIA_ERR_NONE) { + return TRUE; + } + + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("ms_ipc_receive_message_tcp failed [%d]", ret); + send_msg = ret; + goto ERROR; + } + + /* check privileage */ + if(__ms_privilege_check(recv_msg.msg, &privilege) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size); + send_msg = MS_MEDIA_ERR_SOCKET_RECEIVE; + goto ERROR; + } + + if (privilege == TRUE) { + ret = __ms_privilege_ask(client_sock); + if (ret == MS_MEDIA_ERR_PERMISSION_DENIED) { + send_msg = MS_MEDIA_ERR_PERMISSION_DENIED; + goto ERROR; + } + } + + sql_query = strndup(recv_msg.msg, recv_msg.msg_size); + if (sql_query != NULL) { + 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; + } + +ERROR: + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + + return TRUE; +} + + +void _ms_process_tcp_message(gpointer data, gpointer user_data) +{ + int ret = MS_MEDIA_ERR_NONE; + char * sql_query = NULL; + ms_comm_msg_s recv_msg; + int client_sock = GPOINTER_TO_INT (data); + int send_msg = MS_MEDIA_ERR_NONE; + MediaDBHandle *db_handle = NULL; + + memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s)); + + /* Connect Media DB*/ + if(media_db_connect(&db_handle) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("Failed to connect DB"); + send_msg = MS_MEDIA_ERR_DB_CONNECT_FAIL; + goto ERROR; + } + +// MS_DBG_ERR("client sokcet : %d", client_sock); + + while(1) { + if (power_off == TRUE) { + MS_DBG_WARN("in the power off sequence"); + break; + } + + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + media_db_request_update_db_batch_clear(); + MS_DBG_ERR("ms_ipc_receive_message_tcp failed [%d]", ret); + send_msg = ret; + goto ERROR; + } + + sql_query = strndup(recv_msg.msg, recv_msg.msg_size); + if (sql_query != NULL) { + 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 (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } + +// MS_DBG_ERR("client sokcet : %d", client_sock); + if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) { + MS_DBG_WARN("Batch job is successfull!client sockfd [%d]", client_sock); + break; + } + + if (ret < MS_MEDIA_ERR_NONE && recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) { + MS_DBG_ERR("Batch job start is failed!client sockfd [%d]", client_sock); + media_db_request_update_db_batch_clear(); + break; + } + + memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s)); + } else { + MS_DBG_ERR("MS_MALLOC failed"); + media_db_request_update_db_batch_clear(); + /* send error to client */ + send_msg = MS_MEDIA_ERR_SOCKET_RECEIVE; + goto ERROR; + } + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + + /* Disconnect DB*/ + media_db_disconnect(db_handle); + MS_DBG_ERR("END"); + if (g_atomic_int_dec_and_test(&cur_running_task) == FALSE) + MS_DBG_ERR("g_atomic_int_dec_and_test failed"); + + return; + +ERROR: + + /* send error to client */ + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + + /* Disconnect DB*/ + media_db_disconnect(db_handle); + MS_DBG_ERR("END"); + if (g_atomic_int_dec_and_test(&cur_running_task) == FALSE) + MS_DBG_ERR("g_atomic_int_dec_and_test failed"); + + return; +} + +gboolean ms_read_db_tcp_batch_socket(GIOChannel *src, GIOCondition condition, gpointer data) +{ +#define MAX_THREAD_NUM 3 + + static GThreadPool *gtp = NULL; + GError *error = NULL; + int ret = MS_MEDIA_ERR_NONE; + int res = MS_MEDIA_ERR_NONE; + 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; + } + + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sock, &client_sock); + if (ret != MS_MEDIA_ERR_NONE) { + media_db_request_update_db_batch_clear(); + return TRUE; + } + + MS_DBG_SLOG("Client[%d] is accepted", client_sock); + + if (gtp == NULL) { + MS_DBG_SLOG("Create New Thread Pool %d", client_sock); + gtp = g_thread_pool_new((GFunc)_ms_process_tcp_message, NULL, MAX_THREAD_NUM, TRUE, &error); + if (error != NULL) { + res = MS_MEDIA_ERR_ALLOCATE_MEMORY_FAIL; + goto ERROR; + } + } + + /*check number of running thread */ + if (g_atomic_int_get(&cur_running_task) < MAX_THREAD_NUM) { + MS_DBG_SLOG("CURRENT RUNNING TASK %d", cur_running_task); + g_atomic_int_inc(&cur_running_task); + g_thread_pool_push(gtp, GINT_TO_POINTER(client_sock), &error); + + if (error != NULL) { + res = MS_MEDIA_ERR_INTERNAL; + goto ERROR; + } + } else { + /* all thread is working, return busy error */ + res = MS_MEDIA_ERR_DB_BATCH_UPDATE_BUSY; + goto ERROR; + } + + return TRUE; + +ERROR: + { + int send_msg = MS_MEDIA_ERR_NONE; + + if (error != NULL) { + MS_DBG_SLOG("g_thread_pool_push failed [%d]", error->message); + g_error_free(error); + error = NULL; + } + + /* send error to clinet*/ + send_msg = res; + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + } + + return TRUE; +} + +gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data) +{ + ms_comm_msg_s recv_msg; + int fd = MS_SOCK_NOT_ALLOCATE; + int msg_type; + int pid = -1; + int err; + + fd = g_io_channel_unix_get_fd(src); + if (fd < 0) { + MS_DBG_ERR("fd is invalid!"); + return TRUE; + } + + /* read() is blocked until media scanner sends message */ + err = read(fd, &recv_msg, sizeof(recv_msg)); + if (err < 0) { + MS_DBG_STRERROR("fifo read failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } + + MS_DBG_SLOG("receive result from scanner [%d] %d, %s", recv_msg.pid, recv_msg.result, recv_msg.msg); + + msg_type = recv_msg.msg_type; + pid = recv_msg.pid; + if ((msg_type == MS_MSG_SCANNER_RESULT) || + (msg_type == MS_MSG_SCANNER_BULK_RESULT)) { + MS_DBG_WARN("DB UPDATING IS DONE[%d]", msg_type); + + if (pid != 0) { + __ms_send_result_to_client(pid, &recv_msg); + } else { + MS_DBG_SLOG("This request is from media-server"); + } + } else { + MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type ); + } + + return TRUE; +} + diff --git a/src/server/media-server-thumb.c b/src/server/media-server-thumb.c new file mode 100755 index 0000000..ce95de7 --- /dev/null +++ b/src/server/media-server-thumb.c @@ -0,0 +1,1026 @@ +/* + * 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-common-utils.h" +#include "media-server-dbg.h" +#include "media-server-thumb.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "MEDIA_SERVER_THUMB" + +#define THUMB_SERVER_NAME "media-thumbnail" + + +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 gboolean g_shutdowning_thumb_server = FALSE; +static gboolean g_thumb_server_queued_all_extracting_request = 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; + +extern char MEDIA_IPC_PATH[][50]; + +int _ms_thumb_create_socket(int sock_type, int *sock); +int _ms_thumb_create_udp_socket(int *sock); +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_un *from_addr, unsigned int *from_size); +int _ms_thumb_set_buffer(thumbMsg *req_msg, unsigned char **buf, int *buf_size); +gboolean _ms_thumb_check_queued_request(gpointer data); +gboolean _ms_thumb_agent_prepare_udp_socket(); +gboolean _ms_thumb_agent_timer(); + + +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; + g_shutdowning_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 */ + MS_DBG_ERR("Thumbnail server is dead when processing all-thumbs extraction"); + g_thumb_server_extracting = FALSE; + g_server_pid = 0; + } 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"); + 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(AF_UNIX, SOCK_STREAM, 0)) < 0) { + MS_DBG_STRERROR("socket failed"); + 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_STRERROR("setsockopt failed"); + 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_STRERROR("setsockopt failed: %s"); + 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(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + MS_DBG_STRERROR("socket failed"); + 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_STRERROR("setsockopt failed"); + 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"); + if (!_ms_thumb_check_process()) { + MS_DBG_ERR("Thumbnail server is not running!. Reset info for thumb server to execute"); + ms_thumb_reset_server_status(); + } + + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MS_DBG_STRERROR("recvfrom failed"); + 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_STRERROR("recv failed"); + 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_STRERROR("recv failed"); + 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"); + 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_un *from_addr, unsigned int *from_size) +{ + int recv_msg_len = 0; + unsigned int from_addr_size = sizeof(struct sockaddr_un); + 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_STRERROR("ms_ipc_wait_message failed"); + 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_FILEPATH_LEN*2; + org_path_len = strlen(req_msg->org_path) + 1; + dst_path_len = strlen(req_msg->dst_path) + 1; + + MS_DBG_SLOG("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; +} + +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_STRERROR("ms_ipc_receive_message failed"); + 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; + + /* Once all-thumb extraction is done, check if there is queued all-thumb request */ + GSource *check_queued_all_thumb_request = NULL; + check_queued_all_thumb_request = g_idle_source_new (); + g_source_set_callback (check_queued_all_thumb_request, _ms_thumb_check_queued_request, NULL, NULL); + g_source_attach (check_queued_all_thumb_request, g_main_context_get_thread_default()); + + if (g_thumb_server_extracting == FALSE) { + MS_DBG_WARN("Recv thumb server extracting done already"); + return FALSE; + } + + 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; + + MS_DBG_ERR("THUMB SERVER SOCKET %d", sockfd); + + 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_STRERROR("ms_ipc_receive_message failed"); + 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; + } + + 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; + ms_sock_info_s sock_info; + struct sockaddr_un serv_addr; + int send_str_len = strlen(recv_msg->org_path); + + if (send_str_len > MAX_FILEPATH_LEN) { + MS_DBG_ERR("original path's length exceeds %d(max packet size)", MAX_FILEPATH_LEN); + return FALSE; + } + + if (ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sock_info) < 0) { + MS_DBG_ERR("ms_ipc_create_client_socket failed"); + return FALSE; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + sock = sock_info.sock_fd; + serv_addr.sun_family = AF_UNIX; +// MS_DBG_SLOG("%s", MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT], strlen(MEDIA_IPC_PATH[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_STRERROR("sendto failed"); + MS_SAFE_FREE(buf); + ms_ipc_delete_client_socket(&sock_info); + return FALSE; + } + + MS_SAFE_FREE(buf); + MS_DBG_SLOG("Sending msg to thumbnail server is successful"); + + struct sockaddr_un client_addr; + unsigned int client_addr_len; + header_size = sizeof(thumbMsg) - MAX_FILEPATH_LEN*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"); + ms_ipc_delete_client_socket(&sock_info); + return FALSE; + } + + MS_DBG_SLOG("recv %s from thumb daemon is successful", res_msg->dst_path); + ms_ipc_delete_client_socket(&sock_info); + + 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_check_queued_request(gpointer data) +{ + if (g_thumb_server_queued_all_extracting_request) { + MS_DBG_WARN("There is queued request"); + + /* request all-thumb extraction to thumbnail server */ + 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-thumb 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"); + } + + g_thumb_server_queued_all_extracting_request = FALSE; + } else { + MS_DBG("There is no queued request"); + return FALSE; + } + + return FALSE; +} + +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) { + /* 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 */ + g_shutdowning_thumb_server = TRUE; + 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"); + g_shutdowning_thumb_server = FALSE; + } + usleep(200000); + g_io_channel_shutdown(g_udp_channel, FALSE, NULL); + g_io_channel_unref(g_udp_channel); + g_udp_channel = NULL; + g_communicate_sock = 0; + } else { + MS_DBG_ERR("g_server_pid is %d. Maybe there's problem in thumbnail-server", g_server_pid); + } + + return FALSE; +} + +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); + + close(thumb_req->client_sock); + + 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_shutdowning_thumb_server) { + MS_DBG_ERR("Thumb server is shutting down... wait for complete"); + usleep(10000); + return TRUE; + } + + 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 (recv_msg->msg_type == 2 && g_thumb_server_extracting) { // THUMB_REQUEST_ALL_MEDIA + MS_DBG_WARN("Thumbnail server is already extracting..This request is queued."); + g_thumb_server_queued_all_extracting_request = TRUE; + } else { + 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"); + + thumbMsg res_msg; + memset((void *)&res_msg, 0, sizeof(res_msg)); + + res_msg.msg_type = 6; // THUMB_RESPONSE + res_msg.status = 1; //THUMB_FAIL + res_msg.origin_path_size = strlen(recv_msg->org_path); + strncpy(res_msg.org_path, recv_msg->org_path, res_msg.origin_path_size); + res_msg.dst_path[0] = '\0'; + res_msg.dest_path_size = 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_STRERROR("sendto failed"); + } else { + MS_DBG("Sent Refuse msg from %s", recv_msg->org_path); + } + + close(client_sock); + + MS_SAFE_FREE(buf); + 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_STRERROR("sendto failed"); + } else { + MS_DBG_SLOG("Sent %s(%d) from %s", res_msg.dst_path, strlen(res_msg.dst_path), res_msg.org_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) +{ + 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_FILEPATH_LEN*2; + + if (ms_ipc_accept_client_tcp(sock, &client_sock) < 0) { + MS_DBG_STRERROR("accept failed"); + return TRUE; + } + + 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_SLOG("Received [%d] %s(%d) from PID(%d)", 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(); + } + + if (g_queue_get_length(g_request_queue) >= MAX_THUMB_REQUEST) { + MS_DBG_WARN("Request Queue is full"); + thumbMsg res_msg; + memset((void *)&res_msg, 0, sizeof(res_msg)); + + res_msg.msg_type = 6; // THUMB_RESPONSE + res_msg.status = 1; //THUMB_FAIL + res_msg.origin_path_size = strlen(recv_msg->org_path); + strncpy(res_msg.org_path, recv_msg->org_path, res_msg.origin_path_size); + res_msg.dst_path[0] = '\0'; + res_msg.dest_path_size = 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_STRERROR("sendto failed"); + } else { + MS_DBG("Sent Refuse msg from %s", recv_msg->org_path); + } + + close(client_sock); + MS_SAFE_FREE(buf); + MS_SAFE_FREE(thumb_req->recv_msg); + MS_SAFE_FREE(thumb_req); + + return TRUE; + } + + MS_DBG_SLOG("%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; +} + +gboolean _ms_thumb_agent_prepare_tcp_socket(int *sock_fd) +{ + int sock; + unsigned short serv_port; + + serv_port = MS_THUMB_CREATOR_PORT; + + 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_server_socket failed"); + return FALSE; + } + + 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"); + 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); + + close(sockfd); + + return NULL; +} + |