diff --git a/src/freedombone-app-babel b/src/freedombone-app-babel
index 8d9b4946ea636be60a78fcb59db4e330f9f3e869..9310b800637bd548b0bc21f1d122ff0eaf95c29c 100755
--- a/src/freedombone-app-babel
+++ b/src/freedombone-app-babel
@@ -33,6 +33,10 @@ VARIANTS=''
 ENABLE_BABEL="no"
 BABEL_PORT=6696
 
+function configure_interactive_babel {
+    echo -n ''
+}
+
 function install_interactive_babel {
     echo -n ''
 }
diff --git a/src/freedombone-app-batman b/src/freedombone-app-batman
index 23b262a8fc482d8db20ab366976a02405871eb2d..d8a1a8f58e5e84db41a509360d24350c16b2c3f2 100755
--- a/src/freedombone-app-batman
+++ b/src/freedombone-app-batman
@@ -33,6 +33,10 @@ VARIANTS=''
 ENABLE_BATMAN="no"
 BATMAN_CELLID='any'
 
+function configure_interactive_batman {
+    echo -n ''
+}
+
 function install_interactive_batman {
     echo -n ''
 }
diff --git a/src/freedombone-app-blog b/src/freedombone-app-blog
index 6210ba63170395dec442d270c40e413ddcea4b91..c2d4cb5781fea56f5f57bdcb40d355782d2b1f03 100755
--- a/src/freedombone-app-blog
+++ b/src/freedombone-app-blog
@@ -38,6 +38,28 @@ FULLBLOG_COMMIT='bf5fe9486160be4da86d8987d3e5c977e1dc6d32'
 MY_BLOG_TITLE="My Blog"
 MY_BLOG_SUBTITLE="Another ${PROJECT_NAME} Blog"
 
+function configure_interactive_blog {
+    data=$(tempfile 2>/dev/null)
+    trap "rm -f $data" 0 1 2 5 15
+    dialog --title $"Change blog avatar" \
+           --backtitle $"Freedombone Control Panel" \
+           --inputbox $"Enter a URL for an image. It should be approximately a square image." 8 75 2>$data
+    sel=$?
+    case $sel in
+        0)
+            IMAGE_URL=$(<$data)
+            if [ ${#IMAGE_URL} -gt 5 ]; then
+                clear
+                ${PROJECT_NAME}-blog -a $IMAGE_URL
+                if [ "$?" = "0" ]; then
+                    dialog --title $"Change blog avatar" \
+                           --msgbox $"Your blog avatar has been changed" 6 40
+                fi
+            fi
+            ;;
+    esac
+}
+
 function install_interactive_blog {
     echo -n ''
 }
diff --git a/src/freedombone-app-blogstatic b/src/freedombone-app-blogstatic
index 9336565aa85498ca335c395f71870d886344926a..844c7efc411b19345c821da0ecdf119d6e51cc26 100755
--- a/src/freedombone-app-blogstatic
+++ b/src/freedombone-app-blogstatic
@@ -35,6 +35,10 @@ PELICAN_THEMES_REPO="https://github.com/getpelican/pelican-themes"
 PELICAN_PLUGINS_REPO="https://github.com/getpelican/pelican-plugins"
 DEFAULT_BLOG_TITLE=$"Freedombone Blog"
 
+function configure_interactive_blogstatic {
+    echo -n ''
+}
+
 function install_interactive_blogstatic {
     echo -n ''
 }
diff --git a/src/freedombone-app-cjdns b/src/freedombone-app-cjdns
index bcd8d81462974304305ecaa88c9311eeb6b1ee53..e159f316d94f79bc369897eee11584a68da66e82 100755
--- a/src/freedombone-app-cjdns
+++ b/src/freedombone-app-cjdns
@@ -41,6 +41,10 @@ CJDNS_COMMIT='13189fde111d0500427a7a0ce06a970753527bca'
 CJDCMD_REPO="https://github.com/inhies/cjdcmd"
 CJDCMD_COMMIT='973cca6ed0eecf9041c3403a40193c0b1291b808'
 
+function configure_interactive_cjdns {
+    echo -n ''
+}
+
 function install_interactive_cjdns {
     echo -n ''
 }
diff --git a/src/freedombone-app-dlna b/src/freedombone-app-dlna
index 8d6347bc56a87d8e3e97bafe8051971cee1d4605..99c34e717d00938368aea27690eea6a01187b5da 100755
--- a/src/freedombone-app-dlna
+++ b/src/freedombone-app-dlna
@@ -30,6 +30,31 @@
 
 VARIANTS='full media'
 
+function configure_interactive_dlna {
+    while true
+    do
+        data=$(tempfile 2>/dev/null)
+        trap "rm -f $data" 0 1 2 5 15
+        dialog --backtitle $"Freedombone Control Panel" \
+               --title $"Media Menu" \
+               --radiolist $"Choose an operation:" 13 70 3 \
+               1 $"Attach a drive containing playable media" off \
+               2 $"Remove a drive containing playable media" off \
+               3 $"Exit" on 2> $data
+        sel=$?
+        case $sel in
+            1) break;;
+            255) break;;
+        esac
+        case $(cat $data) in
+            1) remove-music
+               attach-music;;
+            2) remove-music;;
+            3) break;;
+        esac
+    done
+}
+
 function install_interactive_dlna {
     echo -n ''
 }
