function account() { $fields = array('name' => ['Username', false], 'pass1' => ['Enter Password', true], 'pass2' => ['Confirm Password', true]); if (CLISetup::readInput($fields)) { CLISetup::log(); if (!User::isValidName($fields['name'], $e)) { CLISetup::log(Lang::account($e == 1 ? 'errNameLength' : 'errNameChars'), CLISetup::LOG_ERROR); } else { if (!User::isValidPass($fields['pass1'], $e)) { CLISetup::log(Lang::account($e == 1 ? 'errPassLength' : 'errPassChars'), CLISetup::LOG_ERROR); } else { if ($fields['pass1'] != $fields['pass2']) { CLISetup::log(Lang::account('passMismatch'), CLISetup::LOG_ERROR); } else { if ($_ = DB::Aowow()->SelectCell('SELECT 1 FROM ?_account WHERE user = ? AND (status <> ?d OR (status = ?d AND statusTimer > UNIX_TIMESTAMP()))', $fields['name'], ACC_STATUS_NEW, ACC_STATUS_NEW)) { CLISetup::log(Lang::account('nameInUse'), CLISetup::LOG_ERROR); } else { // write to db $ok = DB::Aowow()->query('REPLACE INTO ?_account (user, passHash, displayName, joindate, email, allowExpire, userGroups, userPerms) VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?, 0, ?d, 1)', $fields['name'], User::hashCrypt($fields['pass1']), Util::ucFirst($fields['name']), CFG_CONTACT_EMAIL, U_GROUP_ADMIN); if ($ok) { $newId = DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE user = ?', $fields['name']); Util::gainSiteReputation($newId, SITEREP_ACTION_REGISTER); CLISetup::log("account " . $fields['name'] . " created successfully", CLISetup::LOG_OK); } else { // something went wrong CLISetup::log(Lang::main('intError'), CLISetup::LOG_ERROR); } } } } } } else { CLISetup::log(); CLISetup::log("account creation aborted", CLISetup::LOG_WARN); } }
function dbconfig() { $databases = ['aowow', 'world', 'auth', 'characters']; $AoWoWconf = []; $dbFields = array('host' => ['Server Host', false], 'user' => ['User', false], 'pass' => ['Password', true], 'db' => ['Database Name', false], 'prefix' => ['Table prefix', false]); $testDB = function ($idx, $name, $dbInfo) { $buff = '[' . CLISetup::bold($idx) . '] ' . str_pad($name, 17); $errStr = ''; if ($dbInfo['host']) { // test DB if ($link = @mysqli_connect($dbInfo['host'], $dbInfo['user'], $dbInfo['pass'], $dbInfo['db'])) { mysqli_close($link); } else { $errStr = '[' . mysqli_connect_errno() . '] ' . mysqli_connect_error(); } $buff .= $errStr ? CLISetup::red('ERR ') : CLISetup::green('OK '); $buff .= 'mysqli://' . $dbInfo['user'] . ':' . str_pad('', strlen($dbInfo['pass']), '*') . '@' . $dbInfo['host'] . '/' . $dbInfo['db']; $buff .= ($dbInfo['prefix'] ? ' table prefix: ' . $dbInfo['prefix'] : null) . ' ' . $errStr; } else { $buff .= ' ' . CLISetup::bold('<empty>'); } return $buff; }; if (file_exists('config/config.php')) { require 'config/config.php'; } foreach ($databases as $idx => $name) { if (empty($AoWoWconf[$name]) && $name != 'characters') { $AoWoWconf[$name] = array_combine(array_keys($dbFields), ['', '', '', '', '']); } } while (true) { CLISetup::log(); CLISetup::log("select a numerical index to use the corresponding entry"); $nCharDBs = 0; foreach ($databases as $idx => $name) { if ($idx != 3) { CLISetup::log($testDB($idx, $name, $AoWoWconf[$name])); } else { if (!empty($AoWoWconf[$name])) { foreach ($AoWoWconf[$name] as $charIdx => $dbInfo) { CLISetup::log($testDB($idx + $nCharDBs++, $name . ' [' . $charIdx . ']', $AoWoWconf[$name][$charIdx])); } } } } CLISetup::log("[" . CLISetup::bold(3 + $nCharDBs) . "] add an additional Character DB"); while (true) { $inp = ['idx' => ['', true, '/\\d/']]; if (CLISetup::readInput($inp, true) && $inp) { if ($inp['idx'] >= 0 && $inp['idx'] <= 3 + $nCharDBs) { $curFields = $dbFields; if ($inp['idx'] == 3 + $nCharDBs) { // add new realmDB $curFields['realmId'] = ['Realm Id', false, '/[1-9][0-9]*/']; } if (CLISetup::readInput($curFields)) { // auth, world or aowow if ($inp['idx'] < 3) { $AoWoWconf[$databases[$inp['idx']]] = $curFields ?: array_combine(array_keys($dbFields), ['', '', '', '', '']); } else { if ($inp['idx'] == 3 + $nCharDBs) { if ($curFields) { $_ = $curFields['realmId']; unset($curFields['realmId']); $AoWoWconf[$databases[3]][$_] = $curFields; } } else { $i = 0; foreach ($AoWoWconf[$databases[3]] as $realmId => &$dbInfo) { if ($inp['idx'] - 3 != $i++) { continue; } if ($curFields) { $dbInfo = $curFields; } else { unset($AoWoWconf[$databases[3]][$realmId]); } } } } // write config file $buff = "<?php\n\nif (!defined('AOWOW_REVISION'))\n die('illegal access');\n\n\n"; foreach ($databases as $db) { if ($db != 'characters') { $buff .= '$AoWoWconf[\'' . $db . '\'] = ' . var_export($AoWoWconf[$db], true) . ";\n\n"; } else { foreach ($AoWoWconf[$db] as $idx => $charInfo) { $buff .= '$AoWoWconf[\'' . $db . '\'][\'' . $idx . '\'] = ' . var_export($AoWoWconf[$db][$idx], true) . ";\n\n"; } } } $buff .= "?>\n"; CLISetup::log(); CLISetup::writeFile('config/config.php', $buff); continue 2; } else { CLISetup::log(); CLISetup::log("edit canceled! returning to list...", CLISetup::LOG_WARN); sleep(1); continue 2; } } } else { CLISetup::log(); CLISetup::log("db setup aborted", CLISetup::LOG_WARN); break 2; } } } }
function firstrun($resume) { require_once 'setup/tools/sqlGen.class.php'; require_once 'setup/tools/fileGen.class.php'; SqlGen::init(true); FileGen::init(true); /****************/ /* define steps */ /****************/ $steps = array(['dbconfig', null, 'testDB', 'Please enter your database credentials.', 'could not establish connection to:'], ['siteconfig', null, 'testSelf', 'SITE_HOST and STATIC_HOST ' . CLISetup::bold('must') . ' be set. Also enable FORCE_SSL if needed. You may also want to change other variables such as NAME, NAME_SHORT OR LOCALES.', 'could not access:'], ['SqlGen::generate', 'achievementcategory', null, null, null], ['SqlGen::generate', 'achievementcriteria', null, null, null], ['SqlGen::generate', 'glyphproperties', null, null, null], ['SqlGen::generate', 'itemenchantment', null, null, null], ['SqlGen::generate', 'itemenchantmentcondition', null, null, null], ['SqlGen::generate', 'itemextendedcost', null, null, null], ['SqlGen::generate', 'itemlimitcategory', null, null, null], ['SqlGen::generate', 'itemrandomproppoints', null, null, null], ['SqlGen::generate', 'lock', null, null, null], ['SqlGen::generate', 'mailtemplate', null, null, null], ['SqlGen::generate', 'scalingstatdistribution', null, null, null], ['SqlGen::generate', 'scalingstatvalues', null, null, null], ['SqlGen::generate', 'spellfocusobject', null, null, null], ['SqlGen::generate', 'spellrange', null, null, null], ['SqlGen::generate', 'spellvariables', null, null, null], ['SqlGen::generate', 'totemcategory', null, null, null], ['SqlGen::generate', 'classes', null, null, null], ['SqlGen::generate', 'factions', null, null, null], ['SqlGen::generate', 'factiontemplate', null, null, null], ['SqlGen::generate', 'holidays', null, null, null], ['SqlGen::generate', 'icons', null, null, null], ['SqlGen::generate', 'itemrandomenchant', null, null, null], ['SqlGen::generate', 'races', null, null, null], ['SqlGen::generate', 'shapeshiftforms', null, null, null], ['SqlGen::generate', 'skillline', null, null, null], ['SqlGen::generate', 'achievement', null, null, null], ['SqlGen::generate', 'creature', null, null, null], ['SqlGen::generate', 'currencies', null, null, null], ['SqlGen::generate', 'events', null, null, null], ['SqlGen::generate', 'objects', null, null, null], ['SqlGen::generate', 'pet', null, null, null], ['SqlGen::generate', 'quests', null, null, null], ['SqlGen::generate', 'quests_startend', null, null, null], ['SqlGen::generate', 'spell', null, null, null], ['SqlGen::generate', 'spelldifficulty', null, null, null], ['SqlGen::generate', 'taxi', null, null, null], ['SqlGen::generate', 'titles', null, null, null], ['SqlGen::generate', 'items', null, null, null], ['FileGen::generate', 'complexImg', null, null, null], ['SqlGen::generate', 'spawns', null, null, null], ['SqlGen::generate', 'zones', null, null, null], ['SqlGen::generate', 'itemset', null, null, null], ['SqlGen::generate', 'item_stats', null, null, null], ['SqlGen::generate', 'source', null, null, null], ['FileGen::generate', 'searchplugin', null, null, null], ['FileGen::generate', 'power', null, null, null], ['FileGen::generate', 'searchboxScript', null, null, null], ['FileGen::generate', 'demo', null, null, null], ['FileGen::generate', 'searchboxBody', null, null, null], ['FileGen::generate', 'realmMenu', null, null, null], ['FileGen::generate', 'locales', null, null, null], ['FileGen::generate', 'itemScaling', null, null, null], ['FileGen::generate', 'realms', null, null, null], ['FileGen::generate', 'statistics', null, null, null], ['FileGen::generate', 'simpleImg', null, null, null], ['FileGen::generate', 'talents', null, null, null], ['FileGen::generate', 'pets', null, null, null], ['FileGen::generate', 'talentIcons', null, null, null], ['FileGen::generate', 'glyphs', null, null, null], ['FileGen::generate', 'itemsets', null, null, null], ['FileGen::generate', 'enchants', null, null, null], ['FileGen::generate', 'gems', null, null, null], ['FileGen::generate', 'profiler', null, null, null], ['FileGen::generate', 'statistics', null, null, null], ['FileGen::generate', 'statistics', null, null, null], ['update', null, null, null, null], ['account', null, 'testAcc', 'Please create your admin account.', 'There is no user with administrator priviledges in the DB.'], ['endSetup', null, null, null, null]); /**********/ /* helper */ /**********/ $saveProgress = function ($nStep) { $h = fopen('cache/firstrun', 'w'); fwrite($h, AOWOW_REVISION . "\n" . ($nStep + 1) . "\n"); fclose($h); }; $testDB = function (&$error) { require 'config/config.php'; $error = []; foreach (['world', 'aowow', 'auth'] as $what) { if ($what == 'auth' && (empty($AoWoWconf['auth']) || empty($AoWoWconf['auth']['host']))) { continue; } if ($link = @mysqli_connect($AoWoWconf[$what]['host'], $AoWoWconf[$what]['user'], $AoWoWconf[$what]['pass'], $AoWoWconf[$what]['db'])) { mysqli_close($link); } else { $error[] = ' * ' . $what . ': ' . '[' . mysqli_connect_errno() . '] ' . mysqli_connect_error(); } } return empty($error); }; $testSelf = function (&$error) { $error = []; $test = function ($url, &$rCode) { $res = get_headers($url, true); if (preg_match("/HTTP\\/[0-9\\.]+\\s+([0-9]+)/", $res[0], $m)) { $rCode = $m[1]; return $m[1] == 200; } $rCode = 0; return false; }; $res = DB::Aowow()->selectCol('SELECT `key` AS ARRAY_KEY, value FROM ?_config WHERE `key` IN ("site_host", "static_host", "force_ssl")'); $prot = $res['force_ssl'] ? 'https://' : 'http://'; if ($res['site_host']) { if (!$test($prot . $res['site_host'] . '/README', $resp)) { $error[] = ' * could not access ' . $prot . $res['site_host'] . '/README [' . $resp . ']'; } } else { $error[] = ' * SITE_HOST is empty'; } if ($res['static_host']) { if (!$test($prot . $res['static_host'] . '/css/aowow.css', $resp)) { $error[] = ' * could not access ' . $prot . $res['static_host'] . '/css/aowow.css [' . $resp . ']'; } } else { $error[] = ' * STATIC_HOST is empty'; } return empty($error); }; $testAcc = function (&$error) { $error = []; return !!DB::Aowow()->selectCell('SELECT id FROM ?_account WHERE userPerms = 1'); }; function endSetup() { return DB::Aowow()->query('UPDATE ?_config SET value = 0 WHERE `key` = "maintenance"'); } /********************/ /* get current step */ /********************/ $startStep = 0; if ($resume) { if (file_exists('cache/firstrun')) { $rows = file('cache/firstrun'); if ((int) $rows[0] == AOWOW_REVISION) { $startStep = (int) $rows[1]; } else { CLISetup::log('firstrun info is outdated! Starting from scratch.', CLISetup::LOG_WARN); } } if (!$startStep) { CLISetup::log('no usable info found.', CLISetup::LOG_WARN); $inp = ['x' => ['start from scratch? (y/n)', true, '/y|n/i']]; if (!CLISetup::readInput($inp, true) || !$inp || strtolower($inp['x']) == 'n') { CLISetup::log(); return; } CLISetup::log(); } else { CLISetup::log('Resuming setup from step ' . $startStep); sleep(1); } } /*******/ /* run */ /*******/ foreach ($steps as $idx => $step) { if ($startStep > $idx) { continue; } if (!strpos($step[0], '::') && !is_callable($step[0])) { require_once 'setup/tools/clisetup/' . $step[0] . '.func.php'; } if ($step[3]) { CLISetup::log($step[3]); $inp = ['x' => ['Press any key to continue', true]]; if (!CLISetup::readInput($inp, true)) { // we don't actually care about the input return; } } while (true) { $res = call_user_func($step[0], $step[1]); // check script result if ($step[2]) { if (!${$step}[2]($errors)) { CLISetup::log($step[4], CLISetup::LOG_ERROR); foreach ($errors as $e) { CLISetup::log($e); } } else { $saveProgress($idx); break; } } else { if ($res !== false) { $saveProgress($idx); break; } } $inp = ['x' => ['[' . CLISetup::bold('c') . ']ontinue anyway? [' . CLISetup::bold('r') . ']etry? [' . CLISetup::bold('a') . ']bort?', true, '/c|r|a/i']]; if (CLISetup::readInput($inp, true) && $inp) { switch (strtolower($inp['x'])) { case 'c': $saveProgress($idx); break 2; case 'r': CLISetup::log(); break; case 'a': CLISetup::log(); return; } } else { CLISetup::log(); return; } } } unlink('cache/firstrun'); CLISetup::log('setup finished', CLISetup::LOG_OK); }
function siteconfig() { if (!DB::isConnected(DB_AOWOW)) { CLISetup::log(); CLISetup::log("database not yet set up!\n Please use --dbconfig for setup", CLISetup::LOG_WARN); return; } while (true) { CLISetup::log(); CLISetup::log('select a numerical index to use the corresponding entry'); $results = DB::Aowow()->select('SELECT *, (flags & ?d) AS php FROM ?_config ORDER BY php ASC', CON_FLAG_PHP); $hasEmpty = false; foreach ($results as $idx => $data) { if (!($data['flags'] & CON_FLAG_PHP) && $data['value'] === '') { $hasEmpty = true; } $php = $data['flags'] & CON_FLAG_PHP; $buff = "[" . CLISetup::bold($idx) . "] " . ($idx > 9 ? '' : ' ') . ($php ? ' PHP ' : ' AOWOW '); $buff .= str_pad($php ? strtolower($data['key']) : strtoupper('cfg_' . $data['key']), 35); if ($data['value'] === '') { $buff .= CLISetup::red('<empty>'); } else { $info = explode(' - ', $data['comment']); if ($data['flags'] & CON_FLAG_TYPE_BOOL) { $buff .= '[bool] ' . ($data['value'] ? '<Enabled>' : '<Disabled>'); } else { if ($data['flags'] & CON_FLAG_OPT_LIST && !empty($info[2])) { $buff .= "[opt] "; foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $buff .= '[' . ($data['value'] == $opt[0] ? 'x' : ' ') . ']' . $opt[1] . ' '; } } else { if ($data['flags'] & CON_FLAG_BITMASK && !empty($info[2])) { $buff .= "[mask] "; foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $buff .= '[' . ($data['value'] & 1 << $opt[0] ? 'x' : ' ') . ']' . $opt[1] . ' '; } } else { if ($data['flags'] & CON_FLAG_TYPE_STRING) { $buff .= "[str] " . $data['value']; } else { if ($data['flags'] & CON_FLAG_TYPE_FLOAT) { $buff .= "[float] " . floatVal($data['value']); } else { /* if ($data['flags'] & CON_FLAG_TYPE_INT) */ $buff .= "[int] " . intVal($data['value']); } } } } } } CLISetup::log($buff); } CLISetup::log(str_pad("[" . CLISetup::bold(count($results)) . "]", 21) . "add another php configuration"); if ($hasEmpty) { CLISetup::log(); CLISetup::log("please configure the required empty setings", CLISetup::LOG_WARN); } $inp = ['idx' => ['', false, '/\\d/']]; if (CLISetup::readInput($inp) && $inp && $inp['idx'] !== '') { // add new php setting if ($inp['idx'] == count($results)) { CLISetup::log(); CLISetup::log("Adding additional php configuration."); while (true) { $setting = array('key' => ['option name', false, '/[\\w_\\.\\-]/i'], 'val' => ['value']); if (CLISetup::readInput($setting) && $setting) { CLISetup::log(); $key = strtolower($setting['key']); if (ini_get($key) === false || ini_set($key, $setting['val']) === false) { CLISetup::log("this configuration option cannot be set", CLISetup::LOG_ERROR); sleep(1); } else { if (DB::Aowow()->selectCell('SELECT 1 FROM ?_config WHERE `flags` & ?d AND `key` = ?', CON_FLAG_PHP, $key)) { CLISetup::log("this configuration option is already in use", CLISetup::LOG_ERROR); sleep(1); } else { DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `flags`) VALUES (?, ?, ?d)', $key, $setting['val'], CON_FLAG_TYPE_STRING | CON_FLAG_PHP); CLISetup::log("new php configuration added", CLISetup::LOG_OK); sleep(1); } } break; } else { CLISetup::log(); CLISetup::log("edit canceled! returning to list...", CLISetup::LOG_WARN); sleep(1); break; } } } else { if ($inp['idx'] >= 0 && $inp['idx'] < count($results)) { $conf = $results[$inp['idx']]; $info = explode(' - ', $conf['comment']); $buff = ''; CLISetup::log(); $buff .= $conf['flags'] & CON_FLAG_PHP ? " PHP: " : "AOWOW: "; $buff .= $conf['flags'] & CON_FLAG_PHP ? strtolower($conf['key']) : strtoupper('cfg_' . $conf['key']); if (!empty($info[1])) { $buff .= " - " . $info[1]; } CLISetup::log($buff); $buff = "VALUE: "; if ($conf['flags'] & CON_FLAG_TYPE_BOOL) { $buff .= $conf['value'] ? '<Enabled>' : '<Disabled>'; } else { if ($conf['flags'] & CON_FLAG_OPT_LIST && !empty($info[2])) { foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $buff .= '[' . ($conf['value'] == $opt[0] ? 'x' : ' ') . '] ' . $opt[1] . ' '; } } else { if ($conf['flags'] & CON_FLAG_BITMASK && !empty($info[2])) { foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $buff .= '[' . ($conf['value'] & 1 << $opt[0] ? 'x' : ' ') . '] ' . $opt[1] . ' '; } } else { if ($conf['flags'] & CON_FLAG_TYPE_STRING) { $buff .= $conf['value']; } else { if ($conf['flags'] & CON_FLAG_TYPE_FLOAT) { $buff .= floatVal($conf['value']); } else { /* if ($conf['flags'] & CON_FLAG_TYPE_INT) */ $buff .= intVal($conf['value']); } } } } } CLISetup::log($buff); CLISetup::log(); CLISetup::log("[" . CLISetup::bold('E') . "]dit"); if (!($conf['flags'] & CON_FLAG_PERSISTENT)) { CLISetup::log("[" . CLISetup::bold('D') . "]elete"); } if (strstr($info[0], 'default:')) { CLISetup::log("[" . CLISetup::bold('R') . "]estore Default - " . trim(explode('default:', $info[0])[1])); } while (true) { $action = ['idx' => ['', true, '/[edr]/i']]; if (CLISetup::readInput($action, true) && $action) { switch (strtoupper($action['idx'])) { case 'E': // edit value $pattern = false; $single = false; $value = ['idx' => ['Select new value', false, &$pattern]]; if ($conf['flags'] & CON_FLAG_OPT_LIST) { $_valid = []; foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $_valid[] = $opt[0]; CLISetup::log('[' . CLISetup::bold($opt[0]) . '] ' . $opt[1]); } $single = true; $pattern = '/\\d/'; $validate = function ($v) use($_valid) { return in_array($v, $_valid); }; } else { if ($conf['flags'] & CON_FLAG_BITMASK) { CLISetup::log('Bitmask: sum fields to select multiple options'); $_valid = 0x0; foreach (explode(', ', $info[2]) as $option) { $opt = explode(':', $option); $_valid |= 1 << $opt[0]; CLISetup::log('[' . CLISetup::bold(1 << $opt[0]) . ']' . str_pad('', 4 - strlen(1 << $opt[0])) . $opt[1]); } $pattern = '/\\d+/'; $validate = function ($v) use($_valid) { $v = $v & $_valid; return $v; }; } else { if ($conf['flags'] & CON_FLAG_TYPE_BOOL) { CLISetup::log('[' . CLISetup::bold(0) . '] Disabled'); CLISetup::log('[' . CLISetup::bold(1) . '] Enabled'); $single = true; $pattern = '/[01]/'; $validate = function ($v) { return true; }; } else { if ($conf['flags'] & CON_FLAG_TYPE_INT) { $validate = function ($v) { return preg_match('/^-?\\d+$/i', $v); }; } else { if ($conf['flags'] & CON_FLAG_TYPE_FLOAT) { $validate = function ($v) { return preg_match('/^-?\\d*(,|.)?\\d+$/i', $v); }; } else { // string $validate = function ($v) { return true; }; } } } } } while (true) { $use = $value; if (CLISetup::readInput($use, $single) && $use) { CLISetup::log(); if (!$validate($use['idx'])) { CLISetup::log("value not in range", CLISetup::LOG_ERROR); sleep(1); continue; } else { DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $use['idx'], strtolower($conf['key'])); CLISetup::log("setting updated", CLISetup::LOG_OK); sleep(1); break 3; } } else { CLISetup::log("edit canceled! returning to selection...", CLISetup::LOG_WARN); sleep(1); break; } } break 2; case 'R': // restore default if (!strstr($info[0], 'default:')) { continue 2; } // @eval .. some dafault values are supplied as bitmask or the likes if (DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', @eval('return (' . trim(explode('default:', $info[0])[1]) . ');'), strtolower($conf['key']))) { CLISetup::log("default value restored", CLISetup::LOG_OK); sleep(1); } break 2; case 'D': // delete config pair if ($conf['flags'] & CON_FLAG_PERSISTENT) { continue 2; } if (DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0', strtolower($conf['key']), CON_FLAG_PERSISTENT)) { CLISetup::log("php setting deleted ['" . $conf['key'] . "': '" . $conf['value'] . "']", CLISetup::LOG_OK); sleep(1); } break 2; } } else { CLISetup::log(); CLISetup::log("edit canceled! returning to list...", CLISetup::LOG_WARN); sleep(1); break; } } } else { CLISetup::log(); CLISetup::log("invalid selection", CLISetup::LOG_ERROR); sleep(1); } } } else { CLISetup::log(); CLISetup::log("site configuration aborted", CLISetup::LOG_WARN); break; } } }