> 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 . */ if(file_exists('config.php')){die('Already set up');} if(substr($_SERVER['REQUEST_URI'], -16)=='/rpc/rewritetest'){header('Content-type: image/png');readfile('icons/find.png');exit();} // Step 0: Warnings (not mandatory, but persistent through the process which also works as doublechecking if solved) print('

The \'icons\' directory appears to be inaccessible. This could indicate filesystem permissions issues or a webserver directory alias (e.g. icons for directory listings)

'); if(!isset($_POST['DOMAIN'])){print('

mod_rewrite+.htaccess (or equivalent) does not appear to be working correctly (or not yet added. At time of writing there is only Apache mod_rewrite+.htaccess)

');} // Session time limit $sessiontime=ini_get('session.gc_maxlifetime'); if($sessiontime<3*3600) { if($sessiontime%3600==0){$humantime=($sessiontime/3600).' hours';} elseif($sessiontime%60==0){$humantime=($sessiontime/60).' minutes';} else{$humantime=$sessiontime.' seconds';} print('

Warning! session.gc_maxlifetime in php.ini is set to '.$sessiontime.' seconds ('.$humantime.') which means sessions will end after just '.$humantime.' of inactivity. Over '.(4*3600).' (4 hours) is recommended

'); } // Max upload filesize $maxsize=ini_get('upload_max_filesize'); switch(strtoupper(substr($maxsize,-1))) { case 'Y': $maxsize=(int)$maxsize*1024; case 'Z': $maxsize=(int)$maxsize*1024; case 'E': $maxsize=(int)$maxsize*1024; case 'P': $maxsize=(int)$maxsize*1024; case 'T': $maxsize=(int)$maxsize*1024; case 'G': $maxsize=(int)$maxsize*1024; case 'M': $maxsize=(int)$maxsize*1024; case 'K': $maxsize=(int)$maxsize*1024; } if($maxsize<50*1024*1024) { print('

Warning! upload_max_filesize in php.ini limits uploads to '.ini_get('upload_max_filesize').'. Over 50M is recommended