diff --git a/src/freedombone-app-emacs b/src/freedombone-app-emacs
index 6320d66dbd09e18f7d075d7d5deda35d5d35540c..b83228f2dce6b07815620b77c80b217b470a37e0 100755
--- a/src/freedombone-app-emacs
+++ b/src/freedombone-app-emacs
@@ -30,6 +30,10 @@
 
 VARIANTS='all'
 
+function configure_interactive_emacs {
+    echo -n ''
+}
+
 function install_interactive_emacs {
     echo -n ''
 }
diff --git a/src/freedombone-app-gnusocial b/src/freedombone-app-gnusocial
index 0aa3d7d491b739d92c25049b7e62ff36fca87d0d..0e2aa58f07063f8aebe90a0cb6eb0b26f9ac2478 100755
--- a/src/freedombone-app-gnusocial
+++ b/src/freedombone-app-gnusocial
@@ -53,6 +53,10 @@ SHARINGS_THEME_COMMIT='7106c7ef03'
 GNUSOCIAL_NSFW_REPO="https://gitgud.io/ShitposterClub/SensitiveContent"
 GNUSOCIAL_NSFW_COMMIT='a096bbe0cfae9a9b177682920ffb58d32a48e136'
 
+function configure_interactive_gnusocial {
+    echo -n ''
+}
+
 function install_interactive_gnusocial {
     echo -n ''
 }
diff --git a/src/freedombone-app-gogs b/src/freedombone-app-gogs
index 2110417f978f9879c7d4ff68406eef8f5573e24f..7c340ab0e043db3612e59957a53bd2a90824e530 100755
--- a/src/freedombone-app-gogs
+++ b/src/freedombone-app-gogs
@@ -39,6 +39,10 @@ GIT_ONION_PORT=8090
 GIT_ADMIN_PASSWORD=
 GOGS_BIN=
 
+function configure_interactive_gogs {
+    echo -n ''
+}
+
 function install_interactive_gogs {
     echo -n ''
 }
diff --git a/src/freedombone-app-hubzilla b/src/freedombone-app-hubzilla
index 3ea554e6e8594f91769def9f52648cd7f84c189c..e847e2c1003a54ad0ea36fc94ac2d4642e854324 100755
--- a/src/freedombone-app-hubzilla
+++ b/src/freedombone-app-hubzilla
@@ -40,6 +40,91 @@ HUBZILLA_ADMIN_PASSWORD=
 HUBZILLA_COMMIT='8aee932525d0bc341713fe7052e2a5ab318a69c0'
 HUBZILLA_ADDONS_COMMIT='4456f097e3faf2adeab696ad08e3f213e82199bd'
 
