diff options
-rw-r--r-- | .SRCINFO | 53 | ||||
-rw-r--r-- | PKGBUILD | 80 | ||||
-rw-r--r-- | gcc46.patch | 10 | ||||
-rw-r--r-- | jsparse.patch | 144 | ||||
-rw-r--r-- | libav_0.7_support.patch | 64 | ||||
-rw-r--r-- | libavformat.patch | 52 | ||||
-rw-r--r-- | libmp4v2_191_p497.patch | 187 | ||||
-rw-r--r-- | mediatomb-mariadb.service | 13 | ||||
-rw-r--r-- | mediatomb-urifix.patch | 26 | ||||
-rw-r--r-- | mediatomb.conf | 23 | ||||
-rw-r--r-- | mediatomb.install | 17 | ||||
-rw-r--r-- | mediatomb.service | 13 | ||||
-rwxr-xr-x | samsung_video_subtitles.patch | 186 | ||||
-rw-r--r-- | symlinks.patch | 42 | ||||
-rw-r--r-- | tonewjs.patch | 564 |
15 files changed, 1474 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..7165341009a2 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,53 @@ +pkgbase = mediatomb-samsung-tv + pkgdesc = Free UPnP/DLNA media server with Samsung TV compatibility + pkgver = 0.12.1 + pkgrel = 12 + url = http://mediatomb.cc/ + install = mediatomb.install + arch = i686 + arch = x86_64 + arch = armv6h + license = GPL + depends = file + depends = curl + depends = ffmpegthumbnailer + depends = js185 + depends = libexif + depends = libmp4v2 + depends = sqlite3 + depends = taglib + depends = libmysqlclient + depends = libmariadbclient + optdepends = mariadb: to store your music database in mariadb + conflicts = mediatomb + conflicts = mediatomb-git + backup = etc/conf.d/mediatomb + source = http://downloads.sourceforge.net/mediatomb/mediatomb-0.12.1.tar.gz + source = mediatomb.service + source = mediatomb-mariadb.service + source = mediatomb.conf + source = gcc46.patch + source = tonewjs.patch + source = jsparse.patch + source = libav_0.7_support.patch + source = libmp4v2_191_p497.patch + source = libavformat.patch + source = mediatomb-urifix.patch + source = samsung_video_subtitles.patch + source = symlinks.patch + sha256sums = 31163c34a7b9d1c9735181737cb31306f29f1f2a0335fb4f53ecccf8f62f11cd + sha256sums = e46de674e49aa85116a8ff127908f7bac21198ce7625404004b8b7832eccd3f4 + sha256sums = 9c917f0d6e568ce0ad77c0ed17e4bbaabc0e7a1c0a3e4772b786fb1565db9768 + sha256sums = 70e4a4b89cef9a7f6f5f800e1793a6cb807f52b39e5a17d0a91356608b95e62d + sha256sums = 0c02a20032f0c296800b1bb9644638970c2dedbc5ab7141d66a637235e9da6ce + sha256sums = 2cd8f5628c3a38b290526f008bae351b90211825f86e5959bf95f140748de574 + sha256sums = d9a3062858900d32b977f0d50d168fd7d36785b6ecc038c019e661e27f7b1c17 + sha256sums = c6523e8bf5e2da89b7475d6777ef9bffe7d089752ef2f7b27b5e39a4130fb0ff + sha256sums = d39c2f9aab051c5447461718fd0ec72cf5982f6c920a4a985a50831f34babe84 + sha256sums = 76b11706d70ed8f5e157d96ca441c90c46c42176102fcb651b4ab1102b61bfee + sha256sums = 537373654c1d7fa24e14f2e5a9c78228589411509d46fbd53bb38b87d5ee34fb + sha256sums = 716da4f11c24e9383cc166c22651559ed2ddb94fb043c85786ff14708ee30bc3 + sha256sums = 72f7532d7cd827ab655df652d2912175739fe16d2b1ad989d987a0b147a1d2e8 + +pkgname = mediatomb-samsung-tv + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..7198fd9a14d9 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,80 @@ +# Maintainer: S Leduc <sebastien@sleduc.fr> +# Contributor: Martin Villagra <mvillagra0@gmail.com> +# Contributor: William Rea <sillywilly@gmail.com> +# Contributor: Nikhil Bysani <nikron@gmail.com> +# Contributor: Mika Hynnä <igheax@gmail.com> +# Contributor: Jonathan Conder <jonno.conder@gmail.com> +# Contributor : emmanuelux : i add the patch here : http://sourceforge.net/tracker/?func=detail&aid=3532724&group_id=129766&atid=715782 +# Contributor: Peter Richard Lewis <plewis@aur.archlinux.org> + +_distname=mediatomb +pkgname=mediatomb-samsung-tv +pkgver=0.12.1 +pkgrel=12 +pkgdesc="Free UPnP/DLNA media server with Samsung TV compatibility" +arch=('i686' 'x86_64' 'armv6h') +url="http://mediatomb.cc/" +license=('GPL') +depends=('file' 'curl' 'ffmpegthumbnailer' 'js185' 'libexif' 'libmp4v2' 'sqlite3' 'taglib' 'libmysqlclient' 'libmariadbclient') +optdepends=('mariadb: to store your music database in mariadb') +backup=('etc/conf.d/mediatomb') +install=mediatomb.install +conflicts=('mediatomb' 'mediatomb-git') +source=("http://downloads.sourceforge.net/$_distname/$_distname-$pkgver.tar.gz" + 'mediatomb.service' + 'mediatomb-mariadb.service' + 'mediatomb.conf' + 'gcc46.patch' + 'tonewjs.patch' + 'jsparse.patch' + 'libav_0.7_support.patch' + 'libmp4v2_191_p497.patch' + 'libavformat.patch' + 'mediatomb-urifix.patch' + 'samsung_video_subtitles.patch' + 'symlinks.patch') +sha256sums=('31163c34a7b9d1c9735181737cb31306f29f1f2a0335fb4f53ecccf8f62f11cd' + 'e46de674e49aa85116a8ff127908f7bac21198ce7625404004b8b7832eccd3f4' + '9c917f0d6e568ce0ad77c0ed17e4bbaabc0e7a1c0a3e4772b786fb1565db9768' + '70e4a4b89cef9a7f6f5f800e1793a6cb807f52b39e5a17d0a91356608b95e62d' + '0c02a20032f0c296800b1bb9644638970c2dedbc5ab7141d66a637235e9da6ce' + '2cd8f5628c3a38b290526f008bae351b90211825f86e5959bf95f140748de574' + 'd9a3062858900d32b977f0d50d168fd7d36785b6ecc038c019e661e27f7b1c17' + 'c6523e8bf5e2da89b7475d6777ef9bffe7d089752ef2f7b27b5e39a4130fb0ff' + 'd39c2f9aab051c5447461718fd0ec72cf5982f6c920a4a985a50831f34babe84' + '76b11706d70ed8f5e157d96ca441c90c46c42176102fcb651b4ab1102b61bfee' + '537373654c1d7fa24e14f2e5a9c78228589411509d46fbd53bb38b87d5ee34fb' + '716da4f11c24e9383cc166c22651559ed2ddb94fb043c85786ff14708ee30bc3' + '72f7532d7cd827ab655df652d2912175739fe16d2b1ad989d987a0b147a1d2e8') + +build() { + cd "$srcdir/$_distname-$pkgver" + patch -Np1 -i "$srcdir/gcc46.patch" + patch -Np1 -i "$srcdir/tonewjs.patch" + patch -Np1 -i "$srcdir/jsparse.patch" + patch -Np1 -i "$srcdir/libav_0.7_support.patch" + patch -Np1 -i "$srcdir/libmp4v2_191_p497.patch" + patch -Np1 -i "$srcdir/libavformat.patch" + patch -Np1 -i "$srcdir/mediatomb-urifix.patch" + cd src + patch -Np1 -i "$srcdir/samsung_video_subtitles.patch" + cd .. + patch -Np1 -i "$srcdir/symlinks.patch" + + ./configure --prefix=/usr \ + --enable-mysql \ + --enable-libmagic \ + --enable-libjs \ + --enable-ffmpeg + make +} + +package() { + cd "$srcdir/$_distname-$pkgver" + + make DESTDIR="$pkgdir/" install + + install -D -m0644 "$srcdir/mediatomb.service" "$pkgdir/usr/lib/systemd/system/mediatomb.service" + install -D -m0644 "$srcdir/mediatomb-mariadb.service" "$pkgdir/usr/lib/systemd/system/mediatomb-mariadb.service" + install -D -m0644 "$srcdir/mediatomb.conf" "$pkgdir/etc/conf.d/mediatomb" +} diff --git a/gcc46.patch b/gcc46.patch new file mode 100644 index 000000000000..0f4fe490f424 --- /dev/null +++ b/gcc46.patch @@ -0,0 +1,10 @@ +--- a/src/zmm/object.h ++++ b/src/zmm/object.h +@@ -33,6 +33,7 @@ + #define __ZMM_OBJECT_H__ + + #include <new> // for size_t ++#include <cstddef> + #include "atomic.h" + + namespace zmm diff --git a/jsparse.patch b/jsparse.patch new file mode 100644 index 000000000000..9938939b051e --- /dev/null +++ b/jsparse.patch @@ -0,0 +1,144 @@ +diff -rup mediatomb-0.12.1/src/scripting/js_functions.cc ../mediatomb-0.12.1/src/scripting/js_functions.cc +--- mediatomb-0.12.1/src/scripting/js_functions.cc 2011-06-29 21:51:13.641025479 -0400 ++++ ../mediatomb-0.12.1/src/scripting/js_functions.cc 2011-06-29 21:49:21.071800273 -0400 +@@ -51,15 +51,28 @@ extern "C" { + JSBool + js_print(JSContext *cx, uintN argc, jsval *argv) + { +- uintN i; ++ uintN i, j; + JSString *str; + + for (i = 0; i < argc; i++) + { +- str = JS_ValueToString(cx, argv[i]); ++ String fmtStr; ++ for (j = 0; j < argc; j++) ++ { ++ if (j == i) ++ fmtStr = fmtStr + "S"; ++ else ++ fmtStr = fmtStr + "*"; ++ } ++ if(!JS_ConvertArguments(cx, 1, JS_ARGV(cx, argv), fmtStr.c_str(), &str)) ++ { ++ log_debug("Could not parse input arguments\n"); ++ return JS_TRUE; ++ } ++ + if (!str) + return JS_TRUE; +- argv[i] = STRING_TO_JSVAL(str); ++ + char * log_str = JS_EncodeString(cx, str); + log_js("%s\n", log_str); + JS_free(cx, log_str); +@@ -116,24 +129,54 @@ js_addCdsObject(JSContext *cx, uintN arg + { + try + { +- jsval arg; +- JSString *str; +- String path; +- String containerclass; ++ // Inputs from native code ++ JSObject *js_cds_obj = NULL; ++ JSString *str = NULL; ++ JSString *cont = NULL; + +- JSObject *js_cds_obj; ++ String path = nil; ++ String containerclass = nil; ++ ++ JSObject *obj = JS_THIS_OBJECT(cx, argv); + JSObject *js_orig_obj = NULL; + Ref<CdsObject> orig_object; + + Ref<StringConverter> p2i; + Ref<StringConverter> i2i; ++ switch (argc) ++ { ++ case 0: ++ log_debug("No input arguments given\n"); ++ return JS_FALSE; ++ case 1: ++ if(!JS_ConvertArguments(cx, 1, JS_ARGV(cx, argv), "o", &js_cds_obj)) ++ { ++ log_debug("Could not parse input arguments\n"); ++ return JS_TRUE; ++ } ++ break; ++ case 2: ++ if(!JS_ConvertArguments(cx, 2, JS_ARGV(cx, argv), "oS", &js_cds_obj, &str)) ++ { ++ log_debug("Could not parse input arguments\n"); ++ return JS_TRUE; ++ } ++ break; ++ default: ++ if(!JS_ConvertArguments(cx, 3, JS_ARGV(cx, argv), "oSS", &js_cds_obj, &str, &cont)) ++ { ++ log_debug("Could not parse input arguments\n"); ++ return JS_TRUE; ++ } ++ break; ++ } + +- Script *self = (Script *)JS_GetPrivate(cx, JS_THIS_OBJECT(cx, argv)); ++ Script *self = (Script *)JS_GetPrivate(cx, obj); + + if (self == NULL) + { + log_debug("Could not retrieve class instance from global object\n"); +- return JS_FALSE; ++ return JS_TRUE; + } + + if (self->whoami() == S_PLAYLIST) +@@ -144,23 +187,14 @@ js_addCdsObject(JSContext *cx, uintN arg + { + i2i = StringConverter::i2i(); + } +- +- arg = argv[0]; +- if (!JSVAL_IS_OBJECT(arg)) +- return JS_TRUE; +- if (!JS_ValueToObject(cx, arg, &js_cds_obj)) +- return JS_TRUE; + +- // root it +- argv[0] = OBJECT_TO_JSVAL(js_cds_obj); + +- str = JS_ValueToString(cx, argv[1]); + if (!str) + path = _("/"); + else + path = JS_EncodeString(cx, str); + +- JSString *cont = JS_ValueToString(cx, argv[2]); ++ + if (cont) + { + containerclass = JS_EncodeString(cx, cont); +@@ -169,9 +203,9 @@ js_addCdsObject(JSContext *cx, uintN arg + } + + if (self->whoami() == S_PLAYLIST) +- js_orig_obj = self->getObjectProperty(JS_THIS_OBJECT(cx, argv), _("playlist")); ++ js_orig_obj = self->getObjectProperty(obj, _("playlist")); + else if (self->whoami() == S_IMPORT) +- js_orig_obj = self->getObjectProperty(JS_THIS_OBJECT(cx, argv), _("orig")); ++ js_orig_obj = self->getObjectProperty(obj, _("orig")); + + if (js_orig_obj == NULL) + { +@@ -179,9 +213,6 @@ js_addCdsObject(JSContext *cx, uintN arg + return JS_TRUE; + } + +- // root it +- argv[1] = OBJECT_TO_JSVAL(js_orig_obj); +- + orig_object = self->jsObject2cdsObject(js_orig_obj, self->getProcessedObject()); + if (orig_object == nil) + return JS_TRUE; diff --git a/libav_0.7_support.patch b/libav_0.7_support.patch new file mode 100644 index 000000000000..e25697c5021b --- /dev/null +++ b/libav_0.7_support.patch @@ -0,0 +1,64 @@ +=== modified file 'src/metadata/ffmpeg_handler.cc' +--- old/src/metadata/ffmpeg_handler.cc 2010-08-25 17:07:03 +0000 ++++ new/src/metadata/ffmpeg_handler.cc 2011-05-19 04:33:32 +0000 +@@ -89,6 +89,33 @@ + + Ref<StringConverter> sc = StringConverter::m2i(); + ++ /* Tabs are 4 characters here */ ++ typedef struct {const char *avname; metadata_fields_t field;} mapping_t; ++ static const mapping_t mapping[] = ++ { ++ {"title", M_TITLE}, ++ {"artist", M_ARTIST}, ++ {"album", M_ALBUM}, ++ {"date", M_DATE}, ++ {"genre", M_GENRE}, ++ {"comment", M_DESCRIPTION}, ++ {"track", M_TRACKNUMBER}, ++ {NULL, M_MAX}, ++ }; ++ ++ if (!pFormatCtx->metadata) ++ return; ++ for (const mapping_t *m = mapping; m->avname != NULL; m++) ++ { ++ AVMetadataTag *tag = NULL; ++ tag = av_metadata_get(pFormatCtx->metadata, m->avname, NULL, 0); ++ if (tag && tag->value && tag->value[0]) ++ { ++ log_debug("Added metadata %s: %s\n", m->avname, tag->value); ++ item->setMetadata(MT_KEYS[m->field].upnp, sc->convert(tag->value)); ++ } ++ } ++ /* Old algorithm (doesn't work with libav >= 0.7) + if (strlen(pFormatCtx->title) > 0) + { + log_debug("Added metadata title: %s\n", pFormatCtx->title); +@@ -131,6 +158,7 @@ + item->setMetadata(MT_KEYS[M_TRACKNUMBER].upnp, + sc->convert(String::from(pFormatCtx->track))); + } ++ */ + } + + // ffmpeg library calls +@@ -178,7 +206,7 @@ + for(i=0; i<pFormatCtx->nb_streams; i++) + { + AVStream *st = pFormatCtx->streams[i]; +- if((st != NULL) && (videoset == false) && (st->codec->codec_type == CODEC_TYPE_VIDEO)) ++ if((st != NULL) && (videoset == false) && (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) + { + if (st->codec->codec_tag > 0) + { +@@ -209,7 +237,7 @@ + *y = st->codec->height; + } + } +- if(st->codec->codec_type == CODEC_TYPE_AUDIO) ++ if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) + { + // Increase number of audiochannels + audioch++; + diff --git a/libavformat.patch b/libavformat.patch new file mode 100644 index 000000000000..96685ea155b1 --- /dev/null +++ b/libavformat.patch @@ -0,0 +1,52 @@ +--- mediatomb-0.12.1.orig/src/metadata/ffmpeg_handler.cc 2012-06-18 02:50:35.000000000 -0400 ++++ mediatomb-0.12.1/src/metadata/ffmpeg_handler.cc 2012-06-18 02:59:02.000000000 -0400 +@@ -107,8 +107,8 @@ + return; + for (const mapping_t *m = mapping; m->avname != NULL; m++) + { +- AVMetadataTag *tag = NULL; +- tag = av_metadata_get(pFormatCtx->metadata, m->avname, NULL, 0); ++ AVDictionaryEntry *tag = NULL; ++ tag = av_dict_get(pFormatCtx->metadata, m->avname, NULL, 0); + if (tag && tag->value && tag->value[0]) + { + log_debug("Added metadata %s: %s\n", m->avname, tag->value); +@@ -278,7 +278,7 @@ + int x = 0; + int y = 0; + +- AVFormatContext *pFormatCtx; ++ AVFormatContext *pFormatCtx = avformat_alloc_context(); + + // Suppress all log messages + av_log_set_callback(FfmpegNoOutputStub); +@@ -286,15 +286,15 @@ + // Register all formats and codecs + av_register_all(); + +- // Open video file +- if (av_open_input_file(&pFormatCtx, +- item->getLocation().c_str(), NULL, 0, NULL) != 0) ++ // Open video file ++ if (avformat_open_input(&pFormatCtx, ++ item->getLocation().c_str(), NULL, NULL) != 0) + return; // Couldn't open file + + // Retrieve stream information +- if (av_find_stream_info(pFormatCtx) < 0) ++ if (avformat_find_stream_info(pFormatCtx,NULL) < 0) + { +- av_close_input_file(pFormatCtx); ++ avformat_close_input(&pFormatCtx); + return; // Couldn't find stream information + } + // Add metadata using ffmpeg library calls +@@ -303,7 +303,7 @@ + addFfmpegResourceFields(item, pFormatCtx, &x, &y); + + // Close the video file +- av_close_input_file(pFormatCtx); ++ avformat_close_input(&pFormatCtx); + } + + Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) diff --git a/libmp4v2_191_p497.patch b/libmp4v2_191_p497.patch new file mode 100644 index 000000000000..6a6b51e1e05a --- /dev/null +++ b/libmp4v2_191_p497.patch @@ -0,0 +1,187 @@ +diff -urN old/src/metadata/libmp4v2_handler.cc new/src/metadata/libmp4v2_handler.cc +--- old/src/metadata/libmp4v2_handler.cc 2012-04-05 01:46:26.000000000 +0200 ++++ new/src/metadata/libmp4v2_handler.cc 2012-04-05 02:01:24.000000000 +0200 +@@ -65,29 +65,28 @@ + static void addMetaField(metadata_fields_t field, MP4FileHandle mp4, Ref<CdsItem> item) + { + String value; +- char* mp4_retval = NULL; +- u_int16_t track; +- u_int16_t total_tracks; +- + Ref<StringConverter> sc = StringConverter::i2i(); + ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ ++ if (!MP4TagsFetch(new_tags, mp4)) ++ return; ++ + switch (field) + { + case M_TITLE: +- MP4GetMetadataName(mp4, &mp4_retval); ++ value = new_tags->name; + break; + case M_ARTIST: +- MP4GetMetadataArtist(mp4, &mp4_retval); ++ value = new_tags->artist; + break; + case M_ALBUM: +- MP4GetMetadataAlbum(mp4, &mp4_retval); ++ value = new_tags->album; + break; + case M_DATE: +- MP4GetMetadataYear(mp4, &mp4_retval); +- if (mp4_retval) ++ value = new_tags->releaseDate; ++ if (value.length() > 0) + { +- value = mp4_retval; +- free(mp4_retval); + if (string_ok(value)) + value = value + "-01-01"; + else +@@ -95,34 +94,31 @@ + } + break; + case M_GENRE: +- MP4GetMetadataGenre(mp4, &mp4_retval); ++ value = new_tags->genre; + break; + case M_DESCRIPTION: +- MP4GetMetadataComment(mp4, &mp4_retval); ++ value = new_tags->comments; + break; + case M_TRACKNUMBER: +- MP4GetMetadataTrack(mp4, &track, &total_tracks); +- if (track > 0) ++ if (new_tags->track) + { +- value = String::from(track); +- item->setTrackNumber((int)track); ++ value = String::from(new_tags->track->index); ++ item->setTrackNumber((int)new_tags->track->index); + } + else ++ { ++ MP4TagsFree( new_tags ); + return; ++ } + break; + default: ++ MP4TagsFree( new_tags ); + return; + } + +- if ((field != M_DATE) && (field != M_TRACKNUMBER) && +- (mp4_retval)) +- { +- value = mp4_retval; +- free(mp4_retval); +- } +- ++ MP4TagsFree( new_tags ); + value = trim_string(value); +- ++ + if (string_ok(value)) + { + item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); +@@ -190,14 +186,19 @@ + } + + #if defined(HAVE_MAGIC) +- u_int8_t *art_data; +- u_int32_t art_data_len; ++ void *art_data = 0; ++ u_int32_t art_data_len = 0; + String art_mimetype; ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ MP4TagsFetch(new_tags, mp4); ++ if (new_tags->artworkCount) ++ { ++ art_data = new_tags->artwork->data; ++ art_data_len = new_tags->artwork->size; ++ } + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (MP4GetMetadataCoverArtCount(mp4) && +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +-#else +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len); ++ if (new_tags->artworkCount && art_data_len > 0) + #endif + { + if (art_data) +@@ -211,11 +212,10 @@ + } + catch (Exception ex) + { +- free(art_data); ++ MP4TagsFree(new_tags); + throw ex; + } + +- free(art_data); + if (art_mimetype != _(MIMETYPE_DEFAULT)) + { + Ref<CdsResource> resource(new CdsResource(CH_MP4)); +@@ -225,6 +225,7 @@ + } + } + } ++ MP4TagsFree(new_tags); + #endif + MP4Close(mp4); + } +@@ -249,26 +250,35 @@ + + if (ctype != ID3_ALBUM_ART) + throw _Exception(_("LibMP4V2Handler: got unknown content type: ") + ctype); ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ if (MP4TagsFetch(new_tags, mp4)) ++ { + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (!MP4GetMetadataCoverArtCount(mp4)) +- throw _Exception(_("LibMP4V2Handler: resource has no album art information")); ++ if (!new_tags->artworkCount) ++ throw _Exception(_("LibMP4V2Handler: resource has no album art information")); + #endif +- u_int8_t *art_data; +- u_int32_t art_data_len; +- if (MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +- { +- if (art_data) ++ void *art_data = 0; ++ u_int32_t art_data_len; ++ ++ const MP4TagArtwork* art = new_tags->artwork; ++ art_data = art->data; ++ art_data_len = art->size; ++ if (art) + { +- *data_size = (off_t)art_data_len; +- Ref<IOHandler> h(new MemIOHandler((void *)art_data, art_data_len)); +- free(art_data); +- return h; ++ if (art_data) ++ { ++ *data_size = (off_t)art_data_len; ++ Ref<IOHandler> h(new MemIOHandler(art_data, art_data_len)); ++ MP4TagsFree(new_tags); ++ return h; ++ } + } ++ MP4TagsFree(new_tags); + } +- + throw _Exception(_("LibMP4V2Handler: could not serve album art " +- "for file") + item->getLocation() + +- " - embedded image not found"); ++ "for file") + item->getLocation() + ++ " - embedded image not found"); + } + + #endif // HAVE_LIBMP4V2 +De binära filerna old/src/metadata/.libmp4v2_handler.cc.swp och new/src/metadata/.libmp4v2_handler.cc.swp skiljer diff --git a/mediatomb-mariadb.service b/mediatomb-mariadb.service new file mode 100644 index 000000000000..87b95e28424c --- /dev/null +++ b/mediatomb-mariadb.service @@ -0,0 +1,13 @@ +[Unit] +Description=MediaTomb Daemon using MariaDB +After=mysqld.target network.target + +[Service] +EnvironmentFile=/etc/conf.d/mediatomb +ExecStart=/usr/bin/mediatomb -p $MT_PORT -u $MT_USER -g $MT_GROUP \ + -P $MT_PIDFILE -l $MT_LOGFILE -m $MT_HOME -f $MT_CFGDIR $MT_OPTIONS +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/mediatomb-urifix.patch b/mediatomb-urifix.patch new file mode 100644 index 000000000000..4691a47536d9 --- /dev/null +++ b/mediatomb-urifix.patch @@ -0,0 +1,26 @@ +diff -ruN mediatomb.orig/tombupnp/upnp/src/genlib/net/uri/uri.c mediatomb/tombupnp/upnp/src/genlib/net/uri/uri.c +--- mediatomb.orig/tombupnp/upnp/src/genlib/net/uri/uri.c 2012-06-06 23:01:22.000000000 +0200 ++++ mediatomb/tombupnp/upnp/src/genlib/net/uri/uri.c 2012-06-07 08:22:01.000000000 +0200 +@@ -1042,7 +1042,8 @@ + out->path_type = REL_PATH; + } + +- if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' ) ++ //parse hostport only if scheme was found ++ if( ( begin_hostport > 0 ) && ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' ) + && ( in[begin_hostport + 1] == '/' ) ) { + begin_hostport += 2; + +@@ -1059,6 +1060,12 @@ + out->hostport.text.size = 0; + out->hostport.text.buff = 0; + begin_path = begin_hostport; ++ ++ //remove excessive leading slashes (fix for Samsung Smart TV 2012) ++ while( ( ( begin_path + 1 ) < max ) && ( in[begin_path] == '/' ) && ( in[begin_path + 1] == '/') ) { ++ begin_path++; ++ } ++ + } + + begin_fragment = diff --git a/mediatomb.conf b/mediatomb.conf new file mode 100644 index 000000000000..c2b435f92168 --- /dev/null +++ b/mediatomb.conf @@ -0,0 +1,23 @@ +# +# Parameters to be passed to mediatomb +# + +# Port to listen on +MT_PORT='50500' + +# User and group to run as +MT_USER='mediatomb' +MT_GROUP='mediatomb' + +# Location of the PID file +MT_PIDFILE='/var/run/mediatomb.pid' + +# Location of the log file +MT_LOGFILE='/var/log/mediatomb.log' + +# Location of the config file/database +MT_HOME='/var/lib/mediatomb' +MT_CFGDIR='.mediatomb' + +# User defined command line options +MT_OPTIONS='' diff --git a/mediatomb.install b/mediatomb.install new file mode 100644 index 000000000000..74ce78e9d570 --- /dev/null +++ b/mediatomb.install @@ -0,0 +1,17 @@ +post_install() { + post_upgrade + passwd -l mediatomb &>/dev/null + echo 'Warning: the MediaTomb web interface exposes your filesystem to the network' + echo 'For maximum security, set <ui enabled="no"> in your MediaTomb config file' +} + +post_upgrade() { + # create user/group that the daemon will run as by default, do not delete this on uninstall, as it will own files + getent group mediatomb >/dev/null || groupadd -g 241 mediatomb &>/dev/null + getent passwd mediatomb >/dev/null || useradd -c 'Mediatomb DLNA Server' -u 241 -g mediatomb -b '/var/lib' -m -s /bin/false mediatomb &>/dev/null + + echo 'Attention: By default, MediaTomb now runs as its own user: mediatomb.' + echo 'Ensuring ownership of /var/lib/mediatomb is mediatomb:mediatomb...' + chown -R mediatomb:mediatomb /var/lib/mediatomb &>/dev/null + +} diff --git a/mediatomb.service b/mediatomb.service new file mode 100644 index 000000000000..e9869cfb52f7 --- /dev/null +++ b/mediatomb.service @@ -0,0 +1,13 @@ +[Unit] +Description=MediaTomb Daemon +After=network.target + +[Service] +EnvironmentFile=/etc/conf.d/mediatomb +ExecStart=/usr/bin/mediatomb -p $MT_PORT -u $MT_USER -g $MT_GROUP \ + -P $MT_PIDFILE -l $MT_LOGFILE -m $MT_HOME -f $MT_CFGDIR $MT_OPTIONS +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/samsung_video_subtitles.patch b/samsung_video_subtitles.patch new file mode 100755 index 000000000000..cc86de5c8d9f --- /dev/null +++ b/samsung_video_subtitles.patch @@ -0,0 +1,186 @@ +Index: src/config_manager.cc +=================================================================== +--- src/config_manager.cc (revision 2102) ++++ src/config_manager.cc (working copy) +@@ -1433,6 +1433,14 @@ + NEW_BOOL_OPTION(temp == "yes" ? true : false); + SET_BOOL_OPTION(CFG_SERVER_EXTEND_PROTOCOLINFO_CL_HACK); + */ ++ temp = getOption(_("/server/protocolInfo/attribute::samsung-hack"), ++ _(DEFAULT_EXTEND_PROTOCOLINFO_SM_HACK)); ++ if (!validateYesNo(temp)) ++ throw _Exception(_("Error in config file: samsung-hack attribute of the " ++ "protocolInfo tag must be either \"yes\" or \"no\"")); ++ ++ NEW_BOOL_OPTION(temp == "yes" ? true : false); ++ SET_BOOL_OPTION(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK); + #endif + + temp = getOption(_("/server/pc-directory/attribute::upnp-hide"), +Index: src/common.h +=================================================================== +--- src/common.h (revision 2102) ++++ src/common.h (working copy) +@@ -196,6 +196,8 @@ + #define XML_DC_NAMESPACE "http://purl.org/dc/elements/1.1/" + #define XML_UPNP_NAMESPACE_ATTR "xmlns:upnp" + #define XML_UPNP_NAMESPACE "urn:schemas-upnp-org:metadata-1-0/upnp/" ++#define XML_SEC_NAMESPACE_ATTR "xmlns:sec" ++#define XML_SEC_NAMESPACE "http://www.sec.co.kr/" + + // default values + #define DEFAULT_INTERNAL_CHARSET "UTF-8" +@@ -243,6 +245,7 @@ + #define DEFAULT_LAYOUT_TYPE "builtin" + #define DEFAULT_EXTEND_PROTOCOLINFO NO + //#define DEFAULT_EXTEND_PROTOCOLINFO_CL_HACK NO ++#define DEFAULT_EXTEND_PROTOCOLINFO_SM_HACK NO + #define DEFAULT_HIDE_PC_DIRECTORY NO + #ifdef YOUTUBE + #define YOUTUBE_PAGESIZE 106496 +Index: src/config_manager.h +=================================================================== +--- src/config_manager.h (revision 2102) ++++ src/config_manager.h (working copy) +@@ -73,6 +73,7 @@ + CFG_SERVER_EXTEND_PROTOCOLINFO_CL_HACK, + #endif + #endif//EXTEND_PROTOCOLINFO ++ CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK, + CFG_SERVER_HIDE_PC_DIRECTORY, + CFG_SERVER_BOOKMARK_FILE, + CFG_SERVER_CUSTOM_HTTP_HEADERS, +Index: src/cds_resource_manager.cc +=================================================================== +--- src/cds_resource_manager.cc (revision 2102) ++++ src/cds_resource_manager.cc (working copy) +@@ -482,6 +482,14 @@ + res_attrs->put(MetadataHandler::getResAttrName(R_PROTOCOLINFO), + protocolInfo); + ++ if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK)) ++ { ++ if (mimeType.startsWith(_("video"))) ++ { ++ element->appendElementChild(UpnpXML_DIDLRenderCaptionInfo(url)); ++ } ++ } ++ + log_debug("extended protocolInfo: %s\n", protocolInfo.c_str()); + } + #endif +Index: src/file_request_handler.cc +=================================================================== +--- src/file_request_handler.cc (revision 2102) ++++ src/file_request_handler.cc (working copy) +@@ -305,6 +305,53 @@ + /// header, since chunked encoding may be active and we do not + /// know that here + } ++ ++#ifdef EXTEND_PROTOCOLINFO ++ Ref<ConfigManager> cfg = ConfigManager::getInstance(); ++ if (cfg->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK)) ++ { ++ if (item->getMimeType().startsWith(_("video"))) { ++ // Look for subtitle file and returns it's URL ++ // in CaptionInfo.sec response header. ++ // To be more compliant with original Samsung ++ // server we should check for getCaptionInfo.sec: 1 ++ // request header. ++ Ref<Array<StringBase> > subexts(new Array<StringBase>()); ++ subexts->append(_(".srt")); ++ subexts->append(_(".ssa")); ++ subexts->append(_(".smi")); ++ subexts->append(_(".sub")); ++ ++ String bfilepath = path.substring(0, path.rindex('.')); ++ String validext; ++ for (int i=0; i<subexts->size(); i++) { ++ String ext = subexts->get(i); ++ ++ String fpath = bfilepath + ext; ++ if (access(fpath.c_str(), R_OK) == 0) ++ { ++ validext = ext; ++ break; ++ } ++ } ++ ++ ++ if (validext.length() > 0) ++ { ++ String burlpath = _(filename); ++ burlpath = burlpath.substring(0, burlpath.rindex('.')); ++ Ref<Server> server = Server::getInstance(); ++ String url = _("http://") ++ + server->getIP() + ":" + server->getPort() ++ + burlpath + validext; ++ ++ if (string_ok(header)) ++ header = header + _("\r\n"); ++ header = header + "CaptionInfo.sec: " + url; ++ } ++ } ++#endif ++ } + } + + if (!string_ok(mimeType)) +Index: src/upnp_cds_actions.cc +=================================================================== +--- src/upnp_cds_actions.cc (revision 2102) ++++ src/upnp_cds_actions.cc (working copy) +@@ -106,6 +106,14 @@ + + Ref<ConfigManager> cfg = ConfigManager::getInstance(); + ++#ifdef EXTEND_PROTOCOLINFO ++ if (cfg->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO_SM_HACK)) ++ { ++ didl_lite->setAttribute(_(XML_SEC_NAMESPACE_ATTR), ++ _(XML_SEC_NAMESPACE)); ++ } ++#endif ++ + for(int i = 0; i < arr->size(); i++) + { + Ref<CdsObject> obj = arr->get(i); +Index: src/upnp_xml.cc +=================================================================== +--- src/upnp_xml.cc (revision 2102) ++++ src/upnp_xml.cc (working copy) +@@ -381,3 +381,20 @@ + + return res; + } ++ ++Ref<Element> UpnpXML_DIDLRenderCaptionInfo(String URL) { ++ Ref<Element> cap(new Element(_("sec:CaptionInfoEx"))); ++ ++ // Samsung DLNA clients don't follow this URL and ++ // obtain subtitle location from video HTTP headers. ++ // We don't need to know here what the subtitle type ++ // is and even if there is a subtitle. ++ // This tag seems to be only a hint for Samsung devices, ++ // though it's necessary. ++ ++ int endp = URL.rindex('.'); ++ cap->setText(URL.substring(0, endp) + ".srt"); ++ cap->setAttribute(_("sec:type"), _("srt")); ++ ++ return cap; ++} +Index: src/upnp_xml.h +=================================================================== +--- src/upnp_xml.h (revision 2102) ++++ src/upnp_xml.h (working copy) +@@ -76,4 +76,8 @@ + /// \param URL download location of the item (will be child element of the <res> tag) + /// \param attributes Dictionary containing the <res> tag attributes (like resolution, etc.) + zmm::Ref<mxml::Element> UpnpXML_DIDLRenderResource(zmm::String URL, zmm::Ref<Dictionary> attributes); ++ ++/// \brief Renders a subtitle resource tag (Samsung proprietary extension) ++/// \param URL download location of the video item ++zmm::Ref<mxml::Element> UpnpXML_DIDLRenderCaptionInfo(zmm::String URL); + #endif // __UPNP_XML_H__ diff --git a/symlinks.patch b/symlinks.patch new file mode 100644 index 000000000000..8028f2201784 --- /dev/null +++ b/symlinks.patch @@ -0,0 +1,42 @@ +--- mediatomb-0.12.1.orig/src/autoscan_inotify.cc 2010-03-25 10:58:11.000000000 -0400
++++ mediatomb-0.12.1/src/autoscan_inotify.cc 2012-06-18 02:40:11.000000000 -0400
+@@ -281,7 +281,7 @@
+ }
+ }
+
+- if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT))
++ if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT | IN_CREATE))
+ {
+ String fullPath;
+ if (mask & IN_ISDIR)
+@@ -312,16 +312,17 @@
+ if (objectID != INVALID_OBJECT_ID)
+ cm->removeObject(objectID);
+ }
+- if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO))
++ if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE))
+ {
+ log_debug("adding %s\n", path.c_str());
+ // path, recursive, async, hidden, low priority, cancellable
+ cm->addFile(fullPath, adir->getRecursive(), true, adir->getHidden(), true, false);
+
+- if (mask & IN_ISDIR)
++ if (mask & IN_ISDIR && !(mask & IN_CREATE))
+ monitorUnmonitorRecursive(path, false, adir, watchAs->getNormalizedAutoscanPath(), false);
+ }
+ }
++
+ if (mask & IN_IGNORED)
+ {
+ removeWatchMoves(wd);
+--- mediatomb-0.12.1.orig/src/content_manager.cc 2010-03-25 10:58:11.000000000 -0400
++++ mediatomb-0.12.1/src/content_manager.cc 2012-06-18 02:03:55.000000000 -0400
+@@ -202,7 +202,7 @@
+ #ifdef HAVE_MAGIC
+ if (! ignore_unknown_extensions)
+ {
+- ms = magic_open(MAGIC_MIME);
++ ms = magic_open(MAGIC_MIME|MAGIC_SYMLINK);
+ if (ms == NULL)
+ {
+ log_error("magic_open failed\n");
diff --git a/tonewjs.patch b/tonewjs.patch new file mode 100644 index 000000000000..115968530c68 --- /dev/null +++ b/tonewjs.patch @@ -0,0 +1,564 @@ +diff -up mediatomb-0.12.1-back/build/Makefile.in.tonewjs mediatomb-0.12.1-back/build/Makefile.in +--- mediatomb-0.12.1-back/build/Makefile.in.tonewjs 2010-04-08 00:40:15.000000000 +0200 ++++ mediatomb-0.12.1-back/build/Makefile.in 2011-04-19 17:17:01.343509944 +0200 +@@ -257,7 +257,7 @@ CURL_LIBS = @CURL_LIBS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ + CXXDEPMODE = @CXXDEPMODE@ +-CXXFLAGS = @CXXFLAGS@ ++CXXFLAGS = -fpermissive @CXXFLAGS@ + CYGPATH_W = @CYGPATH_W@ + DB_AUTOCREATE_OPTION_ENABLED = @DB_AUTOCREATE_OPTION_ENABLED@ + DB_AUTOCREATE_OPTION_REQUESTED = @DB_AUTOCREATE_OPTION_REQUESTED@ +diff -up mediatomb-0.12.1-back/src/scripting/import_script.cc.tonewjs mediatomb-0.12.1-back/src/scripting/import_script.cc +--- mediatomb-0.12.1-back/src/scripting/import_script.cc.tonewjs 2011-04-18 13:10:48.000000000 +0200 ++++ mediatomb-0.12.1-back/src/scripting/import_script.cc 2011-04-18 13:29:36.000000000 +0200 +@@ -53,8 +53,8 @@ ImportScript::ImportScript(Ref<Runtime> + try + { + load(scriptPath); +- root = JS_NewScriptObject(cx, script); +- JS_AddNamedRoot(cx, &root, "ImportScript"); ++ root = JS_NewObject(cx, NULL, script, NULL); ++ JS_AddNamedObjectRoot(cx, &root, "ImportScript"); + } + catch (Exception ex) + { +@@ -117,7 +117,7 @@ ImportScript::~ImportScript() + #endif + + if (root) +- JS_RemoveRoot(cx, &root); ++ JS_RemoveObjectRoot(cx, &root); + + #ifdef JS_THREADSAFE + JS_EndRequest(cx); +diff -up mediatomb-0.12.1-back/src/scripting/js_functions.cc.tonewjs mediatomb-0.12.1-back/src/scripting/js_functions.cc +--- mediatomb-0.12.1-back/src/scripting/js_functions.cc.tonewjs 2011-04-18 13:29:55.000000000 +0200 ++++ mediatomb-0.12.1-back/src/scripting/js_functions.cc 2011-04-19 16:48:04.009229611 +0200 +@@ -49,7 +49,7 @@ using namespace zmm; + extern "C" { + + JSBool +-js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++js_print(JSContext *cx, uintN argc, jsval *argv) + { + uintN i; + JSString *str; +@@ -60,19 +60,21 @@ js_print(JSContext *cx, JSObject *obj, u + if (!str) + return JS_TRUE; + argv[i] = STRING_TO_JSVAL(str); +- log_js("%s\n", JS_GetStringBytes(str)); ++ char * log_str = JS_EncodeString(cx, str); ++ log_js("%s\n", log_str); ++ JS_free(cx, log_str); + } + return JS_TRUE; + } + + JSBool +-js_copyObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++js_copyObject(JSContext *cx, uintN argc, jsval *argv) + { + jsval arg; + JSObject *js_cds_obj; + JSObject *js_cds_clone_obj; + +- Script *self = (Script *)JS_GetPrivate(cx, obj); ++ Script *self = (Script *)JS_GetPrivate(cx, JS_THIS_OBJECT(cx, argv)); + + try + { +@@ -91,7 +93,7 @@ js_copyObject(JSContext *cx, JSObject *o + + self->cdsObject2jsObject(cds_obj, js_cds_clone_obj); + +- *rval = OBJECT_TO_JSVAL(js_cds_clone_obj); ++ JS_SET_RVAL(cx, argv, OBJECT_TO_JSVAL(js_cds_clone_obj)); + + return JS_TRUE; + +@@ -110,7 +112,7 @@ js_copyObject(JSContext *cx, JSObject *o + } + + JSBool +-js_addCdsObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++js_addCdsObject(JSContext *cx, uintN argc, jsval *argv) + { + try + { +@@ -126,7 +128,7 @@ js_addCdsObject(JSContext *cx, JSObject + Ref<StringConverter> p2i; + Ref<StringConverter> i2i; + +- Script *self = (Script *)JS_GetPrivate(cx, obj); ++ Script *self = (Script *)JS_GetPrivate(cx, JS_THIS_OBJECT(cx, argv)); + + if (self == NULL) + { +@@ -156,20 +158,20 @@ js_addCdsObject(JSContext *cx, JSObject + if (!str) + path = _("/"); + else +- path = JS_GetStringBytes(str); ++ path = JS_EncodeString(cx, str); + + JSString *cont = JS_ValueToString(cx, argv[2]); + if (cont) + { +- containerclass = JS_GetStringBytes(cont); ++ containerclass = JS_EncodeString(cx, cont); + if (!string_ok(containerclass) || containerclass == "undefined") + containerclass = nil; + } + + if (self->whoami() == S_PLAYLIST) +- js_orig_obj = self->getObjectProperty(obj, _("playlist")); ++ js_orig_obj = self->getObjectProperty(JS_THIS_OBJECT(cx, argv), _("playlist")); + else if (self->whoami() == S_IMPORT) +- js_orig_obj = self->getObjectProperty(obj, _("orig")); ++ js_orig_obj = self->getObjectProperty(JS_THIS_OBJECT(cx, argv), _("orig")); + + if (js_orig_obj == NULL) + { +@@ -285,8 +287,7 @@ js_addCdsObject(JSContext *cx, JSObject + JSString *str2 = JS_NewStringCopyN(cx, tmp.c_str(), tmp.length()); + if (!str2) + return JS_TRUE; +- *rval = STRING_TO_JSVAL(str2); +- ++ JS_SET_RVAL(cx, argv, STRING_TO_JSVAL(str2)); + return JS_TRUE; + } + catch (ServerShutdownException se) +@@ -302,7 +303,7 @@ js_addCdsObject(JSContext *cx, JSObject + return JS_TRUE; + } + +-static JSBool convert_charset_generic(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, charset_convert_t chr) ++static JSBool convert_charset_generic(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, charset_convert_t chr) + { + try + { +@@ -321,7 +322,7 @@ static JSBool convert_charset_generic(JS + { + str = JS_ValueToString(cx, argv[0]); + if (str) +- result = JS_GetStringBytes(str); ++ result = JS_EncodeString(cx, str); + } + + if (result != nil) +@@ -330,7 +331,7 @@ static JSBool convert_charset_generic(JS + JSString *str2 = JS_NewStringCopyN(cx, result.c_str(), result.length()); + if (!str2) + return JS_TRUE; +- *rval = STRING_TO_JSVAL(str2); ++ JS_SET_RVAL(cx, argv, STRING_TO_JSVAL(str2)); + } + } + catch (ServerShutdownException se) +@@ -347,24 +348,23 @@ static JSBool convert_charset_generic(JS + } + + +-JSBool js_f2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++JSBool js_f2i(JSContext *cx, uintN argc, jsval *argv) + { +- return convert_charset_generic(cx, obj, argc, argv, rval, F2I); ++ return convert_charset_generic(cx, JS_THIS_OBJECT(cx, argv), argc, argv, F2I); + } + +-JSBool js_m2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++JSBool js_m2i(JSContext *cx, uintN argc, jsval *argv) + { +- return convert_charset_generic(cx, obj, argc, argv, rval, M2I); +-} ++ return convert_charset_generic(cx, JS_THIS_OBJECT(cx, argv), argc, argv, M2I); } + +-JSBool js_p2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++JSBool js_p2i(JSContext *cx, uintN argc, jsval *argv) + { +- return convert_charset_generic(cx, obj, argc, argv, rval, P2I); ++ return convert_charset_generic(cx, JS_THIS_OBJECT(cx, argv), argc, argv, P2I); + } + +-JSBool js_j2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++JSBool js_j2i(JSContext *cx, uintN argc, jsval *argv) + { +- return convert_charset_generic(cx, obj, argc, argv, rval, J2I); ++ return convert_charset_generic(cx, JS_THIS_OBJECT(cx, argv), argc, argv, J2I); + } + + } // extern "C" +diff -up mediatomb-0.12.1-back/src/scripting/js_functions.h.tonewjs mediatomb-0.12.1-back/src/scripting/js_functions.h +--- mediatomb-0.12.1-back/src/scripting/js_functions.h.tonewjs 2010-03-25 15:58:05.000000000 +0100 ++++ mediatomb-0.12.1-back/src/scripting/js_functions.h 2011-04-18 13:59:29.000000000 +0200 +@@ -40,18 +40,18 @@ + extern "C" { + + /// \brief Log output. +-JSBool js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++JSBool js_print(JSContext *cx, uintN argc, jsval *argv); + + /// \brief Adds an object to the database. +-JSBool js_addCdsObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++JSBool js_addCdsObject(JSContext *cx, uintN argc, jsval *argv); + + /// \brief Makes a copy of an CDS object. +-JSBool js_copyObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++JSBool js_copyObject(JSContext *cx, uintN argc, jsval *argv); + +-JSBool js_f2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-JSBool js_m2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-JSBool js_p2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +-JSBool js_j2i(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); ++JSBool js_f2i(JSContext *cx, uintN argc, jsval *argv); ++JSBool js_m2i(JSContext *cx, uintN argc, jsval *argv); ++JSBool js_p2i(JSContext *cx, uintN argc, jsval *argv); ++JSBool js_j2i(JSContext *cx, uintN argc, jsval *argv); + + } // extern "C" + +diff -up mediatomb-0.12.1-back/src/scripting/playlist_parser_script.cc.tonewjs mediatomb-0.12.1-back/src/scripting/playlist_parser_script.cc +--- mediatomb-0.12.1-back/src/scripting/playlist_parser_script.cc.tonewjs 2011-04-18 13:34:14.000000000 +0200 ++++ mediatomb-0.12.1-back/src/scripting/playlist_parser_script.cc 2011-04-18 13:51:59.000000000 +0200 +@@ -46,9 +46,9 @@ using namespace zmm; + extern "C" { + + static JSBool +-js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ++js_readln(JSContext *cx, uintN argc, jsval *argv) + { +- PlaylistParserScript *self = (PlaylistParserScript *)JS_GetPrivate(cx, obj); ++ PlaylistParserScript *self = (PlaylistParserScript *)JS_GetPrivate(cx, JS_THIS_OBJECT(cx, argv)); + + String line; + +@@ -69,7 +69,7 @@ js_readln(JSContext *cx, JSObject *obj, + + JSString *jsline = JS_NewStringCopyZ(cx, line.c_str()); + +- *rval = STRING_TO_JSVAL(jsline); ++ JS_SET_RVAL(cx, argv, STRING_TO_JSVAL(jsline)); + + return JS_TRUE; + } +@@ -93,8 +93,8 @@ PlaylistParserScript::PlaylistParserScri + + String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT); + load(scriptPath); +- root = JS_NewScriptObject(cx, script); +- JS_AddNamedRoot(cx, &root, "PlaylistScript"); ++ root = JS_NewObject(cx, NULL, script, NULL); ++ JS_AddNamedObjectRoot(cx, &root, "PlaylistScript"); + } + catch (Exception ex) + { +@@ -245,7 +245,7 @@ PlaylistParserScript::~PlaylistParserScr + #endif + + if (root) +- JS_RemoveRoot(cx, &root); ++ JS_RemoveObjectRoot(cx, &root); + + #ifdef JS_THREADSAFE + JS_EndRequest(cx); +diff -up mediatomb-0.12.1-back/src/scripting/script.cc.tonewjs mediatomb-0.12.1-back/src/scripting/script.cc +--- mediatomb-0.12.1-back/src/scripting/script.cc.tonewjs 2011-04-18 13:53:07.000000000 +0200 ++++ mediatomb-0.12.1-back/src/scripting/script.cc 2011-04-19 18:26:34.460338804 +0200 +@@ -87,7 +87,7 @@ String Script::getProperty(JSObject *obj + str = JS_ValueToString(cx, val); + if (! str) + return nil; +- return JS_GetStringBytes(str); ++ return JS_EncodeString(cx, str); + } + + int Script::getBoolProperty(JSObject *obj, String name) +@@ -427,14 +427,14 @@ static JSFunctionSpec js_global_function + try + { + common_script = _load(common_scr_path); +- common_root = JS_NewScriptObject(cx, common_script); +- JS_AddNamedRoot(cx, &common_root, "common-script"); ++ common_root = JS_NewObject(cx, NULL, common_script, NULL); ++ JS_AddNamedObjectRoot(cx, &common_root, "common-script"); + _execute(common_script); + } + catch (Exception e) + { + if (common_root) +- JS_RemoveRoot(cx, &common_root); ++ JS_RemoveObjectRoot(cx, &common_root); + + log_js("Unable to load %s: %s\n", common_scr_path.c_str(), + e.getMessage().c_str()); +@@ -460,7 +460,7 @@ Script::~Script() + JS_BeginRequest(cx); + #endif + if (common_root) +- JS_RemoveRoot(cx, &common_root); ++ JS_RemoveObjectRoot(cx, &common_root); + + /* + * scripts are unrooted and will be cleaned up by GC +@@ -504,11 +504,11 @@ void Script::initGlobalObject() + static JSClass global_class = + { + "global", /* name */ +- JSCLASS_HAS_PRIVATE, /* flags */ ++ JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS,/* flags */ + JS_PropertyStub, /* add property */ + JS_PropertyStub, /* del property */ + JS_PropertyStub, /* get property */ +- JS_PropertyStub, /* set property */ ++ JS_StrictPropertyStub, /* set property */ + JS_EnumerateStandardClasses, /* enumerate */ + JS_ResolveStub, /* resolve */ + JS_ConvertStub, /* convert */ +@@ -517,7 +517,7 @@ void Script::initGlobalObject() + }; + + /* create the global object here */ +- glob = JS_NewObject(cx, &global_class, NULL, NULL); ++ glob = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); + if (! glob) + throw _Exception(_("Scripting: could not initialize glboal class")); + +@@ -539,12 +539,12 @@ void Script::defineFunctions(JSFunctionS + throw _Exception(_("Scripting: JS_DefineFunctions failed")); + } + +-JSScript *Script::_load(zmm::String scriptPath) ++JSObject *Script::_load(zmm::String scriptPath) + { + if (glob == NULL) + initGlobalObject(); + +- JSScript *scr; ++ JSObject *scr; + + String scriptText = read_text_file(scriptPath); + +@@ -571,14 +571,11 @@ JSScript *Script::_load(zmm::String scri + + void Script::load(zmm::String scriptPath) + { +- if (script) +- JS_DestroyScript(cx, script); +- + script = _load((scriptPath)); + } + + +-void Script::_execute(JSScript *scr) ++void Script::_execute(JSObject *scr) + { + jsval ret_val; + +@@ -662,7 +659,7 @@ Ref<CdsObject> Script::jsObject2cdsObjec + JSObject *js_meta = getObjectProperty(js, _("meta")); + if (js_meta) + { +- JS_AddNamedRoot(cx, &js_meta, "meta"); ++ JS_AddNamedObjectRoot(cx, &js_meta, "meta"); + /// \todo: only metadata enumerated in MT_KEYS is taken + for (int i = 0; i < M_MAX; i++) + { +@@ -687,7 +684,7 @@ Ref<CdsObject> Script::jsObject2cdsObjec + } + } + } +- JS_RemoveRoot(cx, &js_meta); ++ JS_RemoveObjectRoot(cx, &js_meta); + } + + // stuff that has not been exported to js +diff -up mediatomb-0.12.1-back/src/scripting/script.h.tonewjs mediatomb-0.12.1-back/src/scripting/script.h +--- mediatomb-0.12.1-back/src/scripting/script.h.tonewjs 2011-04-18 12:56:14.000000000 +0200 ++++ mediatomb-0.12.1-back/src/scripting/script.h 2011-04-18 12:56:51.000000000 +0200 +@@ -66,8 +66,8 @@ public: + JSRuntime *rt; + JSContext *cx; + JSObject *glob; +- JSScript *script; +- JSScript *common_script; ++ JSObject *script; ++ JSObject *common_script; + + public: + Script(zmm::Ref<Runtime> runtime); +@@ -115,8 +115,8 @@ private: + JSObject *common_root; + + void initGlobalObject(); +- JSScript *_load(zmm::String scriptPath); +- void _execute(JSScript *scr); ++ JSObject *_load(zmm::String scriptPath); ++ void _execute(JSObject *scr); + zmm::Ref<StringConverter> _p2i; + zmm::Ref<StringConverter> _j2i; + zmm::Ref<StringConverter> _f2i; +--- mediatomb-0.12.1/configure.tonewjs 2011-07-04 20:20:00.290227110 +1200 ++++ mediatomb-0.12.1/configure 2011-07-04 20:20:28.186894644 +1200 +@@ -23784,14 +23784,14 @@ if test "x$ac_cv_lib_smjs_JS_NewObject" + + else + +- LDFLAGS="-L$JS_SEARCH_LIBS $LDFLAGS_SAVE -lmozjs $ADD_PTHREAD_CFLAGS" +- { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs" >&5 +-$as_echo_n "checking for JS_NewObject in -lmozjs... " >&6; } +-if test "${ac_cv_lib_mozjs_JS_NewObject+set}" = set; then ++ LDFLAGS="-L$JS_SEARCH_LIBS $LDFLAGS_SAVE -lmozjs185 $ADD_PTHREAD_CFLAGS" ++ { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs185" >&5 ++$as_echo_n "checking for JS_NewObject in -lmozjs185... " >&6; } ++if test "${ac_cv_lib_mozjs185_JS_NewObject+set}" = set; then + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +-LIBS="-lmozjs $LIBS" ++LIBS="-lmozjs185 $LIBS" + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -23835,12 +23835,12 @@ $as_echo "$ac_try_echo") >&5 + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then +- ac_cv_lib_mozjs_JS_NewObject=yes ++ ac_cv_lib_mozjs185_JS_NewObject=yes + else + $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- ac_cv_lib_mozjs_JS_NewObject=no ++ ac_cv_lib_mozjs185_JS_NewObject=no + fi + + rm -rf conftest.dSYM +@@ -23848,12 +23848,12 @@ rm -f core conftest.err conftest.$ac_obj + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs_JS_NewObject" >&5 +-$as_echo "$ac_cv_lib_mozjs_JS_NewObject" >&6; } +-if test "x$ac_cv_lib_mozjs_JS_NewObject" = x""yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs185_JS_NewObject" >&5 ++$as_echo "$ac_cv_lib_mozjs185_JS_NewObject" >&6; } ++if test "x$ac_cv_lib_mozjs185_JS_NewObject" = x""yes; then + +- JS_LIBS="-L$JS_SEARCH_LIBS -lmozjs" +- MOZLIB=mozjs ++ JS_LIBS="-L$JS_SEARCH_LIBS -lmozjs185" ++ MOZLIB=mozjs185 + + else + +@@ -24020,13 +24020,13 @@ if test "x$ac_cv_lib_smjs_JS_NewObject" + else + + unset ac_cv_lib_smjs_JS_NewObject +- { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs" >&5 +-$as_echo_n "checking for JS_NewObject in -lmozjs... " >&6; } +-if test "${ac_cv_lib_mozjs_JS_NewObject+set}" = set; then ++ { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs185" >&5 ++$as_echo_n "checking for JS_NewObject in -lmozjs185... " >&6; } ++if test "${ac_cv_lib_mozjs185_JS_NewObject+set}" = set; then + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +-LIBS="-lmozjs $LIBS" ++LIBS="-lmozjs185 $LIBS" + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -24070,12 +24070,12 @@ $as_echo "$ac_try_echo") >&5 + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then +- ac_cv_lib_mozjs_JS_NewObject=yes ++ ac_cv_lib_mozjs185_JS_NewObject=yes + else + $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- ac_cv_lib_mozjs_JS_NewObject=no ++ ac_cv_lib_mozjs185_JS_NewObject=no + fi + + rm -rf conftest.dSYM +@@ -24083,12 +24083,12 @@ rm -f core conftest.err conftest.$ac_obj + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs_JS_NewObject" >&5 +-$as_echo "$ac_cv_lib_mozjs_JS_NewObject" >&6; } +-if test "x$ac_cv_lib_mozjs_JS_NewObject" = x""yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs185_JS_NewObject" >&5 ++$as_echo "$ac_cv_lib_mozjs185_JS_NewObject" >&6; } ++if test "x$ac_cv_lib_mozjs185_JS_NewObject" = x""yes; then + +- MOZLIB=mozjs +- JS_LIBS="-lmozjs" ++ MOZLIB=mozjs185 ++ JS_LIBS="-lmozjs185" + + else + +@@ -24239,15 +24239,15 @@ if test "x$ac_cv_lib_smjs_JS_NewObject" + + else + +- LDFLAGS="-L$SEARCH_DIR_LIBS $LDFLAGS_SAVE -lmozjs" +- unset ac_cv_lib_mozjs_JS_NewObject +- { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs" >&5 +-$as_echo_n "checking for JS_NewObject in -lmozjs... " >&6; } +-if test "${ac_cv_lib_mozjs_JS_NewObject+set}" = set; then ++ LDFLAGS="-L$SEARCH_DIR_LIBS $LDFLAGS_SAVE -lmozjs185" ++ unset ac_cv_lib_mozjs185_JS_NewObject ++ { $as_echo "$as_me:$LINENO: checking for JS_NewObject in -lmozjs185" >&5 ++$as_echo_n "checking for JS_NewObject in -lmozjs185... " >&6; } ++if test "${ac_cv_lib_mozjs185_JS_NewObject+set}" = set; then + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +-LIBS="-lmozjs $LIBS" ++LIBS="-lmozjs185 $LIBS" + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ + _ACEOF +@@ -24291,12 +24291,12 @@ $as_echo "$ac_try_echo") >&5 + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then +- ac_cv_lib_mozjs_JS_NewObject=yes ++ ac_cv_lib_mozjs185_JS_NewObject=yes + else + $as_echo "$as_me: failed program was:" >&5 + sed 's/^/| /' conftest.$ac_ext >&5 + +- ac_cv_lib_mozjs_JS_NewObject=no ++ ac_cv_lib_mozjs185_JS_NewObject=no + fi + + rm -rf conftest.dSYM +@@ -24304,12 +24304,12 @@ rm -f core conftest.err conftest.$ac_obj + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs_JS_NewObject" >&5 +-$as_echo "$ac_cv_lib_mozjs_JS_NewObject" >&6; } +-if test "x$ac_cv_lib_mozjs_JS_NewObject" = x""yes; then ++{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_mozjs185_JS_NewObject" >&5 ++$as_echo "$ac_cv_lib_mozjs185_JS_NewObject" >&6; } ++if test "x$ac_cv_lib_mozjs185_JS_NewObject" = x""yes; then + +- JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs" +- MOZLIB=mozjs ++ JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs185" ++ MOZLIB=mozjs185 + + else + |