From 570a8e42684f542d6deceffd59c4eca234ffabc7 Mon Sep 17 00:00:00 2001
From: Britney Fransen <brfransen@gmail.com>
Date: Sat, 2 Nov 2013 17:51:08 -0500
Subject: mythtv stable-0.27 mythtv: initial commit. refs #933

changed the name of pretty to recordings
---
 ...tect-metadata-loads-from-multiple-threads.patch |   52 +
 abs/core/mythtv/stable-0.27/mythtv/PKGBUILD        |  118 ++
 abs/core/mythtv/stable-0.27/mythtv/__changelog     |    2 +
 .../stable-0.27/mythtv/menu-xml/HOST_SETTINGS.xml  |   98 +
 .../stable-0.27/mythtv/menu-xml/dvd_backup.xml     |   39 +
 .../mythtv/stable-0.27/mythtv/menu-xml/game.xml    |   12 +
 .../stable-0.27/mythtv/menu-xml/info_menu.xml      |   76 +
 abs/core/mythtv/stable-0.27/mythtv/menu-xml/is.xml |    3 +
 .../stable-0.27/mythtv/menu-xml/library.xml.patch  |   26 +
 .../mythtv/stable-0.27/mythtv/menu-xml/linhes.xml  |   60 +
 .../stable-0.27/mythtv/menu-xml/mainmenu.xml.patch |   37 +
 .../stable-0.27/mythtv/menu-xml/mythbackup.xml     |   20 +
 .../stable-0.27/mythtv/menu-xml/mythrestore.xml    |   21 +
 .../mythtv/menu-xml/optical_menu.xml.patch         |   23 +
 .../mythtv/menu-xml/original/create_patch.sh       |    5 +
 .../stable-0.27/mythtv/menu-xml/siriusmenu.xml     |  419 +++++
 .../mythtv/stable-0.27/mythtv/menu-xml/update.xml  |    9 +
 .../mythtv/stable-0.27/mythtv/menu-xml/update2.xml |   20 +
 .../mythtv/stable-0.27/mythtv/menu-xml/xmmenu.xml  |  574 ++++++
 .../mythtv/stable-0.27/mythtv/myth_settings.patch  | 1980 ++++++++++++++++++++
 abs/core/mythtv/stable-0.27/mythtv/mythtv.install  |   24 +
 abs/core/mythtv/stable-0.27/mythtv/recordings      |    5 +
 22 files changed, 3623 insertions(+)
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/0001-protect-metadata-loads-from-multiple-threads.patch
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/PKGBUILD
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/__changelog
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/HOST_SETTINGS.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/dvd_backup.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/game.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/info_menu.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/is.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/library.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/linhes.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/mainmenu.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythbackup.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythrestore.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/optical_menu.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/original/create_patch.sh
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/siriusmenu.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/update.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/update2.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/menu-xml/xmmenu.xml
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/myth_settings.patch
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/mythtv.install
 create mode 100644 abs/core/mythtv/stable-0.27/mythtv/recordings

