├── .gitignore ├── install.sh ├── README.md ├── CMakeLists.txt ├── init.d ├── shell_demo └── metashell ├── app ├── cmpshelld └── shell_demo └── share └── solarized.css /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Deployment script of the online Metashell and Preshell demos 4 | # Copyright (C) 2015, Abel Sinkovics (abel@sinkovics.hu) 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | # Config 20 | SHELL_USER=nobody 21 | DIR=/usr/local/share/shell_demo 22 | 23 | # Stop the demo if it is running 24 | sudo /etc/init.d/metashell stop 25 | sudo /etc/init.d/shell_demo stop 26 | sudo rm -rf "${DIR}" 27 | 28 | # Create the demo's directory 29 | sudo mkdir -p "${DIR}" 30 | sudo chown "${SHELL_USER}" "${DIR}" 31 | 32 | # Install dependencies 33 | sudo apt-get -y install \ 34 | git \ 35 | cmake \ 36 | make \ 37 | gcc \ 38 | g++ \ 39 | libboost-dev \ 40 | libboost-test-dev \ 41 | libboost-program-options-dev \ 42 | libboost-wave-dev \ 43 | libboost-system-dev \ 44 | libboost-thread-dev \ 45 | libboost-filesystem-dev \ 46 | libboost-regex-dev \ 47 | libreadline-dev \ 48 | shellinabox \ 49 | unzip \ 50 | libncurses5-dev 51 | 52 | # Install the daemons 53 | mkdir bin 54 | cd bin 55 | cmake .. && sudo make install 56 | cd .. 57 | 58 | # Start the daemons 59 | sudo /etc/init.d/metashell start 60 | sudo /etc/init.d/shell_demo start 61 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ metaprogramming shell daemon 2 | 3 | This repository contains a setup script for the 4 | [Metashell](github.com/sabel83/metashell) online demo on an Ubuntu server. 5 | You can use it to host your own online demo of the shells. 6 | 7 | ## Setting your server up 8 | 9 | * Install Ubuntu server 14.04 10 | * Download the content of this repository 11 | * Run `install.sh`. This will install the dependent packages, create the daemons 12 | and start them. 13 | 14 | * The Metashell demo will be listening on port `4202` 15 | * The Preshell demo will be listening on port `4201` 16 | 17 | * The demos use ShellInABox, which gets installed on your server and is 18 | listening on port 4200 by default. To stop it run 19 | `sudo /etc/init.d/shellinabox stop`. To avoid it being started during system 20 | startup run `sudo update-rc.d shellinabox disable` 21 | 22 | ## The services providing the demo 23 | 24 | The demo is provided by two services: 25 | 26 | * `metashell` This is a ShellInABox service running Metashell as its shell. 27 | * `shell_demo` This is a service periodically updating the C++ headers which 28 | can be used from the services and building the latest version of Preshell 29 | and Metashell. 30 | 31 | The services are using the `/usr/local/share/shell_demo` directory for 32 | downloading the source code of different projects (Metashell, Preshell, 33 | libraries that can be used from the shell) and building the Metashell and 34 | Preshell binaries. 35 | 36 | ## Starting the demos 37 | 38 | The installer configures the demos to be automatically started during system 39 | startup. To start them manually run the following commands: 40 | 41 | ``` 42 | sudo /etc/init.d/shell_demo start 43 | sudo /etc/init.d/metashell start 44 | ``` 45 | 46 | ## Stopping the demos 47 | 48 | To stop the demo, you need to stop the three services providing it: 49 | 50 | ``` 51 | sudo /etc/init.d/shell_demo stop 52 | sudo /etc/init.d/metashell stop 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Preshell - Interactive C/C++ preprocessor shell 2 | # Copyright (C) 2013, Abel Sinkovics (abel@sinkovics.hu) 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | cmake_minimum_required(VERSION 2.6) 18 | 19 | project(cmpshelld) 20 | set(CMAKE_PROJECT_NAME cmpshelld) 21 | set(MAJOR_VERSION 0) 22 | set(MINOR_VERSION 1) 23 | set(PATCH_VERSION 0) 24 | 25 | macro(create_init_symlink RUNLEVEL SHELL START_OR_KILL) 26 | set(LINK_NAME ${CMAKE_CURRENT_BINARY_DIR}/${START_OR_KILL}20${SHELL}) 27 | 28 | execute_process( 29 | COMMAND 30 | "${CMAKE_COMMAND}" -E create_symlink /etc/init.d/${SHELL} "${LINK_NAME}" 31 | ) 32 | install(FILES "${LINK_NAME}" DESTINATION /etc/rc${RUNLEVEL}.d) 33 | endmacro(create_init_symlink) 34 | 35 | # Daemon 36 | if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 37 | set(CMAKE_INSTALL_PREFIX "/usr") 38 | endif() 39 | install(PROGRAMS app/cmpshelld DESTINATION bin) 40 | install(PROGRAMS app/shell_demo DESTINATION bin) 41 | install(FILES share/solarized.css DESTINATION share) 42 | foreach (I metashell shell_demo) 43 | install(PROGRAMS init.d/${I} DESTINATION /etc/init.d) 44 | create_init_symlink(0 ${I} K) 45 | create_init_symlink(1 ${I} K) 46 | create_init_symlink(2 ${I} S) 47 | create_init_symlink(3 ${I} S) 48 | create_init_symlink(4 ${I} S) 49 | create_init_symlink(5 ${I} S) 50 | create_init_symlink(6 ${I} K) 51 | endforeach(I) 52 | 53 | -------------------------------------------------------------------------------- /init.d/shell_demo: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: shell_demo 4 | # Required-Start: $network $remote_fs 5 | # Required-Stop: $network $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Shell demo daemon 9 | # Description: Daemon for publishing a metaprogramming shell demo 10 | ### END INIT INFO 11 | 12 | # Author: Abel Sinkovics 13 | 14 | # Do NOT "set -e" 15 | 16 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 17 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 18 | DESC="Metaprogramming shell daemon" 19 | NAME="shell_demo" 20 | DAEMON=/usr/bin/shell_demo 21 | PIDFILE=/var/run/$NAME.pid 22 | SCRIPTNAME=/etc/init.d/$NAME 23 | SHELL_USER=nobody 24 | 25 | LOGFILE=/var/tmp/${NAME} 26 | 27 | # Exit if the package is not installed 28 | [ -x "$DAEMON" ] || exit 0 29 | 30 | # Read configuration variable file if it is present 31 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 32 | 33 | # Load the VERBOSE setting and other rcS variables 34 | . /lib/init/vars.sh 35 | 36 | # Define LSB log_* functions. 37 | # Depend on lsb-base (>= 3.2-14) to ensure that this file is present 38 | # and status_of_proc is working. 39 | . /lib/lsb/init-functions 40 | 41 | # Set some default values 42 | METASHELL_GROUP="${METASHELL_GROUP:-nogroup}" 43 | 44 | # 45 | # Function that starts the daemon/service 46 | # 47 | do_start() 48 | { 49 | start-stop-daemon --start --pidfile "$PIDFILE" --make-pidfile --user "${SHELL_USER}" --chuid "${SHELL_USER}" --background --startas "$DAEMON" \ 50 | || return 1 51 | } 52 | 53 | # 54 | # Function that stops the daemon/service 55 | # 56 | do_stop() 57 | { 58 | start-stop-daemon --stop --pidfile "$PIDFILE" 59 | rm -f "$PIDFILE" 60 | } 61 | 62 | # 63 | # Function that sends a SIGHUP to the daemon/service 64 | # 65 | do_reload() { 66 | # Only reload if there are no active sessions running 67 | [ -r "$PIDFILE" ] && 68 | [ `ps o pid= --ppid "\`cat "$PIDFILE"\`\`ps o pid= --ppid \\\`cat "$PIDFILE"\\\` | xargs -r -n 1 printf ',%s'\`" | wc -l` gt 1 ] && 69 | return 1 70 | 71 | do_stop 72 | do_start 73 | } 74 | 75 | # 76 | # Function that check the status of the daemon/service 77 | # 78 | do_status() 79 | { 80 | [ -r "$PIDFILE" ] && kill -0 `cat "$PIDFILE"` && 81 | echo "$DESC is running" || echo "$DESC is not running" 82 | } 83 | 84 | 85 | case "$1" in 86 | start) 87 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 88 | do_start 89 | case "$?" in 90 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 91 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 92 | esac 93 | ;; 94 | stop) 95 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 96 | do_stop 97 | case "$?" in 98 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 99 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 100 | esac 101 | ;; 102 | status) 103 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 104 | ;; 105 | restart|force-reload) 106 | [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" 107 | do_stop 108 | case "$?" in 109 | 0|1) 110 | do_start 111 | case "$?" in 112 | 0) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 113 | 1) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 114 | *) [ "$VERBOSE" != no ] && log_end_msg 1 ;; # Failed to start 115 | esac 116 | ;; 117 | *) 118 | # Failed to stop 119 | [ "$VERBOSE" != no ] && log_end_msg 1 120 | ;; 121 | esac 122 | ;; 123 | status) 124 | do_status 125 | ;; 126 | *) 127 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload|status}" >&2 128 | exit 3 129 | ;; 130 | esac 131 | 132 | exit 0 133 | -------------------------------------------------------------------------------- /init.d/metashell: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: metashell 4 | # Required-Start: $network $remote_fs 5 | # Required-Stop: $network $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Metashell daemon 9 | # Description: Daemon for publishing a Metashell 10 | ### END INIT INFO 11 | 12 | # Author: Abel Sinkovics 13 | 14 | # Do NOT "set -e" 15 | 16 | # PATH should only include /usr/* if it runs after the mountnfs.sh script 17 | PATH=/sbin:/usr/sbin:/bin:/usr/bin 18 | DESC="Metashell daemon" 19 | NAME="metashell" 20 | DAEMON=/usr/bin/shellinaboxd 21 | PIDFILE=/var/run/$NAME.pid 22 | SCRIPTNAME=/etc/init.d/$NAME 23 | 24 | LOGFILE=/var/tmp/${NAME} 25 | 26 | # Exit if the package is not installed 27 | [ -x "$DAEMON" ] || exit 0 28 | 29 | # Read configuration variable file if it is present 30 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 31 | 32 | # Load the VERBOSE setting and other rcS variables 33 | . /lib/init/vars.sh 34 | 35 | # Define LSB log_* functions. 36 | # Depend on lsb-base (>= 3.2-14) to ensure that this file is present 37 | # and status_of_proc is working. 38 | . /lib/lsb/init-functions 39 | 40 | # Set some default values 41 | METASHELL_PORT="${METASHELL_PORT:-4202}" 42 | METASHELL_USER="${METASHELL_USER:-nobody}" 43 | METASHELL_GROUP="${METASHELL_GROUP:-nogroup}" 44 | 45 | # 46 | # Function that starts the daemon/service 47 | # 48 | do_start() 49 | { 50 | start-stop-daemon --start --oknodo --pidfile "$PIDFILE" --exec "$DAEMON" -- --disable-ssl --no-beep -p "${METASHELL_PORT}" -u "${METASHELL_USER}" -g "${METASHELL_GROUP}" --css "/usr/share/solarized.css" -s "/:${METASHELL_USER}:${METASHELL_GROUP}:/:/usr/bin/cmpshelld -s /usr/local/share/shell_demo/bin/metashell -i /usr/local/share/shell_demo/include/headers -l ${LOGFILE} -p \${peer} -u \${url}" --background="${PIDFILE}" \ 51 | || return 1 52 | } 53 | 54 | # 55 | # Function that stops the daemon/service 56 | # 57 | do_stop() 58 | { 59 | start-stop-daemon --stop --oknodo --pidfile "$PIDFILE" 60 | rm -f "$PIDFILE" 61 | } 62 | 63 | # 64 | # Function that sends a SIGHUP to the daemon/service 65 | # 66 | do_reload() { 67 | # Only reload if there are no active sessions running 68 | [ -r "$PIDFILE" ] && 69 | [ `ps o pid= --ppid "\`cat "$PIDFILE"\`\`ps o pid= --ppid \\\`cat "$PIDFILE"\\\` | xargs -r -n 1 printf ',%s'\`" | wc -l` gt 1 ] && 70 | return 1 71 | 72 | do_stop 73 | do_start 74 | } 75 | 76 | # 77 | # Function that check the status of the daemon/service 78 | # 79 | do_status() 80 | { 81 | [ -r "$PIDFILE" ] && kill -0 `cat "$PIDFILE"` && 82 | echo "$DESC is running" || echo "$DESC is not running" 83 | } 84 | 85 | 86 | case "$1" in 87 | start) 88 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 89 | do_start 90 | case "$?" in 91 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 92 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 93 | esac 94 | ;; 95 | stop) 96 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 97 | do_stop 98 | case "$?" in 99 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 100 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 101 | esac 102 | ;; 103 | status) 104 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? 105 | ;; 106 | restart|force-reload) 107 | [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" 108 | do_stop 109 | case "$?" in 110 | 0|1) 111 | do_start 112 | case "$?" in 113 | 0) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 114 | 1) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 115 | *) [ "$VERBOSE" != no ] && log_end_msg 1 ;; # Failed to start 116 | esac 117 | ;; 118 | *) 119 | # Failed to stop 120 | [ "$VERBOSE" != no ] && log_end_msg 1 121 | ;; 122 | esac 123 | ;; 124 | status) 125 | do_status 126 | ;; 127 | *) 128 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload|status}" >&2 129 | exit 3 130 | ;; 131 | esac 132 | 133 | exit 0 134 | -------------------------------------------------------------------------------- /app/cmpshelld: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | """ 3 | C++ metaprogramming shell launcher 4 | 5 | This utility starts the shell in CGI-mode. 6 | 7 | Supported options: 8 | 9 | -e, --extra Pass extra argument to the shell (after --) 10 | -h, --help Display this help message 11 | -i, --includes The root of the header collection (default: /usr/include/headers) 12 | -s, --shell Path of the shell binary 13 | -l, --log Log into that file 14 | -p, --peer Name of remote peer 15 | -u, --url The URL with the GET parameters 16 | Accepted GET parameters: 17 | _std=c++0x|c++11|c++1y 18 | _version= 19 | """ 20 | 21 | import sys 22 | import getopt 23 | import urlparse 24 | import os 25 | import resource 26 | import time 27 | import fcntl 28 | import json 29 | import datetime 30 | import tempfile 31 | import shutil 32 | import subprocess 33 | 34 | class TempDir: 35 | def __enter__(self): 36 | self.path = tempfile.mkdtemp() 37 | return self 38 | 39 | def __exit__(self, type, value, traceback): 40 | shutil.rmtree(self.path) 41 | 42 | 43 | def append_to_file(filename, s): 44 | f = open(filename, 'a') 45 | fcntl.flock(f, fcntl.LOCK_EX) 46 | try: 47 | f.write(s) 48 | finally: 49 | fcntl.flock(f, fcntl.LOCK_UN) 50 | f.close() 51 | 52 | def log(filename, msg): 53 | if filename != '': 54 | suffix = datetime.datetime.now().strftime("_%Y_%m_%d") 55 | msg['timestamp'] = time.time() 56 | append_to_file(filename + suffix, json.dumps(msg) + '\n') 57 | 58 | def allowed_version_char(c): 59 | return c.isalnum() or c in ['.', '_'] 60 | 61 | def valid_version(s): 62 | return \ 63 | all([allowed_version_char(c) for c in s]) \ 64 | and any([c.isalnum() for c in s]) 65 | 66 | def valid_standard(s): 67 | return s in ['c++0x', 'c++11', 'c++1y'] 68 | 69 | def lib_exists(includes, s): 70 | return os.path.isdir('%s/%s' % (includes, s)) 71 | 72 | def limit_memory(mb): 73 | b = mb * 1024 * 1024 74 | resource.setrlimit(resource.RLIMIT_AS, (b, b)) 75 | 76 | def main(): 77 | try: 78 | opts, args = getopt.getopt( 79 | sys.argv[1:], 80 | 'hs:i:u:l:p:e:', 81 | ['help', 'shell=', 'includes=', 'url=', 'log=', 'peer=', 'extra='] 82 | ) 83 | except getopt.error, msg: 84 | print msg 85 | print "Getting help: --help" 86 | sys.exit(1) 87 | 88 | binary = '' 89 | includes = '/usr/include/headers' 90 | lib_versions = {} 91 | std = '' 92 | logfile = '' 93 | peer = '' 94 | url = '' 95 | extra_args = [] 96 | 97 | for o, a in opts: 98 | if o in ('-h', '--help'): 99 | print __doc__ 100 | sys.exit(0) 101 | elif o in ('-l', '--log'): 102 | logfile = a 103 | elif o in ('-p', '--peer'): 104 | peer = a 105 | elif o in ('-s', '--shell'): 106 | binary = a 107 | elif o in ('-i', '--includes'): 108 | includes = a 109 | elif o in ('-u', '--url'): 110 | url = a 111 | errors = [] 112 | for name, value in urlparse.parse_qsl(urlparse.urlparse(a).query): 113 | if name.endswith('_version'): 114 | lib_name = name[:len(name) - len('_version')] 115 | if valid_version(lib_name): 116 | if valid_version(value): 117 | lib_versions[lib_name] = value 118 | else: 119 | errors.append('Invalid %s version: %s' % (lib_name, value)) 120 | boost_version = value 121 | else: 122 | errors.append('Invalid library name: %s' % (lib_name)) 123 | elif name == '_std': 124 | if valid_standard(value): 125 | std = value 126 | else: 127 | errors.append('Invalid GET option: ' + name) 128 | if len(errors) > 0: 129 | print '\n'.join(errors) 130 | sys.exit(1) 131 | elif o in ('-e', '--extra'): 132 | extra_args.append(a) 133 | 134 | if binary == '': 135 | print 'The shell binary has not been provided.' 136 | print 'Getting help: --help' 137 | sys.exit(1) 138 | 139 | shell_args = [binary, '--disable_saving'] 140 | for l,v in lib_versions.items(): 141 | if lib_exists(includes, l): 142 | extra_args.extend( 143 | ['-I', os.path.realpath('%s/%s/%s' % (includes, l, v))] 144 | ) 145 | else: 146 | print 'Library not found: %s' % (l) 147 | sys.exit(1) 148 | if std != '': 149 | extra_args.extend(['--std', std]) 150 | if len(extra_args) != 0: 151 | shell_args.append('--') 152 | shell_args.extend(extra_args) 153 | 154 | log(logfile, {'peer' : peer, 'cmd' : shell_args, 'url' : url}) 155 | 156 | limit_memory(2048) 157 | 158 | try: 159 | with TempDir() as temp: 160 | os.chdir(temp.path) 161 | subprocess.call([binary] + shell_args) 162 | except OSError as e: 163 | print 'Error running the shell: %s' % (e) 164 | sys.exit(1) 165 | 166 | if __name__ == '__main__': 167 | try: 168 | main() 169 | except SystemExit: 170 | raise 171 | except: 172 | print 'Uncaught exception' 173 | 174 | -------------------------------------------------------------------------------- /app/shell_demo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Deployment script of the online Metashell and Preshell demos 4 | # Copyright (C) 2015, Abel Sinkovics (abel@sinkovics.hu) 5 | # 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | function git_repo_begin { 20 | HOST="$1" 21 | USER="$2" 22 | NAME="$3" 23 | BRANCH="$4" 24 | DIR_NAME="${USER}_${NAME}" 25 | if [ -e "${DIR_NAME}" ]; then 26 | echo "${DIR_NAME} already exists" 27 | else 28 | git clone --recursive "https://${HOST}/${USER}/${NAME}.git" "${DIR_NAME}" 29 | fi 30 | cd "${DIR_NAME}" 31 | git branch "${BRANCH}" "origin/${BRANCH}" 32 | git checkout "${BRANCH}" 33 | git pull origin "${BRANCH}" 34 | git submodule foreach git pull 35 | } 36 | 37 | function git_repo_end { 38 | cd .. 39 | } 40 | 41 | function follow_git_repo { 42 | HOST="$1" 43 | USER="$2" 44 | NAME="$3" 45 | BRANCH="$4" 46 | HEADER_PATH="$5" 47 | HEADER_PATH2_SRC="$6" 48 | HEADER_PATH2_DST="$7" 49 | INCLUDE="$(pwd)/include" 50 | 51 | git_repo_begin "${HOST}" "${USER}" "${NAME}" "${BRANCH}" 52 | REV=`git rev-parse "${BRANCH}"` 53 | INSTALLED="${INCLUDE}/headers/${NAME}/${REV}" 54 | if [ ! -d "${INSTALLED}" ] 55 | then 56 | mkdir -p "${INSTALLED}" 57 | cp -r "${HEADER_PATH}" "${INSTALLED}" 58 | if [ -n "${HEADER_PATH2_SRC}" ] 59 | then 60 | mkdir -p "${INSTALLED}/${HEADER_PATH2_DST}" 61 | cp -r "${HEADER_PATH2_SRC}" "${INSTALLED}/${HEADER_PATH2_DST}" 62 | fi 63 | fi 64 | if [ "$(readlink "${INCLUDE}/headers/${NAME}/${BRANCH}")" != "${REV}" ] 65 | then 66 | rm "${INCLUDE}/headers/${NAME}/${BRANCH}" 67 | ln -fs "${REV}" "${INCLUDE}/headers/${NAME}/${BRANCH}" 68 | fi 69 | git_repo_end 70 | } 71 | 72 | function write_version_desc { 73 | git log -1 --pretty="%h %B" | head -1 \ 74 | | sed 's/\\/\\\\/g' \ 75 | | sed 's/"/\\"/g' \ 76 | | sed 's/^/"/' | sed 's/$/\\n This demo is supported by the Eotvos Lorand University, Faculty of Informatics"/' \ 77 | > lib/core/version_desc.hpp 78 | } 79 | 80 | function upgrade { 81 | BIN="$(pwd)/bin" 82 | INCLUDE="$(pwd)/include" 83 | USR_INCLUDE="${INCLUDE}/usr/include" 84 | METASHELL_INCLUDE="${INCLUDE}/metashell" 85 | 86 | mkdir bin 87 | 88 | mkdir -p "${USR_INCLUDE}" 89 | mkdir -p "${METASHELL_INCLUDE}" 90 | ln -s \ 91 | $(ls -d /usr/include/* | egrep -v '^/usr/include/(boost|mpllibs)$') \ 92 | "${USR_INCLUDE}" 93 | 94 | git_repo_begin github.com sabel83 metashell master 95 | REV=`git rev-parse master` 96 | INSTALLED_METASHELL="${BIN}/metashell_${REV}" 97 | INSTALLED_TEMPLIGHT="${BIN}/templight_metashell_${REV}" 98 | 99 | if [ ! -f "${INSTALLED_METASHELL}" ] || [ ! -f "${INSTALLED_TEMPLIGHT=}" ] 100 | then 101 | write_version_desc 102 | 103 | rm -rf bin 104 | ./build.sh 105 | 106 | METASHELL_SRC="$(pwd)" 107 | TEMPLIGHT_SRC="${METASHELL_SRC}/3rd/templight" 108 | cd bin 109 | TEMPLIGHT_HEADERS="${TEMPLIGHT_SRC}/$(cmake .. -DTEMPLIGHT_DEBUG=1 | egrep 'TEMPLIGHT_HEADERS = ' | sed 's/^.*3rd\/templight\/build\//build\//')" 110 | echo "TEMPLIGHT_HEADERS = ${TEMPLIGHT_HEADERS}" 111 | test/unit/metashell_unit_test \ 112 | && ln -fs "${TEMPLIGHT_HEADERS}" "${METASHELL_INCLUDE}/templight" \ 113 | && cp app/metashell "${INSTALLED_METASHELL}" \ 114 | && ln -fs "${INSTALLED_METASHELL}" "${BIN}/metashell" \ 115 | && cp app/templight_metashell "${INSTALLED_TEMPLIGHT}" \ 116 | && ln -fs "${INSTALLED_TEMPLIGHT}" "${BIN}/templight_metashell" 117 | cd .. 118 | fi 119 | git_repo_end 120 | 121 | git_repo_begin github.com sabel83 headers master 122 | rsync -r headers "${INCLUDE}" 123 | git_repo_end 124 | 125 | git_repo_begin github.com boostorg boost master 126 | REV=`git rev-parse master` 127 | INSTALLED="${INCLUDE}/headers/boost/${REV}" 128 | if [ ! -d "${INSTALLED}" ] 129 | then 130 | mkdir -p "${INSTALLED}" 131 | for l in $(ls -d libs/*/) 132 | do 133 | cp -r "${l}include/boost" "${INSTALLED}" 134 | done 135 | ln -fs "${REV}" "${INCLUDE}/headers/boost/master" 136 | fi 137 | git_repo_end 138 | 139 | follow_git_repo github.com sabel83 metatest master include/metatest 140 | follow_git_repo github.com sabel83 mpllibs master mpllibs libs/metaparse/example/getting_started mpllibs/metaparse 141 | follow_git_repo github.com minamiyama1994 FTMP master include/FTMP 142 | follow_git_repo github.com ldionne hana master include/boost 143 | follow_git_repo github.com pfultz2 Ripple master ripple 144 | follow_git_repo github.com facebook fatal master fatal 145 | follow_git_repo github.com facebook fatal dev fatal 146 | follow_git_repo github.com ericniebler meta master include/meta 147 | } 148 | 149 | 150 | 151 | 152 | ######## 153 | # Main # 154 | ######## 155 | 156 | export LC_ALL=C 157 | 158 | while true 159 | do 160 | cd /usr/local/share/shell_demo 161 | 162 | upgrade > /usr/local/share/shell_demo/last_log.txt 2>&1 163 | 164 | sleep 3600 165 | done 166 | 167 | -------------------------------------------------------------------------------- /share/solarized.css: -------------------------------------------------------------------------------- 1 | /* The original solarized.css was found here: 2 | * https://github.com/georgegoh/configs/tree/master/shellinabox 3 | */ 4 | 5 | #vt100 a { 6 | text-decoration: none; 7 | color: inherit; 8 | } 9 | 10 | #vt100 a:hover { 11 | text-decoration: underline; 12 | } 13 | 14 | #vt100 #reconnect { 15 | position: absolute; 16 | z-index: 2; 17 | } 18 | 19 | #vt100 #reconnect input { 20 | padding: 1ex; 21 | font-weight: bold; 22 | font-size: x-large; 23 | } 24 | 25 | #vt100 #cursize { 26 | background: #EEEEEE; 27 | border: 1px solid black; 28 | font-family: sans-serif; 29 | font-size: large; 30 | font-weight: bold; 31 | padding: 1ex; 32 | position: absolute; 33 | z-index: 2; 34 | } 35 | 36 | #vt100 pre { 37 | margin: 0px; 38 | } 39 | 40 | #vt100 pre pre { 41 | overflow: hidden; 42 | } 43 | 44 | #vt100 #scrollable { 45 | color: #839496; 46 | background-color: #002b36; 47 | 48 | overflow-x: hidden; 49 | overflow-y: scroll; 50 | position: relative; 51 | padding: 1px; 52 | } 53 | 54 | #vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight { 55 | font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", "Lucida Console", monospace; 56 | } 57 | 58 | #vt100 #lineheight { 59 | position: absolute; 60 | visibility: hidden; 61 | } 62 | 63 | #vt100 #cursor { 64 | position: absolute; 65 | left: 0px; 66 | top: 0px; 67 | overflow: hidden; 68 | z-index: 1; 69 | } 70 | 71 | #vt100 #cursor.bright { 72 | background-color: #839496; 73 | color: white; 74 | } 75 | 76 | #vt100 #cursor.dim { 77 | visibility: hidden; 78 | } 79 | 80 | #vt100 #cursor.inactive { 81 | border: 1px solid #839496; 82 | margin: -1px; 83 | } 84 | 85 | #vt100 #padding { 86 | visibility: hidden; 87 | width: 1px; 88 | height: 0px; 89 | overflow: hidden; 90 | } 91 | 92 | #vt100 .hidden { 93 | position: absolute; 94 | top: -10000px; 95 | left: -10000px; 96 | width: 0px; 97 | height: 0px; 98 | } 99 | 100 | #vt100 #menu { 101 | overflow: visible; 102 | position: absolute; 103 | z-index: 3; 104 | } 105 | 106 | #vt100 #menu .popup { 107 | background-color: #EEEEEE; 108 | border: 1px solid black; 109 | font-family: sans-serif; 110 | position: absolute; 111 | } 112 | 113 | #vt100 #menu .popup ul { 114 | list-style-type: none; 115 | padding: 0px; 116 | margin: 0px; 117 | min-width: 10em; 118 | } 119 | 120 | #vt100 #menu .popup li { 121 | padding: 3px 0.5ex 3px 0.5ex; 122 | } 123 | 124 | #vt100 #menu .popup li.hover { 125 | background-color: #444444; 126 | color: white; 127 | } 128 | 129 | #vt100 #menu .popup li.disabled { 130 | color: #AAAAAA; 131 | } 132 | 133 | #vt100 #menu .popup hr { 134 | margin: 0.5ex 0px 0.5ex 0px; 135 | } 136 | 137 | #vt100 #menu img { 138 | margin-right: 0.5ex; 139 | width: 1ex; 140 | height: 1ex; 141 | } 142 | 143 | /*#vt100 #scrollable.inverted { color: #002b36; 144 | background-color: #839496; } 145 | */ 146 | #vt100 #scrollable.inverted { color: #839496; 147 | background-color: #002b36; } 148 | [if DEFINES_COLORS] 149 | /* IE cannot properly handle "inherit" properties. So, the monochrome.css/ 150 | * color.css style sheets cannot work, if we define colors in styles.css. 151 | */ 152 | [else DEFINES_COLORS] 153 | #vt100 .ansi0 { } /* base0 ? */ 154 | #vt100 .ansi1 { color: #dc322f; } /* red */ 155 | #vt100 .ansi2 { color: #859900; } /* green */ 156 | #vt100 .ansi3 { color: #b58900; } /* yellow */ 157 | #vt100 .ansi4 { color: #268bd2; } /* blue */ 158 | #vt100 .ansi5 { color: #d33682; } /* magenta */ 159 | #vt100 .ansi6 { color: #2aa198; } /* cyan */ 160 | #vt100 .ansi7 { color: #fdf6e3; } /* base3 */ 161 | #vt100 .ansi8 { color: #eee8d5; } /* base2 */ 162 | #vt100 .ansi9 { color: #cb4b16; } /* orange */ 163 | #vt100 .ansi10 { color: #586e75; } /* base01 */ 164 | #vt100 .ansi11 { color: #657b83; } /* base00 */ 165 | #vt100 .ansi12 { color: #839496; } /* base0 */ 166 | #vt100 .ansi13 { color: #073642; } /* base02 ? */ 167 | #vt100 .ansi14 { color: #93a1a1; } /* base1 */ 168 | #vt100 .ansi15 { color: #ffffff; } /* base03 (modified) */ 169 | 170 | #vt100 .bgAnsi0 { background-color: #073642; } 171 | #vt100 .bgAnsi1 { background-color: #dc322f; } 172 | #vt100 .bgAnsi2 { background-color: #859900; } 173 | #vt100 .bgAnsi3 { background-color: #b58900; } 174 | #vt100 .bgAnsi4 { background-color: #268bd2; } 175 | #vt100 .bgAnsi5 { background-color: #d33682; } 176 | #vt100 .bgAnsi6 { background-color: #2aa198; } 177 | #vt100 .bgAnsi7 { background-color: #fdf6e3; } 178 | #vt100 .bgAnsi8 { background-color: #eee8d5; } 179 | #vt100 .bgAnsi9 { background-color: #cb4b16; } 180 | #vt100 .bgAnsi10 { background-color: #586e75; } 181 | #vt100 .bgAnsi11 { background-color: #657b83; } 182 | #vt100 .bgAnsi12 { background-color: #839496; } 183 | #vt100 .bgAnsi13 { background-color: #073642; } 184 | #vt100 .bgAnsi14 { background-color: #93a1a1; } 185 | #vt100 .bgAnsi15 { } 186 | [endif DEFINES_COLORS] 187 | 188 | @media print { 189 | #vt100 .scrollback { 190 | display: none; 191 | } 192 | 193 | #vt100 #reconnect, #vt100 #cursor, #vt100 #menu { 194 | visibility: hidden; 195 | } 196 | 197 | #vt100 #scrollable { 198 | overflow: hidden; 199 | } 200 | 201 | #vt100 #console, #vt100 #alt_console { 202 | overflow: hidden; 203 | width: 1000000ex; 204 | } 205 | } 206 | --------------------------------------------------------------------------------