| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091 | #!/bin/bash
#
# .---.                  .              .
# |                      |              |
# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
#
#                    Freedom in the Cloud
#
# Based on bin/freedombox-customize from freedom-maker
#
# License
# =======
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
set -e
set -x
PROJECT_NAME='freedombone'
INSTALL_DIR=/root/build
COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt
PROJECT_REPO="https://github.com/bashrc/${PROJECT_NAME}"
VARIANT='full'
# username created by default within a debian image
GENERIC_IMAGE_USERNAME='fbone'
export TEXTDOMAIN=${PROJECT_NAME}-image-customise
export TEXTDOMAINDIR="/usr/share/locale"
# Whether to minimise the number of decisions during interactive install
MINIMAL_INSTALL="yes"
MY_USERNAME='debian'
MY_PASSWORD="${PROJECT_NAME}"
# Minimum number of characters in a password
MINIMUM_PASSWORD_LENGTH=10
# IP address of the router (gateway)
ROUTER_IP_ADDRESS="192.168.1.254"
# The fixed IP address of the Beaglebone Black on your local network
BOX_IP_ADDRESS="192.168.1.55"
# DNS
NAMESERVER1='213.73.91.35'
NAMESERVER2='85.214.20.141'
# optional configuration file containing freedombone settings
CONFIG_FILENAME=
# Optional ssh public key to allow
SSH_PUBKEY="no"
# Whether this is a generic image for mass redistribution on the interwebs
GENERIC_IMAGE="no"
# default SSH port
SSH_PORT=2222
# for mesh installs
TRACKER_PORT=6969
# Whether sites are accessible only within a Tor browser
ONION_ONLY="no"
# Whether to only install debian and nothing else
DEBIAN_INSTALL_ONLY="no"
# wifi settings
WIFI_INTERFACE='wlan0'
WIFI_SSID=
WIFI_TYPE='wpa2-psk'
WIFI_PASSPHRASE=
WIFI_HOTSPOT='no'
WIFI_NETWORKS_FILE=~/${PROJECT_NAME}-wifi.cfg
# Whether to install non-free wifi drivers for the mesh client
INSECURE='no'
# optional desktop background image for mesh
MESH_DESKTOP_BACKGROUND_IMAGE=/usr/local/share/${PROJECT_NAME}_mesh_initial_background.png
# The browser application to use
BROWSER=midori
MESH_INSTALL_DIR=/var/lib
# for mesh installs whether to delete all data and generate
# a new identity at every shutdown/boot
AMNESIC='no'
# defines the initial keyboard layout
KEYBOARD_MAP='gb'
# Strings used for setting the username
MESH_TITLE=$"Freedombone Mesh"
MESH_SET_USERNAME=$"Welcome to the Freedombone mesh.\n\nThe first thing you will need to do is set a username so that other peers can find you."
# Whether to enable zeronet on the mesh
ENABLE_ZERONET=
MESH_TEXT_EDITOR='pluma'
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
function configure_backports {
    echo "deb http://${DEBIAN_REPO}/debian/ ${DEBIAN_VERSION}-backports main" >> $rootdir/etc/apt/sources.list
}
function configure_contrib_repo {
    if ! grep -q "contrib" $rootdir/etc/apt/sources.list; then
        chroot "$rootdir" /bin/sed -i "s| main| main contrib|g" /etc/apt/sources.list
    fi
}
enable_eatmydata_override() {
    chroot $rootdir apt-get install -y eatmydata
    if [ -x $rootdir/usr/bin/eatmydata ] && \
           [ ! -f $rootdir/etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata ]; then
        echo $"info: Adding apt config to call dpkg via eatmydata"
        printf "#!/bin/sh\nexec eatmydata dpkg \"\$@\"\n" \
               > $rootdir/var/tmp/dpkg-eatmydata
        chmod 755 $rootdir/var/tmp/dpkg-eatmydata
        cat > $rootdir/etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata <<EOF
Dir::Bin::dpkg "/var/tmp/dpkg-eatmydata";
EOF
    else
        echo $"error: unable to find /usr/bin/eatmydata after installing the eatmydata package"
    fi
}
disable_eatmydata_override() {
    for override in \
        /etc/apt/apt.conf.d/95debian-edu-install-dpkg-eatmydata \
            /var/tmp/dpkg-eatmydata ; do
        echo $"info: Removing apt config to call dpkg via eatmydata"
        if [ -f $rootdir$override ] ; then
            rm -f $rootdir$override
        else
            echo $"warning: missing $rootdir$override"
        fi
    done
    sync # Flush file buffers before continuing
}
set_apt_sources() {
    NEW_MIRROR="$1"
    COMPONENTS="main"
    cat <<EOF > etc/apt/sources.list
deb $NEW_MIRROR $SUITE $COMPONENTS
deb-src $NEW_MIRROR $SUITE $COMPONENTS
#deb http://security.debian.org/ $SUITE/updates main
#deb-src http://security.debian.org/ $SUITE/updates main
EOF
}
configure_networking() {
    if [[ $DEBIAN_INSTALL_ONLY != "no" ]]; then
        return
    fi
    if [[ $GENERIC_IMAGE == "no" ]]; then
        echo "# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
    address $BOX_IP_ADDRESS
    netmask 255.255.255.0
    gateway $ROUTER_IP_ADDRESS
    dns-nameservers $NAMESERVER1 $NAMESERVER2
        # Example to keep MAC address between reboots
        #hwaddress ether B5:A2:BE:3F:1A:FE
        # The secondary network interface
        #auto eth1
        #iface eth1 inet dhcp
        # WiFi Example
        #auto wlan0
        #iface wlan0 inet dhcp
        #    wpa-ssid \"essid\"
        #    wpa-psk  \"password\"
        # Ethernet/RNDIS gadget (g_ether)
        # ... or on host side, usbnet and random hwaddr
        # Note on some boards, usb0 is automaticly setup with an init script
        #iface usb0 inet static
        #    address 192.168.7.2
        #    netmask 255.255.255.0
        #    network 192.168.7.0
        #    gateway 192.168.7.1" > $rootdir/etc/network/interfaces
        hexarray=( 1 2 3 4 5 6 7 8 9 0 a b c d e f )
        a=${hexarray[$RANDOM%16]}${hexarray[$RANDOM%16]}
        b=${hexarray[$RANDOM%16]}${hexarray[$RANDOM%16]}
        c=${hexarray[$RANDOM%16]}${hexarray[$RANDOM%16]}
        d=${hexarray[$RANDOM%16]}${hexarray[$RANDOM%16]}
        e=${hexarray[$RANDOM%16]}${hexarray[$RANDOM%16]}
        sed -i "s|#hwaddress ether.*|hwaddress ether de:$a:$b:$c:$d:$e|g" \
            $rootdir/etc/network/interfaces
    fi
    sed -i "s/nameserver.*/nameserver $NAMESERVER1/g" $rootdir/etc/resolv.conf
    sed -i "/nameserver $NAMESERVER1/a\nameserver $NAMESERVER2" $rootdir/etc/resolv.conf
    if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
        # change the motd to show further install instructions
        echo $"
 .---.                  .              .
 |                      |              |
 |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
 |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
 '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
                    Initial base install
Your system is not yet installed. To complete the process run the
following commands, then enter your details.
    sudo su
    ${PROJECT_NAME} menuconfig
" > $rootdir/etc/motd
    else
        echo $"
 .---.                  .              .
 |                      |              |
 |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
 |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
 '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
                    Freedom in the Mesh
" > $rootdir/etc/motd
    fi
}
configure_ssh() {
    if [[ $VARIANT == "mesh" || $VARIANT == "meshclient" || $VARIANT == "meshusb" ]]; then
        return
    fi
    sed -i "s/Port .*/Port ${SSH_PORT}/g" $rootdir/etc/ssh/sshd_config
    if [[ "$SSH_PUBKEY" != "no" ]]; then
        if [ ! -d $rootdir/home/$MY_USERNAME/.ssh ]; then
            mkdir $rootdir/home/$MY_USERNAME/.ssh
        fi
        echo "$SSH_PUBKEY" > $rootdir/home/$MY_USERNAME/.ssh/authorized_keys
        chroot $rootdir /bin/chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.ssh
        sed -i 's|PasswordAuthentication.*|PasswordAuthentication no|g' $rootdir/etc/ssh/sshd_config
        echo $"Using ssh public key:"
        echo $SSH_PUBKEY
        echo $'Password ssh authentication turned off'
    fi
}
create_generic_image() {
    if [[ $DEBIAN_INSTALL_ONLY != "no" ]]; then
        return
    fi
    if [[ $GENERIC_IMAGE == "no" ]]; then
        return
    fi
    if [ $CONFIG_FILENAME ]; then
        if [[ "$CONFIG_FILENAME" == *"mesh.cfg"* ]]; then
            VARIANT="mesh"
        fi
    fi
    # Don't install any configuration. This will be a base system
    if [[ $VARIANT != "mesh" && $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
        CONFIG_FILENAME=
    else
        touch $rootdir/root/.initial_mesh_setup
    fi
    # Stick with the existing login for mesh clients
    if [[ $VARIANT == "meshclient" || $VARIANT == "meshusb" ]]; then
        return
    fi
    # The presence of this file indicates that the initial
    # setup has not yet been completed
    touch $rootdir/home/$MY_USERNAME/.initial_setup
    chroot $rootdir /bin/chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.initial_setup
    touch $rootdir/root/.initial_setup
    cat >> $rootdir/home/$MY_USERNAME/.bashrc <<EOF
# initial setup of the system
if [ -f ~/.initial_setup ]; then
    clear
    echo "
 .---.                  .              .
 |                      |              |
 |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
 |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
 '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
                    Initial setup process
          Please enter your password a second time.
"
    sudo su
fi
EOF
    echo "MY_USERNAME=${MY_USERNAME}" >> $rootdir/root/.bashrc
    echo "SSH_PORT=${SSH_PORT}" >> $rootdir/root/.bashrc
    echo '# initial setup of the system' >> $rootdir/root/.bashrc
    echo 'if [ -f ~/.initial_setup ]; then' >> $rootdir/root/.bashrc
    echo '    if [ -f ~/login.txt ]; then' >> $rootdir/root/.bashrc
    echo '        NEW_USER_PASSWORD=$(printf `cat ~/login.txt`)' >> $rootdir/root/.bashrc
    echo '    else' >> $rootdir/root/.bashrc
    echo '        ENTROPY=$(cat /proc/sys/kernel/random/entropy_avail)' >> $rootdir/root/.bashrc
    echo '        if [ $ENTROPY -lt 500 ]; then' >> $rootdir/root/.bashrc
    ENTROPY_MESSAGE1=$'Initial setup process'
    ENTROPY_MESSAGE2=$'Password Generation'
    ENTROPY_MESSAGE3=$'WARNING: The entropy available on this system is too low to generate a password.\n\nThe installation process cannot continue.'
    echo "            dialog --backtitle \"${ENTROPY_MESSAGE1}\" --title \"${ENTROPY_MESSAGE2}\" --msgbox \"${ENTROPY_MESSAGE3}\" 8 50" >> $rootdir/root/.bashrc
    echo '            exit' >> $rootdir/root/.bashrc
    echo '        fi' >> $rootdir/root/.bashrc
    echo -n '        NEW_USER_PASSWORD="$(openssl rand -base64 30 | cut -c1-' >> $rootdir/root/.bashrc
    echo "${DEFAULT_PASSWORD_LENGTH})\"" >> $rootdir/root/.bashrc
    echo '    fi' >> $rootdir/root/.bashrc
    echo '    echo "${NEW_USER_PASSWORD}" > ~/login.txt' >> $rootdir/root/.bashrc
    echo '    clear' >> $rootdir/root/.bashrc
    echo '    echo ""' >> $rootdir/root/.bashrc
    NEW_LOGIN_PASSWORD_MESSAGE1=$'Your new login password is:'
    NEW_LOGIN_PASSWORD_MESSAGE2=$'Use it whenever you wish to ssh into this system.'
    NEW_LOGIN_PASSWORD_MESSAGE3=$'IMPORTANT: Please take a moment to enter the above password into a\npassword manager or write it down somewhere.'
    PRESS_KEY_MESSAGE=$'Press any key to continue...'
    echo "    echo \"${NEW_LOGIN_PASSWORD_MESSAGE1}\"" >> $rootdir/root/.bashrc
    echo '    echo ""' >> $rootdir/root/.bashrc
    echo '    echo "                          ${NEW_USER_PASSWORD}"' >> $rootdir/root/.bashrc
    echo '    echo ""' >> $rootdir/root/.bashrc
    echo "    echo \"${NEW_LOGIN_PASSWORD_MESSAGE2}\"" >> $rootdir/root/.bashrc
    echo '    echo ""' >> $rootdir/root/.bashrc
    echo "    echo \"${NEW_LOGIN_PASSWORD_MESSAGE3}\"" >> $rootdir/root/.bashrc
    echo '    echo ""' >> $rootdir/root/.bashrc
    echo "    read -n1 -r -p \"${PRESS_KEY_MESSAGE}\" key" >> $rootdir/root/.bashrc
    # change the password for the admin user
    echo -n "    echo \"${MY_USERNAME}:" >> $rootdir/root/.bashrc
    echo '$(printf `cat ~/login.txt`)"|chpasswd' >> $rootdir/root/.bashrc
    # update before continuing
    echo "    cd /root/${PROJECT_NAME}" >> $rootdir/root/.bashrc
    echo "    git stash" >> $rootdir/root/.bashrc
    echo "    git pull" >> $rootdir/root/.bashrc
    echo "    make install" >> $rootdir/root/.bashrc
    if [[ $VARIANT != "mesh" && $VARIANT != "meshclient" && $VARIANT != "meshusb" && $VARIANT != "usb" ]]; then
        if [[ $ONION_ONLY == "no" ]]; then
            if [[ $MINIMAL_INSTALL == "no" ]]; then
                echo "    ${PROJECT_NAME} menuconfig-full" >> $rootdir/root/.bashrc
            else
                echo "    ${PROJECT_NAME} menuconfig" >> $rootdir/root/.bashrc
            fi
        else
            echo "    ${PROJECT_NAME} menuconfig-onion" >> $rootdir/root/.bashrc
        fi
    else
        echo "    echo ''" >> $rootdir/root/.bashrc
    fi
    echo '    if [ "$?" = "0" ]; then' >> $rootdir/root/.bashrc
    echo "        if [ -f ~/${PROJECT_NAME}-completed.txt ]; then" >> $rootdir/root/.bashrc
    # Remove the initial setup files
    echo '            rm /root/.initial_setup' >> $rootdir/root/.bashrc
    echo '            rm /home/fbone/.initial_setup' >> $rootdir/root/.bashrc
    echo "            touch /root/.remove_${GENERIC_IMAGE_USERNAME}" >> $rootdir/root/.bashrc
    echo '            shred -zu ~/login.txt' >> $rootdir/root/.bashrc
    END_MESSAGE1=$'Congratulations!'
    if [[ $VARIANT != "mesh" && $VARIANT != "meshclient" && $VARIANT != "meshusb" && $VARIANT != "usb" ]]; then
        END_MESSAGE2=$'\nYour system has now installed\n\nThe onion ssh service is at:\n\n  ${SSH_ONION_HOSTNAME}\n\nTo copy the above address hold down the shift key and double left click on it, then right click and select "copy".\n\nPress any key to reboot and begin using the system'
        echo '            SSH_ONION_HOSTNAME=$(cat /var/lib/tor/hidden_service_ssh/hostname)' >> $rootdir/root/.bashrc
        echo '            if [ ${#SSH_ONION_HOSTNAME} -lt 2 ]; then' >> $rootdir/root/.bashrc
        echo '                exit 62392' >> $rootdir/root/.bashrc
        echo '            fi' >> $rootdir/root/.bashrc
        END_MESSAGE_HEIGHT=16
    else
        END_MESSAGE2=$'\nYour system has now installed\n\nPress any key to reboot and begin using it'
        END_MESSAGE_HEIGHT=12
    fi
    echo "            if [ -f /root/${PROJECT_NAME}-wifi.cfg ]; then" >> $rootdir/root/.bashrc
    echo "                echo '[Unit]' > /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'Description=WifiStartup (Start wifi networking)' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'After=syslog.target' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'After=network.target' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'After=remote-fs.target' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo '' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo '[Service]' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'Type=simple' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'User=root' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'Group=root' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'WorkingDirectory=/root' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'ExecStart=/usr/local/bin/freedombone-wifi --wait 5 2> /dev/null' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo '' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo '[Install]' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                echo 'WantedBy=multi-user.target' >> /etc/systemd/system/wifistart.service" >> $rootdir/root/.bashrc
    echo "                systemctl enable wifistart" >> $rootdir/root/.bashrc
    echo "                systemctl daemon-reload" >> $rootdir/root/.bashrc
    echo '            fi' >> $rootdir/root/.bashrc
    echo "            dialog --title '$END_MESSAGE1' --msgbox \"$END_MESSAGE2\" ${END_MESSAGE_HEIGHT} 60" >> $rootdir/root/.bashrc
    echo '            reboot' >> $rootdir/root/.bashrc
    echo '        fi' >> $rootdir/root/.bashrc
    echo '    else' >> $rootdir/root/.bashrc
    echo '        key=' >> $rootdir/root/.bashrc
    echo '        while [[ $key != "x" ]]; do' >> $rootdir/root/.bashrc
    INSTALL_FAIL_MESSAGE=$"Install failed. Press x to continue..."
    echo "            read -n1 -r -p \"${INSTALL_FAIL_MESSAGE}\" key" >> $rootdir/root/.bashrc
    echo '        done' >> $rootdir/root/.bashrc
    echo '    fi' >> $rootdir/root/.bashrc
    echo '    exit' >> $rootdir/root/.bashrc
    echo 'else' >> $rootdir/root/.bashrc
    echo '    # Remove default account after install' >> $rootdir/root/.bashrc
    echo "    if [ -f /root/.remove_${GENERIC_IMAGE_USERNAME} ]; then" >> $rootdir/root/.bashrc
    echo "        if [ -d /home/${GENERIC_IMAGE_USERNAME} ]; then" >> $rootdir/root/.bashrc
    echo "           userdel -r ${GENERIC_IMAGE_USERNAME}" >> $rootdir/root/.bashrc
    echo "           if [ -d /home/${GENERIC_IMAGE_USERNAME} ]; then" >> $rootdir/root/.bashrc
    echo "               rm -rf /home/${GENERIC_IMAGE_USERNAME}" >> $rootdir/root/.bashrc
    echo "               rm /root/.remove_${GENERIC_IMAGE_USERNAME}" >> $rootdir/root/.bashrc
    echo '           fi' >> $rootdir/root/.bashrc
    echo '        fi' >> $rootdir/root/.bashrc
    echo '    fi' >> $rootdir/root/.bashrc
    echo 'fi' >> $rootdir/root/.bashrc
}
continue_installation() {
    # If a configuration file exists then run with it
    # otherwise the interactive installer can be used
    # This is equivalent to installing freedombox-setup on freedombox
    if [ $CONFIG_FILENAME ]; then
        if [ ${#CONFIG_FILENAME} -gt 2 ]; then
            cp $CONFIG_FILENAME $rootdir/root/$PROJECT_NAME.cfg
            cat $rootdir/root/$PROJECT_NAME.cfg
            chroot "$rootdir" su -c "$PROJECT_NAME -c /root/$PROJECT_NAME.cfg" - root
        fi
    fi
}
atheros_wifi() {
    firmware_filename="open-ath9k-htc-firmware_1.3-1_all.deb"
    firmware_hash='5fea58ffefdf0ef15b504db7fbe3bc078c03e0d927bba64085e4b6f2546102f5'
    firmware_url="http://us.archive.trisquel.info/trisquel/pool/main/o/open-ath9k-htc-firmware/$firmware_filename"
    firmware_tempfile="/tmp/$firmware_filename"
    wget "$firmware_url" -O "$rootdir$firmware_tempfile"
    downloaded_firmware_hash=$(sha256sum "$rootdir$firmware_tempfile" | awk -F ' ' '{print $1}')
    if [[ "$downloaded_firmware_hash" == "$firmware_hash" ]]; then
        chroot "$rootdir" dpkg -i "$firmware_tempfile"
    else
        echo 'WARNING: Atheros Wifi firmware hash does not match. The driver has not been installed.'
    fi
}
configure_wifi() {
    if [[ $VARIANT == "mesh"* ]]; then
        return
    fi
    if [ -f $WIFI_NETWORKS_FILE ]; then
        chroot "$rootdir" ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE
        return
    fi
    if [[ $WIFI_TYPE != 'none' ]]; then
        if [ ${#WIFI_PASSPHRASE} -lt 2 ]; then
            return
        fi
        chroot "$rootdir" ${PROJECT_NAME}-wifi -s $WIFI_SSID -t $WIFI_TYPE -p $WIFI_PASSPHRASE --hotspot $WIFI_HOTSPOT
    else
        chroot "$rootdir" ${PROJECT_NAME}-wifi -s $WIFI_SSID -t $WIFI_TYPE --hotspot $WIFI_HOTSPOT
    fi
}
##############################################################################
# Mesh networking
##############################################################################
# for mesh installs
TRACKER_PORT=6969
WIFI_CHANNEL=2
# B.A.T.M.A.N settings
BATMAN_CELLID='02:BA:00:00:03:01'
WIFI_SSID='mesh'
# To avoid confusions these are obtained from the main project file
TOXID_REPO=
TOX_PORT=
TOXCORE_REPO=
TOXIC_REPO=
TOXCORE_COMMIT=
TOXIC_COMMIT=
# These are some default nodes, but you can replace them with trusted nodes
# as you prefer. See https://wiki.tox.im/Nodes
TOX_NODES=
#TOX_NODES=(
#  '192.254.75.102,2607:5600:284::2,33445,951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F,Tox RELENG,US'
#  '144.76.60.215,2a01:4f8:191:64d6::1,33445,04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F,sonOfRa,DE'
#)
# To avoid confusions these are obtained from the main project file
ZERONET_REPO=
ZERONET_COMMIT=
ZERONET_PORT=
ZERONET_BLOG_REPO=
ZERONET_BLOG_COMMIT=
ZERONET_MAIL_REPO=
ZERONET_MAIL_COMMIT=
ZERONET_FORUM_REPO=
ZERONET_FORUM_COMMIT=
ZERONET_ID_REPO=
ZERONET_ID_COMMIT=
# Directory where source code is downloaded and compiled
INSTALL_DIR=$HOME/build
INSTALLING_MESH=
initialise_mesh() {
    if [[ $VARIANT != "mesh" && $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
        return
    fi
    if [[ $DEBIAN_INSTALL_ONLY != "no" ]]; then
        return
    fi
    if [[ $INSECURE == $'yes' ]]; then
        echo  '*********************************************************'
        echo $'WARNING: non-free wifi drivers are being installed.'
        echo $'         This may compromise the security of your system.'
        echo  '*********************************************************'
        # enable non-free repo
        if ! grep -q "non-free" $rootdir/etc/apt/sources.list; then
            chroot "$rootdir" /bin/sed -i "s| main| main non-free|g" /etc/apt/sources.list
        fi
        chroot "$rootdir" apt-get update
        # install proprietary wifi drivers
        # see https://wiki.debian.org/iwlwifi
        chroot "$rootdir" apt-get -yq install firmware-iwlwifi firmware-b43-installer firmware-brcm80211
    fi
    INSTALLING_MESH=1
    configure_firewall
    install_avahi
    install_batman
    install_tomb
    #install_tahoelafs
    #install_librevault
    install_ipfs
    install_tox
    install_web_server
    install_pelican
    if [ $ENABLE_ZERONET ]; then
        install_zeronet
    fi
    MESH_SERVICE='mesh-setup.service'
    MESH_SETUP_DAEMON=$rootdir/etc/systemd/system/$MESH_SERVICE
    MESH_STARTUP_PARAMS="${MY_USERNAME}"
    if [[ $AMNESIC != 'no' ]]; then
        MESH_STARTUP_PARAMS="${MY_USERNAME} amnesic"
    fi
    echo '[Unit]' > $MESH_SETUP_DAEMON
    echo 'Description=Initial mesh router configuration' >> $MESH_SETUP_DAEMON
    echo 'After=syslog.target' >> $MESH_SETUP_DAEMON
    echo 'After=network.target' >> $MESH_SETUP_DAEMON
    echo '[Service]' >> $MESH_SETUP_DAEMON
    echo 'Type=simple' >> $MESH_SETUP_DAEMON
    echo 'User=root' >> $MESH_SETUP_DAEMON
    echo 'Group=root' >> $MESH_SETUP_DAEMON
    echo 'WorkingDirectory=/root' >> $MESH_SETUP_DAEMON
    echo "ExecStart=/usr/local/bin/${PROJECT_NAME}-image-mesh ${MESH_STARTUP_PARAMS} > /var/log/mesh-setup.log" >> $MESH_SETUP_DAEMON
    echo '' >> $MESH_SETUP_DAEMON
    echo 'TimeoutSec=99999' >> $MESH_SETUP_DAEMON
    echo '' >> $MESH_SETUP_DAEMON
    echo '[Install]' >> $MESH_SETUP_DAEMON
    echo 'WantedBy=multi-user.target' >> $MESH_SETUP_DAEMON
    chroot "$rootdir" systemctl enable $MESH_SERVICE
}
# User interface for USB drive installs ######################################
function mesh_client_startup_applications {
    if [ ! -d $rootdir/home/$MY_USERNAME/Desktop ]; then
        mkdir -p $rootdir/home/$MY_USERNAME/Desktop
    fi
    if [ ! -d $rootdir/home/$MY_USERNAME/.config/autostart ]; then
        mkdir -p $rootdir/home/$MY_USERNAME/.config/autostart
        chroot "$rootdir" /bin/chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.config
    fi
    START_DESKTOP=$rootdir/home/$MY_USERNAME/mesh-desktop.sh
    FIRST_BOOT=/home/$MY_USERNAME/.first_boot
    TAHOE_COMMAND="cd /var/lib/tahoelafs && venv/bin/tahoe"
    echo '#!/bin/bash' > $START_DESKTOP
    echo "setxkbmap ${KEYBOARD_MAP}" > $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/volumes-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/computer-icon-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/home-icon-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/network-icon-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/trash-icon-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/caja/desktop/volumes-visible false' >> $START_DESKTOP
    echo 'dconf write /org/mate/desktop/media-handling/automount-open false' >> $START_DESKTOP
    echo 'dconf write /org/mate/screensaver/lock-enabled false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-keyring-suspend false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-suspend false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-use-screensaver false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-blank-screen false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-hibernate false' >> $START_DESKTOP
    echo 'dconf write /org/mate/power-manager/lock-keyring-hibernate false' >> $START_DESKTOP
    echo 'dconf write /org/mate/desktop/peripherals/touchpad/scroll-method 2' >> $START_DESKTOP
    echo "touch /home/$MY_USERNAME/.dbus/Xdbus" >> $START_DESKTOP
    echo "chmod 600 /home/$MY_USERNAME/.dbus/Xdbus" >> $START_DESKTOP
    echo "env | grep DBUS_SESSION_BUS_ADDRESS > /home/$MY_USERNAME/.dbus/Xdbus" >> $START_DESKTOP
    echo "echo 'export DBUS_SESSION_BUS_ADDRESS' >> /home/$MY_USERNAME/.dbus/Xdbus" >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo "amixer set 'Master' unmute" >> $START_DESKTOP
    echo "amixer set 'Master' 50%" >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo "if [ ! -f $FIRST_BOOT ]; then" >> $START_DESKTOP
    echo "  $TAHOE_COMMAND start" >> $START_DESKTOP
    echo '  exit 0' >> $START_DESKTOP
    echo 'fi' >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo 'INITIAL_TOX_USERNAME=""' >> $START_DESKTOP
    echo 'while [ ${#INITIAL_TOX_USERNAME} -eq 0 ]; do' >> $START_DESKTOP
    echo '  data=$(tempfile 2>/dev/null)' >> $START_DESKTOP
    echo '  trap "rm -f $data" 0 1 2 5 15' >> $START_DESKTOP
    echo -n "   dialog --title \"${MESH_TITLE}\" " >> $START_DESKTOP
    echo -n "--backtitle \"${MESH_TITLE}\" " >> $START_DESKTOP
    echo -n "--inputbox \"${MESH_SET_USERNAME}\" 12 60 Anon " >> $START_DESKTOP
    echo '2>$data' >> $START_DESKTOP
    echo '  sel=$?' >> $START_DESKTOP
    echo '  case $sel in' >> $START_DESKTOP
    echo '      0)' >> $START_DESKTOP
    echo '          INITIAL_TOX_USERNAME=$(<$data)' >> $START_DESKTOP
    echo '          ;;' >> $START_DESKTOP
    echo '  esac' >> $START_DESKTOP
    echo 'done' >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo 'toxid --setuser "$INITIAL_TOX_USERNAME"' >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo "if [ -f /home/$MY_USERNAME/.tahoe/tahoe.cfg ]; then" >> $START_DESKTOP
    echo "    sed -i 's|nickname =.*|nickname = \$INITIAL_TOX_USERNAME|g' /home/$MY_USERNAME/.tahoe/tahoe.cfg" >> $START_DESKTOP
    echo "    $TAHOE_COMMAND restart" >> $START_DESKTOP
    echo 'fi' >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo "rm -f $FIRST_BOOT" >> $START_DESKTOP
    echo '' >> $START_DESKTOP
    echo 'exit 0' >> $START_DESKTOP
    chmod +x $START_DESKTOP
    START_DESKTOP2=$rootdir/home/$MY_USERNAME/.config/autostart/mesh-start.desktop
    echo '[Desktop Entry]' > $START_DESKTOP2
    echo 'Type=Application' >> $START_DESKTOP2
    echo 'Name=Mesh start desktop script' >> $START_DESKTOP2
    echo "Exec=bash -c '~/mesh-desktop.sh'" >> $START_DESKTOP2
    echo 'X-GNOME-Autostart-enabled=true' >> $START_DESKTOP2
    chmod +x $START_DESKTOP2
    START_DESKTOP3=$rootdir/home/$MY_USERNAME/.config/autostart/set_username.desktop
    echo '[Desktop Entry]' > $START_DESKTOP3
    echo 'Version=1.0' >> $START_DESKTOP3
    echo 'Name=Set Username' >> $START_DESKTOP3
    echo 'Type=Application' >> $START_DESKTOP3
    echo 'Comment=Set username' >> $START_DESKTOP3
    echo "Exec=mate-terminal -e \"bash -c /home/${MY_USERNAME}/mesh-desktop.sh\"" >> $START_DESKTOP3
    echo 'Icon=user-away' >> $START_DESKTOP3
    echo 'Terminal=false' >> $START_DESKTOP3
    echo 'Categories=Application;' >> $START_DESKTOP3
    chmod +x $START_DESKTOP3
}
function mesh_desktop_icons {
    if [ ! -d $rootdir/home/$MY_USERNAME/Desktop ]; then
        mkdir -p $rootdir/home/$MY_USERNAME/Desktop
    fi
    # Terminal
    #echo '[Desktop Entry]' > $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'Name=MATE Terminal' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'Type=Application' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'Comment=Use the command line' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'TryExec=mate-terminal' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'Exec=mate-terminal' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'Icon=terminal' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    #echo 'StartupNotify=true' >> $rootdir/home/$MY_USERNAME/Desktop/terminal.desktop
    chroot "$rootdir" /bin/chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Desktop
}
function configure_user_interface {
    if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" && $VARIANT != "usb" ]]; then
        return
    fi
    # desktop
    chroot "$rootdir" apt-get -yq install mate-desktop-environment
    # tool to change desktop settings from command line
    chroot "$rootdir" apt-get -yq install dconf-cli dconf-gsettings-backend dbus dbus-x11
    # for tomb
    chroot "$rootdir" apt-get -yq install pinentry-gtk2
    # for tox video
    chroot "$rootdir" apt-get -yq install ffmpeg cheese v4l-utils
    # to provide notifications
    chroot "$rootdir" apt-get -yq install libnotify-bin
    # for video/audio
    chroot "$rootdir" apt-get -yq install libtheora-bin libvorbis-dev v4l-utils
    # a sane editor
    chroot "$rootdir" apt-get -yq install emacs24
    # for wifi monitoring
    chroot "$rootdir" apt-get -yq install horst
    # for sound level control
    chroot "$rootdir" apt-get -yq install alsa-utils
    # to play various media types
    chroot "$rootdir" apt-get -yq install vlc
    # android adb to allow phones to be connected and for example transfer photos/documents
    chroot "$rootdir" apt-get -yq install android-tools-adb
    # Produce a text file on the desktop listing users on the mesh
    cat <<EOF > $rootdir/usr/bin/list-tox-users
#!/bin/bash
users_list=\$(lstox | awk -F ' ' '{\$1=""; print \$0}' | sed -e 's/^[[:space:]]*//' | sort -d)
if [ ! \$users_list ]; then
    no_of_users=0
else
    no_of_users=\$(echo "\$users_list" | wc -l)
fi
if [ \$no_of_users -gt 0 ]; then
    echo "\$users_list" > /tmp/Users.txt
    chown $MY_USERNAME:$MY_USERNAME /tmp/Users.txt
    echo 'showing_users=\$(ps aux | grep $MESH_TEXT_EDITOR | grep "Users.txt")' > /home/$MY_USERNAME/showusers
    echo 'if [ \${#showing_users} -eq 0 ]; then' >> /home/$MY_USERNAME/showusers
    echo '    $MESH_TEXT_EDITOR /tmp/Users.txt' >> /home/$MY_USERNAME/showusers
    echo 'fi' >> /home/$MY_USERNAME/showusers
    echo 'exit 0' >> /home/$MY_USERNAME/showusers
    chmod +x /home/$MY_USERNAME/showusers
    chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/showusers
    echo '[Desktop Entry]' > /home/$MY_USERNAME/Desktop/Users.desktop
    if [ \$no_of_users -lt 2 ]; then
        echo "Name=\$no_of_users Other User" >> /home/$MY_USERNAME/Desktop/Users.desktop
    else
        echo "Name=\$no_of_users Other Users" >> /home/$MY_USERNAME/Desktop/Users.desktop
    fi
    echo 'Type=Application' >> /home/$MY_USERNAME/Desktop/Users.desktop
    echo 'Comment=List of users' >> /home/$MY_USERNAME/Desktop/Users.desktop
    echo 'Exec=bash /home/$MY_USERNAME/showusers' >> /home/$MY_USERNAME/Desktop/Users.desktop
    echo 'Icon=/usr/share/$PROJECT_NAME/avatars/otheruser.png' >> /home/$MY_USERNAME/Desktop/Users.desktop
    echo 'StartupNotify=false' >> /home/$MY_USERNAME/Desktop/Users.desktop
    chmod +x /home/$MY_USERNAME/Desktop/Users.desktop
    chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Desktop/Users.desktop
    if [ -f /tmp/.ipfs-users ]; then
        echo '[Desktop Entry]' > /home/$MY_USERNAME/Desktop/sites.desktop
        echo 'Type=Application' >> /home/$MY_USERNAME/Desktop/sites.desktop
        echo "Name=Visit a site" >> /home/$MY_USERNAME/Desktop/sites.desktop
        echo 'Comment=Visit a site' >> /home/$MY_USERNAME/Desktop/sites.desktop
        echo 'Exec=mate-terminal -e /usr/local/bin/${PROJECT_NAME}-mesh-visit-site' >> /home/$MY_USERNAME/Desktop/sites.desktop
        echo 'Icon=/usr/share/${PROJECT_NAME}/avatars/ipfs.jpg' >> /home/$MY_USERNAME/Desktop/sites.desktop
        echo 'StartupNotify=false' >> /home/$MY_USERNAME/Desktop/sites.desktop
        chmod +x /home/$MY_USERNAME/Desktop/sites.desktop
        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Desktop/sites.desktop
        echo '[Desktop Entry]' > /home/$MY_USERNAME/Desktop/blog.desktop
        echo 'Type=Application' >> /home/$MY_USERNAME/Desktop/blog.desktop
        echo "Name=Blog" >> /home/$MY_USERNAME/Desktop/blog.desktop
        echo 'Comment=View or create blog entries' >> /home/$MY_USERNAME/Desktop/blog.desktop
        echo 'Exec=mate-terminal -e /usr/local/bin/${PROJECT_NAME}-mesh-blog' >> /home/$MY_USERNAME/Desktop/blog.desktop
        echo 'Icon=/usr/share/${PROJECT_NAME}/avatars/blog.png' >> /home/$MY_USERNAME/Desktop/blog.desktop
        echo 'StartupNotify=false' >> /home/$MY_USERNAME/Desktop/blog.desktop
        chmod +x /home/$MY_USERNAME/Desktop/blog.desktop
        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Desktop/blog.desktop
    fi
    if [ ! -f /home/$MY_USERNAME/runtox ]; then
        echo 'qtox_running=\$(ps aux | grep qtox | grep data)' > /home/$MY_USERNAME/runtox
        echo 'if [ \${#qtox_running} -eq 0 ]; then' >> /home/$MY_USERNAME/runtox
        echo '    bash -c "qtox -p data"' >> /home/$MY_USERNAME/runtox
        echo 'fi' >> /home/$MY_USERNAME/runtox
        echo 'exit 0' >> /home/$MY_USERNAME/runtox
        chmod +x /home/$MY_USERNAME/runtox
        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/runtox
    fi
    if [ ! -f /home/$MY_USERNAME/Desktop/tox.desktop ]; then
        echo '[Desktop Entry]' > /home/$MY_USERNAME/Desktop/tox.desktop
        echo 'Name=Chat' >> /home/$MY_USERNAME/Desktop/tox.desktop
        echo 'Type=Application' >> /home/$MY_USERNAME/Desktop/tox.desktop
        echo 'Comment=Chat, Voice and Video' >> /home/$MY_USERNAME/Desktop/tox.desktop
        echo 'Exec=bash /home/$MY_USERNAME/runtox' >> /home/$MY_USERNAME/Desktop/tox.desktop
        echo "Icon=/usr/share/$PROJECT_NAME/avatars/chat.png" >> /home/$MY_USERNAME/Desktop/tox.desktop
        echo 'StartupNotify=true' >> /home/$MY_USERNAME/Desktop/tox.desktop
        chmod +x /home/$MY_USERNAME/Desktop/tox.desktop
        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Desktop/tox.desktop
    fi
else
    if [ -f /tmp/Users.txt ]; then
        rm /tmp/Users.txt
        rm /home/$MY_USERNAME/Desktop/Users.desktop
        if [ -f /home/$MY_USERNAME/Desktop/Users.desktop ]; then
            rm /home/$MY_USERNAME/Desktop/Users.desktop
        fi
        if [ -f /home/$MY_USERNAME/Desktop/sites.desktop ]; then
            rm /home/$MY_USERNAME/Desktop/sites.desktop
        fi
        if [ -f /home/$MY_USERNAME/Desktop/blog.desktop ]; then
            rm /home/$MY_USERNAME/Desktop/blog.desktop
        fi
        if [ -f /home/$MY_USERNAME/Desktop/tox.desktop ]; then
            rm /home/$MY_USERNAME/Desktop/tox.desktop
        fi
        pkill qtox
    fi
fi
EOF
    chroot "$rootdir" /bin/chown $MY_USERNAME:$MY_USERNAME /usr/bin/list-tox-users
    chroot "$rootdir" /bin/chmod +x /usr/bin/list-tox-users
    echo "* *       * * *   $MY_USERNAME    bash -c /usr/bin/list-tox-users > /dev/null" >> $rootdir/etc/crontab
    if [[ $VARIANT != "usb" ]]; then
        # log in automatically
        chroot "$rootdir" apt-get -y install nodm xinit
        echo 'NODM_ENABLED=true' > /etc/default/nodm
        echo "NODM_USER=$MY_USERNAME" >> /etc/default/nodm
        chroot "$rootdir" mkdir /etc/systemd/system/getty@tty1.service.d
        echo '[Service]' > $rootdir/etc/systemd/system/getty@tty1.service.d/override.conf
        echo 'ExecStart=' >> $rootdir/etc/systemd/system/getty@tty1.service.d/override.conf
        echo 'ExecStart=-/sbin/agetty --autologin fbone --noclear %I $TERM' >> $rootdir/etc/systemd/system/getty@tty1.service.d/override.conf
        echo '[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec startx' >> $rootdir/home/$MY_USERNAME/.profile
        chroot "$rootdir" systemctl set-default multi-user.target
        mesh_client_startup_applications
        mesh_desktop_icons
        # Different desktop background for amnesic
        if [[ $AMNESIC != 'no' ]]; then
            MESH_DESKTOP_BACKGROUND_IMAGE=/usr/local/share/${PROJECT_NAME}_mesh_amnesic_background.png
        fi
        # change the desktop background
        if [ $MESH_DESKTOP_BACKGROUND_IMAGE ]; then
            if [ -f $MESH_DESKTOP_BACKGROUND_IMAGE ]; then
                if [ -d $rootdir/usr/share/images/desktop-base ]; then
                    cp $MESH_DESKTOP_BACKGROUND_IMAGE $rootdir/usr/share/images/desktop-base/${PROJECT_NAME}_mesh_background.png
                    chroot "$rootdir" /bin/rm /usr/share/images/desktop-base/desktop-background
                    chroot "$rootdir" ln -s /usr/share/images/desktop-base/${PROJECT_NAME}_mesh_background.png /usr/share/images/desktop-base/desktop-background
                fi
            fi
        fi
    else
        chroot "$rootdir" apt-get -yq install lightdm
    fi
    # browser
    chroot "$rootdir" apt-get -yq install $BROWSER
    # help
    mkdir -p $rootdir/home/${MY_USERNAME}/help/images
    cd $rootdir/root/${PROJECT_NAME}/website
    ./deploy.sh EN $rootdir/home/${MY_USERNAME}/help
    chroot "$rootdir" /bin/chown -R ${MY_USERNAME}:${MY_USERNAME} /home/${MY_USERNAME}/help
    # Tox user interface
    enable_tox_repo
    mesh_tox_qtox
    # copy the default qtox ini file
    if [ ! -d ${rootdir}/home/${MY_USERNAME}/.config/tox ]; then
        mkdir ${rootdir}/home/${MY_USERNAME}/.config/tox
        cp /usr/local/bin/${PROJECT_NAME}-config-qtox ${rootdir}/home/${MY_USERNAME}/.config/tox/qtox.ini
        chroot "$rootdir" /bin/chown -R ${MY_USERNAME}:${MY_USERNAME} /home/${MY_USERNAME}/.config
    fi
    if [[ $VARIANT == "usb" ]]; then
        # tor
        chroot "$rootdir" apt-get -y install tor
        # xmpp client
        chroot "$rootdir" echo "deb ftp://ftp.gajim.org/debian unstable main" > /etc/apt/sources.list.d/gajim.list
        chroot "$rootdir" apt-get update
        chroot "$rootdir" apt-get -yq install gajim-dev-keyring
        chroot "$rootdir" apt-get -yq install git python-dev python-pip gajim-nightly
        chroot "$rootdir" mkdir /home/$GENERIC_IMAGE_USERNAME/.local/share/gajim/plugins -p
        chroot "$rootdir" git clone https://github.com/omemo/gajim-omemo /home/$GENERIC_IMAGE_USERNAME/.local/share/gajim/plugins/gajim-omemo
        chroot "$rootdir" pip install protobuf==2.6.1, python-axolotl==0.1.35
        chroot "$rootdir" /bin/chown -R $GENERIC_IMAGE_USERNAME:$GENERIC_IMAGE_USERNAME /home/$GENERIC_IMAGE_USERNAME/.local
        # IRC client
        chroot "$rootdir" apt-get -yq install hexchat profanity
    fi
}
##############################################################################
# Set to true/false to control if eatmydata is used during build
use_eatmydata=true
rootdir="$1"
fmdir="$(pwd)"
image="$fmdir"/"$2"
cd "$rootdir"
echo info: building $MACHINE for $ARCHITECTURE
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
export LC_ALL=C LANGUAGE=C LANG=C
# Override libpam-tmpdir setting during build, as the directories
# are not created yet.
export TMP=/tmp/ TMPDIR=/tmp/
if [ ! $MY_USERNAME ]; then
    echo $'No username was specified'
    exit 52825
fi
username=$MY_USERNAME
echo $"warning: creating initial user $username with well known password!"
password=$MY_PASSWORD
chroot "$rootdir" /usr/bin/env -i \
    HOME=/root                    \
    PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
echo "export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:" >> $rootdir/root/.bashrc
chroot "$rootdir" adduser --gecos $username --disabled-password $username
echo $username:$password | chroot "$rootdir" /usr/sbin/chpasswd
chroot "$rootdir" adduser $username sudo
if [ ! $DEBIAN_REPO ]; then
    DEBIAN_REPO='ftp.de.debian.org'
fi
if [ ! $DEBIAN_VERSION ]; then
    DEBIAN_VERSION='jessie'
fi
set_apt_sources $BUILD_MIRROR
chroot "$rootdir" apt-get clean
chroot "$rootdir" /bin/rm -rf /var/lib/apt/lists/*
chroot "$rootdir" apt-get clean
set_apt_sources $MIRROR
configure_backports
configure_contrib_repo
chroot "$rootdir" apt-get update
chroot "$rootdir" apt-get install -y apt-utils
cat > $rootdir/usr/sbin/policy-rc.d <<EOF
#!/bin/sh
exit 101
EOF
chmod a+rx $rootdir/usr/sbin/policy-rc.d
if $use_eatmydata ; then
    enable_eatmydata_override
fi
if [ -n "$CUSTOM_SETUP" ]; then
    cp "$CUSTOM_SETUP" "$rootdir"/tmp
    chroot "$rootdir" apt-get install -y gdebi-core
    chroot "$rootdir" gdebi -n /tmp/"$(basename $CUSTOM_SETUP)"
fi
if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" && $VARIANT != "mesh" ]]; then
    chroot "$rootdir" apt-get install -y openssh-server
fi
chroot "$rootdir" apt-get install -y sudo git dialog build-essential
chroot "$rootdir" apt-get install -y avahi-daemon avahi-utils avahi-discover avahi-autoipd
chroot "$rootdir" apt-get install -y iptables dnsutils net-tools network-manager iputils-ping
chroot "$rootdir" apt-get install -y libnss-mdns libnss-myhostname libnss-gw-name nano man ntp
chroot "$rootdir" apt-get install -y locales locales-all debconf wireless-tools wpasupplicant usbutils
if [[ $ARCHITECTURE == 'qemu'* || $ARCHITECTURE == 'i386' || $ARCHITECTURE == 'i686' || $ARCHITECTURE == 'amd64' || $ARCHITECTURE == 'x86_64' ]]; then
    chroot "$rootdir" apt-get install -y cryptsetup zsh pinentry-curses iotop bc
    chroot "$rootdir" apt-get install -y grub2 hostapd
fi
sed -i "s|#host-name=.*|host-name=${PROJECT_NAME}|g" $rootdir/etc/avahi/avahi-daemon.conf
sed -i "s|host-name=.*|host-name=${PROJECT_NAME}|g" $rootdir/etc/avahi/avahi-daemon.conf
chroot "$rootdir" /bin/bash -x <<EOF
git clone $PROJECT_REPO /root/$PROJECT_NAME
cd /root/$PROJECT_NAME
git checkout origin/stockholm -b stockholm
make install
EOF
chroot "$rootdir" ${PROJECT_NAME}-image-hardware-setup 2>&1 | \
    tee $rootdir/var/log/${PROJECT_NAME}-image-hardware-setup.log
rm $rootdir/usr/sbin/policy-rc.d
# Set up HRNG for systems known to have one
# Otherwise install haveged
if [[ "$MACHINE" != "beaglebone" ]]; then
    chroot $rootdir apt-get -yq install haveged
else
    chroot $rootdir apt-get -yq install rng-tools
    sed -i 's|#HRNGDEVICE=/dev/hwrng|HRNGDEVICE=/dev/hwrng|g' $rootdir/etc/default/rng-tools
fi
# copy u-boot to beginning of image
case "$MACHINE" in
    beaglebone)
        dd if=$rootdir/usr/lib/u-boot/am335x_boneblack/MLO of="$image" \
           count=1 seek=1 conv=notrunc bs=128k
        dd if=$rootdir/usr/lib/u-boot/am335x_boneblack/u-boot.img of="$image" \
           count=2 seek=1 conv=notrunc bs=384k
        ;;
    cubieboard2)
        dd if=$rootdir/usr/lib/u-boot/Cubieboard2/u-boot-sunxi-with-spl.bin of="$image" \
           seek=8 conv=notrunc bs=1k
        ;;
    a20-olinuxino-lime)
        dd if=$rootdir/usr/lib/u-boot/A20-OLinuXino-Lime/u-boot-sunxi-with-spl.bin \
           of="$image" seek=8 conv=notrunc bs=1k
        ;;
esac
if $use_eatmydata ; then
    disable_eatmydata_override
fi
configure_ssh
configure_networking
admin_user_sudo
create_generic_image
atheros_wifi
continue_installation
initialise_mesh
configure_wifi
configure_user_interface
# remove downloaded packages
chroot $rootdir apt-get clean
cd /
echo $"info: killing leftover processes in chroot"
fuser -mvk $rootdir/. || true
exit 0
 |