+function hubzilla_renew_cert {
+    dialog --title $"Renew SSL certificate" \
+           --backtitle $"Freedombone Control Panel" \
+           --yesno $"\nThis will renew a letsencrypt certificate. Select 'yes' to continue" 16 60
+    sel=$?
+    case $sel in
+        1) return;;
+        255) return;;
+    esac
+    HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
+    if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
+        dialog --title $"Renew SSL certificate" \
+               --msgbox $"Hubzilla install directory not found" 6 40
+        return
+    fi
+    ${PROJECT_NAME}-renew-cert -h $HUBZILLA_DOMAIN_NAME -p 'letsencrypt'
+    if [ ! "$?" = "0" ]; then
+        any_key
+    else
+        dialog --title $"Renew SSL certificate" \
+               --msgbox $"Hubzilla certificate has been renewed" 6 40
+    fi
+}
+
+function hubzilla_channel_directory_server {
+    if ! grep -q "Hubzilla domain" $COMPLETION_FILE; then
+        dialog --title $"Hubzilla channel directory server" \
+               --msgbox $"Hubzilla is not installed on this system" 6 40
+        return
+    fi
+    HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
+    if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
+        dialog --title $"Hubzilla channel directory server" \
+               --msgbox $"Hubzilla install directory not found" 6 40
+        return
+    fi
+
+    data=$(tempfile 2>/dev/null)
+    trap "rm -f $data" 0 1 2 5 15
+    dialog --title $"Hubzilla channel directory server" \
+           --backtitle $"Freedombone Control Panel" \
+           --inputbox $"When you click on 'channel directory' this is where Hubzilla will obtain its list from" 8 60 2>$data
+    sel=$?
+    case $sel in
+        0)
+            hubzilla_domain_server=$(<$data)
+            if [[ $hubzilla_domain_server != *"."* ]]; then
+                return
+            fi
+            if [[ $hubzilla_domain_server != "https"* ]]; then
+                dialog --title $"Hubzilla channel directory server" \
+                       --msgbox $"Invalid domain - include the https://" 6 40
+                return
+            fi
+            ./var/www/$HUBZILLA_DOMAIN_NAME/htdocs/util/config system directory_server $hubzilla_domain_server
+            dialog --title $"Hubzilla channel directory server" \
+                   --msgbox $"Domain channel directory server changed to $hubzilla_domain_server" 6 40
+            ;;
+    esac
+}
+
+function configure_interactive_hubzilla {
+    while true
+    do
+        data=$(tempfile 2>/dev/null)
+        trap "rm -f $data" 0 1 2 5 15
+        dialog --backtitle $"Freedombone Control Panel" \
+               --title $"Hubzilla" \
+               --radiolist $"Choose an operation:" 13 70 4 \
+               1 $"Set channel directory server" off \
+               2 $"Renew SSL certificate" off \
+               3 $"Back to main menu" on 2> $data
+        sel=$?
+        case $sel in
+            1) break;;
+            255) break;;
+        esac
+        case $(cat $data) in
+            1) hubzilla_channel_directory_server;;
+            2) hubzilla_renew_cert;;
+            3) break;;
+        esac
+    done
+}
+
 function install_interactive_hubzilla {
     echo -n ''
 }
diff --git a/src/freedombone-app-ipfs b/src/freedombone-app-ipfs
index 611b2933e04c1a111acfc5cb3d6cfbbd3b6ce227..cd071f30cce484074fd47a572ce6735b71071199 100755
--- a/src/freedombone-app-ipfs
+++ b/src/freedombone-app-ipfs
@@ -41,6 +41,10 @@ IPFS_JS_RONIN_VERSION='0.3.11'
 IPFS_KEY_LENGTH=2048
 IPFS_GO_VERSION=0.4.2
 
+function configure_interactive_ipfs {
+    echo -n ''
+}
+
 function install_interactive_ipfs {
     echo -n ''
 }
diff --git a/src/freedombone-app-irc b/src/freedombone-app-irc
index c98e8a42f825a93b740b231b2fec79d3a1fb346d..600393689476ce431547abe63f07aa498d8a19eb 100755
--- a/src/freedombone-app-irc
+++ b/src/freedombone-app-irc
@@ -36,6 +36,74 @@ IRC_ONION_PORT=6697
 # An optional password to log into IRC. This applies to all users
 IRC_PASSWORD=
 