diff --git a/abs/core/mythtv/stable-0.27/mythtv/0001-protect-metadata-loads-from-multiple-threads.patch b/abs/core/mythtv/stable-0.27/mythtv/0001-protect-metadata-loads-from-multiple-threads.patch
new file mode 100644
index 0000000..d8f4a0c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/0001-protect-metadata-loads-from-multiple-threads.patch
@@ -0,0 +1,52 @@
+From b20171597097f8b933065ef3291c63194d310fbf Mon Sep 17 00:00:00 2001
+From: George Nassas <george@nassas.com>
+Date: Sun, 10 Jun 2012 13:36:42 -0400
+Subject: [PATCH] protect metadata loads from multiple threads
+
+---
+ mythtv/libs/libmythmetadata/dbaccess.cpp |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/mythtv/libs/libmythmetadata/dbaccess.cpp b/mythtv/libs/libmythmetadata/dbaccess.cpp
+index 67cd904..46adb7a 100644
+--- a/mythtv/libs/libmythmetadata/dbaccess.cpp
++++ b/mythtv/libs/libmythmetadata/dbaccess.cpp
+@@ -47,8 +47,11 @@ class SingleValueImp
+ 
+     virtual ~SingleValueImp() {}
+ 
++    mutable QMutex mutex;
++
+     void load_data()
+     {
++        QMutexLocker locker(&mutex);
+         if (!m_ready)
+         {
+             fill_from_db();
+@@ -271,8 +274,11 @@ class MultiValueImp
+                 .arg(m_value_name).arg(m_table_name).arg(m_id_name);
+     }
+ 
++    mutable QMutex mutex;
++
+     void load_data()
+     {
++        QMutexLocker locker(&mutex);
+         if (!m_ready)
+         {
+             fill_from_db();
+@@ -730,8 +736,11 @@ class FileAssociationsImp
+         }
+     }
+ 
++    mutable QMutex mutex;
++
+     void load_data()
+     {
++        QMutexLocker locker(&mutex);
+         if (!m_ready)
+         {
+             fill_from_db();
+-- 
+1.7.2.5
+
diff --git a/abs/core/mythtv/stable-0.27/mythtv/PKGBUILD b/abs/core/mythtv/stable-0.27/mythtv/PKGBUILD
new file mode 100644
index 0000000..a00c869
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/PKGBUILD
@@ -0,0 +1,118 @@
+pkgname=mythtv
+pkgver=0.27
+pkgrel=1
+commit_hash=`cat ../git_src/git_hash`
+pkgdesc="A Homebrew PVR project $commit_hash"
+arch=('i686' 'x86_64')
+url="http://www.mythtv.org/"
+license=('GPL')
+depends=('avahi' 'fftw' 'glew' 'lame' 'libass' 'libavc1394' 'libcdio'
+         'libcec' 'libiec61883' 'libva' 'libvpx' 'libxinerama' 'libxml2'
+         'lirc-utils' 'mysql-clients' 'mysql-python' 'openssl'
+         'perl-dbd-mysql' 'perl-io-socket-inet6' 'perl-libwww'
+         'perl-net-upnp' 'python2-lxml' 'qtwebkit' 'taglib' 'urlgrabber'
+         'x264' 'xmltv'
+         #'qt'
+         #'ffmpeg'
+         #'fribidi'
+         #'perl-soap-lite'
+         #'perl-date-manip'
+         #'perl-xml-sax'
+         #'perl-math-round'
+         #'perl-time-hires'
+         #'wget'
+         #'libxrandr'
+         #'faad2'
+         #'libvdpau'
+         #'libcrystalhd-git'
+         #'python-pycurl'
+         #'lsdvd'
+         #'dvdbackup'
+         )
+makedepends=('mesa' 'libgl' 'yasm' 'git' 'rsync')
+replaces=()
+groups=('pvr')
+backup=()
+install='mythtv.install'
+
+patches=(#'myth_settings.patch' 
+         '0001-protect-metadata-loads-from-multiple-threads.patch')
+    #http://code.mythtv.org/trac/ticket/10825   thread safety in video metadata load
+ 
+optdepends=()
+replaces=('mythvideo' 'myththemes')
+conflicts=('mythvideo' 'myththemes')
+source=(`echo ${patches[@]:0}` 'recordings')
+
+build() {
+    if [ -e ${srcdir}/mythtv ]
+    then
+        msg "Removing old mythtv src"
+        rm -rf ${srcdir}/mythtv
+    fi
+
+    cd ${startdir}
+    msg "Copying in mythtv git_src"
+    cp -rp ../git_src/mythtv/mythtv $srcdir
+    cd ${srcdir}/$pkgname
+    echo "#!/bin/bash" > version.sh
+
+    msg "--------------------------applying patches------------------------------"
+    for i in `echo ${patches[@]:0} `
+    do
+        echo applying $i
+        echo "-----------------------------"
+        patch -Np2  -i ${startdir}/src/$i  || return 1
+    done
+    msg "--------------------------done applying patches-------------------------"
+
+    msg "Configuring mythtv"
+    ARCH=${CARCH/_/-}
+    ./configure --prefix=/usr \
+                --cpu=${ARCH} \
+                --disable-altivec \
+                --disable-audio-jack \
+                --disable-audio-pulse \
+                --disable-ccache \
+                --disable-distcc \
+                --dvb-path=/usr/include \
+                --enable-libfftw3 \
+                --enable-libmp3lame \
+                --enable-libvpx \
+                --enable-libx264 \
+                --enable-vaapi \
+                --python=python2 \
+                --with-bindings=perl,python || return 1
+    msg "Compiling mythtv"
+    make all || return 1
+}
+
+package() {
+    cd "${srcdir}/${pkgname}"
+    # basic install
+    make INSTALL_ROOT="${pkgdir}" install
+    # install contrib files
+    rsync -arp --exclude .svn --delete-excluded contrib ${pkgdir}/usr/share/mythtv/ || return 1
+    # install database structure
+    rsync -arp --exclude .svn --delete-excluded database ${pkgdir}/usr/share/mythtv/ || return 1
+    # install docs
+    rsync -arp --exclude .svn --delete-excluded docs ${pkgdir}/usr/share/mythtv/ || return 1
+
+    # patch the xml LinHES style
+    cp -r ${startdir}/menu-xml/*.xml ${pkgdir}/usr/share/mythtv/themes/defaultmenu/
+    cd ${pkgdir}/usr/share/mythtv
+    patch -p0 < ${startdir}/menu-xml/mainmenu.xml.patch || return 1
+    patch -p0 < ${startdir}/menu-xml/optical_menu.xml.patch || return 1
+    patch -p0 < ${startdir}/menu-xml/library.xml.patch || return 1
+
+    # make mythtv log dir for old scripts that use it
+    mkdir -p ${pkgdir}/var/log/mythtv
+    chown 1000.1000 ${pkgdir}/var/log/mythtv
+
+    #install recordings (was pretty)
+    mkdir -p ${pkgdir}/etc/cron.hourly/
+    install -m0755 ${srcdir}/recordings ${pkgdir}/etc/cron.hourly/
+}
+
+md5sums=('67f7316c750fba17fa578d10840b9dbd'
+         '65a08d8949431ecdeb51a686dc6f9c21')
diff --git a/abs/core/mythtv/stable-0.27/mythtv/__changelog b/abs/core/mythtv/stable-0.27/mythtv/__changelog
new file mode 100644
index 0000000..91a959c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/__changelog
@@ -0,0 +1,2 @@
+update to 0.27-fixes
+
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/HOST_SETTINGS.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/HOST_SETTINGS.xml
new file mode 100644
index 0000000..b1fa6b5
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/HOST_SETTINGS.xml
@@ -0,0 +1,98 @@
+<mythmenu name="HOST_SETTINGS">
+    <button>
+        <type>MV_ACCESS_SETUP_MENU</type>
+        <text>Access Control</text>
+        <action>EXEC  mythinstall -s accesscontrol </action>
+    </button>
+
+    <button>
+        <type>MV_SOFTWARE_MENU</type>
+        <text>Add/Remove software</text>
+        <action>EXEC  mythinstall -s  plugins,software </action>
+    </button>
+
+    <button>
+        <type>MV_ADVANCED_SETUP_MENU</type>
+        <text>Advanced</text>
+        <action>EXEC  mythinstall -s advanced</action>
+    </button>
+
+    <button>
+        <type>MV_AUDIO_SETUP_MENU</type>
+        <text>Audio Settings</text>
+        <action>EXEC  mythinstall -s sound </action>
+    </button>
+
+    <button>
+        <type>MV_ADVANCED_X_SETUP_MENU</type>
+        <text>Display</text>
+        <action>EXEC  mythinstall -s advancedX</action>
+    </button>
+
+    <button>
+        <type>MV_NETWORK_SETUP_MENU</type>
+        <text>Dynamic DNS</text>
+        <action>EXEC  mythinstall -s ddns </action>
+    </button>
+
+   <button>
+       <type>MV_FILESHARES_MENU</type>
+       <text>File Shares</text>
+       <action>EXEC  mythinstall -s fileshare</action>
+   </button>
+
+   <button>
+       <type>MV_MISC_SETUP_MENU</type>
+       <text>Miscellanous</text>
+       <action>EXEC  mythinstall -s misc </action>
+   </button>
+
+   <button>
+       <type>MV_NETWORK_SETUP_MENU</type>
+       <text>Network</text>
+       <action>EXEC  mythinstall -s network </action>
+   </button>
+
+   <button>
+       <type>MV_IR_SETUP_MENU</type>
+       <text>Remotes</text>
+       <action>EXEC  mythinstall -s ir </action>
+   </button>
+
+   <button>
+       <type>MV_SCREENSAVER_SETUP_MENU</type>
+       <text>Screensaver</text>
+       <action>EXEC  mythinstall -s screensaver </action>
+   </button>
+
+   <button>
+       <type>MV_SHUTDOWN_SETUP_MENU</type>
+       <text>Shutdown Settings</text>
+       <action>EXEC  mythinstall -s sleep </action>
+   </button>
+
+   <button>
+       <type>MV_SYSTEM_SETUP_MENU</type>
+       <text>System Type</text>
+       <action>EXEC  mythinstall -s hostype </action>
+   </button>
+
+   <button>
+       <type>MV_USER_SETUP_MENU</type>
+       <text>User Accounts</text>
+       <action>EXEC  mythinstall -s user </action>
+   </button>
+
+   <button>
+       <type>MV_VNC_SETUP_MENU</type>
+       <text>VNC Service</text>
+       <action>EXEC  mythinstall -s vnc </action>
+   </button>
+
+   <button>
+       <type>MV_WEBACCESS_SETUP_MENU</type>
+       <text>Web Security</text>
+       <action>EXEC  mythinstall -s webuser </action>
+   </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/dvd_backup.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/dvd_backup.xml
new file mode 100644
index 0000000..2647d81
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/dvd_backup.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<mythmenu name="OPTICAL_DISK">
+
+    <button>
+        <type>DVD_RIP</type>
+        <text>Mirror DVD</text>
+        <description>Creates a mirror of your DVD</description>
+	<action>EXEC /usr/LH/bin/ripD_eject.sh m &amp;</action>
+    </button>
+
+    <button>
+        <type>DVD_RIP</type>
+        <text>ISO of DVD</text>
+        <description>Creates an ISO of your DVD</description>
+	<action>EXEC /usr/LH/bin/ripD_eject.sh i &amp;</action>
+    </button>
+
+    <button>
+        <type>DVD_RIP</type>
+        <text>High Quality</text>
+        <description>Creates a high quality MPEG4 of your DVD</description>
+	<action>EXEC /usr/LH/bin/ripD_eject.sh h &amp;</action>
+    </button>
+
+    <button>
+        <type>DVD_RIP</type>
+        <text>Normal Quality</text>
+        <description>Creates a normal quality MPEG4 of your DVD</description>
+	<action>EXEC /usr/LH/bin/ripD_eject.sh n &amp;</action>
+    </button>
+
+    <button>
+        <type>DVD_RIP</type>
+        <text>Low Quality</text>
+        <description>Creates a low quality MPEG4 of your DVD</description>
+	<action>EXEC /usr/LH/bin/ripD_eject.sh l &amp;</action>
+    </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/game.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/game.xml
new file mode 100644
index 0000000..293a9e6
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/game.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<mythmenu name="GAME">
+
+    <button>
+        <type>GAME</type>
+        <text>MythGame</text>
+        <description>Play video games</description>
+        <action>PLUGIN mythgame</action>
+        <depends>mythgame</depends>
+    </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/info_menu.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/info_menu.xml
new file mode 100644
index 0000000..017f90b
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/info_menu.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<mythmenu name="INFO">
+
+    <button>
+        <type>NEWS</type>
+        <text>News Feeds</text>
+        <description>Keep up with the news</description>
+        <action>PLUGIN mythnews</action>
+        <depends>mythnews</depends>
+    </button>
+
+    <button>
+        <type>MYTHTWITTER_TIMELINE</type>
+        <text>Twitter</text>
+        <description>Send and receive tweets</description>
+        <action>JUMP MythTwitter_Timeline</action>
+        <depends>mythtwitter</depends>
+    </button>
+
+    <button>
+        <type>WEATHER</type>
+        <text>Weather</text>
+        <action>PLUGIN mythweather</action>
+        <description>Local weather forecast</description>
+        <depends>mythweather</depends>
+    </button>
+
+    <button>
+       <type>WEATHER</type>
+        <text>Weather Station</text>
+        <action>PLUGIN mythwstation</action>
+        <depends>mythwstation</depends>
+    </button>
+
+    <button>
+        <type>WEBPAGE</type>
+        <text>Web</text>
+        <description>Browse the web</description>
+        <action>PLUGIN mythbrowser</action>
+        <depends>mythbrowser</depends>
+    </button>
+
+    <button>
+        <type>RECIPE</type>
+        <text>Recipes</text>
+        <description>Start cooking!</description>
+        <action>PLUGIN mythRecipe</action>
+        <depends>mythrecipe</depends>
+    </button>
+
+    <button>
+        <type>TV_STATUS</type>
+        <text>System Status</text>
+        <description>See what your system is doing</description>
+        <action>TV_STATUS</action>
+    </button>
+
+    <button>
+        <type>ZONEMINDER</type>
+        <text>ZoneMinder</text>
+        <description>Home surveillance</description>
+        <action>PLUGIN mythzoneminder</action>
+        <depends>mythzoneminder</depends>
+ </button>
+
+<!-- 
+ <button>
+        <type>SMOLT</type>
+        <text>Hardware profile</text>
+        <description>Tell us what hardware you have so we can support it</description>
+        <action>PLUGIN mythsmolt</action>
+        <depends>mythsmolt</depends>
+ </button>
+ -->
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/is.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/is.xml
new file mode 100644
index 0000000..88b7e6b
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/is.xml
@@ -0,0 +1,3 @@
+<mythmenu name="Internet Steams">
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/library.xml.patch b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/library.xml.patch
new file mode 100644
index 0000000..8f80928
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/library.xml.patch
@@ -0,0 +1,26 @@
+--- themes/defaultmenu/library.xml.orig	2012-06-10 08:02:54.000000000 +0000
++++ themes/defaultmenu/library.xml	2012-06-10 08:03:38.000000000 +0000
+@@ -40,6 +40,13 @@
+     </button>
+ 
+     <button>
++        <type>STREAM</type>
++        <text>Online Content</text>
++        <description>Play content from online sources</description>
++        <action>MENU gen_is.xml</action>
++    </button>
++
++    <button>
+         <type>IMAGES</type>
+         <text>Image Gallery</text>
+         <description>Look at Pictures</description>
+@@ -51,8 +58,7 @@
+         <type>GAME</type>
+         <text>Play Games</text>
+         <description>Play video games</description>
+-        <action>PLUGIN mythgame</action>
+-        <depends>mythgame</depends>
++        <action>MENU game.xml</action>
+     </button>
+ 
+ </mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/linhes.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/linhes.xml
new file mode 100644
index 0000000..342766d
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/linhes.xml
@@ -0,0 +1,60 @@
+<mythmenu name="LinHES">
+
+    <button>
+        <type>SETUP_GENERAL</type>
+        <text>MythTV Configuration</text>
+        <text lang="IT">Impostazioni</text>
+        <text lang="ES">Configuración</text>
+        <text lang="DE">Zubehör / Konfiguration</text>
+        <text lang="DA">Tilbehør/Indstillinger</text>
+        <text lang="IS">Uppsetning</text>
+        <text lang="NL">Configuratie</text>
+        <text lang="PT">Utensílios</text>
+        <text lang="SV">Verktyg / Inställningar</text>
+        <text lang="JA">設�~Z</text>
+        <text lang="FI">Oheis/Asetukset</text>
+        <text lang="ZH_TW">工�~E�/設�~Z</text>
+        <text lang="SL">Nastavitve</text>
+        <text lang="ET">Utiliidid / sätted</text>
+        <text lang="RU">У�~Bили�~B�~K / �~]а�~A�~B�~@ойки</text>
+        <text lang="AR">تضب�~Jطات</text>
+        <text lang="PL">Narz�~Ydzia / ustawienia</text>
+        <text lang="HE">ע�~Vר�~Y�~] / �~T�~R�~Sר�~Uת</text>
+        <text lang="HU">Eszközök / Beállítások</text>
+        <alttext lang="DE">Verschiedenes</alttext>
+        <alttext lang="SV">Inställningar</alttext>
+        <alttext lang="ET">Sätted</alttext>
+        <alttext lang="RU">�~]а�~A�~B�~@ойки</alttext>
+        <alttext lang="AR">تضب�~Jطات</alttext>
+        <description>Configure MythTV and plugins</description>
+        <description lang="DE">MythTV und Plugins konfigurieren</description>
+        <action>MENU util_menu.xml</action>
+    </button>
+
+   <button>
+     <type>LINHES_SETUP</type>
+     <text>LinHES Configuration</text>
+     <description>Configure LinHES</description>
+     <action>MENU HOST_SETTINGS.xml</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>Backup LinHES</text>
+     <action>MENU mythbackup.xml</action>
+   </button>
+
+   <button>
+     <type>RESTORE</type>
+     <text>Restore LinHES</text>
+     <action>MENU mythrestore.xml</action>
+   </button>
+
+<!--#Check for updates-->
+   <button>
+     <type>UPGRADE</type>
+     <text>Update LinHES</text>
+     <action>MENU update.xml</action>
+   </button>
+<!--#Check for updates-->
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mainmenu.xml.patch b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mainmenu.xml.patch
new file mode 100644
index 0000000..73a8940
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mainmenu.xml.patch
@@ -0,0 +1,37 @@
+--- themes/defaultmenu/mainmenu.xml.orig	2012-07-29 21:39:46.000000000 +0000
++++ themes/defaultmenu/mainmenu.xml	2012-07-29 21:41:50.000000000 +0000
+@@ -1,5 +1,11 @@
+ <?xml version="1.0" encoding="UTF-8" ?>
+ <mythmenu name="MAIN">
++    <button>
++        <type>TV_WATCH_TV</type>
++        <text>Watch TV</text>
++        <description>Watch live television</description>
++        <action>TV_WATCH_LIVE</action>
++    </button>
+ 
+     <button>
+         <type>MENU_MEDIA_LIBRARY</type>
+@@ -30,18 +36,11 @@
+     </button>
+ 
+     <button>
+-        <type>TV_WATCH_TV</type>
+-        <text>Watch TV</text>
+-        <description>Watch live television</description>
+-        <action>TV_WATCH_LIVE</action>
+-    </button>
+-
+-    <button>
+         <type>MENU_UTILITIES_SETUP</type>
+-        <text>Setup</text>
+-        <description>Configure MythTV and plugins</description>
+-        <action>MENU main_settings.xml</action>
+-        <password>SetupPinCode</password>
++        <text>Service Menu</text>
++        <description>Configure your system</description>
++	<action>MENU linhes.xml</action>
++	<password>SetupPinCode</password>
+     </button>
+ 
+ </mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythbackup.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythbackup.xml
new file mode 100644
index 0000000..7890d88
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythbackup.xml
@@ -0,0 +1,20 @@
+<mythmenu name="LinHES">
+   <button>
+     <type>BACKUP</type>
+     <text>Do you wish to backup?</text>
+     <description></description>
+     <action>NONE</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>Yes</text>
+     <action>EXEC sudo /usr/LH/bin/lh_system_backup &amp;</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>No</text>
+     <action>UPMENU</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythrestore.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythrestore.xml
new file mode 100644
index 0000000..161f13f
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/mythrestore.xml
@@ -0,0 +1,21 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>RESTORE</type>
+     <text>Do you wish to restore?</text>
+     <description>This will restore from most recent backup.</description>
+     <action>NONE</action>
+   </button>
+
+   <button>
+     <type>RESTORE</type>
+     <text>Yes</text>
+     <action>EXEC sudo /usr/LH/bin/lh_system_restore &amp;</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>No</text>
+     <action>UPMENU</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/optical_menu.xml.patch b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/optical_menu.xml.patch
new file mode 100644
index 0000000..b836e85
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/optical_menu.xml.patch
@@ -0,0 +1,23 @@
+--- themes/defaultmenu/optical_menu.xml.orig	2012-05-02 18:41:38.000000000 +0000
++++ themes/defaultmenu/optical_menu.xml	2012-07-30 05:33:03.000000000 +0000
+@@ -17,6 +17,20 @@
+     </button>
+ 
+     <button>
++        <type>DVD_RIP</type>
++        <text>Backup DVD</text>
++       <description>Backup your DVDs</description>
++        <action>MENU dvd_backup.xml</action>
++    </button>
++
++    <button>
++        <type>DVD_RIP</type>
++        <text>Import Files from DVD</text>
++       <description>Import all files from a data DVD</description>
++        <action>EXEC /usr/LH/bin/importfiles.sh &amp;</action>
++    </button>
++
++    <button>
+         <type>MUSIC_RIP</type>
+         <text>Import CD</text>
+         <description>Import music from an audio CD</description>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/original/create_patch.sh b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/original/create_patch.sh
new file mode 100644
index 0000000..34d8b8c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/original/create_patch.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+for i in *.xml
+do
+	diff -u $i.orig $i > ../$i.patch
+done
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/siriusmenu.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/siriusmenu.xml
new file mode 100644
index 0000000..e317b36
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/siriusmenu.xml
@@ -0,0 +1,419 @@
+<mythmenu name="SIRIUS">
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Hits 1</text>
+      <action>EXEC /usr/bin/cliSipie siriushits1</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>StarLite</text>
+      <action>EXEC /usr/bin/cliSipie starlite</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Love</text>
+      <action>EXEC /usr/bin/cliSipie siriuslove</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Movin EZ</text>
+      <action>EXEC /usr/bin/cliSipie movineasy</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Gold</text>
+      <action>EXEC /usr/bin/cliSipie siriusgold</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>'60s Vibrations</text>
+      <action>EXEC /usr/bin/cliSipie 60svibrations</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Totally '70s</text>
+      <action>EXEC /usr/bin/cliSipie totally70s</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Big '80s</text>
+      <action>EXEC /usr/bin/cliSipie big80s</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>ThePulse</text>
+      <action>EXEC /usr/bin/cliSipie thepulse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Bridge</text>
+      <action>EXEC /usr/bin/cliSipie thebridge</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BBC Radio 1</text>
+      <action>EXEC /usr/bin/cliSipie bbcradio1</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Super Shuffle</text>
+      <action>EXEC /usr/bin/cliSipie supershuffle</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Elvis Radio</text>
+      <action>EXEC /usr/bin/cliSipie elvisradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Classic Vinyl</text>
+      <action>EXEC /usr/bin/cliSipie classicvinyl</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Classic Rewind</text>
+      <action>EXEC /usr/bin/cliSipie classicrewind</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>TheVault</text>
+      <action>EXEC /usr/bin/cliSipie thevault</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Jam_ON</text>
+      <action>EXEC /usr/bin/cliSipie jamon</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spectrum</text>
+      <action>EXEC /usr/bin/cliSipie thespectrum</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BuzzSaw</text>
+      <action>EXEC /usr/bin/cliSipie buzzsaw</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Octane</text>
+      <action>EXEC /usr/bin/cliSipie octane</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Alt Nation</text>
+      <action>EXEC /usr/bin/cliSipie altnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>1st Wave</text>
+      <action>EXEC /usr/bin/cliSipie firstwave</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hair Nation</text>
+      <action>EXEC /usr/bin/cliSipie hairnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>'90s Alternative</text>
+      <action>EXEC /usr/bin/cliSipie 90salternative</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Garage</text>
+      <action>EXEC /usr/bin/cliSipie undergroundgarage</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Left of Center</text>
+      <action>EXEC /usr/bin/cliSipie leftofcenter</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hard Attack</text>
+      <action>EXEC /usr/bin/cliSipie hardattack</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Faction</text>
+      <action>EXEC /usr/bin/cliSipie faction</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Punk</text>
+      <action>EXEC /usr/bin/cliSipie punk</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>The Coffee House</text>
+      <action>EXEC /usr/bin/cliSipie coffeehouse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Margaritaville</text>
+      <action>EXEC /usr/bin/cliSipie radiomargaritaville</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Disorder</text>
+      <action>EXEC /usr/bin/cliSipie siriusdisorder</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Reggae</text>
+      <action>EXEC /usr/bin/cliSipie reggaerhythms</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Area 33</text>
+      <action>EXEC /usr/bin/cliSipie area33</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Boombox</text>
+      <action>EXEC /usr/bin/cliSipie boombox</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Chill</text>
+      <action>EXEC /usr/bin/cliSipie chill</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>The Beat</text>
+      <action>EXEC /usr/bin/cliSipie thebeat</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Strobe</text>
+      <action>EXEC /usr/bin/cliSipie thestrobe</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hip-Hop Nation</text>
+      <action>EXEC /usr/bin/cliSipie hiphopnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BackSpin</text>
+      <action>EXEC /usr/bin/cliSipie backspin</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Shade 45</text>
+      <action>EXEC /usr/bin/cliSipie shade45</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hot Jamz</text>
+      <action>EXEC /usr/bin/cliSipie hotjamz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Heart  &amp; Soul</text>
+      <action>EXEC /usr/bin/cliSipie heartandsoul</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>SoulTown</text>
+      <action>EXEC /usr/bin/cliSipie soultown</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>New Country</text>
+      <action>EXEC /usr/bin/cliSipie newcountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Prime Country</text>
+      <action>EXEC /usr/bin/cliSipie primecountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Roadhouse</text>
+      <action>EXEC /usr/bin/cliSipie theroadhouse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Outlaw Country</text>
+      <action>EXEC /usr/bin/cliSipie outlawcountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Bluegrass</text>
+      <action>EXEC /usr/bin/cliSipie bluegrass</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spirit</text>
+      <action>EXEC /usr/bin/cliSipie spirit</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Praise</text>
+      <action>EXEC /usr/bin/cliSipie praise</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Planet Jazz</text>
+      <action>EXEC /usr/bin/cliSipie planetjazz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>JazzCafe</text>
+      <action>EXEC /usr/bin/cliSipie jazzcafe</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>PureJazz</text>
+      <action>EXEC /usr/bin/cliSipie purejazz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spa 73</text>
+      <action>EXEC /usr/bin/cliSipie spa73</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Blues</text>
+      <action>EXEC /usr/bin/cliSipie siriusblues</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Siriusly Sinatra</text>
+      <action>EXEC /usr/bin/cliSipie siriuslysinatra</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Broadway's Best</text>
+      <action>EXEC /usr/bin/cliSipie broadwaysbest</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Symphony Hall</text>
+      <action>EXEC /usr/bin/cliSipie symphonyhall</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Met Opera Radio</text>
+      <action>EXEC /usr/bin/cliSipie metropolitanopera</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Pops</text>
+      <action>EXEC /usr/bin/cliSipie siriuspops</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Universo Latino</text>
+      <action>EXEC /usr/bin/cliSipie universolatino</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Rumbon</text>
+      <action>EXEC /usr/bin/cliSipie rumbon</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Martha Stewart</text>
+      <action>EXEC /usr/bin/cliSipie marthastewartlivingradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Stars</text>
+      <action>EXEC /usr/bin/cliSipie siriusstars</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>OutQ Gay Radio</text>
+      <action>EXEC /usr/bin/cliSipie siriusoutq</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Patriot</text>
+      <action>EXEC /usr/bin/cliSipie siriuspatriot</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Left</text>
+      <action>EXEC /usr/bin/cliSipie siriusleft</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>CNN</text>
+      <action>EXEC /usr/bin/cliSipie cnn</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>wrn</text>
+      <action>EXEC /usr/bin/cliSipie wrn</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Blue Collar Comedy</text>
+      <action>EXEC /usr/bin/cliSipie bluecollarcomedy</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Raw Dog Comedy</text>
+      <action>EXEC /usr/bin/cliSipie rawdog</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Laugh Break Comedy</text>
+      <action>EXEC /usr/bin/cliSipie laughbreak</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>thefoxxhole</text>
+      <action>EXEC /usr/bin/cliSipie thefoxxhole</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>lime</text>
+      <action>EXEC /usr/bin/cliSipie lime</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Kids Stuff</text>
+      <action>EXEC /usr/bin/cliSipie kidsstuff</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Catholic Channel</text>
+      <action>EXEC /usr/bin/cliSipie thecatholicchannel</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>EWTN</text>
+      <action>EXEC /usr/bin/cliSipie ewtnglobal</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>christiantalk</text>
+      <action>EXEC /usr/bin/cliSipie christiantalk</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius NFL Radio</text>
+      <action>EXEC /usr/bin/cliSipie siriusnflradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Maxim Radio</text>
+      <action>EXEC /usr/bin/cliSipie maximradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Cosmo Radio</text>
+      <action>EXEC /usr/bin/cliSipie cosmopolitanradio</action>
+   </button>
+   <button>
+     <type>TV_DELETE</type>
+     <text>Stop Listening</text>
+     <action>EXEC /usr/bin/sipie_kill</action>
+  </button>
+
+</mythmenu>
+
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update.xml
new file mode 100644
index 0000000..d2ac3fe
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update.xml
@@ -0,0 +1,9 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Check for Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update.sh</action>
+   </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update2.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update2.xml
new file mode 100644
index 0000000..64388cb
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/update2.xml
@@ -0,0 +1,20 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Install Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update2.sh install</action>
+   </button>
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Cancel Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update2.sh</action>
+   </button>
+
+   <button>
+     <type>UPGRADE</type>
+     <text>View Updates</text>
+     <action>MENU update3.xml</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/menu-xml/xmmenu.xml b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/xmmenu.xml
new file mode 100644
index 0000000..6b26d11
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/menu-xml/xmmenu.xml
@@ -0,0 +1,574 @@
+<!-- Current as of April 25, 2007 -->
+<mythmenu name="XM">
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '40s</text>
+		<action>EXEC /usr/bin/xamp kill 4</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '50s</text>
+		<action>EXEC /usr/bin/xamp kill 5</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '60s</text>
+		<action>EXEC /usr/bin/xamp kill 6</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '70s</text>
+		<action>EXEC /usr/bin/xamp kill 7</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '80s</text>
+		<action>EXEC /usr/bin/xamp kill 8</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '90s</text>
+		<action>EXEC /usr/bin/xamp kill 9</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>America</text>
+		<action>EXEC /usr/bin/xamp kill 10</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>X Country</text>
+		<action>EXEC /usr/bin/xamp kill 12</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Willie's Place</text>
+		<action>EXEC /usr/bin/xamp kill 13</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bluegrass Junction</text>
+		<action>EXEC /usr/bin/xamp kill 14</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Village</text>
+		<action>EXEC /usr/bin/xamp kill 15</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Highway 16</text>
+		<action>EXEC /usr/bin/xamp kill 16</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>US Country</text>
+		<action>EXEC /usr/bin/xamp kill 17</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>20 on 20</text>
+		<action>EXEC /usr/bin/xamp kill 20</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Heart</text>
+		<action>EXEC /usr/bin/xamp kill 23</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Blend</text>
+		<action>EXEC /usr/bin/xamp kill 25</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Flight 26</text>
+		<action>EXEC /usr/bin/xamp kill 26</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Cinemagic</text>
+		<action>EXEC /usr/bin/xamp kill 27</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>On Broadway</text>
+		<action>EXEC /usr/bin/xamp kill 28</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>U-Pop</text>
+		<action>EXEC /usr/bin/xamp kill 29</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Hitlist</text>
+		<action>EXEC /usr/bin/xamp kill 30</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Torch</text>
+		<action>EXEC /usr/bin/xamp kill 31</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Message</text>
+		<action>EXEC /usr/bin/xamp kill 32</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Spirit</text>
+		<action>EXEC /usr/bin/xamp kill 33</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>enLighten</text>
+		<action>EXEC /usr/bin/xamp kill 34</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Deep Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 40</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Boneyard</text>
+		<action>EXEC /usr/bin/xamp kill 41</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Liquid Metal</text>
+		<action>EXEC /usr/bin/xamp kill 42</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XMU</text>
+		<action>EXEC /usr/bin/xamp kill 43</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fred</text>
+		<action>EXEC /usr/bin/xamp kill 44</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Cafe</text>
+		<action>EXEC /usr/bin/xamp kill 45</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Top Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 46</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Ethel</text>
+		<action>EXEC /usr/bin/xamp kill 47</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Squizz</text>
+		<action>EXEC /usr/bin/xamp kill 48</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Big Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 49</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Loft</text>
+		<action>EXEC /usr/bin/xamp kill 50</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Music Lab</text>
+		<action>EXEC /usr/bin/xamp kill 51</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Verge</text>
+		<action>EXEC /usr/bin/xamp kill 52</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fungus</text>
+		<action>EXEC /usr/bin/xamp kill 53</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Lucy</text>
+		<action>EXEC /usr/bin/xamp kill 54</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Soul Street</text>
+		<action>EXEC /usr/bin/xamp kill 60</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Flow</text>
+		<action>EXEC /usr/bin/xamp kill 61</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Suite 62</text>
+		<action>EXEC /usr/bin/xamp kill 62</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Groove</text>
+		<action>EXEC /usr/bin/xamp kill 64</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Rhyme</text>
+		<action>EXEC /usr/bin/xamp kill 65</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>RAW</text>
+		<action>EXEC /usr/bin/xamp kill 66</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The City</text>
+		<action>EXEC /usr/bin/xamp kill 67</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Heat</text>
+		<action>EXEC /usr/bin/xamp kill 68</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Real Jazz</text>
+		<action>EXEC /usr/bin/xamp kill 70</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Watercolors</text>
+		<action>EXEC /usr/bin/xamp kill 71</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Beyond Jazz</text>
+		<action>EXEC /usr/bin/xamp kill 72</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>High Standards</text>
+		<action>EXEC /usr/bin/xamp kill 73</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bluesville</text>
+		<action>EXEC /usr/bin/xamp kill 74</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Hear Music</text>
+		<action>EXEC /usr/bin/xamp kill 75</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fine Tuning</text>
+		<action>EXEC /usr/bin/xamp kill 76</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Audio Visions</text>
+		<action>EXEC /usr/bin/xamp kill 77</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Escape</text>
+		<action>EXEC /usr/bin/xamp kill 78</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>On The Rocks</text>
+		<action>EXEC /usr/bin/xamp kill 79</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Move</text>
+		<action>EXEC /usr/bin/xamp kill 80</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>BPM</text>
+		<action>EXEC /usr/bin/xamp kill 81</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The System</text>
+		<action>EXEC /usr/bin/xamp kill 82</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Chrome</text>
+		<action>EXEC /usr/bin/xamp kill 83</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM-Chill</text>
+		<action>EXEC /usr/bin/xamp kill 84</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fuego</text>
+		<action>EXEC /usr/bin/xamp kill 90</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Viva</text>
+		<action>EXEC /usr/bin/xamp kill 91</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Aguila</text>
+		<action>EXEC /usr/bin/xamp kill 92</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Caliente</text>
+		<action>EXEC /usr/bin/xamp kill 94</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Luna</text>
+		<action>EXEC /usr/bin/xamp kill 95</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Air Musique</text>
+		<action>EXEC /usr/bin/xamp kill 100</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Joint</text>
+		<action>EXEC /usr/bin/xamp kill 101</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Sur La Route</text>
+		<action>EXEC /usr/bin/xamp kill 102</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>World Zone</text>
+		<action>EXEC /usr/bin/xamp kill 103</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Ngoma</text>
+		<action>EXEC /usr/bin/xamp kill 104</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Classics</text>
+		<action>EXEC /usr/bin/xamp kill 110</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Vox</text>
+		<action>EXEC /usr/bin/xamp kill 112</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Pops</text>
+		<action>EXEC /usr/bin/xamp kill 113</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Kids</text>
+		<action>EXEC /usr/bin/xamp kill 116</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bob Edwards Show</text>
+		<action>EXEC /usr/bin/xamp kill 133</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Comedy</text>
+		<action>EXEC /usr/bin/xamp kill 150</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Laugh USA</text>
+		<action>EXEC /usr/bin/xamp kill 151</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Special X</text>
+		<action>EXEC /usr/bin/xamp kill 154</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Agenda</text>
+		<action>EXEC /usr/bin/xamp kill 134</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Oprah and Friends</text>
+		<action>EXEC /usr/bin/xamp kill 156</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Virus</text>
+		<action>EXEC /usr/bin/xamp kill 202</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>1 Hit Wonders</text>
+		<action>EXEC /usr/bin/xamp kill 300</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Metalcore</text>
+		<action>EXEC /usr/bin/xamp kill 301</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Indie First</text>
+		<action>EXEC /usr/bin/xamp kill 302</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Late Night Mix</text>
+		<action>EXEC /usr/bin/xamp kill 303</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Sessions@AOL</text>
+		<action>EXEC /usr/bin/xamp kill 304</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Shuffle</text>
+		<action>EXEC /usr/bin/xamp kill 305</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Rock First</text>
+		<action>EXEC /usr/bin/xamp kill 306</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Country First</text>
+		<action>EXEC /usr/bin/xamp kill 307</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Hip Hop First</text>
+		<action>EXEC /usr/bin/xamp kill 308</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Pop First</text>
+		<action>EXEC /usr/bin/xamp kill 309</action>
+	</button>
+
+	<button>
+		<type>TV_DELETE</type>
+		<text>Stop Listening</text>
+		<action>EXEC /usr/bin/xamp kill</action>
+	</button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.27/mythtv/myth_settings.patch b/abs/core/mythtv/stable-0.27/mythtv/myth_settings.patch
new file mode 100644
index 0000000..dd1de24
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/myth_settings.patch
@@ -0,0 +1,1980 @@
+commit 9b4205fa320c06afde8c6d866b854cb12d3ec99c
+Author: root <root@localhost.localdomain>
+Date:   Fri Sep 28 14:25:06 2012 -0500
+
+    new patch
+    
+    Signed-off-by: root <root@localhost.localdomain>
+
+diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp
+index 84cb01a..6e3c54a 100644
+--- a/mythtv/libs/libmythbase/mythcorecontext.cpp
++++ b/mythtv/libs/libmythbase/mythcorecontext.cpp
+@@ -1260,6 +1260,90 @@ void MythCoreContext::ResetLanguage(void)
+     d->language.clear();
+ }
+ 
++//JM ADDED
++void MythCoreContext::savesettings_togroup (QString src_hostname,
++                                            QString saved_settingsgroupname )
++{
++    return d->m_database->savesettings_togroup(src_hostname,
++                                               saved_settingsgroupname);
++}
++
++void MythCoreContext::deletesettings(QString delete_hostname,
++                                     QString saved_settingsgroupname)
++{
++    return d->m_database->deletesettings(delete_hostname,
++                                         saved_settingsgroupname);
++}
++
++QMap<QString,QStringList> MythCoreContext::list_settingsgroupname()
++{
++    return d->m_database->list_settingsgroupname();
++}
++
++QMap<QString,QStringList> MythCoreContext::diff_settingsgroupname(
++    QString diff_hostname1,
++    QString diff_hostname2,
++    QStringList table_list)
++{
++    return d->m_database->diff_settingsgroupname(diff_hostname1,
++                                                 diff_hostname2,
++                                                 table_list);
++}
++
++void MythCoreContext::clonesettings(QString src_hostname,
++                                    QString saved_settingsgroupname,
++                                    QStringList table_list,
++                                    bool is_full_clone,
++                                    QString dest_hostname)
++{
++    return d->m_database->clonesettings(src_hostname,
++                                        saved_settingsgroupname,
++                                        table_list,
++                                        is_full_clone,
++                                        dest_hostname);
++}
++
++void MythCoreContext::restoresettings(QString dest_hostname,
++                                      QString saved_settingsgroupname,
++                                      QStringList table_list )
++{
++    return d->m_database->restoresettings( dest_hostname,
++                                           saved_settingsgroupname,
++                                           table_list);
++}
++
++void MythCoreContext::change_hostname(QString old_hostname,
++                                      QString new_hostname)
++{
++    return d->m_database->change_hostname(old_hostname, new_hostname) ;
++}
++
++bool MythCoreContext::settings_check(QString src_hostname,
++                                     QString saved_settingsgroupname)
++{
++    return d->m_database->settings_check(src_hostname,saved_settingsgroupname);
++}
++
++void MythCoreContext::import_settings(QMap<QString,QString> vp_map,
++                                      QString table)
++{
++    return d->m_database->import_settings(vp_map, table);
++}
++
++
++QMap<QString, QMap<QString,QString> > MythCoreContext::export_settings(
++    QString src_hostname,
++    QString saved_settingsgroupname,
++    QStringList table_list, bool skip_host )
++{
++    return d->m_database->export_settings(src_hostname,
++                                          saved_settingsgroupname,
++                                          table_list , skip_host );
++}
++
++//END JM ADDED
++
++
+ void MythCoreContext::InitLocale(void )
+ {
+     if (!d->m_locale)
+diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h
+index 0917313..3f6d5f8 100644
+--- a/mythtv/libs/libmythbase/mythcorecontext.h
++++ b/mythtv/libs/libmythbase/mythcorecontext.h
+@@ -168,6 +168,40 @@ class MBASE_PUBLIC MythCoreContext : public MythObservable, public MythSocketCBs
+     QString GetLanguageAndVariant(void);
+     void ResetLanguage(void);
+ 
++    //JM ADDED
++    void savesettings_togroup(QString src_hostname,
++                              QString saved_settingsgroupname );
++
++    void deletesettings(QString delete_hostname,
++                        QString saved_settingsgroupname);
++
++    QMap<QString,QStringList> list_settingsgroupname();
++    QMap<QString,QStringList> diff_settingsgroupname(QString diff_hostname1,
++                                                     QString diff_hostname2,
++                                                     QStringList table_list);
++
++    void clonesettings(QString src_hostname,
++                       QString saved_settingsgroupname,
++                       QStringList table_list,
++                       bool is_full_clone=TRUE,
++                       QString dest_hostname="");
++
++    void restoresettings (QString dest_hostname,
++                          QString saved_settingsgroupname,
++                          QStringList table_list);
++
++    void change_hostname (QString old_hostname, QString new_hostname);
++
++    bool settings_check (QString src_hostname ,QString saved_settingsgroupname);
++    void import_settings(QMap<QString,QString> vp_map, QString table);
++
++    QMap<QString,QMap <QString,QString> > export_settings(
++                                             QString src_hostname,
++                                             QString saved_settingsgroupname,
++                                             QStringList table_list,
++                                             bool skip_host = FALSE );
++    //END JM ADDED
++
+   private:
+     MythCoreContextPrivate *d;
+ 
+diff --git a/mythtv/libs/libmythbase/mythdb.cpp b/mythtv/libs/libmythbase/mythdb.cpp
+index ea30783..e4c1781 100644
+--- a/mythtv/libs/libmythbase/mythdb.cpp
++++ b/mythtv/libs/libmythbase/mythdb.cpp
+@@ -774,7 +774,7 @@ void MythDB::OverrideSettingForSession(
+     QString mk = key.toLower(), mk2 = d->m_localhostname + ' ' + mk, mv = value;
+     if ("dbschemaver" == mk)
+     {
+-        LOG(VB_GENERAL, LOG_ERR, 
++        LOG(VB_GENERAL, LOG_ERR,
+             QString("ERROR: Refusing to allow override for '%1'.").arg(key));
+         return;
+     }
+@@ -1055,6 +1055,1015 @@ void MythDB::WriteDelayedSettings(void)
+     }
+ }
+ 
++//JM ADDED
++void MythDB::savesettings_togroup(QString src_hostname,
++                                  QString saved_settingsgroupname )
++{
++    LOG(VB_GENERAL, LOG_ERR, QString("Using hostname of : %1")
++                                    .arg(src_hostname));
++    LOG(VB_GENERAL, LOG_ERR, QString("Saving to group: %1")
++                                    .arg(saved_settingsgroupname));
++    if ( settings_check( src_hostname , "current" ) )
++    {
++        QStringList table_list;
++        QString hostname_clause;
++        table_list.append("settings");
++        table_list.append("keybindings");
++        table_list.append("jumppoints");
++        if ( src_hostname == "GLOBAL" )
++            hostname_clause = "hostname IS NULL";
++        else
++            hostname_clause ="hostname = :HOSTNAME";
++
++        foreach (QString table, table_list)
++        {
++            QString dest_tablename = table +"_" + saved_settingsgroupname ;
++            create_new_table(dest_tablename,table);
++
++            QString query_string;
++            // Remove old saved values
++            MSqlQuery query(MSqlQuery::InitCon());
++            query_string = QString("DELETE FROM %1 WHERE %2")
++                                   .arg(dest_tablename)
++                                   .arg(hostname_clause);
++
++            //query_string = QString("DELETE FROM %1 WHERE "
++            //                       "hostname = :HOSTNAME").arg(dest_tablename);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME" ,src_hostname);
++            query.exec();
++
++            //insert all new settings
++            query_string = QString("REPLACE INTO %1 "
++                                   "SELECT  * from %2 where %3")
++                                   .arg(dest_tablename)
++                                   .arg(table)
++                                   .arg(hostname_clause);
++//             query_string = QString("REPLACE INTO %1 "
++//                               "SELECT  * from %2 where  hostname = :HOSTNAME)")
++//                               .arg(dest_tablename)
++//                               .arg(table);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME",src_hostname);
++            query.exec();
++        }
++    }
++    else
++        LOG(VB_GENERAL| VB_STDIO|VB_FLUSH, LOG_ERR,
++            QString("Couldn't find settings for: %1 \n").arg(src_hostname));
++    return;
++
++};
++
++void MythDB::deletesettings(QString delete_hostname,
++                            QString saved_settingsgroupname)
++{
++    LOG(VB_GENERAL, LOG_ERR, QString("Using hostname of : %1")
++                                    .arg(delete_hostname));
++    LOG(VB_GENERAL, LOG_ERR, QString("Deleting: %1")
++                                    .arg(saved_settingsgroupname));
++    int tempItem;
++    QString src_tablename;
++    QStringList table_list;
++
++    table_list.append("settings");
++    table_list.append("keybindings");
++    table_list.append("jumppoints");
++    QString hostname_clause;
++    if ( delete_hostname == "GLOBAL" )
++        hostname_clause = "hostname IS NULL";
++    else
++        hostname_clause ="hostname = :HOSTNAME";
++
++    foreach (QString table, table_list)
++    {
++        src_tablename = find_group_table_name(table, saved_settingsgroupname);
++        MSqlQuery query(MSqlQuery::InitCon());
++        // Remove old saved values
++        if ( does_table_exist(src_tablename))
++        {
++            QString query_string = QString("DELETE from %1 "
++                                           "WHERE %2")
++                                           .arg(src_tablename)
++                                           .arg(hostname_clause);
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME" ,delete_hostname);
++            query.exec();
++
++            //check if ok to delete table
++            query_string = QString("SELECT count(*) from %1")
++                                   .arg(src_tablename);
++            query.prepare(query_string);
++            if (query.exec() && query.isActive() && query.size() > 0)
++            {
++                query.next();
++                tempItem = query.value(0).toInt();
++                if (  tempItem == 0 )
++                    drop_temp_table(src_tablename);
++            }
++        }
++        else
++            LOG(VB_GENERAL, LOG_ERR,
++                QString("Couldn't find table: %1").arg(src_tablename));
++    }
++    return;
++}; // end delete settings
++
++
++QMap<QString,QStringList> MythDB::list_settingsgroupname()
++{
++    //Returns a QMAP of  "settings_groups: hostname"
++    MSqlQuery query(MSqlQuery::InitCon());
++    MSqlQuery subquery(MSqlQuery::InitCon());
++    QString tempItem;
++    QString temp_hostnameItem;
++    QStringList hostname_list;
++    QMap<QString,QStringList> return_list;
++    QString full_table_name;
++    query.prepare( "show tables like \"settings%\" " );
++    if (query.exec() && query.isActive() && query.size() > 0)
++    {
++        while (query.next())
++        {
++            full_table_name = query.value(0).toString();
++            tempItem=query.value(0).toString().remove(QRegExp("settings_"));
++            if ( tempItem != "distro_default" )
++            {
++                //loop over tables looking for hostnames
++                QString query_string = QString("SELECT DISTINCT "
++                                               "hostname from %1")
++                                               .arg(full_table_name);
++                subquery.prepare(query_string);
++
++                if (subquery.exec() && subquery.isActive()
++                    && subquery.size() > 0)
++                {
++                    while (subquery.next())
++                    {
++                        temp_hostnameItem = subquery.value(0).toString();
++                        hostname_list.append(temp_hostnameItem);
++                    }
++                }
++                //Special case of naming for the settings table;
++                //This only affects output.
++                if ( tempItem  == "settings" )
++                    return_list["current"] = hostname_list;
++                else
++                    return_list[tempItem] = hostname_list;
++
++                //reset hostname_list for the next group
++                hostname_list = QStringList();
++            }
++        }
++    }
++    return return_list;
++}; // end list_settingsgroupname
++
++QMap<QString,QStringList> MythDB::diff_settingsgroupname(
++            QString diff_hostname1 ,
++            QString diff_hostname2,
++            QStringList table_list  )
++{
++   // Returns a QMAP of tablename : diff results
++    LOG(VB_GENERAL, LOG_ERR, QString("Comparing settings for:"));
++    LOG(VB_GENERAL, LOG_ERR, QString("host 1: %1").arg(diff_hostname1));
++    LOG(VB_GENERAL, LOG_ERR, QString("host 2: %1").arg(diff_hostname2));
++
++    QString qstr;
++    QString tempItem;
++    QString tempString;
++
++    QStringList diff_list;
++    QStringList settings_list;
++    QStringList keybinding_list;
++
++    QMap<QString,QStringList> return_list;
++    if ( table_list.isEmpty() )
++    {
++        table_list.append("settings");
++        table_list.append("keybindings");
++    }
++
++    MSqlQuery query(MSqlQuery::InitCon());
++    foreach (QString table, table_list)
++    {
++        if ( table == "settings")
++        {
++
++            qstr= "SELECT  distinct settings.value, :DIFF_HOSTNAME1 AS `hostname`, settings_a.data, :DIFF_HOSTNAME2 AS `hostname`"
++                  " , settings_b.data FROM settings LEFT JOIN settings AS settings_a ON settings_a.value = settings.value AND settings_a.hostname = :DIFF_HOSTNAME1"
++                  " LEFT JOIN settings AS settings_b ON settings_b.value = settings.value AND settings_b.hostname = :DIFF_HOSTNAME2"
++                  " WHERE settings_a.data != settings_b.data OR "
++                  " (settings_a.data IS NULL AND settings_b.data IS NOT NULL) OR (settings_a.data IS NOT NULL AND settings_b.data IS NULL);";
++
++            query.prepare(qstr);
++            query.bindValue(":DIFF_HOSTNAME1" , diff_hostname1);
++            query.bindValue(":DIFF_HOSTNAME2" , diff_hostname2);
++
++            if (query.exec() && query.isActive() && query.size() > 0)
++            {
++                while (query.next())
++                {
++                    tempString="";
++                    //value
++                    tempItem = query.value(0).toString();
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //hostname_1
++                    tempItem = query.value(1).toString();
++                    if (tempItem.isEmpty())
++                        tempItem=diff_hostname1;
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //data
++                    tempItem = query.value(2).toString();
++                    if (tempItem.isEmpty())
++                        tempItem="NULL";
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //hostname_2
++                    tempItem = query.value(3).toString();
++                    if (tempItem.isEmpty())
++                        tempItem=diff_hostname2;
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //data
++                    tempItem = query.value(4).toString();
++                    if (tempItem.isEmpty())
++                        tempItem="NULL";
++                    tempString.append(tempItem);
++
++                    settings_list.append(tempString);
++                }
++                return_list["Settings"] = settings_list;
++            }
++        }
++        else if ( table == "keybindings")
++        {
++
++            qstr="SELECT distinct  keybindings.context, keybindings.action, :DIFF_HOSTNAME1 AS `hostname`, keybindings_a.keylist, :DIFF_HOSTNAME2 AS `hostname`, keybindings_b.keylist FROM keybindings "
++                 " LEFT JOIN keybindings AS keybindings_a ON keybindings_a.context = keybindings.context AND keybindings_a.action = keybindings.action "
++                 " AND keybindings_a.hostname = :DIFF_HOSTNAME1 "
++                 " LEFT JOIN keybindings AS keybindings_b ON keybindings_b.context = keybindings.context "
++                 " AND keybindings_b.action = keybindings.action AND keybindings_b.hostname = :DIFF_HOSTNAME2 "
++                 " WHERE keybindings_a.keylist != keybindings_b.keylist OR "
++                 " (keybindings_a.keylist IS NULL AND keybindings_b.keylist IS NOT NULL) OR (keybindings_a.keylist IS NOT NULL AND keybindings_b.keylist IS NULL);";
++            query.prepare(qstr);
++            query.bindValue(":DIFF_HOSTNAME1" , diff_hostname1);
++            query.bindValue(":DIFF_HOSTNAME2" , diff_hostname2);
++
++            if (query.exec() && query.isActive() && query.size() > 0)
++            {
++                while (query.next())
++                {
++                    tempString="";
++                    //context
++                    tempItem = query.value(0).toString();
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //action
++                    tempItem = query.value(1).toString();
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //hostname
++                    tempItem = query.value(2).toString();
++                    if (tempItem.isEmpty())
++                        tempItem=diff_hostname1;
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //keylist
++                    tempItem = query.value(3).toString();
++                    if (tempItem.isEmpty())
++                        tempItem="NULL";
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //hostname
++                    tempItem = query.value(4).toString();
++                    if (tempItem.isEmpty())
++                        tempItem=diff_hostname2;
++                    tempString.append(tempItem);
++                    tempString.append("|");
++
++                    //keylist
++                    tempItem = query.value(5).toString();
++                    if (tempItem.isEmpty())
++                       tempItem="NULL";
++                    tempString.append(tempItem);
++                    keybinding_list.append(tempString);
++                }
++                return_list["Keybindings"] = keybinding_list;
++            }
++        }
++
++    }
++    return return_list;
++}; //end diff_settingsgroupname
++
++void MythDB::clonesettings(QString src_hostname,
++                           QString saved_settingsgroupname,
++                           QStringList table_list,
++                           bool is_full_clone, QString dest_hostname)
++{
++    LOG(VB_GENERAL, LOG_ERR, QString("Using src hostname of : %1")
++                                     .arg(src_hostname));
++    LOG(VB_GENERAL, LOG_ERR, QString("Using dest hostname of : %1")
++                                     .arg(dest_hostname));
++    LOG(VB_GENERAL, LOG_ERR, QString("Cloning setting group: %1")
++                                     .arg(saved_settingsgroupname));
++    LOG(VB_GENERAL, LOG_ERR, QString("Full Copy : %1")
++                                     .arg(is_full_clone));
++
++    MSqlQuery query(MSqlQuery::InitCon());
++    QStringList::Iterator it;
++    QString current_table;
++    QString dest_tablename;
++    QString temptable;
++
++    if ( table_list.isEmpty() )
++    {
++        table_list.append("settings");
++        table_list.append("keybindings");
++        table_list.append("jumppoints");
++    }
++
++    for ( it = table_list.begin(); it != table_list.end(); ++it )
++    {
++        current_table = *it ;
++        dest_tablename = find_group_table_name(current_table,
++                                               saved_settingsgroupname);
++
++        if ( does_table_exist(dest_tablename))
++        {
++            // create temp table for merging settings
++            temptable="temp_table_" + dest_tablename;
++            create_temp_table(temptable, current_table );
++
++            // copy in stored settings
++            QString query_string = QString("REPLACE INTO %1 "
++                             "(SELECT  * from %2 where  hostname = :HOSTNAME)")
++                             .arg(temptable)
++                             .arg(dest_tablename);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME",src_hostname );
++            query.exec();
++
++            // update hostname for dest_hostname
++            query_string = QString("UPDATE   %1 set hostname = :HOSTNAME")
++                                   .arg(temptable);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME" , dest_hostname );
++            query.exec();
++
++            //if not full clone remove HOST% settings from temp table;
++            if ( current_table == "settings" && !is_full_clone)
++            {
++                query_string = QString("DELETE FROM %1 WHERE "
++                                 "hostname=:HOSTNAME and value like 'HOST%' " )
++                                 .arg(temptable);
++
++                query.prepare(query_string);
++                query.bindValue( ":HOSTNAME" ,   dest_hostname  );
++                query.exec();
++            }
++
++            //remove current settings from dest table,
++            //if not full clone, then leave HOST%
++            //Need to remove because the old table allows for duplicates
++
++            if ( current_table == "settings" && !is_full_clone)
++                query_string = QString ("DELETE FROM %1 WHERE "
++                                        "hostname = :HOSTNAME "
++                                        "and value not like 'HOST%'")
++                                        .arg(dest_tablename);
++
++            else
++                query_string = QString ("DELETE FROM %1 WHERE "
++                                        "hostname = :HOSTNAME ")
++                                        .arg(dest_tablename);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME",dest_hostname);
++            query.exec();
++
++            // copy new settings from temp to current
++            query_string = QString("REPLACE INTO %1 "
++                                   "(SELECT  * from %2)")
++                                   .arg(dest_tablename)
++                                   .arg(temptable);
++
++            query.prepare(query_string);
++            query.exec();
++
++            // drop temptable
++            drop_temp_table(temptable);
++        }
++        else
++            LOG(VB_GENERAL, LOG_NOTICE, QString("Couldn't find table: %1")
++                                                .arg(dest_tablename));
++    }
++}; //end clonesettings
++
++void MythDB::restoresettings (QString dest_hostname,
++                              QString saved_settingsgroupname,
++                              QStringList table_list )
++{
++    LOG(VB_GENERAL, LOG_NOTICE, QString("Restoring Settings:"));
++    LOG(VB_GENERAL, LOG_NOTICE, QString("    src: %1")
++                                        .arg(saved_settingsgroupname));
++    LOG(VB_GENERAL, LOG_NOTICE, QString("    dest:%1")
++                                        .arg(dest_hostname));
++
++    QString hostname_clause;
++    if ( dest_hostname == "GLOBAL" )
++        hostname_clause = "hostname IS NULL";
++    else
++        hostname_clause ="hostname = :HOSTNAME";
++
++    bool table_check;
++    if ( saved_settingsgroupname == "distro_default" )
++        table_check =  settings_check ( "distro_default" , saved_settingsgroupname );
++    else
++        table_check = settings_check ( dest_hostname , saved_settingsgroupname );
++
++
++    if ( table_check == TRUE )
++    {
++        MSqlQuery query(MSqlQuery::InitCon());
++        QStringList::Iterator it;
++        QString current_table;
++        if ( table_list.isEmpty() )
++        {
++            table_list.append("settings");
++            table_list.append("keybindings");
++            table_list.append("jumppoints");
++        }
++
++        for ( it = table_list.begin(); it != table_list.end(); ++it )
++        {
++            current_table = *it ;
++            //find tablenames to use
++            QString src_tablename = find_group_table_name(current_table,
++                                         saved_settingsgroupname);
++
++            QString temptable="temp_table_" + src_tablename;
++            if ( ! does_table_exist(src_tablename))
++            {
++                LOG(VB_GENERAL, LOG_NOTICE, QString("table does not exist: %1")
++                        .arg(src_tablename));
++                continue;
++            }
++            // create temp table for merging settings
++            create_temp_table(temptable, current_table );
++
++            //could copy in current settings here to account for new stuff
++
++
++
++            // copy in stored settings
++            QString query_string;
++            if ( saved_settingsgroupname == "distro_default" )
++            {  //special case for restoring default settings
++                query_string = QString("REPLACE INTO %1 "
++                    "(SELECT  * from %2 WHERE %3)")
++                    .arg(temptable)
++                    .arg(src_tablename)
++                    .arg(hostname_clause);
++
++                query.prepare(query_string);
++                query.bindValue(":HOSTNAME", "distro_default" );
++                query.exec();
++
++                // update hostname in temp table from distro_default
++                query_string = QString("UPDATE  %1 set hostname = :HOSTNAME")
++                                       .arg(temptable);
++
++                query.prepare(query_string);
++                query.bindValue(":HOSTNAME" , dest_hostname );
++                query.exec();
++
++            }
++            else
++            {   //normal use case
++                query_string = QString("REPLACE INTO %1 "
++                                "(SELECT  * from %2 WHERE %3)")
++                                .arg(temptable)
++                                .arg(src_tablename)
++                                .arg(hostname_clause);
++
++                query.prepare(query_string);
++                query.bindValue(":HOSTNAME",dest_hostname );
++                query.exec();
++            }
++
++            //Remove current settings.
++            //Need to remove because the old table allows for duplicates
++            query_string = QString("DELETE FROM %1 WHERE "
++                                   "%2")
++                                   .arg(current_table)
++                                   .arg(hostname_clause);
++
++            query.prepare(query_string);
++            query.bindValue(":HOSTNAME",dest_hostname);
++            query.exec();
++
++            // copy new settings from temp to current
++            query_string = QString("REPLACE INTO %1 "
++                                   "(SELECT  * from %2)")
++                                   .arg(current_table)
++                                   .arg(temptable);
++
++            query.prepare(query_string);
++            query.exec();
++            // drop temptable
++            drop_temp_table(temptable);
++        }
++    }
++}; //end restore settings
++
++void MythDB::change_hostname (QString old_hostname, QString new_hostname)
++{
++    LOG(VB_GENERAL, LOG_NOTICE, QString("Changing hostname from %1 -> %2")
++                                        .arg(old_hostname)
++                                        .arg(new_hostname));
++
++    MSqlQuery query(MSqlQuery::InitCon());
++    MSqlQuery sub_query(MSqlQuery::InitCon());
++    query.prepare( "SHOW TABLES" );
++
++    if (query.exec() && query.isActive() && query.size() > 0)
++    {
++        while (query.next())
++        {
++            QString table_name = query.value(0).toString();
++            LOG(VB_GENERAL, LOG_NOTICE, QString("Scanning  %1")
++                                                .arg(table_name));
++
++            // LOOP OVER TABLES, CHECK IF IT HAS A HOSTNAME FIELD
++            QString query_string=QString("SHOW COLUMNS from %1 "
++                                         "where field='hostname'")
++                                         .arg(table_name);
++            sub_query.prepare(query_string);
++
++            if (sub_query.exec() && sub_query.size() > 0)
++            {  //update hostname
++               LOG(VB_GENERAL, LOG_NOTICE, QString("  Updating hostname in: %1")
++                                                   .arg(table_name));
++               query_string = QString("UPDATE %1 SET hostname = :NEW_HOSTNAME "
++                               "WHERE hostname = :OLD_HOSTNAME")
++                               .arg(table_name);
++               sub_query.prepare(query_string);
++               sub_query.bindValue(":NEW_HOSTNAME" , new_hostname);
++               sub_query.bindValue(":OLD_HOSTNAME" , old_hostname);
++               sub_query.exec();
++            }
++        }
++    }
++
++
++
++
++
++
++}
++
++bool MythDB::settings_check(QString src_hostname,
++                            QString saved_settingsgroupname)
++{
++    int tempItem;
++    bool returncode = FALSE ;
++    QString table="settings";
++
++    QString tablename = find_group_table_name(table, saved_settingsgroupname);
++    QString hostname_clause;
++    if ( src_hostname == "GLOBAL" )
++        hostname_clause = "hostname IS NULL";
++    else
++        hostname_clause ="hostname = :HOSTNAME";
++
++    if (does_table_exist (tablename))
++    {
++        MSqlQuery query(MSqlQuery::InitCon());
++        QString query_string = QString("SELECT COUNT(data) from %1 "
++                                       "WHERE %2")
++                                       .arg(tablename)
++                                       .arg(hostname_clause);
++
++        query.prepare(query_string);
++        query.bindValue(":HOSTNAME" , src_hostname );
++
++        if (query.exec() && query.isActive() && query.size() > 0 )
++        {
++            while (query.next())
++            {
++                 tempItem = query.value(0).toInt();
++                 if (  tempItem >= 1 )
++                     returncode = TRUE;
++                 else
++                 {
++                     LOG(VB_GENERAL, LOG_NOTICE,
++                         QString("Group %1 does not contain"
++                                 " valid settings")
++                                 .arg(saved_settingsgroupname));
++                 }
++             }
++        }
++    }
++    else
++       LOG(VB_GENERAL, LOG_NOTICE, QString("Couldn't find table: %1")
++                                           .arg(tablename));
++    return returncode;
++}; // end settings_check
++
++void MythDB::import_settings(QMap<QString,QString> vp_map,
++                             QString table)
++{
++    MSqlQuery query(MSqlQuery::InitCon());
++
++    //IMPORT SETTINGS TABLE
++    if (table.startsWith("settings"))
++    {
++         if ( table != "settings" )
++             create_new_table(table,"settings");
++         QString hostname = vp_map.value("hostname");
++         QString value = vp_map.value("value");
++         QString data = vp_map.value("data");
++
++         QString hostname_clause;
++         QVariant import_hostname = QVariant(QVariant::String);
++
++         if ( hostname.isEmpty())
++             hostname_clause = "hostname IS NULL";
++         else
++         {
++             hostname_clause ="hostname = :HOSTNAME";
++             import_hostname = hostname;
++         }
++
++         QString query_string=QString("SELECT  value, data, hostname "
++                              "FROM %1 "
++                              "WHERE %2 AND value = :VALUE "
++                              "ORDER BY value")
++                              .arg(table)
++                              .arg(hostname_clause);
++
++         query.prepare(query_string);
++         query.bindValue(":HOSTNAME", hostname);
++         query.bindValue(":VALUE", value);
++
++         // if already exisiting records then update, otherwise insert
++         if (query.exec() && query.isActive())
++         {
++            MSqlQuery sub_query(MSqlQuery::InitCon());
++            if ( query.size() > 0 )
++            {
++                query_string = QString("UPDATE  "
++                    "%1 "
++                    "set data = :DATA "
++                    "WHERE %2 AND "
++                    "value = :VALUE ")
++                    .arg(table)
++                    .arg(hostname_clause);
++
++                sub_query.prepare(query_string);
++                sub_query.bindValue(":HOSTNAME", import_hostname);
++                sub_query.bindValue(":VALUE", value);
++                sub_query.bindValue(":DATA", data);
++                sub_query.exec();
++            }
++            else
++            {
++                 query_string = QString("INSERT INTO   "
++                    " %1 "
++                    "(value,data,hostname) "
++                    "VALUES ( :VALUE , :DATA , :HOSTNAME)").arg(table);
++
++                sub_query.prepare(query_string);
++                sub_query.bindValue(":HOSTNAME", import_hostname);
++                sub_query.bindValue(":VALUE", value);
++                sub_query.bindValue(":DATA", data);
++                sub_query.exec();
++            }
++        }
++    }
++    //KEYBINDINGS TABLE
++    else if (table.startsWith("keybindings"))
++    {
++       if ( table !=  "keybindings" )
++           create_new_table(table,"keybindings");
++       QString hostname = vp_map.value("hostname");
++       QString context = vp_map.value("context");
++       QString action = vp_map.value("action");
++       QString description = vp_map.value("description");
++       QString keylist = vp_map.value("keylist");
++
++       QString query_string=QString("SELECT  context,action,hostname "
++           "FROM %1 "
++           "WHERE hostname = :HOSTNAME AND "
++           "context = :CONTEXT "
++           "AND action = :ACTION ").arg(table);
++       query.prepare(query_string);
++       query.bindValue(":HOSTNAME", hostname);
++       query.bindValue(":CONTEXT", context);
++       query.bindValue(":ACTION", action);
++
++       if (query.exec() && query.isActive())
++       {
++           MSqlQuery sub_query(MSqlQuery::InitCon());
++           if ( query.size() > 0 )
++           {
++               query_string = QString("UPDATE  "
++               " %1 "
++               "set keylist = :KEYLIST "
++               "WHERE hostname = :HOSTNAME AND "
++               "context = :CONTEXT "
++               "AND action = :ACTION ").arg(table);
++
++               sub_query.prepare(query_string);
++               sub_query.bindValue(":HOSTNAME", hostname);
++               sub_query.bindValue(":KEYLIST", keylist);
++               sub_query.bindValue(":CONTEXT", context);
++               sub_query.bindValue(":ACTION", action);
++               sub_query.exec();
++           }
++           else
++           {
++               query_string = QString("INSERT INTO "
++               " %1 "
++               " (context , action , description , keylist , hostname) "
++               " VALUES( "
++               " :CONTEXT ,"
++               " :ACTION , "
++               " :DESCRIPTION , "
++               " :KEYLIST , "
++               " :HOSTNAME)").arg(table) ;
++
++               sub_query.prepare(query_string);
++               sub_query.bindValue(":HOSTNAME", hostname);
++               sub_query.bindValue(":KEYLIST", keylist);
++               sub_query.bindValue(":CONTEXT", context);
++               sub_query.bindValue(":ACTION", action);
++               sub_query.bindValue(":DESCRIPTION", description);
++               sub_query.exec();
++           }
++       }
++   }
++   //JUMP POINTS
++   else if (table.startsWith("jumppoints"))
++   {
++       if ( table != "jumppoints" )
++           create_new_table(table,"jumppoints");
++       QString hostname = vp_map.value("hostname");
++       QString description = vp_map.value("description");
++       QString destination = vp_map.value("destination");
++       QString keylist = vp_map.value("keylist");
++
++       QString query_string=QString("SELECT  destination, keylist  "
++        "FROM %1 "
++        "WHERE hostname = :HOSTNAME AND "
++        "destination = :DESTINATION "
++        "AND keylist = :KEYLIST ").arg(table);
++       query.prepare(query_string);
++       query.bindValue(":HOSTNAME", hostname);
++       query.bindValue(":DESTINATION", destination);
++       query.bindValue(":KEYLIST", keylist);
++
++       if (query.exec() && query.isActive())
++       {
++           MSqlQuery sub_query(MSqlQuery::InitCon());
++           if ( query.size() > 0 )
++           {
++               query_string = QString("UPDATE  "
++               " %1 "
++               "set keylist = :KEYLIST "
++               "WHERE hostname = :HOSTNAME AND "
++               "destination = :DESTINATION ").arg(table);
++
++               sub_query.prepare(query_string);
++               sub_query.bindValue(":HOSTNAME", hostname);
++               sub_query.bindValue(":KEYLIST", keylist);
++               sub_query.bindValue(":DESTINATION", destination);
++               sub_query.exec();
++           }
++           else
++           {
++               query_string = QString("INSERT INTO "
++               " %1 "
++               " (description , destination,  keylist , hostname) "
++               " VALUES( "
++               " :DESCRIPTION ,"
++               " :DESTINATION , "
++               " :KEYLIST , "
++               " :HOSTNAME)").arg(table) ;
++
++               sub_query.prepare(query_string);
++               sub_query.bindValue(":HOSTNAME", hostname);
++               sub_query.bindValue(":KEYLIST", keylist);
++               sub_query.bindValue(":DESTINATION", destination);
++               sub_query.bindValue(":DESCRIPTION", description);
++               sub_query.exec();
++           }
++       }
++   }
++}; //end import_settings
++
++QMap<QString, QMap<QString,QString> >
++            MythDB::export_settings(QString src_hostname,
++                                    QString saved_settingsgroupname,
++                                    QStringList table_list, bool skip_host )
++{
++    QMap<QString, QMap<QString,QString> >  result_set;
++    QStringList::Iterator it;
++    QString current_table;
++    int record_count = 0;
++
++    if ( table_list.isEmpty() )
++    {
++        table_list.append("settings");
++        table_list.append("keybindings");
++        table_list.append("jumppoints");
++    }
++
++    MSqlQuery query(MSqlQuery::InitCon());
++    QString query_string;
++
++    //loop over tablelist
++    for ( it = table_list.begin(); it != table_list.end(); ++it )
++    {
++        current_table = *it ;
++        QString sub_sql;
++        QStringList fields;
++        QString field_query;
++
++        QString table_name = find_group_table_name(current_table,
++                                                   saved_settingsgroupname);
++
++        QString hostname_clause;
++        if ( src_hostname == "GLOBAL" )
++            hostname_clause = "hostname IS NULL";
++        else
++            hostname_clause ="hostname = :HOSTNAME";
++
++        // find field names
++        query_string = QString("SHOW COLUMNS from %1").arg(table_name);
++        query.prepare(query_string);
++
++        //build up field name vars
++        if (query.exec() && query.isActive() && query.size() > 0)
++        {
++            while (query.next())
++            {
++                if (! field_query.isEmpty())
++                    field_query +=',';
++                QString tempItem = query.value(0).toString();
++                fields.append(tempItem);
++                field_query += tempItem;
++            }
++        }
++        // when working with settings table skip HOST if skip_host is true
++        if ( current_table == "settings" && skip_host == TRUE )
++        {
++            QString skip_host_clause;
++            skip_host_clause = " VALUE not like 'HOST%' AND DATA not like 'HardwareProfile%UUID'" ;
++            query_string = QString("SELECT %1 FROM %2 WHERE %3 AND %4")
++            .arg(field_query)
++            .arg(table_name)
++            .arg(hostname_clause)
++            .arg(skip_host_clause);
++
++        }
++        else
++        {
++            query_string = QString("SELECT %1 FROM %2 WHERE %3")
++                                .arg(field_query)
++                                .arg(table_name)
++                                .arg(hostname_clause);
++        }
++        query.prepare(query_string);
++        query.bindValue(":HOSTNAME" , src_hostname);
++
++        //looping over each record in the table query
++        if (query.exec() && query.isActive() && query.size() > 0)
++        {
++            while (query.next())
++            {
++                //construct qmap of elements
++                //add table name
++                QMap<QString,QString> value_pair;
++                value_pair["table"]=table_name;
++
++                for ( int i=0 ; i < fields.size();i++ )
++                {
++                    QString tempvalue = fields[i];
++                    QString tempItem = query.value(i).toString();
++                    value_pair[tempvalue]=tempItem;
++                }
++                result_set[QString(record_count)] = value_pair;
++                record_count++;
++            }
++        }
++
++    } // end table loop
++    return result_set;
++}; //end export_settings
++
++
++void MythDB::create_new_table (QString create_table_name,QString like_name)
++{
++    if ( ! does_table_exist(create_table_name))
++    {
++        MSqlQuery query(MSqlQuery::InitCon());
++        QString query_string = QString("CREATE TABLE %1 like %2")
++                                       .arg(create_table_name)
++                                       .arg(like_name);
++
++        query.prepare(query_string);
++        query.exec();
++    }
++    else
++        LOG(VB_GENERAL, LOG_NOTICE, QString("Table is already present,"
++                                            "will not create it: %1")
++                                            .arg(create_table_name));
++};
++
++
++void MythDB::drop_temp_table (QString table_name)
++{
++    MSqlQuery query(MSqlQuery::InitCon());
++    if (table_name == "settings" | table_name == "keybindings" | table_name == "jumppoints")
++        return;
++    QString query_string = QString("DROP TABLE %1").arg(table_name);
++    query.prepare(query_string);
++    query.exec();
++    return;
++}
++
++void MythDB::create_temp_table (QString create_table_name,QString like_name)
++{
++    MSqlQuery query(MSqlQuery::InitCon());
++    create_new_table(create_table_name,like_name);
++    QString query_string;
++    if ( like_name == "settings")
++    {
++         query_string = QString ("ALTER TABLE %1 ADD UNIQUE( value)")
++                                 .arg(create_table_name);
++         query.prepare(query_string);
++         query.exec();
++    }
++
++    query_string = QString("TRUNCATE %1").arg(create_table_name);
++    query.prepare(query_string);
++    query.exec();
++ return;
++}
++
++bool MythDB::does_table_exist(QString table_name)
++{
++    bool table_exist = FALSE;
++    QString full_table_name;
++    MSqlQuery query(MSqlQuery::InitCon());
++
++    query.prepare( "SHOW TABLES" );
++    if (query.exec() && query.isActive() && query.size() > 0)
++    {
++        while (query.next())
++        {
++            full_table_name = query.value(0).toString();
++            if (table_name == full_table_name)
++            {
++                table_exist = TRUE;
++                break;
++            }
++        }
++    }
++    return table_exist;
++};
++
++
++QString MythDB::find_group_table_name(QString current_table,
++                                      QString saved_settingsgroupname)
++{
++    QString table_name;
++    if ( saved_settingsgroupname.toLower() == "current" )
++        table_name =  current_table ;
++    else
++        table_name =  current_table + "_" + saved_settingsgroupname ;
++
++   return table_name;
++};
++//END JM ADDED
++
+ /**
+  *  \brief Set a flag indicating we have successfully connected to the database
+  */
+diff --git a/mythtv/libs/libmythbase/mythdb.h b/mythtv/libs/libmythbase/mythdb.h
+index 79abe56..fd6044e 100644
+--- a/mythtv/libs/libmythbase/mythdb.h
++++ b/mythtv/libs/libmythbase/mythdb.h
+@@ -75,6 +75,49 @@ class MBASE_PUBLIC MythDB
+ 
+     void WriteDelayedSettings(void);
+ 
++    //JM ADDED
++    void savesettings_togroup(QString src_hostname,
++                              QString saved_settingsgroupname );
++    void deletesettings(QString delete_hostname,
++                        QString saved_settingsgroupname);
++
++    QMap<QString,QStringList> list_settingsgroupname();
++
++    QMap<QString,QStringList> diff_settingsgroupname(QString diff_hostname1,
++                                                     QString diff_hostname2,
++                                                     QStringList table_list);
++
++    void clonesettings(QString src_hostname,
++                       QString saved_settingsgroupname,
++                       QStringList table_list,
++                       bool is_full_clone=TRUE,
++                       QString dest_hostname="");
++
++    void restoresettings (QString dest_hostname,
++                          QString saved_settingsgroupname,
++                          QStringList table_list);
++
++    void change_hostname (QString old_hostname, QString new_hostname);
++    bool settings_check (QString src_hostname, QString saved_settingsgroupname);
++    void import_settings(QMap<QString,QString> vp_map, QString table);
++
++
++    QMap<QString,QMap <QString,QString> > export_settings(
++                         QString src_hostname,
++                         QString saved_settingsgroupname,
++                         QStringList table_list,
++                         bool skip_host = FALSE);
++
++    void create_new_table (QString create_table_name,QString like_name);
++    void drop_temp_table (QString table_name);
++    void create_temp_table (QString create_table_name,QString like_name);
++    bool does_table_exist(QString table_name);
++    QString find_group_table_name(QString current_table,
++                                  QString saved_settingsgroupname);
++    //END JM ADDED
++
++
++
+     void SetHaveDBConnection(bool connected);
+     void SetHaveSchema(bool schema);
+     bool HaveSchema(void) const;
+diff --git a/mythtv/programs/mythutil/commandlineparser.cpp b/mythtv/programs/mythutil/commandlineparser.cpp
+index f4a6035..fdeeb8e 100644
+--- a/mythtv/programs/mythutil/commandlineparser.cpp
++++ b/mythtv/programs/mythutil/commandlineparser.cpp
+@@ -118,6 +118,37 @@ void MythUtilCommandLineParser::LoadArguments(void)
+         << add("--print-template", "printtemplate", false,
+                 "Print the template to be sent to the frontend", "")
+                 ->SetGroup("Messaging")
++
++        //settingsutil.cpp
++        << add("--save-settings", "savesettings", false,
++                "Save current settings", "")
++                ->SetGroup("Settings")
++        << add("--delete-settings", "deletesettings", false,
++                "Delete current settings", "")
++                ->SetGroup("Settings")
++        << add("--restore-settings", "restoresettings", false,
++                "Restore settings from previous backup", "")
++                ->SetGroup("Settings")
++        << add("--list-groups", "listgroups", false,
++                "List hosts and groups of settings", "")
++                ->SetGroup("Settings")
++        << add("--copy-settings", "copysettings", false,
++                "Copy or Clone settings from one host to another", "")
++                ->SetGroup("Settings")
++        << add("--diff-settings", "diffsettings", false,
++                "Show settings that are different between two hosts", "")
++                ->SetGroup("Settings")
++        << add("--change-hostname", "changehostname", false,
++                 "Change the hostname", "")
++                ->SetGroup("Settings")
++        << add("--import-settings", "importsettings", false,
++               "import settings", "")
++                ->SetRequiredChild("infile")
++
++        << add("--export-settings", "exportsettings", false,
++               "export settings", "")
++               ->SetRequiredChild("outfile")
++
+         );
+ 
+     // mpegutils.cpp
+@@ -140,6 +171,59 @@ void MythUtilCommandLineParser::LoadArguments(void)
+     add("--bcastaddr", "bcastaddr", "127.0.0.1", "(optional) IP address to send to", "")
+         ->SetChildOf("message");
+ 
++    //settingsutils.cpp
++    add("--groupname", "groupname", "", "Group of settings name", "")
++        ->SetRequiredChildOf("savesettings")
++        ->SetRequiredChildOf("restoresettings")
++        ->SetRequiredChildOf("deletesettings")
++        ->SetChildOf("copysettings");
++
++    add("--hostname", "hostname", "", "System name to save/restore settings", "")
++        ->SetChildOf("savesettings")
++        ->SetChildOf("restoresettings")
++        ->SetChildOf("copysettings")
++        ->SetChildOf("deletesettings")
++        ->SetChildOf("exportsettings")
++        ->SetChildOf("importsettings");
++
++    add("--host_1", "host_1", "", "First host in compare list", "")
++        ->SetRequiredChildOf("diffsettings");
++
++    add("--host_2", "host_2", "", "Second host in compare list", "")
++        ->SetRequiredChildOf("diffsettings");
++
++
++    add("--tablelist", "table_list", "", "List of tables to operate on "
++        "[keybindings,settings]", "")
++        ->SetChildOf("diffsettings")
++        ->SetChildOf("restoresettings")
++        ->SetChildOf("copysettings")
++        ->SetChildOf("exportsettings");
++
++    add("--clone", "fullclone", false, "Enable copy of all settings, "
++        "including those that are unique to each system.", "")
++        ->SetChildOf("copysettings");
++
++
++    add("--old-host", "oldhost", "", "Hostname to change", "")
++        ->SetRequiredChildOf("changehostname");
++
++    add("--new-host", "newhost", "", "New hostname", "")
++        ->SetRequiredChildOf("changehostname")
++        ->SetRequiredChildOf("copysettings");
++
++    add("--format", "format", false, "Format output of differences", "")
++        ->SetChildOf("diffsettings");
++    add("--distro-default", "distro-default", false, "Export settings for"
++        "import into the default table", "")
++        ->SetChildOf("exportsettings");
++    add("--generic", "generic", false, "export settings without saving "
++        "the hostname", "")
++        ->SetChildOf("exportsettings");
++
++
++
++
+     // Generic Options used by more than one utility
+     addRecording();
+     addInFile(true);
+diff --git a/mythtv/programs/mythutil/main.cpp b/mythtv/programs/mythutil/main.cpp
+index 418ea01..bd4a1f4 100644
+--- a/mythtv/programs/mythutil/main.cpp
++++ b/mythtv/programs/mythutil/main.cpp
+@@ -21,6 +21,7 @@
+ #include "jobutils.h"
+ #include "markuputils.h"
+ #include "messageutils.h"
++#include "settingsutils.h"
+ #include "signalhandling.h"
+ 
+ 
+@@ -105,6 +106,7 @@
+     registerJobUtils(utilMap);
+     registerMarkupUtils(utilMap);
+     registerMessageUtils(utilMap);
++    registerSettingsUtils(utilMap);
+ 
+     bool cmdFound = false;
+     int cmdResult = GENERIC_EXIT_OK;
+diff --git a/mythtv/programs/mythutil/mythutil.pro b/mythtv/programs/mythutil/mythutil.pro
+index 066e618..87d7952 100644
+--- a/mythtv/programs/mythutil/mythutil.pro
++++ b/mythtv/programs/mythutil/mythutil.pro
+@@ -10,7 +10,7 @@ TARGET = mythutil
+ target.path = $${PREFIX}/bin
+ INSTALLS = target
+ 
+-LIBS += $$EXTRA_LIBS 
++LIBS += $$EXTRA_LIBS
+ INCLUDEPATH += ../../libs/libmythbase
+ 
+ QMAKE_CLEAN += $(TARGET)
+@@ -19,8 +19,10 @@ QMAKE_CLEAN += $(TARGET)
+ HEADERS += mythutil.h commandlineparser.h
+ HEADERS += backendutils.h fileutils.h jobutils.h markuputils.h
+ HEADERS += messageutils.h mpegutils.h
++HEADERS += settingsutils.h
++
+ SOURCES += main.cpp mythutil.cpp commandlineparser.cpp
+ SOURCES += backendutils.cpp fileutils.cpp jobutils.cpp markuputils.cpp
+ SOURCES += messageutils.cpp mpegutils.cpp
+-
++SOURCES += settingsutils.cpp
+ mingw: LIBS += -lwinmm -lws2_32
+diff --git a/mythtv/programs/mythutil/settingsutils.cpp b/mythtv/programs/mythutil/settingsutils.cpp
+new file mode 100644
+index 0000000..8fc7b0e
+--- /dev/null
++++ b/mythtv/programs/mythutil/settingsutils.cpp
+@@ -0,0 +1,586 @@
++// C++ includes
++#include <iostream>
++
++//QT includes
++#include <qdom.h>
++#include <QFile>
++#include <QDomElement>
++
++// libmyth* includes
++#include "compat.h"
++#include "exitcodes.h"
++#include "mythlogging.h"
++#include "mythcontext.h"
++
++
++#include "settingsutils.h"
++
++
++static int SaveSettings(const MythUtilCommandLineParser &cmdline)
++{
++    QString src_hostname;
++    QString groupname;
++
++    if (cmdline.toBool("groupname"))
++        groupname = cmdline.toString("groupname");
++
++    if (cmdline.toBool("hostname"))
++        src_hostname = cmdline.toString("hostname");
++    else
++        src_hostname = gCoreContext->GetHostName();
++
++    gCoreContext->savesettings_togroup(src_hostname,groupname);
++    return GENERIC_EXIT_OK;
++}
++
++static int DeleteSettings(const MythUtilCommandLineParser &cmdline)
++{
++
++    QString delete_hostname;
++    QString groupname;
++
++    if (cmdline.toBool("groupname"))
++        groupname = cmdline.toString("groupname");
++
++    if (cmdline.toBool("hostname"))
++        delete_hostname = cmdline.toString("hostname");
++    else
++        delete_hostname = gCoreContext->GetHostName();
++
++
++    gCoreContext->deletesettings(delete_hostname,groupname);
++
++    return GENERIC_EXIT_OK;
++}
++
++
++static int RestoreSettings(const MythUtilCommandLineParser &cmdline)
++{
++    QString dest_hostname;
++    QString groupname;
++    QString tablestring;
++    QStringList table_list;
++
++    if (cmdline.toBool("groupname"))
++        groupname = cmdline.toString("groupname");
++
++
++    if (cmdline.toBool("hostname"))
++        dest_hostname = cmdline.toString("hostname");
++    else
++        dest_hostname = gCoreContext->GetHostName();
++
++    if (cmdline.toBool("table_list"))
++    {
++        tablestring = QString(cmdline.toString("table_list"));
++        table_list = tablestring.split(",", QString::SkipEmptyParts);
++    }
++
++    gCoreContext->restoresettings(dest_hostname,
++                                  groupname,
++                                  table_list);
++
++    return GENERIC_EXIT_OK;
++}
++
++
++static int CopySettings(const MythUtilCommandLineParser &cmdline)
++{
++    QString src_hostname;
++    QString groupname;
++    QString tablestring;
++    QStringList table_list;
++    bool is_full_clone;
++    QString dest_hostname;
++
++    if (cmdline.toBool("groupname"))
++        groupname = cmdline.toString("groupname");
++    else
++        groupname = "Current";
++
++    if (cmdline.toBool("hostname"))
++        src_hostname = cmdline.toString("hostname");
++    else
++        src_hostname = gCoreContext->GetHostName();
++
++    if (cmdline.toBool("newhost"))
++        dest_hostname = cmdline.toString("newhost");
++
++    if (cmdline.toBool("table_list"))
++    {
++        tablestring = QString(cmdline.toString("table_list"));
++        table_list = tablestring.split(",", QString::SkipEmptyParts);
++    }
++
++    if (cmdline.toBool("fullclone"))
++        is_full_clone = TRUE;
++    else
++        is_full_clone = FALSE;
++
++    gCoreContext->clonesettings(src_hostname,
++                                groupname,
++                                table_list,
++                                is_full_clone,
++                                dest_hostname);
++
++    return GENERIC_EXIT_OK;
++}
++
++void print_out_diff_formated(QMap<QString, QStringList> resultset)
++{
++    QString settings_header;
++    QString keybindings_header;
++    QString tempString;
++    QString tempItem;
++    QString dashline_settings;
++    QString dashline_key;
++    QStringList tempList;
++
++    QString host_1;
++    QString host_2;
++    QString data_1;
++    QString data_2;
++    QString value;
++    QString context;
++    QString action;
++
++    int value_width = 35;
++    int data_width = 40;
++
++    int context_width = 22;
++    int action_width = 22;
++    int key_width = 35;
++
++    dashline_key = (tempString.fill('-', 133));
++    dashline_settings = (tempString.fill('-', 130));
++
++    QMap<QString, QStringList>::iterator i;
++
++
++    for (i = resultset.begin(); i != resultset.end(); ++i)
++    {
++        cout << endl<<i.key().toLocal8Bit().constData() << ": \t" << endl;;
++        //construct the headers
++        if (i.key() == "Settings")
++        {
++            //settings header
++            tempList = (i.value().at(0)).split("|", QString::SkipEmptyParts);
++            host_1 = tempList.at(1);
++            host_2 = tempList.at(3);
++            tempString="|";
++            tempItem = "Value";
++            tempString.append(tempItem.leftJustified(value_width));
++            tempString.append("|");
++            tempItem = host_1;                //hostname 1
++            tempString.append(tempItem.leftJustified(data_width));
++            tempString.append("|");
++            tempItem = host_2;    //hostname 2
++            tempString.append(tempItem.leftJustified(data_width));
++            tempString.append("|");
++            settings_header = tempString;
++
++            cout << settings_header.toLocal8Bit().constData() << endl;;
++            cout << dashline_settings.toLocal8Bit().constData() << endl;
++        }
++
++         if (i.key() == "Keybindings")
++         {
++             //keybindings_header
++             tempList = (i.value().at(0)).split("|", QString::SkipEmptyParts);
++             host_1 = tempList.at(2);
++             host_2 = tempList.at(4);
++             tempString="|";
++             tempItem = "Context";
++             tempString.append(tempItem.leftJustified(context_width));
++             tempString.append("|");
++             tempItem = "Action";
++             tempString.append(tempItem.leftJustified(action_width));
++             tempString.append("|");
++             tempItem = host_1;
++             tempString.append(tempItem.leftJustified(key_width));
++             tempString.append("|");
++             tempItem = host_2;
++             tempString.append(tempItem.leftJustified(key_width));
++             tempString.append("|");
++             keybindings_header = tempString;
++
++             cout << keybindings_header.toLocal8Bit().constData() << endl;;
++             cout << dashline_key.toLocal8Bit().constData() << endl;
++
++         }
++         // format each line
++         for (int y = 0; y < i.value().size(); ++y)
++         {
++             if (i.key() == "Settings")
++             {
++                 tempList = (i.value().at(y)).split("|",
++                                                    QString::SkipEmptyParts);
++                 data_1 = tempList.at(2);
++                 data_2 = tempList.at(4);
++                 value  = tempList.at(0);
++                 tempString="|";
++                 tempItem = value;
++                 tempString.append(tempItem.leftJustified(value_width));
++                 tempString.append("|");
++                 tempItem = data_1;
++                 tempString.append(tempItem.leftJustified(data_width));
++                 tempString.append("|");
++                 tempItem = data_2;
++                 tempString.append(tempItem.leftJustified(data_width));
++                 tempString.append("|");
++             }
++             if (i.key() == "Keybindings")
++             {
++                 tempList = (i.value().at(y)).split("|",
++                                                    QString::SkipEmptyParts);
++                 data_1 = tempList.at(3);
++                 data_2 = tempList.at(5);
++                 context  = tempList.at(0);
++                 action = tempList.at(1);
++
++                 tempString="|";
++                 tempItem = context;
++                 tempString.append(tempItem.leftJustified(context_width));
++                 tempString.append("|");
++                 tempItem = action;
++                 tempString.append(tempItem.leftJustified(action_width));
++                 tempString.append("|");
++                 tempItem = data_1;
++                 tempString.append(tempItem.leftJustified(key_width));
++                 tempString.append("|");
++                 tempItem = data_2;
++                 tempString.append(tempItem.leftJustified(key_width));
++                 tempString.append("|");
++             }
++
++             cout << tempString.toLocal8Bit().constData()<<endl;
++         }
++    }
++};
++
++static int DiffSettings(const MythUtilCommandLineParser &cmdline)
++{
++    QMap<QString, QStringList> resultset;
++    QString diff_hostname1;
++    QString diff_hostname2;
++    QStringList table_list;
++    bool format_results = FALSE;
++    QMap<QString, QStringList>::iterator i;
++
++    if (cmdline.toBool("host_1"))
++        diff_hostname1 = cmdline.toString("host_1");
++    if (cmdline.toBool("host_2"))
++        diff_hostname2 = cmdline.toString("host_2");
++
++    if (cmdline.toBool("table_list"))
++    {
++        QString tablestring = QString(cmdline.toString("table_list"));
++        table_list = tablestring.split(",", QString::SkipEmptyParts);
++    }
++
++    if (cmdline.toBool("format"))
++        format_results = TRUE;
++
++    resultset = gCoreContext->diff_settingsgroupname(diff_hostname1,
++                                                     diff_hostname2,
++                                                     table_list);
++    if  (resultset.isEmpty())
++        cout << "No differences found" << endl;
++    else
++    {
++        if (format_results)
++            print_out_diff_formated(resultset);
++        else
++        {
++            for (i = resultset.begin(); i != resultset.end(); ++i)
++            {
++                cout << i.key().toLocal8Bit().constData() << " : \t" << endl;;
++                for (int y = 0; y < i.value().size(); ++y)
++                    cout << i.value().at(y).toLocal8Bit().constData()<<endl;
++                cout << endl;
++            }
++        }
++    }
++    return GENERIC_EXIT_OK;
++};// DiffSettings
++
++static int ListGroups(const MythUtilCommandLineParser &cmdline)
++{
++    QMap<QString, QStringList> resultset;
++    resultset = gCoreContext->list_settingsgroupname();
++    QMap<QString, QStringList>::iterator i;
++    cout <<  endl;
++    for (i = resultset.begin(); i != resultset.end(); ++i)
++    {
++        cout << i.key().toLocal8Bit().constData() << " : \t";
++        for (int y = 0; y < i.value().size(); ++y)
++            cout << i.value().at(y).toLocal8Bit().constData()<<" " ;
++        cout << endl;
++    }
++    return GENERIC_EXIT_OK;
++};
++
++static int ImportSettings(const MythUtilCommandLineParser &cmdline)
++{
++
++    if (cmdline.toString("infile").isEmpty())
++    {
++        LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n");
++        return GENERIC_EXIT_INVALID_CMDLINE;
++    }
++    QString import_hostname;
++    bool change_name = FALSE;
++    if (cmdline.toBool("hostname"))
++    {
++        change_name = TRUE;
++        import_hostname = cmdline.toString("hostname");
++    }
++    QString import_filename = cmdline.toString("infile");
++    QFile myFile(import_filename);
++
++    QDomDocument doc( "exported_xml" );
++    doc.setContent( &myFile );
++
++    QDomElement docElement = doc.documentElement();
++    QDomElement record_element;
++
++    if ( docElement.nodeName() != "exported_xml" )
++    {
++       cout << "not a valid exported xml file" << endl;
++       return 1;
++    }
++
++    QString out_string = "Importing records, please be patient";
++    cout << out_string.toLocal8Bit().constData()  << endl;
++    //Gives list of records in the file + count
++    QDomNodeList nodeList = docElement.childNodes();
++    int total_records = nodeList.count();
++    out_string = QString("\nFound %1 records \n").arg(total_records);
++    cout << out_string.toLocal8Bit().constData()  << endl;
++    LOG(VB_STDIO|VB_FLUSH, LOG_ERR, out_string);
++
++    for(QDomNode n = docElement.firstChild(); !n.isNull(); n = n.nextSibling())
++    {
++        QString table_name=QString();
++        QMap<QString,QString> value_pair_map ;
++
++        //find table name for this record
++        QDomNode tablenode=n.namedItem("table");
++        record_element = tablenode.toElement();
++        table_name = record_element.text();
++
++        //loop over childern of n and convert to element
++        for(QDomNode subn = n.firstChild();
++            !subn.isNull();
++            subn = subn.nextSibling())
++        {
++            record_element = subn.toElement();
++            if ( record_element.nodeName() == "table" )
++                    continue;
++            if ( change_name && record_element.nodeName() == "hostname" )
++                value_pair_map[record_element.nodeName()] = import_hostname;
++            else
++                value_pair_map[record_element.nodeName()] = record_element.text();
++        }
++        if (import_filename.endsWith("syssettings.xml"))
++        {
++            if  ( value_pair_map["value"] == "BackendServerIP")
++            {
++                out_string = "sysettings, ignoring backendserver ip record";
++                cout << out_string.toLocal8Bit().constData()  << endl;
++            }
++            else
++                gCoreContext->import_settings(value_pair_map,table_name);
++        }
++        else
++            //perform insert
++            gCoreContext->import_settings(value_pair_map,table_name);
++    }
++    return GENERIC_EXIT_OK;
++}; //end ImportSettings
++
++
++static int ExportSettings(const MythUtilCommandLineParser &cmdline)
++{
++    QMap<QString, QMap<QString,QString> > records;
++    QString src_hostname;
++    QString groupname;
++    QStringList table_list;
++    QString tablestring;
++    bool distro_default =  FALSE;
++    bool generic = FALSE;
++    bool skip_host = FALSE;
++
++
++
++    QDomDocument doc("mythutils_exported_settings");
++
++    if (cmdline.toBool("groupname"))
++        groupname = cmdline.toString("groupname");
++    else
++        groupname = "current";
++
++    if (cmdline.toBool("hostname"))
++        src_hostname = cmdline.toString("hostname");
++    else
++        src_hostname = gCoreContext->GetHostName();
++
++    if (cmdline.toBool("distro-default"))
++    {
++        distro_default = TRUE;
++        skip_host = TRUE;
++    }
++    if (cmdline.toBool("generic"))
++    {
++        generic = TRUE;
++        //skip_host = TRUE;
++    }
++    if (cmdline.toBool("table_list"))
++    {
++        tablestring = QString(cmdline.toString("table_list"));
++        table_list = tablestring.split(",", QString::SkipEmptyParts);
++    }
++    else
++        table_list << "settings" <<"keybindings" <<"jumppoints" ;
++
++    if (cmdline.toString("outfile").isEmpty())
++    {
++        LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --outfile option\n");
++        return GENERIC_EXIT_INVALID_CMDLINE;
++    }
++
++    QString export_filename = cmdline.toString("outfile");
++
++    records = gCoreContext->export_settings(src_hostname,groupname,
++                                            table_list, skip_host);
++
++    QDomElement exported_xml = doc.createElement("exported_xml");
++    doc.appendChild(exported_xml);
++
++    QMap<QString,int> record_count;
++    QMap<QString,QMap<QString,QString>  >::iterator i;
++    for (i = records.begin(); i != records.end(); ++i )
++    {
++            QDomElement record = doc.createElement("record");
++            exported_xml.appendChild(record);
++
++            //loop over all values in the record
++            QMap<QString,QString> value_pair = i.value();
++            QMap<QString, QString>::iterator y;
++            //because we don't know the name of the key, we loop over it
++            for (y = value_pair.begin(); y != value_pair.end(); ++y)
++           {
++                //add key/pair to xml document
++                QDomElement tag = doc.createElement(y.key());
++                record.appendChild(tag);
++                QDomText  t;
++                if ( distro_default == TRUE )
++                {   // If exporting distro_default then change hostname + table
++                    if ( y.key() == "hostname" )
++                    {   //check for global values here, empty value means global
++                        if ( y.value().isEmpty() )
++                            t = doc.createTextNode(y.value());
++                        else
++                            t = doc.createTextNode("distro_default");
++                    }
++                    else if ( y.key() == "table")
++                        t = doc.createTextNode(y.value()+"_distro_default");
++                    else
++                        t = doc.createTextNode(y.value());
++                }
++
++                else if ( generic == TRUE )
++                {   // If exporting generic then change hostname
++                    if ( y.key() == "hostname" )
++                    {   //check for global values here, empty value means global
++                        if ( y.value().isEmpty() )
++                            t = doc.createTextNode(y.value());
++                        else
++                            t = doc.createTextNode("REPLACE_ME");
++                    }
++                    else
++                       t = doc.createTextNode(y.value());
++               }
++               else
++                   t = doc.createTextNode(y.value());
++
++               tag.appendChild(t);
++                //create record counts
++                if ( y.key() == "table" )
++                {
++                    if ( record_count.contains( y.value()) )
++                    {
++                        int record_num = record_count[y.value()];
++                        record_count[y.value()] = ++record_num;
++                    }
++                    else
++                        record_count[y.value()] = 1;
++                }
++           }
++     }
++     QFile file( export_filename );
++
++     if( !file.open(QIODevice::WriteOnly) )
++            return -1;
++
++     QTextStream ts( &file );
++     ts << doc.toString();
++     file.close();
++     QMap<QString, int >::iterator rc_it;
++     for ( rc_it = record_count.begin(); rc_it != record_count.end(); ++rc_it)
++     {
++            QString table = rc_it.key();
++            int rc_count = rc_it.value();
++            QString out_string = QString ("Exported table %1: %2 records")
++                                                            .arg(table)
++                                                            .arg(rc_count);
++            cout << out_string.toLocal8Bit().constData()  << endl;
++     }
++    return GENERIC_EXIT_OK;
++}; // end export_settings
++
++
++static int ChangeHostname(const MythUtilCommandLineParser &cmdline)
++{
++
++    QString old_hostname;
++    QString new_hostname;
++
++
++    if (cmdline.toBool("oldhost"))
++        old_hostname = cmdline.toString("oldhost");
++
++    if (cmdline.toBool("newhost"))
++        new_hostname = cmdline.toString("newhost");
++
++    if (old_hostname.isEmpty())
++    {
++        LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing or empty --old-host option\n");
++        return GENERIC_EXIT_INVALID_CMDLINE;
++    }
++
++    if (new_hostname.isEmpty())
++    {
++        LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing or empty --new-host option\n");
++        return GENERIC_EXIT_INVALID_CMDLINE;
++    }
++
++    gCoreContext->change_hostname(old_hostname, new_hostname);
++
++    return GENERIC_EXIT_OK;
++}; //end ChangeHostname
++
++void registerSettingsUtils(UtilMap &utilMap)
++{
++    utilMap["savesettings"]             = &SaveSettings;
++    utilMap["deletesettings"]           = &DeleteSettings;
++    utilMap["restoresettings"]          = &RestoreSettings;
++    utilMap["copysettings"]             = &CopySettings;
++    utilMap["diffsettings"]             = &DiffSettings;
++    utilMap["listgroups"]               = &ListGroups;
++    utilMap["importsettings"]           = &ImportSettings;
++    utilMap["exportsettings"]           = &ExportSettings;
++    utilMap["changehostname"]           = &ChangeHostname;
++}
++
++/* vim: set expandtab tabstop=4 shiftwidth=4: */
+\ No newline at end of file
+diff --git a/mythtv/programs/mythutil/settingsutils.h b/mythtv/programs/mythutil/settingsutils.h
+new file mode 100644
+index 0000000..413496c
+--- /dev/null
++++ b/mythtv/programs/mythutil/settingsutils.h
+@@ -0,0 +1,3 @@
++#include "mythutil.h"
++
++void registerSettingsUtils(UtilMap &utilMap);
diff --git a/abs/core/mythtv/stable-0.27/mythtv/mythtv.install b/abs/core/mythtv/stable-0.27/mythtv/mythtv.install
new file mode 100644
index 0000000..8e900ed
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/mythtv.install
@@ -0,0 +1,24 @@
+# arg 1:  the new package version
+post_install() {
+        gen_is_xml.py
+        gen_lib_xml.py
+}
+
+pre_upgrade() {
+        /bin/true
+}
+
+post_upgrade() {
+        post_install
+}
+
+
+# arg 1:  the old package version
+post_remove() {
+        /bin/true
+
+}
+
+op=$1
+shift
+$op $*
diff --git a/abs/core/mythtv/stable-0.27/mythtv/recordings b/abs/core/mythtv/stable-0.27/mythtv/recordings
new file mode 100644
index 0000000..7fdde51
--- /dev/null
+++ b/abs/core/mythtv/stable-0.27/mythtv/recordings
@@ -0,0 +1,5 @@
+#!/bin/bash
+if [ -f /usr/share/mythtv/contrib/user_jobs/mythlink.pl ]
+then
+    su - mythtv -c "perl /usr/share/mythtv/contrib/user_jobs/mythlink.pl --link /data/storage/disk0/media/recordings"
+fi
-- 
cgit v0.12