'); } // Step 1: PHP Modules $modules=Array(); if(!function_exists('curl_exec')){$modules[]='curl';} if(!function_exists('mysqli_connect')){$modules[]='mysqli';} if(!function_exists('imagepng')){$modules[]='gd';} if(!function_exists('openssl_sign')){$modules[]='openssl';} if(!function_exists('_')){$modules[]='gettext';} // TODO: Offer to create a noop _() and stick to english? put _() in config.php (and maybe don't even bother to warn until there are some translations) if(count($modules)>0) { print('

PHP Modules

'); print('To continue setting up Thingshare, make sure the following PHP modules are installed and enabled:'); print('
'); exit(); } // Step 2: Check that . is writable if(!touch('configtest')) { print('

Filesystem Permissions

'); print('The account this script runs as ('.exec('whoami').') is unable to write to the web root directory, make sure the filesystem permissions are correct and that there is enough available disk space'); print('
'); exit(); } unlink('configtest'); // Step 3: Check that things are installed and accessible $deps=''; $mandatory=false; if(substr_count(shell_exec('assimp --help'), 'listext')<1) { $deps.='
  • The program assimp appears to be missing. It is required to convert between 3D model filetypes for previews. On Debian it is provided by the package \'assimp-utils\'
  • '; $mandatory=true; } if(!is_dir('parsedown')) { $deps.='
  • The PHP library Parsedown appears to be missing. It is required to render markdown formatted text into HTML. See Dependencies for how to obtain it
  • '; $mandatory=true; } if(!is_dir('mdjs')){$deps.='
  • The javascript library mdjs appears to be missing. It can optionally be used to generate live previews of markdown formatted text. See Dependencies for how to obtain it
  • ';} if(!file_exists('x3dom.debug.js') || !file_exists('x3dom.css')){$deps.='
  • The javascript library x3dom appears to be missing. It can optionally be used to preview models in 3D. See Dependencies for how to obtain it
  • ';} if($deps!='') { print('

    Dependencies

    '); if($mandatory) { print('
    '); exit(); } } // Step 4: Gather information to write a config.php $valuecheck=false; if(isset($_POST['DOMAIN'])) // Sanity checks on provided values { $valuecheck=true; $dbtest=mysqli_connect($_POST['DB_HOST'], $_POST['DB_USER'], $_POST['DB_PASS'], $_POST['DB_NAME']); if(!$dbtest){$valuecheck=false; print('

    Error! Connecting to database failed: '.mysqli_connect_error().'

    ');} if(!is_dir($_POST['TMPDIR']) && !mkdir($_POST['TMPDIR'], 0755)){$valuecheck=false; print('

    Error! Temp directory does not exist and could not be created

    ');} if(touch($_POST['TMPDIR'].'/test', 0644)){unlink($_POST['TMPDIR'].'/test');}else{$valuecheck=false; print('

    Error! Temp directory is unwritable for user '.shell_exec('whoami').'

    ');} if(!preg_match('/^[a-zA-Z]*$/', $_POST['PREVIEW_RENDERMETHOD'])) { $valuecheck=false; print('

    Error! Invalid rendermethod

    '); }else{ exec($_POST['PREVIEW_RENDERMETHOD'].' --version', $x, $ret); if($ret!=0) { $valuecheck=false; print('

    Error! '.$_POST['PREVIEW_RENDERMETHOD'].' does not appear to be installed

    '); } } } if(!$valuecheck) { // TODO: Handle preview color and size print('
    '); $baseurl=$_SERVER['REQUEST_URI']; $baseurl=substr($baseurl,0,strrpos($baseurl,'/')); // This ended up being a little bit longer than just copying the sample file and adjusting the format to be a form, but now it won't need to be updated when the sample config changes $f=fopen('config.php.sample', 'r'); $title=''; while($line=fgets($f)) { if(substr($line,0,2)=='//'){$title=substr($line,2);} if(preg_match("/define\('([^']*)', *'([^']*)'\); *\/\/(.*)/", $line, $matches)) { if($title!=''){print('

    '.$title.'

    '); $title='';} $key=$matches[1]; $default=$matches[2]; $name=$matches[3]; if($key=='DOMAIN'){$default=$_SERVER['HTTP_HOST'];} // Special defaults if($key=='BASEURL'){$default=$baseurl;} if(isset($_POST[$key])){$default=$_POST[$key];} if($optionpos=strpos($name, '[')) // Dropdown for options { $options=substr($name, $optionpos+1); if($end=strpos($options, ']')){$options=substr($options,0,$end);} $options=explode(',', $options); $name=substr($name, 0, $optionpos); print($name.':
    '); }else{ // Regular text input $type=(substr_count($key, 'PASS')?'password':'text'); print($name.':
    '); } } } print('
    '); }else{ // Step 5: Write config.php based on config.php.sample and the submitted values $config=file_get_contents('config.php.sample'); foreach($_POST as $key=>$value) { $config=preg_replace("/define\('".$key."', *'[^']*'\)/", "define('".$key."', '".$value."')", $config); } file_put_contents('config.php', $config); print('

    Done!

    '); print('Your Thingshare instance is now live.
    '); print('Click here to register the first account, which will get the administrative privileges'); // Step 6: Initiate database include_once('db.php'); db_create_tables(); // Generate and store key, used to verify remote activities of local users $config = array( 'digest_alg'=>'sha512', // TODO: Is there a better digest for this? Would using HASH from config.php be a good idea? (I suspect not) 'private_key_bits'=>4096, 'private_key_type'=>OPENSSL_KEYTYPE_RSA, ); $res=openssl_pkey_new($config); openssl_pkey_export($res, $pem); // Store this in DB setoption('rpckey', $pem); $res=openssl_pkey_get_details($res);//['key']; file_put_contents('rpckey.pem', $res['key']); // Insert some default allowed filetypes foreach(Array( // Meshes '3mf'=>'model/3mf', 'obj'=>'model/obj', 'stl'=>'model/stl', 'x3d'=>'model/x3d+xml', // Interchange formats 'iges'=>'model/iges', 'step'=>'application/step', 'stp'=>'application/step', // Source files 'blend'=>'application/x-blender', 'blender'=>'application/x-blender', 'fcstd'=>'application/x-extension-fcstd', 'scad'=>'application/x-openscad', // Images 'gif'=>'image/gif', 'jpeg'=>'image/jpeg', 'jpg'=>'image/jpeg', 'png'=>'image/png', 'svg'=>'image/svg+xml', 'txt'=>'text/plain') as $ext=>$mime) { mysqli_query($db, 'insert into filetypes(extension, mimetype) values("'.$ext.'", "'.$mime.'")'); } // Insert some sane default licenses, TODO: Include CC0? Or maybe not, CC themselves make a rather big deal out of it and it seems to be somewhat country-specific foreach(Array( Array('Creative Commons BY 4.0', 'Free to share, use for commercial purposes, and create derivative works, requiring attribution', 'https://creativecommons.org/licenses/by/4.0/'), Array('Creative Commons BY-SA 4.0', 'Free to share, use for commercial purposes, and create derivative works, requiring attribution and that derivative works use the same license', 'https://creativecommons.org/licenses/by-sa/4.0/', true), Array('Creative Commons BY-ND 4.0', 'Free to share and use for commercial purposes, requiring attribution, forbidding derivative works', 'https://creativecommons.org/licenses/by-nd/4.0/'), Array('Creative Commons BY-NC 4.0', 'Free to share and create derivative works, requiring attribution, forbidding commercial use', 'https://creativecommons.org/licenses/by-nc/4.0/'), Array('Creative Commons BY-NC-SA 4.0', 'Free to share and create derivative works, requiring attribution and that derivative works use the same license, forbidding commercial use', 'https://creativecommons.org/licenses/by-nc-sa/4.0/'), Array('Creative Commons BY-NC-ND 4.0', 'Free to share, requiring attribution, forbidding commercial use and derivative works', 'https://creativecommons.org/licenses/by-nc-nd/4.0/'), Array('AGPL 3.0', 'Free to share, use for commercial purposes, and create derivative works, requiring attribution, source files, and that derivative works use the same license. Considers remote interaction equivalent to distribution', 'https://www.gnu.org/licenses/agpl-3.0.txt'), Array('GPL 3.0', 'Free to share, use for commercial purposes, and create derivative works, requiring attribution, source files, and that derivative works use the same license', 'https://www.gnu.org/licenses/gpl-3.0.txt'), ) as $license) { $name=mysqli_real_escape_string($db, $license[0]); $simple=mysqli_real_escape_string($db, $license[1]); $full=mysqli_real_escape_string($db, $license[2]); $default=((isset($license[3]) && $license[3])?'true':'false'); mysqli_query($db, 'insert into licenses(name, simple, full, removed, defaultlicense) values("'.$name.'", "'.$simple.'", "'.$full.'", false, '.$default.')'); } } ?>