33 $internalPlugins = array(
34 'filebrowser',
'meta_tags',
'page_params',
'tinymce' 36 if (in_array(
$plugin, $internalPlugins)) {
39 $filename = $pth[
'folder'][
'plugins'] .
$plugin .
'/version.nfo';
40 if (is_readable($filename)) {
41 $contents = file_get_contents($filename);
42 $contents = explode(
',', $contents);
43 $version = $contents[2];
68 $stx = $tx[
'syscheck'];
70 $o =
"<h4>$stx[title]</h4>\n<ul id=\"xh_system_check\">\n";
72 if (key_exists(
'phpversion', $data)) {
73 $ok = version_compare(PHP_VERSION, $data[
'phpversion']) >= 0;
74 $o .=
XH_systemCheckLi(
'', $ok ?
'success' :
'fail', sprintf($stx[
'phpversion'], $data[
'phpversion']));
77 if (key_exists(
'extensions', $data)) {
78 $cat =
'xh_system_check_cat_start';
79 foreach ($data[
'extensions'] as $ext) {
81 $notok = $ext[1] ?
'fail' :
'warning';
88 extension_loaded($ext) ?
'success' : $notok,
89 sprintf($stx[
'extension'], $ext)
95 if (key_exists(
'writable', $data)) {
96 $cat =
'xh_system_check_cat_start';
97 foreach ($data[
'writable'] as
$file) {
98 if (is_array($file)) {
99 $notok = $file[1] ?
'fail' :
'warning';
104 $o .=
XH_systemCheckLi($cat, is_writable($file) ?
'success' : $notok, sprintf($stx[
'writable'], $file));
109 if (key_exists(
'other', $data)) {
110 $cat =
'xh_system_check_cat_start';
111 foreach ($data[
'other'] as $check) {
112 $notok = $check[1] ?
'fail' :
'warning';
140 $class =
"class=\"xh_$state $class\"";
142 . sprintf($tx[
'syscheck'][
'message'],
$text, $tx[
'syscheck'][$state])
161 $base = preg_replace(
'/index\.php$/',
'', $sn);
162 $parts = explode(
'/', $base . $path);
164 while (
$i < count($parts)) {
165 switch ($parts[
$i]) {
167 array_splice($parts, $i, 1);
170 array_splice($parts, $i - 1, 2);
177 $path = implode(
'/', $parts);
192 $url = preg_replace(
'/index\.php$/',
'',
CMSIMPLE_URL) . $path;
193 $defaultContext = stream_context_set_default(
194 array(
'http' => array(
'method' =>
'HEAD',
'timeout' => 5))
196 $headers = get_headers($url);
197 stream_context_set_default(stream_context_get_params($defaultContext));
199 if (preg_match(
'/^HTTP\S*\s+4/', $headers[0])) {
222 $o =
'<p><b>' . $tx[
'sysinfo'][
'version'] .
'</b></p>' .
"\n";
226 $o .=
'<p><b>' . $tx[
'sysinfo'][
'plugins'] .
'</b></p>' .
"\n" .
"\n";
233 $o .=
'</ul>' .
"\n" .
"\n";
235 $serverSoftware = !empty($_SERVER[
'SERVER_SOFTWARE'])
236 ? $_SERVER[
'SERVER_SOFTWARE']
237 : $tx[
'sysinfo'][
'unknown'];
238 $o .=
'<p><b>' . $tx[
'sysinfo'][
'webserver'] .
'</b></p>' .
"\n" 239 .
'<ul>' .
"\n" .
'<li>' . $serverSoftware .
'</li>' .
"\n" 241 $o .=
'<p><b>' . $tx[
'sysinfo'][
'php_version'] .
'</b></p>' .
"\n" 242 .
'<ul>' .
"\n" .
'<li>' . phpversion() .
'</li>' .
"\n" 243 .
'<li><a href="' . $sn .
'?&phpinfo" target="blank"><b>' 244 . $tx[
'sysinfo'][
'phpinfo_link'] .
'</b></a> ' 245 . $tx[
'sysinfo'][
'phpinfo_hint'] .
'</li>' .
"\n" .
'</ul>' .
"\n" .
"\n";
247 $o .=
'<h4>' . $tx[
'sysinfo'][
'helplinks'] .
'</h4>' .
"\n" .
"\n";
250 <
li><
a href=
"http://www.cmsimple-xh.org/">cmsimple-xh.org »</
a></
li>
251 <
li><
a href=
"http://www.cmsimple-xh.org/wiki/">cmsimple-xh.org/wiki/ »</
a></
li>
252 <
li><
a href=
"http://www.cmsimpleforum.com/">cmsimpleforum.com »</
a></
li>
253 <
li><
a href=
"http://www.cmsimple-xh.org/de/?Alles_auf_einen_Blick">cmsimple-xh.org/de/?Alles_auf_einen_Blick »</
a></
li>
258 $stx = $tx[
'syscheck'];
260 'phpversion' =>
'5.3.7',
261 'extensions' => array(
262 array(
'intl',
false),
267 'writable' => array(),
271 'content',
'corestyle',
'images',
'downloads',
'userfiles',
'media' 273 foreach ($temp as
$i) {
274 $checks[
'writable'][] = $pth[
'folder'][
$i];
276 $temp = array(
'config',
'log',
'language',
'content',
'template',
'stylesheet');
277 foreach ($temp as $i) {
278 $checks[
'writable'][] = $pth[
'file'][
$i];
280 $checks[
'writable'] = array_unique($checks[
'writable']);
281 sort($checks[
'writable']);
283 $pth[
'file'][
'config'], $pth[
'file'][
'content'], $pth[
'file'][
'template']
285 foreach ($files as
$file) {
286 $checks[
'other'][] = array(
288 sprintf($stx[
'access_protected'], $file)
291 if ($tx[
'locale'][
'all'] ==
'') {
292 $checks[
'other'][] = array(
true,
false, $stx[
'locale_default']);
294 $checks[
'other'][] = array(
295 setlocale(LC_ALL, $tx[
'locale'][
'all']),
false,
296 sprintf($stx[
'locale_available'], $tx[
'locale'][
'all'])
299 $checks[
'other'][] = array(
300 date_default_timezone_get() !==
'UTC',
301 false, $stx[
'timezone']
303 $checks[
'other'][] = array(
304 !get_magic_quotes_runtime(),
false, $stx[
'magic_quotes']
306 $checks[
'other'][] = array(
307 !ini_get(
'safe_mode'),
false, $stx[
'safe_mode']
309 $checks[
'other'][] = array(
310 !ini_get(
'session.use_trans_sid'),
false, $stx[
'use_trans_sid']
312 $checks[
'other'][] = array(
313 ini_get(
'session.use_only_cookies'),
false, $stx[
'use_only_cookies']
315 $checks[
'other'][] = array(
316 ini_get(
'session.cookie_lifetime') == 0,
false, $stx[
'cookie_lifetime']
318 $checks[
'other'][] = array(
319 strpos(ob_get_contents(),
"\xEF\xBB\xBF") !== 0,
322 $checks[
'other'][] = array(
323 !password_verify(
'test', $cf[
'security'][
'password']),
324 false, $stx[
'password']
326 $checks[
'other'][] = array(
327 function_exists(
'fsockopen'),
false, $stx[
'fsockopen']
348 $o =
'<p>' . $tx[
'settings'][
'warning'] .
'</p>' .
"\n" 349 .
'<h4>' . $tx[
'settings'][
'systemfiles'] .
'</h4>' .
"\n" .
'<ul>' .
"\n";
351 foreach (array(
'config',
'language') as
$i) {
352 $o .=
'<li><a href="' . $sn .
'?file=' . $i .
'&action=array">' 354 . $tx[
'filetype'][
$i] .
'</a></li>' .
"\n";
357 foreach (array(
'stylesheet',
'template') as $i) {
358 $o .=
'<li><a href="' . $sn .
'?file=' . $i .
'&action=edit">' 360 . $tx[
'filetype'][
$i] .
'</a></li>' .
"\n";
362 foreach (array(
'log') as $i) {
363 $o .=
'<li><a href="' . $sn .
'?file=' . $i .
'&action=view">' 365 . $tx[
'filetype'][
$i] .
'</a></li>' .
"\n";
367 $o .=
'</ul>' .
"\n";
369 $o .=
'<h4>' . $tx[
'settings'][
'backup'] .
'</h4>' .
"\n";
371 $o .=
'<h4>' . $tx[
'settings'][
'more'] .
'</h4>' .
"\n" 373 .
'<li><a href="' . $sn .
'?&validate">' . $tx[
'editmenu'][
'validate'] .
'</a></li>' 374 .
'<li><a href="' . $sn .
'?&xh_pagedata">' .$tx[
'editmenu'][
'pagedata'] .
'</a></li>' 375 .
'<li><a href="' . $sn .
'?&xh_change_password">' . $tx[
'editmenu'][
'change_password'] .
'</a></li>' 376 .
'<li><a href="' . $sn .
'?&sysinfo">' . $tx[
'editmenu'][
'sysinfo'] .
'</a></li>' 396 $title = $tx[
'title'][
'log'];
397 return '<h1>' . $tx[
'title'][
'log'] .
'</h1>' 400 .
'<script type="text/javascript">' 402 .
'var elt = document.getElementById("xh_logfile");' 403 .
'elt.scrollTop = elt.scrollHeight;' 407 . $tx[
'log'][
'timestamp'] .
' – ' 408 . $tx[
'log'][
'type'] .
' – ' 409 . $tx[
'log'][
'module'] .
' – ' 410 . $tx[
'log'][
'category'] .
' – ' 411 . $tx[
'log'][
'description']
432 if (isset($_GET[
'xh_success'])) {
435 $o .=
'<li>' .
utf8_ucfirst($tx[
'filetype'][
'content']) .
' <a href="' 436 . $sn .
'?file=content&action=view" target="_blank">' 437 . $tx[
'action'][
'view'] .
'</a>' .
' <a href="' . $sn .
'?file=content">' 438 . $tx[
'action'][
'edit'] .
'</a>' .
' <a href="' 439 . $sn .
'?file=content&action=download">' . $tx[
'action'][
'download']
441 .
' <form action="' . $sn .
'?&xh_backups" method="post"' 442 .
' class="xh_inline_form" id="xh_backup_form">' 443 .
'<input type="hidden" name="file" value="content">' 444 .
'<input type="hidden" name="action" value="backup">' 445 .
'<input type="hidden" name="xh_suffix" value="extra">' 446 .
'<input type="submit" class="submit" value="' 447 . $tx[
'action'][
'backup'] .
'">' 448 . $_XH_csrfProtection->tokenInput()
450 .
' <form action="' . $sn .
'?&xh_backups" method="post"' 451 .
' class="xh_inline_form">' 452 .
'<input type="hidden" name="file" value="content">' 453 .
'<input type="hidden" name="action" value="empty">' 454 .
'<input type="submit" class="submit" value="' 455 . $tx[
'action'][
'empty'] .
'">' 456 . $_XH_csrfProtection->tokenInput()
459 $o .=
'</ul>' .
"\n" .
'<hr>' .
"\n" .
'<p>' 460 . $tx[
'settings'][
'backupexplain1'] .
'</p>' .
"\n" .
'<p>' 461 . $tx[
'settings'][
'backupexplain2'] .
'</p>' .
"\n" .
'<ul>' .
"\n";
462 $fs =
sortdir($pth[
'folder'][
'content']);
463 foreach ($fs as $p) {
465 $size = filesize($pth[
'folder'][
'content'] .
'/' . $p);
466 $size = round(($size) / 102.4) / 10;
467 $o .=
'<li><a href="' . $sn .
'?file=' . $p
468 .
'&action=view" target="_blank">' 469 . $p .
'</a> (' . $size .
' KB)' 470 .
' <form action="' . $sn .
'?&xh_backups" method="post"' 471 .
' class="xh_inline_form">' 472 .
'<input type="hidden" name="file" value="' . $p .
'">' 473 .
'<input type="hidden" name="action" value="restore">' 474 .
'<input type="submit" class="submit" value="' 475 . $tx[
'action'][
'restore'] .
'">' 476 . $_XH_csrfProtection->tokenInput()
481 $o .=
'</ul>' .
"\n";
501 $hiddenPlugins = explode(
',', $cf[
'plugins'][
'hidden']);
502 $hiddenPlugins = array_map(
'trim', $hiddenPlugins);
503 $plugins = array_diff($plugins, $hiddenPlugins);
504 natcasesort($plugins);
505 $plugins = array_values($plugins);
507 $o =
'<h1>' . $tx[
'title'][
'plugins'] .
'</h1><ul>';
508 foreach ($plugins as
$plugin) {
511 'url' =>
"$sn?$plugin&normal",
535 function pluginMenu($add =
'', $link =
'', $target =
'',
$text =
'', array $style = array())
539 switch (strtoupper($add)) {
541 $_XH_pluginMenu->makeRow($style);
544 $_XH_pluginMenu->makeTab($link, $target,
$text, $style);
547 $_XH_pluginMenu->makeData(
$text, $style);
550 return $_XH_pluginMenu->show();
567 $pluginMenu->render($showMain);
587 static $pluginMenu = array();
589 if (isset($label) && isset($url)) {
590 $pluginMenu[
$plugin][] = array(
596 if (isset($pluginMenu[
$plugin])) {
629 $changeMode = $edit ?
'normal' :
'edit';
630 $changeText = $edit ? $tx[
'editmenu'][
'normal'] : $tx[
'editmenu'][
'edit'];
632 $filesMenu = array();
633 foreach (array(
'images',
'downloads',
'media') as $item) {
634 $filesMenu[] = array(
636 'url' => $sn .
'?&edit&' . $item
639 $settingsMenu = array(
641 'label' =>
utf8_ucfirst($tx[
'editmenu'][
'configuration']),
642 'url' => $sn .
'?file=config&action=array' 646 'url' => $sn .
'?file=language&action=array' 650 'url' => $sn .
'?file=template&action=edit' 654 'url' => $sn .
'?file=stylesheet&action=edit' 658 'url' => $sn .
'?file=log&action=view' 662 'url' => $sn .
'?&validate' 666 'url' => $sn .
'?&xh_backups' 670 'url' => $sn .
'?&xh_pagedata' 673 'label' =>
utf8_ucfirst($tx[
'editmenu'][
'change_password']),
674 'url' => $sn .
'?&xh_change_password' 678 'url' => $sn .
'?&sysinfo' 681 $hiddenPlugins = explode(
',', $cf[
'plugins'][
'hidden']);
682 $hiddenPlugins = array_map(
'trim', $hiddenPlugins);
683 $plugins = array_diff($plugins, $hiddenPlugins);
684 $total = count($plugins);
686 $columns = ceil($total / $rows);
687 $rows = ceil($total / $columns);
688 $width = 125 * $columns;
689 $marginLeft = min($width, 250) - $width;
690 natcasesort($plugins);
691 $plugins = array_values($plugins);
692 $orderedPlugins = array();
693 for (
$j = 0;
$j < $rows; ++
$j) {
694 for (
$i = 0;
$i < $total;
$i += $rows) {
695 $orderedPlugins[] = isset($plugins[
$i +
$j]) ? $plugins[
$i +
$j] :
'';
698 $plugins = $orderedPlugins;
699 $pluginMenu = array();
700 foreach ($plugins as
$plugin) {
701 $label = isset($plugin_tx[$plugin][
'menu_plugin'])
702 ? $plugin_tx[
$plugin][
'menu_plugin']
704 $pluginMenuItem = array(
'label' => $label);
706 $pluginMenuItem[
'url'] = $sn .
'?' . $plugin .
'&normal';
708 $pluginMenuItem[
'children'][] = $item;
711 $pluginMenu[] = $pluginMenuItem;
715 'label' => $changeText,
716 'url' => $sn .
'?' . $su .
'&' . $changeMode,
719 'label' =>
utf8_ucfirst($tx[
'editmenu'][
'pagemanager']),
720 'url' => $sn .
'?&normal&xhpages' 724 'url' => $sn .
'?&edit&userfiles',
725 'children' => $filesMenu
729 'url' => $sn .
'?&settings',
730 'children' => $settingsMenu
734 'url' => $sn .
'?&xh_plugins',
735 'children' => $pluginMenu,
736 'id' =>
'xh_adminmenu_plugins',
737 'style' =>
'width:' . $width .
'px; margin-left: ' . $marginLeft .
'px' 741 'url' => $sn .
'?&logout' 745 $t =
"\n" .
'<div id="xh_adminmenu">';
746 $t .=
"\n" .
'<ul>' .
"\n";
747 foreach ($menu as $item) {
751 .
'<div class="xh_break"></div>' .
"\n" .
'</div>' .
"\n";
767 $indent = str_repeat(
' ', $level);
768 $t = $indent .
'<li>';
769 if (isset($item[
'url'])) {
770 $t .=
'<a href="' .
XH_hsc($item[
'url']) .
'"';
771 if (isset($item[
'target'])) {
772 $t .=
' target="' . $item[
'target'] .
'"';
778 $t .= $item[
'label'];
779 if (isset($item[
'url'])) {
784 if (isset($item[
'children'])) {
785 $t .=
"\n" . $indent .
' <ul';
786 if (isset($item[
'id'])) {
787 $t .=
' id="' . $item[
'id'] .
'"';
789 if (isset($item[
'style'])) {
790 $t .=
' style="' . $item[
'style'] .
'"';
793 foreach ($item[
'children'] as $child) {
796 $t .= $indent .
' </ul>' .
"\n" . $indent;
798 $t .=
'</li>' .
"\n";
816 return $_XH_pluginMenu->render(strtoupper($main) ==
'ON');
833 case 'plugin_config':
836 case 'plugin_language':
839 case 'plugin_stylesheet':
848 return $fileEdit->form();
850 case 'plugin_textsave':
851 return $fileEdit->submit();
877 global
$sn,
$su,
$s,
$u,
$c,
$e,
$cf,
$tx,
$_XH_csrfProtection,
$l,
$h,
$s;
881 $editor = $cf[
'editor'][
'external'] ==
'' ||
init_editor();
883 $msg = sprintf($tx[
'error'][
'noeditor'], $cf[
'editor'][
'external']);
884 $e .=
'<li>' . $msg .
'</li>' .
"\n";
886 $o =
'<form method="POST" id="ta" action="' . $sn .
'">' 887 .
tag(
'input type="hidden" name="selected" value="' . $u[$s] .
'"');
890 if (!$cf[
'mode'][
'advanced']) {
891 $o .=
tag(
'input type="hidden" name="level" value="' . $l[$s] .
'"')
892 .
tag(
'input type="hidden" name="heading" value="' . $h[$s] .
'"');
894 $tempContent = preg_replace(
'/<!--XH_ml[1-9]:.*?-->/isu',
'', $c[$s]);
896 $tempContent = $c[
$s];
898 $o .=
tag(
'input type="hidden" name="function" value="save"')
899 .
'<textarea name="text" id="text" class="xh-editor" style="height: ' 900 . $cf[
'editor'][
'height'] .
'px; width: 100%;" rows="30" cols="80">' 903 .
'<script type="text/javascript">' 904 .
'document.getElementById("text").style.height=(' . $cf[
'editor'][
'height']
905 .
') + "px";</script>' 906 . $_XH_csrfProtection->tokenInput();
907 if ($cf[
'editor'][
'external'] ==
'' || !$editor) {
909 $o .=
'<input type="submit" value="' . $value .
'">';
934 'Function ' . __FUNCTION__ .
'() must not be called in view mode',
939 $hot =
'<!--XH_ml[1-9]:';
942 $cnts =
"<html><head><title>$title</title>\n" 943 . $pd_router->headAsPHP()
944 .
'</head><body>' .
"\n";
945 foreach ($c as
$j =>
$i) {
946 preg_match(
"/(.*?)($hot(.+?)$hct)(.*)/isu",
$i, $matches);
947 $page = $matches[1] . $matches[2] . PHP_EOL . $pd_router->pageAsPHP(
$j)
949 $cnts .=
rmnl($page .
"\n");
951 $cnts .=
'</body></html>';
952 if (!file_exists($pth[
'folder'][
'content'])) {
953 mkdir($pth[
'folder'][
'content'],
true);
955 return XH_writeFile($pth[
'file'][
'content'], $cnts) !==
false;
981 if (!$cf[
'mode'][
'advanced']) {
982 $text = preg_replace(
'/<!--XH_ml[1-9]:.*?-->/isu',
'',
$text);
983 $split =
'<!--XH_ml' .
stsl($_POST[
'level']) .
':' 984 .
stsl($_POST[
'heading']) .
'-->' 988 $hot =
'<!--XH_ml[1-9]:';
994 $text = preg_replace(
"/$hot( | |\xC2\xA0| )?$hct/isu",
'',
$text);
996 $text = preg_replace(
'/<p>({{{.*?}}}|#CMSimple .*?#)<\/p>/isu',
'<div>$1</div>',
$text);
1000 if (!preg_match(
'/^<!--XH_ml[1-9]:.+-->/isu',
$text)
1001 && !preg_match(
'/^(<p[^>]*>)?(\ | |<br \/>)?(<\/p>)?$/isu',
$text)
1003 $text =
'<!--XH_ml1:' . $tx[
'toc'][
'missing'] .
'-->' .
"\n" .
$text;
1009 $text = preg_replace(
'/<!--XH_ml[1-9]:/is',
"\x00" .
'$0',
$text);
1010 $pages = explode(
"\x00",
$text);
1013 $c[$s - 1] .= $pages[0];
1015 array_shift($pages);
1016 array_splice($c, $s, 1, $pages);
1019 preg_match_all(
"/$hot(.+?)$hct/isu",
$text, $matches);
1020 if ($pd_router->refresh_from_texteditor($matches[1], $s)) {
1022 if (count($matches[1]) > 0) {
1024 $urlParts = explode($cf[
'uri'][
'seperator'], $selected);
1025 array_splice($urlParts, -1, 1,
uenc(trim(xh_rmws(strip_tags($matches[1][0])))));
1026 $su = implode($cf[
'uri'][
'seperator'], $urlParts);
1029 $su = $u[max($s - 1, 0)];
1034 e(
'notwritable',
'content', $pth[
'file'][
'content']);
1059 $pd_router->destroy(
$i);
1063 $url =
CMSIMPLE_URL .
'?&xh_backups&xh_success=emptied';
1064 header(
'Location: ' . $url,
true, 303);
1067 e(
'cntsave',
'content', $pth[
'file'][
'content']);
1087 $tempFilename = $pth[
'folder'][
'content'] .
'restore.htm';
1088 if (!rename($filename, $tempFilename)) {
1089 e(
'cntsave',
'backup', $tempFilename);
1094 if (!unlink($tempFilename)) {
1095 e(
'cntdelete',
'content', $tempFilename);
1099 if (!rename($tempFilename, $pth[
'file'][
'content'])) {
1100 e(
'cntsave',
'content', $pth[
'file'][
'content']);
1104 $url =
CMSIMPLE_URL .
'?&xh_backups&xh_success=restored';
1105 header(
'Location: ' . $url,
true, 303);
1122 $date = date(
"Ymd_His");
1123 $dest = $pth[
'folder'][
'content'] . $date .
'_' . $suffix .
'.htm';
1124 if (!copy($pth[
'file'][
'content'], $dest)) {
1125 e(
'cntsave',
'backup', $dest);
1127 $url =
CMSIMPLE_URL .
'?&xh_backups&xh_success=backedup';
1128 header(
'Location: ' . $url,
true, 303);
1147 'action' => array(
'advanced_hide',
'advanced_show',
'cancel',
'ok'),
1148 'error' => array(
'server'),
1149 'password' => array(
'score'),
1150 'settings' => array(
'backupsuffix')
1153 foreach ($keys as $category => $keys2) {
1154 foreach ($keys2 as $key) {
1155 $l10n[$category][$key] = $tx[$category][$key];
1158 $o =
'<script type="text/javascript">XH.i18n = ' 1174 return (
bool) preg_match(
'/(?:^|&)' . preg_quote($pluginName,
'/') .
'(?=&|$)/',
sv(
'QUERY_STRING'));
print_plugin_admin($main)
pluginMenu($add='', $link='', $target='', $text='', array $style=array())
XH_isAccessProtected($path)
XH_isContentBackup($filename, $regularOnly=true)
XH_adminMenuItem(array $item, $level=0)
XH_saveEditorContents($text)
XH_writeFile($filename, $contents)
XH_registerPluginMenuItem($plugin, $label=null, $url=null, $target=null)
XH_adminMenu(array $plugins=array())
const CMSIMPLE_XH_VERSION
XH_pluginVersion($plugin)
XH_systemCheckLi($class, $state, $text)
XH_registerStandardPluginMenuItems($showMain)
XH_wantsPluginAdministration($pluginName)
foreach(XH_plugins() as $plugin) $_XH_csrfProtection
XH_systemCheck(array $data)
init_editor(array $elementClasses=array(), $initFile=false)
XH_message($type, $message)
XH_absoluteUrlPath($path)