00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 @require_once('config.inc.php');
00013 require_once('html.inc.php');
00014 require_once('modules.inc.php');
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 function cache_output($category, $name, $out)
00026 {
00027
00028 if (!empty($_SERVER['HTTPS'])) {
00029 log_msg('debug', 'common: not caching '.quot($name).' because of https');
00030 return false;
00031 }
00032
00033
00034 $f = CONTENT_DIR.'/cache';
00035 if (!is_dir($f)) {
00036 $m = umask(0000);
00037 if (!@mkdir($f, 0777)) {
00038 umask($m);
00039 log_msg('error', 'common: cannot create cache directory '.quot($f));
00040 return false;
00041 }
00042 umask($m);
00043 }
00044
00045
00046 $f .= '/'.$category;
00047 if (!is_dir($f)) {
00048 $m = umask(0000);
00049 if (!@mkdir($f, 0777)) {
00050 umask($m);
00051 log_msg('error', 'common: cannot create cache directory '.quot($f));
00052 return false;
00053 }
00054 umask($m);
00055 }
00056
00057
00058 $f .= '/'.$name;
00059 $m = umask(0111);
00060 if (!file_put_contents($f, $out)) {
00061 umask($m);
00062 log_msg('error', 'common: error writing cache file '.quot($f));
00063 return false;
00064 }
00065 umask($m);
00066
00067 log_msg('debug', 'common: cached '.$category.' '.quot($name));
00068 return true;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078 function default_html($add_glue)
00079 {
00080 html_title(SITE_NAME);
00081 $favicon = FAVICON;
00082 if (!empty($favicon)) {
00083 if (is_url($favicon)) {
00084 html_favicon($favicon);
00085 } else {
00086 html_favicon(base_url().$favicon);
00087 }
00088 }
00089 if (USE_MIN_FILES) {
00090 html_add_css(base_url().'css/reset.min.css', 1);
00091 } else {
00092 html_add_css(base_url().'css/reset.css', 1);
00093 }
00094
00095 html_add_css(base_url().'css/main.css', 3);
00096 if ($add_glue) {
00097 html_add_css(base_url().'css/glue.css', 4);
00098 }
00099 if ($add_glue) {
00100 $jquery = JQUERY;
00101 if (is_url($jquery)) {
00102 html_add_js($jquery, 1);
00103 } else {
00104 html_add_js(base_url().$jquery, 1);
00105 }
00106
00107 if (USE_MIN_FILES) {
00108 html_add_js(base_url().'js/glue.min.js', 3);
00109 } else {
00110 html_add_js(base_url().'js/glue.js', 3);
00111 }
00112 html_add_js_var('$.glue.base_url', base_url());
00113 html_add_js_var('$.glue.conf.show_frontend_errors', SHOW_FRONTEND_ERRORS);
00114 html_add_js_var('$.glue.version', glue_version());
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 function drop_cache($category, $name = '')
00127 {
00128 if (empty($name)) {
00129 $d = @scandir(CONTENT_DIR.'/cache/'.$category);
00130 if ($d === false) {
00131 return;
00132 }
00133 } else {
00134 $d = array($name);
00135 }
00136
00137 foreach ($d as $f) {
00138 if ($f == '.' || $f == '..') {
00139 continue;
00140 }
00141 $fn = CONTENT_DIR.'/cache/'.$category.'/'.$f;
00142 if (@unlink($fn)) {
00143 log_msg('debug', 'common: dropped cache of '.$category.' '.quot($f));
00144 }
00145 }
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 function glue_version()
00155 {
00156 $a = expl('.', HOTGLUE_VERSION);
00157 $ret = array(0, 0, 0);
00158 for ($i=0; $i < count($a); $i++) {
00159 $ret[$i] = intval($a[$i]);
00160 }
00161 return $ret;
00162 }
00163
00164
00165
00166
00167
00168 function handle_updates()
00169 {
00170 $new = glue_version();
00171 $write_file = false;
00172
00173 if (($s = @file_get_contents(CONTENT_DIR.'/version')) !== false) {
00174
00175 $a = expl('.', $s);
00176 $old = array(0, 0, 0);
00177 for ($i=0; $i < count($a); $i++) {
00178 $old[$i] = $a[$i];
00179 }
00180
00181 if ($old != $new) {
00182 log_msg('info', 'common: detected hotglue update from version '.implode('.', $old).' to '.implode('.', $new));
00183
00184 invoke_hook('glue_update', array('old'=>$old, 'new'=>$new));
00185 $write_file = true;
00186 }
00187 } else {
00188 $write_file = true;
00189 }
00190
00191 if ($write_file) {
00192 $m = umask(0111);
00193 @file_put_contents(CONTENT_DIR.'/version', implode('.', $new));
00194 umask($m);
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 function hotglue_error($code, $no_header = false)
00208 {
00209 if (!$no_header) {
00210
00211 if (USE_HOTGLUE_ERRORS) {
00212 $header_only = true;
00213 } else {
00214 $header_only = false;
00215 }
00216 if (!http_error($code, $header_only)) {
00217 return false;
00218 }
00219 }
00220
00221
00222 html_flush();
00223 default_html(false);
00224 html_add_css(base_url().'css/hotglue_error.css');
00225 $bdy = &body();
00226 elem_attr($bdy, 'id', 'hotglue_error');
00227 body_append(tab(1).'<div id="paper">'.nl());
00228 body_append(tab(2).'<div id="wrapper">'.nl());
00229 body_append(tab(3).'<div id="content">'.nl());
00230 body_append(tab(4).'<div id="left-nav">'.nl());
00231 body_append(tab(5).'<img src="'.htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8').'img/hotglue-logo.png" alt="logo">'.nl());
00232 body_append(tab(4).'</div>'.nl());
00233 body_append(tab(4).'<div id="main">'.nl());
00234 if ($code == 400) {
00235 body_append(tab(5).'<h1 id="error-title">ERROR 400, bad request!</h1>'.nl());
00236 } elseif ($code == 401) {
00237 body_append(tab(5).'<h1 id="error-title">Authorization required!</h1>'.nl());
00238 } elseif ($code == 404) {
00239 body_append(tab(5).'<h1 id="error-title">ERROR 404, not found!</h1>'.nl());
00240 } elseif ($code == 500) {
00241 body_append(tab(5).'<h1 id="error-title">ERROR 500, server fault!</h1>'.nl());
00242 }
00243 body_append(tab(5).'<p>'.nl());
00244 if ($code == 400) {
00245 body_append(tab(6).'Something got screwed up...<br>'.nl());
00246 body_append(tab(6).'The page is sending a bad request to the server!'.nl());
00247 } elseif ($code == 401) {
00248 body_append(tab(6).'You need to be logged in in order to do this.<br>'.nl());
00249 } elseif ($code == 404) {
00250 body_append(tab(6).'It looks like you got lost in cyber-space...<br>'.nl());
00251 body_append(tab(6).'The page you are trying to reach does not exist!'.nl());
00252 } elseif ($code == 500) {
00253 body_append(tab(6).'Are we runnining out of fuel?!<br>'.nl());
00254 body_append(tab(6).'Something is causing serious server errors!'.nl());
00255 }
00256 body_append(tab(5).'</p>'.nl());
00257 body_append(tab(6).'<a href="'.htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8').'" id="home">take me home!</a>'.nl());
00258 body_append(tab(4).'</div>'.nl());
00259 body_append(tab(3).'</div>'.nl());
00260 body_append(tab(2).'</div>'.nl());
00261 body_append(tab(2).'<div style="position: absolute; left: 200px; top: -10px; z-index: 2;">'.nl());
00262 body_append(tab(3).'<img src="'.htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8').'img/hotglue-404.png" alt="404">'.nl());
00263 body_append(tab(2).'</div>'.nl());
00264 body_append(tab(1).'</div>'.nl());
00265 echo html_finalize();
00266
00267 die();
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 function is_auth()
00277 {
00278 if (AUTH_METHOD == 'none') {
00279 log_msg('debug', 'common: auth success (auth_method none)');
00280 return true;
00281 } elseif (AUTH_METHOD == 'basic') {
00282 if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
00283 if ($_SERVER['PHP_AUTH_USER'] == AUTH_USER && $_SERVER['PHP_AUTH_PW'] == AUTH_PASSWORD) {
00284 log_msg('debug', 'common: auth success (auth_method basic)');
00285 return true;
00286 } else {
00287 log_msg('info', 'common: auth failure (auth_method basic)');
00288 return false;
00289 }
00290 } else {
00291 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
00292 log_msg('warn', 'common: no auth data (auth_method basic) but HTTP_AUTHORIZATION is '.quot(var_dump_inl($_SERVER['HTTP_AUTHORIZATION'])));
00293 } else {
00294 log_msg('debug', 'common: no auth data (auth_method basic)');
00295 }
00296 return false;
00297 }
00298 } elseif (AUTH_METHOD == 'digest') {
00299 if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
00300 log_msg('debug', 'common: auth digest '.var_dump_inl($_SERVER['PHP_AUTH_DIGEST']));
00301 $res = http_digest_check(array(AUTH_USER=>AUTH_PASSWORD), SITE_NAME);
00302 if ($res == 0) {
00303 log_msg('debug', 'common: auth success (auth_method digest)');
00304 return true;
00305 } else {
00306 log_msg('info', 'common: auth failure '.$res.' (auth_method digest)');
00307 return false;
00308 }
00309 } else {
00310 if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
00311 log_msg('warn', 'common: no auth data (auth_method digest) but HTTP_AUTHORIZATION is '.quot(var_dump_inl($_SERVER['HTTP_AUTHORIZATION'])));
00312 } else {
00313 log_msg('debug', 'common: no auth data (auth_method digest)');
00314 }
00315 return false;
00316 }
00317 } else {
00318 log_msg('error', 'common: invalid or missing AUTH_METHOD config setting');
00319 return false;
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 function is_cached($category, $name, $max_age)
00333 {
00334
00335
00336 if (!empty($_SERVER['HTTPS'])) {
00337 return false;
00338 }
00339
00340 $f = CONTENT_DIR.'/cache/'.$category.'/'.$name;
00341 if (!is_file($f)) {
00342 return false;
00343 }
00344
00345 if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
00346 clearstatcache(true, realpath($f));
00347 } else {
00348 clearstatcache();
00349 }
00350 $age = filemtime($f);
00351 if ($max_age < abs(time()-$age)) {
00352 return false;
00353 } else {
00354 return true;
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 function object_exists($s)
00366 {
00367 $a = expl('.', $s);
00368
00369
00370 if (2 < count($a) && is_file(CONTENT_DIR.'/'.str_replace('.', '/', $s))) {
00371 return true;
00372 } else {
00373 return false;
00374 }
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 function page_canonical(&$s)
00385 {
00386 $a = expl('.', $s);
00387
00388 if (count($a) == 1) {
00389 $s .= '.head';
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 function page_exists($s)
00402 {
00403 $a = expl('.', $s);
00404 if (1 < count($a) && !empty($a[0]) && !empty($a[1]) && is_dir(CONTENT_DIR.'/'.$a[0].'/'.$a[1])) {
00405 return true;
00406 } else {
00407 return false;
00408 }
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418 function page_reserved($s)
00419 {
00420 $a = expl('.', $s);
00421 $r = expl(' ', RESERVED_PAGE_NAMES);
00422 if (in_array($a[0], $r)) {
00423 return true;
00424 } else {
00425 return false;
00426 }
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436 function page_short($s)
00437 {
00438 $a = expl('.', $s);
00439 if (count($a) == 1) {
00440 return $s;
00441 } elseif (count($a) == 2 && $a[1] == 'head') {
00442 return $a[0];
00443 } elseif (count($a) == 2) {
00444 return $s;
00445 } else {
00446 return '';
00447 }
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457 function prompt_auth($header_only = false)
00458 {
00459 if (AUTH_METHOD == 'none') {
00460
00461 } elseif (AUTH_METHOD == 'basic') {
00462 header('WWW-Authenticate: Basic realm="'.str_replace("\"", '', SITE_NAME).'"');
00463 header($_SERVER['SERVER_PROTOCOL'].' 401 Unauthorized');
00464 } elseif (AUTH_METHOD == 'digest') {
00465 http_digest_prompt(SITE_NAME);
00466 } else {
00467 log_msg('error', 'common: invalid or missing AUTH_METHOD config setting');
00468 }
00469 hotglue_error(401, true);
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 function resolve_aliases($s, $name = '')
00481 {
00482
00483 $s = str_replace('$BASEURL$', base_url(), $s);
00484 $s = str_replace('$baseurl$', base_url(), $s);
00485
00486 $s = str_replace('$GLUE$', HOTGLUE_VERSION, $s);
00487 $s = str_replace('$glue$', HOTGLUE_VERSION, $s);
00488 if (!empty($name)) {
00489
00490 $s = str_replace('$OBJ$', $name, $s);
00491 $s = str_replace('$obj$', $name, $s);
00492
00493 $s = str_replace('$PAGE$', implode('.', array_slice(expl('.', $name), 0, 2)), $s);
00494 $s = str_replace('$page$', implode('.', array_slice(expl('.', $name), 0, 2)), $s);
00495
00496 $s = str_replace('$PAGENAME$', array_shift(expl('.', $name)), $s);
00497 $s = str_replace('$pagename$', array_shift(expl('.', $name)), $s);
00498
00499 $s = str_replace('$PROT$', empty($_SERVER['HTTPS']) ? 'http' : 'https', $s);
00500 $s = str_replace('$prot$', empty($_SERVER['HTTPS']) ? 'http' : 'https', $s);
00501
00502 $s = str_replace('$REV$', array_shift(array_slice(expl('.', $name), 1, 1)), $s);
00503 $s = str_replace('$rev$', array_shift(array_slice(expl('.', $name), 1, 1)), $s);
00504 }
00505 return $s;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 function resolve_relative_urls($s)
00518 {
00519 $attrs = array('href', 'src');
00520
00521 foreach ($attrs as $attr) {
00522 $start = 0;
00523 while (($start = strpos($s, $attr.'="', $start)) !== false) {
00524 if (($end = strpos($s, '"', $start+strlen($attr)+2)) !== false) {
00525 $link = substr($s, $start+strlen($attr)+2, $end-$start-strlen($attr)-2);
00526 if (!is_url($link) && substr($link, 0, 1) != '#') {
00527
00528 log_msg('debug', 'common: resolving relative url '.quot($link));
00529 if (SHORT_URLS) {
00530 $link = base_url().$link;
00531 } else {
00532 $link = base_url().'?'.$link;
00533 }
00534 } else {
00535 log_msg('debug', 'common: not resolving url '.quot($link));
00536 }
00537 $start = $end+1;
00538 } else {
00539 break;
00540 }
00541 }
00542 }
00543 return $s;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 function serve_cached($category, $name)
00555 {
00556 $f = CONTENT_DIR.'/cache/'.$category.'/'.$name;
00557 if (@readfile($f)) {
00558 log_msg('info', 'common: serving '.$category.' '.quot($name).' from cache');
00559 return true;
00560 } else {
00561 log_msg('error', 'common: cannot serve '.$category.' '.quot($name).' from cache');
00562 return false;
00563 }
00564 }
00565
00566
00567
00568
00569
00570
00571
00572 function startpage()
00573 {
00574
00575
00576 $s = @file_get_contents(CONTENT_DIR.'/startpage');
00577 if ($s !== false && 0 < strlen($s)) {
00578 return $s;
00579 } else {
00580 $s = DEFAULT_PAGE;
00581 page_canonical($s);
00582 return $s;
00583 }
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 function upload_file($fn, $page, $orig_fn = '', &$existed = false)
00599 {
00600
00601 if ($orig_fn == '') {
00602 $orig_fn = $fn;
00603 }
00604
00605 $a = expl('.', $page);
00606 if (count($a) < 1 || !is_dir(CONTENT_DIR.'/'.$a[0])) {
00607 log_msg('error', 'common: page '.quot($page).' does not exist, cannot move uploaded file');
00608
00609 return false;
00610 }
00611
00612
00613 $d = CONTENT_DIR.'/'.$a[0].'/shared';
00614 if (!is_dir($d)) {
00615 $m = umask(0000);
00616 if (!@mkdir($d, 0777)) {
00617 umask($m);
00618 log_msg('error', 'common: cannot create shared directory '.quot($d).', cannot move uploaded file');
00619
00620 return false;
00621 }
00622 umask($m);
00623 }
00624
00625
00626 if (($f = dir_has_same_file($d, $fn, $orig_fn)) !== false) {
00627 log_msg('info', 'common: reusing file '.quot($f).' instead of newly uploaded file as they don\'t differ');
00628 @unlink($fn);
00629 $existed = true;
00630 return $f;
00631 } else {
00632
00633 $f = unique_filename($d, basename($orig_fn));
00634 $m = umask(0111);
00635 if (!@move_uploaded_file($fn, $d.'/'.$f)) {
00636 umask($m);
00637 log_msg('error', 'common: error moving uploaded file to '.quot($d.'/'.$f));
00638
00639 return false;
00640 } else {
00641 umask($m);
00642 log_msg('info', 'common: moved uploaded file to '.quot($d.'/'.$f));
00643 $existed = false;
00644 return $f;
00645 }
00646 }
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 function valid_pagename($s)
00658 {
00659 $a = expl('.', $s);
00660 if (count($a) != 2) {
00661 return false;
00662 } elseif (empty($a[0]) || empty($a[1])) {
00663 return false;
00664 } elseif (in_array($a[0], array('cache', 'shared'))) {
00665
00666
00667
00668
00669
00670
00671 return false;
00672 } elseif (in_array($a[1], array('shared'))) {
00673
00674 return false;
00675 } elseif (is_file($a[0]) || is_dir($a[0]) || is_link($a[0])) {
00676
00677
00678 return false;
00679 } else {
00680 return true;
00681 }
00682 }