$val) { if (is_array($val)) { $res[] = "[$key]"; foreach ($val as $skey => $sval) { $res[] = "$skey = $sval"; } } else { $res[] = "$key = $val"; } } if (safefilerewrite($file, implode(PHP_EOL, $res))) { return true; } else { return false; } } function safefilerewrite($fileName, $dataToSave) { if ($fp = fopen($fileName, 'w')) { $startTime = microtime(true); do { $canWrite = flock($fp, LOCK_EX); // If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load if (!$canWrite) { usleep(round(rand(0, 100)*1000)); } } while ((!$canWrite)and((microtime(true)-$startTime) < 5)); //file was locked so now we can store information if ($canWrite) { fwrite($fp, $dataToSave.PHP_EOL); flock($fp, LOCK_UN); } fclose($fp); return true; } else { return false; } } /** * Saves a CSRF token in the session */ function ensureCSRFSessionToken() { if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } } /** * Add CSRF Token to form */ function CSRFTokenFieldTag() { $token = htmlspecialchars($_SESSION['csrf_token']); return ''; } /** * Retuns a CSRF meta tag (for use with xhr, for example) */ function CSRFMetaTag() { $token = htmlspecialchars($_SESSION['csrf_token']); return ''; } /** * Validate CSRF Token */ function CSRFValidate() { $post_token = $_POST['csrf_token']; $header_token = $_SERVER['HTTP_X_CSRF_TOKEN']; if (empty($post_token) && empty($header_token)) { return false; } $request_token = $post_token; if (empty($post_token)) { $request_token = $header_token; } if (hash_equals($_SESSION['csrf_token'], $request_token)) { return true; } else { error_log('CSRF violation'); return false; } } /** * Should the request be CSRF-validated? */ function csrfValidateRequest() { $request_method = strtolower($_SERVER['REQUEST_METHOD']); return in_array($request_method, [ "post", "put", "patch", "delete" ]); } /** * Handle invalid CSRF */ function handleInvalidCSRFToken() { header('HTTP/1.1 500 Internal Server Error'); header('Content-Type: text/plain'); echo 'Invalid CSRF token'; exit; } /** * Test whether array is associative */ function isAssoc($arr) { return array_keys($arr) !== range(0, count($arr) - 1); } /** * Display a selector field for a form. Arguments are: * * @param string $name: Field name * @param array $options: Array of options * @param string $selected: Selected option (optional) * @param string $id: $options is an associative array this should be the key * @param string $event: onChange event (optional) * @param string $disabled (optional) */ function SelectorOptions($name, $options, $selected = null, $id = null, $event = null, $disabled = null) { echo '' , PHP_EOL; } /** * * @param string $input * @param string $string * @param int $offset * @param string $separator * @return $string */ function GetDistString($input, $string, $offset, $separator) { $string = substr($input, strpos($input, $string)+$offset, strpos(substr($input, strpos($input, $string)+$offset), $separator)); return $string; } /** * * @param array $arrConfig * @return $config */ function ParseConfig($arrConfig) { $config = array(); foreach ($arrConfig as $line) { $line = trim($line); if ($line == "" || $line[0] == "#") { continue; } list($option, $value) = array_map("trim", explode("=", $line, 2)); if (empty($config[$option])) { $config[$option] = $value ?: true; } else { if (!is_array($config[$option])) { $config[$option] = [ $config[$option] ]; } $config[$option][] = $value; } } return $config; } /** * * @param string $freq * @return $channel */ function ConvertToChannel($freq) { if ($freq >= 2412 && $freq <= 2484) { $channel = ($freq - 2407)/5; } elseif ($freq >= 4915 && $freq <= 4980) { $channel = ($freq - 4910)/5 + 182; } elseif ($freq >= 5035 && $freq <= 5865) { $channel = ($freq - 5030)/5 + 6; } else { $channel = -1; } if ($channel >= 1 && $channel <= 196) { return $channel; } else { return 'Invalid Channel'; } } /** * Converts WPA security string to readable format * * @param string $security * @return string */ function ConvertToSecurity($security) { $options = array(); preg_match_all('/\[([^\]]+)\]/s', $security, $matches); foreach ($matches[1] as $match) { if (preg_match('/^(WPA\d?)/', $match, $protocol_match)) { $protocol = $protocol_match[1]; $matchArr = explode('-', $match); if (count($matchArr) > 2) { $options[] = htmlspecialchars($protocol . ' ('. $matchArr[2] .')', ENT_QUOTES); } else { $options[] = htmlspecialchars($protocol, ENT_QUOTES); } } } if (count($options) === 0) { // This could also be WEP but wpa_supplicant doesn't have a way to determine // this. // And you shouldn't be using WEP these days anyway. return 'Open'; } else { return implode(' / ', $options); } } /** * Renders a simple PHP template */ function renderTemplate($name, $data = []) { $file = realpath(dirname(__FILE__) . "/../templates/$name.php"); if (!file_exists($file)) { return "template $name ($file) not found"; } if (is_array($data)) { extract($data); } ob_start(); include $file; return ob_get_clean(); } function expandCacheKey($key) { return RASPI_CACHE_PATH . "/" . $key; } function hasCache($key) { $cacheKey = expandCacheKey($key); return file_exists($cacheKey); } function readCache($key) { $cacheKey = expandCacheKey($key); if (!file_exists($cacheKey)) { return null; } return file_get_contents($cacheKey); } function writeCache($key, $data) { mkdir(RASPI_CACHE_PATH, 0777, true); $cacheKey = expandCacheKey($key); file_put_contents($cacheKey, $data); } function deleteCache($key) { if (hasCache($key)) { $cacheKey = expandCacheKey($key); unlink($cacheKey); } } function cache($key, $callback) { if (hasCache($key)) { return readCache($key); } else { $data = $callback(); writeCache($key, $data); return $data; } }