#!/bin/sh # Mini/Temporary ProteanOS Development Kit # miniprokit.sh # Main program file # # Copyright (C) 2013, 2014 Patrick "P. J." McDermott # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -u SHA256SUMS=' c126f241291f052b0662e9dac3ee71f6352ccc3e344c4b189bff8ab3e2bc5c81 amd64-linux-glibc_dev_base ac16de260be8d1594f9a300f4baccf8c92085dccfb685a326bf37561a1ab4f9b amd64-linux-glibc_all_base 8d4645bca214361dd63e3e4f6aed8040f90124ca8dc228eef4c501eba032768d i686-linux-glibc_dev_base f570049c6c304d3471a45c9cb218c50799a6e79e21b12e74c7d7597f3fd37a7a i686-linux-glibc_all_base c3ab37f17bbc85ab2f222f61b5970d6f94ebb3cc0e5efc9cbec6ee8975738b94 all_all_base ' PKGS=' base-files busybox '\ 'libc-bin libc.6 libopkg.1 opkg tzcode '\ 'locales tzdata-northamerica tzdata ' main() { local cmd= if [ ${#} -lt 1 ]; then print_usage >&2 exit 1 fi cmd="${1}" shift 1 case "${cmd}" in 'install') cmd_install "${@}" ;; 'shell') cmd_shell "${@}" ;; esac return 0 } print_usage() { printf 'Usage: %s []\n\n' "${0}" printf 'Available commands are:\n' printf ' install install a ProteanOS system\n' printf ' shell enter a ProteanOS shell\n' } error() { local status=${1} local fmt="${2}" shift 2 printf "Error: ${fmt}\n" "${@}" >&2 exit ${status} } info() { local fmt="${1}" shift 1 printf "${fmt}\n" "${@}" } cmd_install() { local usage= local opt= local arch= local plat= local mirror= local root= local uname_m= local uname_s= local aps= local url_aps= local feed= local sha256sum= local line= local package= local filename= usage='[-a ] [-P ] [-m ] ' while getopts 'a:P:m:' opt; do case ${opt} in a) arch="${OPTARG}";; P) plat="${OPTARG}";; m) mirror="${OPTARG}";; ?) printf 'Usage: %s install %s\n' \ "${0}" "${usage}" >&2 exit 1 ;; esac done shift $(($OPTIND - 1)) if [ ${#} -ne 1 ]; then printf 'Usage: %s install %s\n' "${0}" "${usage}" >&2 exit 1 fi root="${1}" if [ "x${arch}" = 'x' ]; then uname_m="$( (uname -m) 2>/dev/null)" || uname_m='?' uname_s="$( (uname -s) 2>/dev/null)" || uname_s='?' case "${uname_m}:${uname_s}" in 'i686:Linux') arch='i686-linux-glibc';; 'x86_64:Linux') arch='amd64-linux-glibc';; '?:?') error 2 'Error: Architecture unknown';; *) error 2 'Error: Architecture unsupported';; esac fi info 'Using architecture %s' "${arch}" if [ "x${plat}" = 'x' ]; then plat='dev' fi info 'Using platform %s' "${plat}" if [ "x${mirror}" = 'x' ]; then rand=$(date '+%S') rand=$(($rand % 2)) case ${rand} in 0) mirror='http://proteanos.mirror.gnu.dk' mirror="${mirror}/pub/proteanos" ;; 1) mirror='http://mirror.oss.maxcdn.com/proteanos' ;; esac fi info 'Using mirror %s' "${mirror}" info 'Setting up root...' mkdir -p "${root}/etc/opkg" \ "${root}/var/lib/opkg/lists" "${root}/var/lib/opkg/info" \ "${root}/var/cache/opkg/archives" || \ error 2 'Failed to set up root' info 'Configuring opkg and retrieving Packages...' exec 3>"${root}/etc/opkg/opkg.conf" || \ error 2 'Failed to open opkg.conf' for aps in "${arch}_${plat}_base" "${arch}_all_base" 'all_all_base'; do url_aps="$(printf '%s\n' "${aps}" | sed 's|_|/|g')" feed="${mirror}/feeds/dev/trunk/${url_aps}" printf 'src %s %s\n' "trunk_${aps}" "${feed}" >&3 wget -q -O "${root}/var/lib/opkg/lists/trunk_${aps}" \ "${feed}/Packages" || \ error 2 'Failed to download %s' "${feed}/Packages" sha256sum="$(sha256sum \ "${root}/var/lib/opkg/lists/trunk_${aps}" | \ cut -d ' ' -f 1)" printf '%s' "${SHA256SUMS}" | grep -Fq "${sha256sum} ${aps}" \ || error 2 'Checksum of Packages index file failed' done printf '\ndest root /\n' >&3 printf 'arch %s 1\n' 'all' "${arch}" 'src' >&3 exec 3>&- while IFS='' read -r line; do if [ "x${line%: *}" = 'xPackage' ]; then package="${line#Package: }" elif [ "x${line%: *}" = 'xFilename' ]; then filename="${line#Filename: }" elif [ "x${line%: *}" = 'xSHA256sum' ]; then sha256sum="${line#SHA256sum: }" elif [ "x${line}" = 'x' ]; then printf '%s\n' "${PKGS}" | grep -Fq " ${package} " || \ continue get_pkg "${mirror}" \ "${package}" "${filename}" "${sha256sum}" fi done <<-EOF $(cat "${root}/var/lib/opkg/lists/trunk_"*) EOF [ -r /etc/resolv.conf ] && cp /etc/resolv.conf "${root}/etc" [ -r /etc/hostname ] && cp /etc/hostname "${root}/etc" } get_pkg() { local mirror="${1}" local package="${2}" local filename="${3}" local sha256sum="${4}" info 'Downloading %s...' "${package}" filename="${filename#../../../../../../}" wget -q -O "${root}/var/cache/opkg/archives/${filename##*/}" \ "${mirror}/${filename}" || error 2 'Failed to download package' filename="${root}/var/cache/opkg/archives/${filename##*/}" printf '%s %s\n' "${sha256sum}" "${filename}" | sha256sum --quiet -c \ || error 2 'Checksum of source package file failed' (cd ${root}; tar -xzOf "${filename#${root}/}" data.tar.gz | tar -xz) } cmd_shell() { local root= local arch= if [ ${#} -ne 1 ]; then printf 'Usage: %s shell \n' "${0}" >&2 exit 1 fi root="${1}" if ! [ -d "${root}" ] || ! [ -r "${root}/etc/proteanos_arch" ]; then error 2 'Error: ProteanOS root file system not found' fi arch="$(cat "${root}/etc/proteanos_arch")" case "${arch}" in *'-linux-'*) mount -t proc proc "${root}/proc" mount -t sysfs sys "${root}/sys" mount -o bind /dev "${root}/dev" mount -t devpts -o noexec,nosuid,gid=5,mode=0620 \ devpts "${root}/dev/pts" ;; *) error 2 'ProteanOS architecture %s not supported' \ "${arch}" esac chroot "${root}" /bin/sh case "$(cat "${root}/etc/proteanos_arch")" in *'-linux-'*) umount "${root}/dev/pts" umount "${root}/proc" umount "${root}/sys" umount "${root}/dev" ;; esac } main "${@}"