<?php
require_once(__DIR__ . '/log.inc.php');
require_once(__DIR__ . '/sql.inc.php');
require_once(__DIR__ . '/token.inc.php');
require_once(__DIR__ . '/prof.inc.php');
$rg_sid = '';
/*
* Add a session
*/
function rg_sess_add($db, $uid, $sid, $session_time, $lock_ip)
{
global $rg_sid;
rg_prof_start("sess_add");
rg_log_enter("sess_add: uid=$uid, sid=$sid, session_time=$session_time"
. " lock_ip=$lock_ip");
if ($lock_ip == 1)
$ip = rg_ip();
else
$ip = "";
$now = time();
$ret = FALSE;
while (1) {
$params = array("sid" => $sid,
"uid" => $uid,
"expire" => $now + $session_time,
"session_time" => $session_time,
"ip" => $ip);
$sql = "INSERT INTO sess (sid, uid, expire, session_time, ip)"
. " VALUES (@@sid@@, @@uid@@, @@expire@@"
. ", @@session_time@@, @@ip@@)";
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE) {
rg_log("Cannot insert (" . rg_sql_error() . ")!");
break;
}
rg_sql_free_result($res);
$params['last_db_write'] = $now;
rg_cache_set('sess' . '::' . $sid . '::' . 'info',
$params, RG_SOCKET_NO_WAIT);
$rg_sid = $sid;
$ret = TRUE;
break;
}
rg_log_exit();
rg_prof_end("sess_add");
return $ret;
}
/*
* Tests if a session is still valid. Will return FALSE on error or session
* info.
*/
function rg_sess_valid($db)
{
global $rg_sid;
rg_prof_start("sess_valid");
rg_log_enter("sess_valid: sid=$rg_sid...");
$ret = FALSE;
while (1) {
if (empty($rg_sid))
break;
// Is a pre-login session?
if (strncmp($rg_sid, 'X', 1) == 0)
break;
$r = rg_cache_get('sess' . '::' . $rg_sid . '::' . 'info');
if ($r === FALSE) {
$params = array("sid" => $rg_sid);
$sql = "SELECT * FROM sess WHERE sid = @@sid@@";
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE) {
rg_log("Cannot select (" . rg_sql_error() . ")!");
break;
}
$rows = rg_sql_num_rows($res);
if ($rows > 0) {
$r = rg_sql_fetch_array($res);
$r['last_db_write'] = $r['expire'] - $r['session_time'];
rg_cache_set('sess' . '::' . $rg_sid . '::' . 'info',
$r, RG_SOCKET_NO_WAIT);
}
rg_sql_free_result($res);
}
if ($r === FALSE) {
rg_log("Session not found.");
break;
}
$now = time();
if ($r['expire'] < $now) {
rg_log("Session too old (" . ($now - $r['expire']) . "s).");
break;
}
$ip = rg_ip();
if (!empty($r['ip']) && (strcmp($r['ip'], $ip) != 0)) {
rg_log("Session invalid because of IP"
. " login=" . $r['ip'] . " now=$ip.");
break;
}
$uid = $r['uid'];
rg_log("Session valid, uid=$uid, expire=+"
. ($r['expire'] - $now) . "s");
$ret = $r;
unset($ret['sid']);
break;
}
rg_log_exit();
rg_prof_end("sess_valid");
return $ret;
}
/*
* Refreshes a session.
* Because of performance reasons, we will not update database
* every time.
*/
function rg_sess_update($db, $sess)
{
global $rg_sid;
rg_prof_start("sess_update");
rg_log_enter("sess_update: sess=" . rg_array2string($sess));
$now = time();
$ret = FALSE;
while (1) {
if ($sess['last_db_write'] + 60 > $now) {
$_diff = $now - $sess['last_db_write'];
rg_log_debug('last_db_write is fresh enough (' . $_diff . 's)');
$ret = TRUE;
break;
}
$sess['expire'] = $now + $sess['session_time'];
$params = $sess;
$params['sid'] = $rg_sid;
$sql = "UPDATE sess SET expire = @@expire@@"
. " WHERE sid = @@sid@@";
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE) {
rg_log("Cannot update (" . rg_sql_error() . ")!");
// We will not exit here. At least in cache to be ok
} else {
$sess['last_db_write'] = $now;
rg_sql_free_result($res);
}
rg_cache_set('sess' . '::' . $rg_sid . '::' . 'info',
$sess, RG_SOCKET_NO_WAIT);
$ret = TRUE;
break;
}
rg_log_exit();
rg_prof_end("sess_update");
return $ret;
}
/*
* Destroy session
*/
function rg_sess_destroy($db)
{
global $rg_sid;
rg_prof_start('sess_destroy');
rg_log_enter('sess_destroy: sid=' . $rg_sid);
$ret = FALSE;
while (1) {
$params = array("sid" => $rg_sid);
$sql = "DELETE FROM sess WHERE sid = @@sid@@";
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE) {
rg_log("Cannot delete (" . rg_sql_error() . ")!");
break;
}
rg_sql_free_result($res);
// Delete all tokens associated with this session
rg_token_delete($db, $rg_sid, '');
rg_ui_login_reset();
rg_cache_unset('sess' . '::' . $rg_sid . '::'. 'info',
RG_SOCKET_NO_WAIT);
$ret = TRUE;
break;
}
rg_log_exit();
rg_prof_end('sess_destroy');
return $ret;
}