+function irc_show_password {
+    IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
+    dialog --title $"IRC Password" \
+           --msgbox "$IRC_PASSWORD" 6 40
+}
+
+function irc_set_global_password {
+    dialog --title $"IRC Password" \
+           --clear \
+           --backtitle $"Freedombone Control Panel" \
+           --passwordbox $"Password for all IRC users, or press Enter for no password" 10 50 2> $data
+    sel=$?
+    case $sel in
+        0)
+            EXISTING_IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
+            NEW_IRC_PASSWORD=$(<$data)
+            sed -i "0,/RE/s/Password =.*/Password =$NEW_IRC_PASSWORD/" /etc/ngircd/ngircd.conf
+
+            # replace the password for all users
+            for d in /home/*/ ; do
+                IRC_USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
+                if [[ $IRC_USERNAME != "git" && $IRC_USERNAME != "mirrors" && $IRC_USERNAME != "sync" && $IRC_USERNAME != "tahoelafs" ]]; then
+                    if [ -f /home/$IRC_USERNAME/.irssi/config ]; then
+                        sed -i "s|$EXISTING_IRC_PASSWORD|$NEW_IRC_PASSWORD|g" /home/$IRC_USERNAME/.irssi/config
+                        chown -R $IRC_USERNAME:$IRC_USERNAME /home/$IRC_USERNAME/.irssi
+                    fi
+                fi
+            done
+
+            # restart the daemon for the new password to take effect
+            systemctl restart ngircd
+
+            dialog --title $"IRC Password" \
+                   --msgbox $"The IRC password was changed" 6 40
+            ;;
+    esac
+}
+
+function configure_interactive_irc {
+    if [ ! -d /etc/ngircd ]; then
+        dialog --title $"IRC Menu" \
+               --msgbox $"No IRC server is installed" 6 70
+        return
+    fi
+
+    while true
+    do
+        data=$(tempfile 2>/dev/null)
+        trap "rm -f $data" 0 1 2 5 15
+        dialog --backtitle $"Freedombone Control Panel" \
+               --title $"IRC Menu" \
+               --radiolist $"Choose an operation:" 14 70 4 \
+               1 $"Set a password for all IRC users" off \
+               2 $"Show current IRC login password" off \
+               3 $"Exit" on 2> $data
+        sel=$?
+        case $sel in
+            1) break;;
+            255) break;;
+        esac
+        case $(cat $data) in
+            1) irc_set_global_password;;
+            2) irc_show_password;;
+            3) break;;
+        esac
+    done
+}
+
 function install_interactive_irc {
     echo -n ''
 }
diff --git a/src/freedombone-app-librevault b/src/freedombone-app-librevault
index 427a1043ce41f465eda146b6ded4a2d8bd07ffde..f442798c158c7c618a97520597c11821d67b8a92 100755
--- a/src/freedombone-app-librevault
+++ b/src/freedombone-app-librevault
@@ -37,6 +37,10 @@ LIBREVAULT_REPO="https://github.com/Librevault/librevault"
 LIBREVAULT_COMMIT='86a6aefcb5cc458f4d42195368fbcff2871f98e3'
 LIBREVAULT_PORT=42345
 
+function configure_interactive_librevault {
+    echo -n ''
+}
+
 function install_interactive_librevault {
     echo -n ''
 }
diff --git a/src/freedombone-app-mediagoblin b/src/freedombone-app-mediagoblin
index 92d4b2a38c293c13c0371bb5d917d6c61c03dfbc..3cc37fccaed90986cb155c96df82360dccdbcef1 100755
--- a/src/freedombone-app-mediagoblin
+++ b/src/freedombone-app-mediagoblin
@@ -37,6 +37,10 @@ MEDIAGOBLIN_COMMIT='d1ac2d52fd8859c3f32fa38e4836ffe9615e5bba'
 MEDIAGOBLIN_ADMIN_PASSWORD=
 MEDIAGOBLIN_ONION_PORT=8096
 
+function configure_interactive_mediagoblin {
+    echo -n ''
+}
+
 function install_interactive_mediagoblin {
     echo -n ''
 }
diff --git a/src/freedombone-app-mumble b/src/freedombone-app-mumble
index 1f843d3a19317fc2a7fa820a68fdbb1c6ada6b2a..3ee47dee8fd0d463e2aba59eec1eb77d39922b95 100755
--- a/src/freedombone-app-mumble
+++ b/src/freedombone-app-mumble
@@ -39,6 +39,10 @@ VOIP_PORT=64738
 VOIP_DATABASE="mumble-server.sqlite"
 VOIP_CONFIG_FILE="mumble-server.ini"
 
+function configure_interactive_mumble {
+    echo -n ''
+}
+
 function install_interactive_mumble {
     echo -n ''
 }
diff --git a/src/freedombone-app-rss b/src/freedombone-app-rss
index 2376722a8dfcc56b6f9c816164510c5d39e593ca..e0bf06cfc5a369e5fdb75c5ba603af5af3cfd375 100755
--- a/src/freedombone-app-rss
+++ b/src/freedombone-app-rss
@@ -42,6 +42,10 @@ RSS_READER_PATH=/etc/share/tt-rss
 RSS_READER_GNUSOCIAL_REPO="https://github.com/bashrc/ttrss-gnusocial"
 RSS_READER_GNUSOCIAL_COMMIT='20b2535e3f2b0ddc0117b584bdcaa6bf7a2d9fa2'
 
+function configure_interactive_rss {
+    echo -n ''
+}
+
 function install_interactive_rss {
     echo -n ''
 }
diff --git a/src/freedombone-app-searx b/src/freedombone-app-searx
index 9900c39fb63ad24f43563e23529ce12f88afbc3a..d123879fc8f7bec351af721aec4fffc717d28c4d 100755
--- a/src/freedombone-app-searx
+++ b/src/freedombone-app-searx
@@ -38,6 +38,10 @@ SEARX_ONION_HOSTNAME=
 SEARX_LOGIN_TEXT=$"Search engine login"
 SEARX_PASSWORD=
 
+function configure_interactive_searx {
+    echo -n ''
+}
+
 function install_interactive_searx {
     echo -n ''
 }
diff --git a/src/freedombone-app-sip b/src/freedombone-app-sip
index 89b8f2d3d9d7f731daabb8701008eb6f4257defe..6a9cf0f5ddb42edcfdfc1461b465fb945eead8dd 100755
--- a/src/freedombone-app-sip
+++ b/src/freedombone-app-sip
@@ -37,6 +37,10 @@ VOIP_TURN_PORT=3478
 VOIP_TURN_TLS_PORT=5349
 VOIP_TURN_NONCE=
 
+function configure_interactive_sip {
+    echo -n ''
+}
+
 function install_interactive_sip {
     echo -n ''
 }
diff --git a/src/freedombone-app-syncthing b/src/freedombone-app-syncthing
index 9ad1558eebb8bc3c0a0e8300107fa4e3eded9372..e49010aac27f428016569cb12416339710e4d13a 100755
--- a/src/freedombone-app-syncthing
+++ b/src/freedombone-app-syncthing
@@ -39,6 +39,10 @@ SYNCTHING_PORT=22000
 SYNCTHING_SHARED_DATA=/var/lib/syncthing/SyncShared
 SYNCTHING_USER_IDS_FILE='.syncthingids'
 
+function configure_interactive_syncthing {
+    echo -n ''
+}
+
 function install_interactive_syncthing {
     echo -n ''
 }
diff --git a/src/freedombone-app-tahoelafs b/src/freedombone-app-tahoelafs
index 7a50647e9b16299e0364536144537327572093d7..67d5144f74bdd50017c3b9f8efdb570c404fd09e 100755
--- a/src/freedombone-app-tahoelafs
+++ b/src/freedombone-app-tahoelafs
@@ -39,6 +39,10 @@ TAHOELAFS_STORAGE_SPACE=1G
 TAHOELAFS_SHARED_DIR='Shared'
 TAHOE_COMMAND="cd /var/lib/tahoelafs && venv/bin/tahoe"
 
+function configure_interactive_tahoelafs {
+    echo -n ''
+}
+
 function install_interactive_tahoelafs {
     echo -n ''
 }
diff --git a/src/freedombone-app-tox b/src/freedombone-app-tox
index de8e26dba9ce09d60dbd1892c5f192246ab9ead2..adfb7fc71889401567c8d3f2a774bc58096ca441 100755
--- a/src/freedombone-app-tox
+++ b/src/freedombone-app-tox
@@ -49,6 +49,10 @@ TOXIC_FILE=/usr/local/bin/toxic
 QTOX_REPO="https://github.com/bashrc/qTox"
 QTOX_COMMIT='27a628a3789fca4f31516c3982e580052dd3c773'
 
+function configure_interactive_tox {
+    echo -n ''
+}
+
 function install_interactive_tox {
     echo -n ''
 }
diff --git a/src/freedombone-app-vpn b/src/freedombone-app-vpn
index 0dc29b735aa716df5b83df26ce478ca7467c127d..365ae9697d27d1b262e8153f22efad0bf5ae05ba 100755
--- a/src/freedombone-app-vpn
+++ b/src/freedombone-app-vpn
@@ -30,6 +30,10 @@
 
 VARIANTS=''
 
+function configure_interactive_vpn {
+    echo -n ''
+}
+
 function install_interactive_vpn {
     echo -n ''
 }
diff --git a/src/freedombone-app-webmail b/src/freedombone-app-webmail
index 7f9a048e0ee1feda21b010a2d17edd1676282365..e25b396c3f4c1e7672eb466c1c9aa8d288c01fab 100755
--- a/src/freedombone-app-webmail
+++ b/src/freedombone-app-webmail
@@ -38,6 +38,10 @@ WEBMAIL_ADMIN_PASSWORD=
 WEB_PATH=/var/www
 WEBMAIL_PATH=$WEB_PATH/webmail
 
+function configure_interactive_webmail {
+    echo -n ''
+}
+
 function install_interactive_webmail {
     echo -n ''
 }
diff --git a/src/freedombone-app-wiki b/src/freedombone-app-wiki
index ea057968b9044d456768296e94c111e248bdf681..8fad8254aa5fd7e32a08e20dc58de425b8d58fe1 100755
--- a/src/freedombone-app-wiki
+++ b/src/freedombone-app-wiki
@@ -36,6 +36,10 @@ WIKI_TITLE="${PROJECT_NAME} Wiki"
 WIKI_CODE=
 WIKI_ONION_PORT=8089
 
+function configure_interactive_wiki {
+    echo -n ''
+}
+
 function install_interactive_wiki {
     echo -n ''
 }
diff --git a/src/freedombone-app-xmpp b/src/freedombone-app-xmpp
index 37f54a6b4849e1428472b475c5b95e3f358d1ade..a17c74583a06d94fd12a52744dde1ff43f74f948 100755
--- a/src/freedombone-app-xmpp
+++ b/src/freedombone-app-xmpp
@@ -37,6 +37,10 @@ XMPP_PASSWORD=
 XMPP_CIPHERS='"EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA"'
 XMPP_ECC_CURVE='"secp384r1"'
 
+function configure_interactive_xmpp {
+    echo -n ''
+}
+
 function install_interactive_xmpp {
     echo -n ''
 }
diff --git a/src/freedombone-app-zeronet b/src/freedombone-app-zeronet
index 4c64a35596146d2f62498b8eb252b2c6faff62e1..5e6ed8f75b247c250422ce2704f2c2c18612f54a 100755
--- a/src/freedombone-app-zeronet
+++ b/src/freedombone-app-zeronet
@@ -49,6 +49,10 @@ ZERONET_DEFAULT_MAIL_TAGLINE="Mail for the Mesh"
 ZERONET_ID_REPO="https://github.com/HelloZeroNet/ZeroID"
 ZERONET_ID_COMMIT='ccf14fdc96fa9cdb2ddd8a7ab283a8e17a4f234b'
 
+function configure_interactive_zeronet {
+    echo -n ''
+}
+
 function install_interactive_zeronet {
     echo -n ''
 }
diff --git a/src/freedombone-controlpanel b/src/freedombone-controlpanel
index 863787df46446e324506195dbd1c46518983a749..b206bad08336a3d06537107df0a3d41d2c4aff77 100755
--- a/src/freedombone-controlpanel
+++ b/src/freedombone-controlpanel
@@ -686,66 +686,6 @@ function change_password {
            --msgbox $"Password for $SELECTED_USERNAME was changed" 6 40
 }
 
-function irc_show_password {
-    IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
-    dialog --title $"IRC Password" \
-           --msgbox "$IRC_PASSWORD" 6 40
-}
-
-function irc_set_global_password {
-    dialog --title $"IRC Password" \
-           --clear \
-           --backtitle $"Freedombone Control Panel" \
-           --passwordbox $"Password for all IRC users, or press Enter for no password" 10 50 2> $data
-    sel=$?
-    case $sel in
-        0)
-            EXISTING_IRC_PASSWORD=$(cat /etc/ngircd/ngircd.conf | grep "Password =" | head -n 1 | awk -F '=' '{print $2}')
-            NEW_IRC_PASSWORD=$(<$data)
-            sed -i "0,/RE/s/Password =.*/Password =$NEW_IRC_PASSWORD/" /etc/ngircd/ngircd.conf
-
-            # replace the password for all users
-            for d in /home/*/ ; do
-                IRC_USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
-                if [[ $IRC_USERNAME != "git" && $IRC_USERNAME != "mirrors" && $IRC_USERNAME != "sync" && $IRC_USERNAME != "tahoelafs" ]]; then
-                    if [ -f /home/$IRC_USERNAME/.irssi/config ]; then
-                        sed -i "s|$EXISTING_IRC_PASSWORD|$NEW_IRC_PASSWORD|g" /home/$IRC_USERNAME/.irssi/config
-                        chown -R $IRC_USERNAME:$IRC_USERNAME /home/$IRC_USERNAME/.irssi
-                    fi
-                fi
-            done
-
-            # restart the daemon for the new password to take effect
-            systemctl restart ngircd
-
-            dialog --title $"IRC Password" \
-                   --msgbox $"The IRC password was changed" 6 40
-            ;;
-    esac
-}
-
-function change_blog_avatar {
-    data=$(tempfile 2>/dev/null)
-    trap "rm -f $data" 0 1 2 5 15
-    dialog --title $"Change blog avatar" \
-           --backtitle $"Freedombone Control Panel" \
-           --inputbox $"Enter a URL for an image. It should be approximately a square image." 8 75 2>$data
-    sel=$?
-    case $sel in
-        0)
-            IMAGE_URL=$(<$data)
-            if [ ${#IMAGE_URL} -gt 5 ]; then
-                clear
-                ${PROJECT_NAME}-blog -a $IMAGE_URL
-                if [ "$?" = "0" ]; then
-                    dialog --title $"Change blog avatar" \
-                           --msgbox $"Your blog avatar has been changed" 6 40
-                fi
-            fi
-            ;;
-    esac
-}
-
 function change_ssh_public_key {
     select_user
     if [ ! $SELECTED_USERNAME ]; then
@@ -1367,67 +1307,6 @@ function reset_tripwire {
     any_key
 }
 
-function hubzilla_renew_cert {
-    dialog --title $"Renew SSL certificate" \
-           --backtitle $"Freedombone Control Panel" \
-           --yesno $"\nThis will renew a letsencrypt certificate. Select 'yes' to continue" 16 60
-    sel=$?
-    case $sel in
-        1) return;;
-        255) return;;
-    esac
-    HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
-    if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
-        dialog --title $"Renew SSL certificate" \
-               --msgbox $"Hubzilla install directory not found" 6 40
-        return
-    fi
-    ${PROJECT_NAME}-renew-cert -h $HUBZILLA_DOMAIN_NAME -p 'letsencrypt'
-    if [ ! "$?" = "0" ]; then
-        any_key
-    else
-        dialog --title $"Renew SSL certificate" \
-               --msgbox $"Hubzilla certificate has been renewed" 6 40
-    fi
-}
-
-function hubzilla_channel_directory_server {
-    if ! grep -q "Hubzilla domain" $COMPLETION_FILE; then
-        dialog --title $"Hubzilla channel directory server" \
-               --msgbox $"Hubzilla is not installed on this system" 6 40
-        return
-    fi
-    HUBZILLA_DOMAIN_NAME=$(cat $COMPLETION_FILE | grep "Hubzilla domain" | awk -F ':' '{print $2}')
-    if [ ! -d /var/www/$HUBZILLA_DOMAIN_NAME/htdocs ]; then
-        dialog --title $"Hubzilla channel directory server" \
-               --msgbox $"Hubzilla install directory not found" 6 40
-        return
-    fi
-
-    data=$(tempfile 2>/dev/null)
-    trap "rm -f $data" 0 1 2 5 15
-    dialog --title $"Hubzilla channel directory server" \
-           --backtitle $"Freedombone Control Panel" \
-           --inputbox $"When you click on 'channel directory' this is where Hubzilla will obtain its list from" 8 60 2>$data
-    sel=$?
-    case $sel in
-        0)
-            hubzilla_domain_server=$(<$data)
-            if [[ $hubzilla_domain_server != *"."* ]]; then
-                return
-            fi
-            if [[ $hubzilla_domain_server != "https"* ]]; then
-                dialog --title $"Hubzilla channel directory server" \
-                       --msgbox $"Invalid domain - include the https://" 6 40
-                return
-            fi
-            ./var/www/$HUBZILLA_DOMAIN_NAME/htdocs/util/config system directory_server $hubzilla_domain_server
-            dialog --title $"Hubzilla channel directory server" \
-                   --msgbox $"Domain channel directory server changed to $hubzilla_domain_server" 6 40
-            ;;
-    esac
-}
-
 function format_drive {
     drive=
     data=$(tempfile 2>/dev/null)
@@ -1917,55 +1796,6 @@ function menu_users {
     done
 }
 
-function menu_hubzilla {
-    while true
-    do
-        data=$(tempfile 2>/dev/null)
-        trap "rm -f $data" 0 1 2 5 15
-        dialog --backtitle $"Freedombone Control Panel" \
-               --title $"Hubzilla" \
-               --radiolist $"Choose an operation:" 13 70 4 \
-               1 $"Set channel directory server" off \
-               2 $"Renew SSL certificate" off \
-               3 $"Back to main menu" on 2> $data
-        sel=$?
-        case $sel in
-            1) break;;
-            255) break;;
-        esac
-        case $(cat $data) in
-            1) hubzilla_channel_directory_server;;
-            2) hubzilla_renew_cert;;
-            3) break;;
-        esac
-    done
-}
-
-function menu_media {
-    while true
-    do
-        data=$(tempfile 2>/dev/null)
-        trap "rm -f $data" 0 1 2 5 15
-        dialog --backtitle $"Freedombone Control Panel" \
-               --title $"Media Menu" \
-               --radiolist $"Choose an operation:" 13 70 3 \
-               1 $"Attach a drive containing playable media" off \
-               2 $"Remove a drive containing playable media" off \
-               3 $"Exit" on 2> $data
-        sel=$?
-        case $sel in
-            1) break;;
-            255) break;;
-        esac
-        case $(cat $data) in
-            1) remove-music
-               attach-music;;
-            2) remove-music;;
-            3) break;;
-        esac
-    done
-}
-
 function wifi_enable {
     disable_wifi='yes'
     dialog --title $"Enable Wifi" \
@@ -2018,34 +1848,42 @@ function menu_wifi {
     done
 }
 
-function menu_irc {
-    if [ ! -d /etc/ngircd ]; then
-        dialog --title $"IRC Menu" \
-               --msgbox $"No IRC server is installed" 6 70
-        return
-    fi
+function app_settings {
 
-    while true
+
+    detect_installable_apps
+
+    applist=""
+    appnames=()
+    n=1
+    app_index=0
+    for a in "${APPS_AVAILABLE[@]}"
     do
-        data=$(tempfile 2>/dev/null)
-        trap "rm -f $data" 0 1 2 5 15
-        dialog --backtitle $"Freedombone Control Panel" \
-               --title $"IRC Menu" \
-               --radiolist $"Choose an operation:" 14 70 4 \
-               1 $"Set a password for all IRC users" off \
-               2 $"Show current IRC login password" off \
-               3 $"Exit" on 2> $data
-        sel=$?
-        case $sel in
-            1) break;;
-            255) break;;
-        esac
-        case $(cat $data) in
-            1) irc_set_global_password;;
-            2) irc_show_password;;
-            3) break;;
-        esac
+        if [[ ${APPS_INSTALLED[$app_index]} != "0" ]]; then
+            if [[ $(function_exists configure_interactive_${a}) == "1" ]]; then
+                applist="$applist $n $a off"
+                n=$[n+1]
+                appnames+=("$a")
+            fi
+        fi
+        app_index=$[app_index+1]
     done
+    backstr=$'Back to main menu'
+    applist="$applist $n $backstr on"
+    appnames+=("Exit")
+
+    choices=$(dialog --stdout --backtitle $"Freedombone" \
+                     --title $"Change Settings for an App" \
+                     --radiolist $'Choose:' \
+                     27 40 20 $applist)
+
+    if [ $? -eq 0 ]; then
+        for choice in $choices
+        do
+            app_index = $[choice-1]
+            configure_interactive_${appname[$app_index]}
+        done
+    fi
 }
 
 function menu_top_level {
@@ -2059,25 +1897,22 @@ function menu_top_level {
                1 $"About this system" off \
                2 $"Backup and Restore" off \
                3 $"Reset Tripwire" off \
-               4 $"Logging on/off" off \
-               5 $"Ping enable/disable" off \
-               6 $"Manage Users" off \
-               7 $"Email Filtering Rules" off \
-               8 $"Outgoing Email Proxy" off \
-               9 $"Security Settings" off \
-               10 $"Set the main repository (repo mirrors)" off \
-               11 $"Hubzilla" off \
-               12 $"Media menu" off \
-               13 $"IRC menu" off \
-               14 $"Change your blog avatar" off \
-               15 $"Change the name of this system" off \
-               16 $"Set the TLS date/time source" off \
-               17 $"Set a static local IP address" off \
-               18 $"Wifi menu" off \
-               19 $"Check for updates" off \
-               20 $"Power off the system" off \
-               21 $"Restart the system" off \
-               22 $"Exit" on 2> $data
+               4 $"App Settings" off \
+               5 $"Logging on/off" off \
+               6 $"Ping enable/disable" off \
+               7 $"Manage Users" off \
+               8 $"Email Filtering Rules" off \
+               9 $"Outgoing Email Proxy" off \
+               10 $"Security Settings" off \
+               11 $"Set the main repository (repo mirrors)" off \
+               12 $"Change the name of this system" off \
+               13 $"Set the TLS date/time source" off \
+               14 $"Set a static local IP address" off \
+               15 $"Wifi menu" off \
+               16 $"Check for updates" off \
+               17 $"Power off the system" off \
+               18 $"Restart the system" off \
+               19 $"Exit" on 2> $data
         sel=$?
         case $sel in
             1) exit 1;;
@@ -2087,25 +1922,22 @@ function menu_top_level {
             1) show_about;;
             2) menu_backup_restore;;
             3) reset_tripwire;;
-            4) logging_on_off;;
-            5) ping_enable_disable;;
-            6) menu_users;;
-            7) menu_email;;
-            8) smtp_proxy;;
-            9) security_settings;;
-            10) set_main_repo;;
-            11) menu_hubzilla;;
-            12) menu_media;;
-            13) menu_irc;;
-            14) change_blog_avatar;;
-            15) change_system_name;;
-            16) set_tls_time_source;;
-            17) set_static_IP;;
-            18) menu_wifi;;
-            19) check_for_updates;;
-            20) shut_down_system;;
-            21) restart_system;;
-            22) break;;
+            4) app_settings;;
+            5) logging_on_off;;
+            6) ping_enable_disable;;
+            7) menu_users;;
+            8) menu_email;;
+            9) smtp_proxy;;
+            10) security_settings;;
+            11) set_main_repo;;
+            12) change_system_name;;
+            13) set_tls_time_source;;
+            14) set_static_IP;;
+            15) menu_wifi;;
+            16) check_for_updates;;
+            17) shut_down_system;;
+            18) restart_system;;
+            19) break;;
         esac
     done
 }