/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2010, Tomasz Sowa * All rights reserved. * */ #include "sessioncontainer.h" #include "log.h" #include "misc.h" SessionContainer::SessionContainer() { request = 0; table_size = 0; } void SessionContainer::SetRequest(Request * prequest) { request = prequest; } void SessionContainer::Clear() { Table::iterator inext, i = table.begin(); // don't use table.clear(); // because plugins session data would not be erased while( i != table.end() ) { inext = i; ++inext; request->session = &(*i); table.erase(i); i = inext; } // erasing all indexes index_id.clear(); index_time.clear(); table_size = 0; request->session = 0; } void SessionContainer::SetLastContainer(LastContainer * plast_container) { last_container = plast_container; } SessionContainer::TableSize SessionContainer::Size() { // don't use table.size() as it has O(n) complexity on FreeBSD return table_size; } SessionContainer::Iterator SessionContainer::Begin() { return table.begin(); } SessionContainer::Iterator SessionContainer::End() { return table.end(); } Session & SessionContainer::Back() { return table.back(); } bool SessionContainer::PushBack(const Session & session) { if( index_id.find(session.id) != index_id.end() ) // that element already exists return false; Iterator last = table.insert(table.end(), session); index_id.insert( std::make_pair(session.id, last) ); index_time.insert( std::make_pair(session.last_time, last) ); table_size += 1; log << log3 << "SC: added session, id: " << session.id << logend; return true; } SessionContainer::Iterator SessionContainer::FindById(long id) { IndexId::iterator i; i = index_id.find(id); if( i == index_id.end() ) return table.end(); return i->second; } void SessionContainer::DelFirstByTimeInterval(time_t interval, bool skip_remember_flag) { IndexTime::iterator i = index_time.begin(); IndexTime::iterator iold; time_t limit = std::time(0) - interval; Session * old_session = request->session; while( i != index_time.end() && i->second->last_time < limit ) { long id = i->second->id; iold = i; ++i; // incrementing before deleting old one if( skip_remember_flag && iold->second->puser && iold->second->remember_me ) // don't delete sessions which have 'remember_me' flag (and a user is logged) continue; if( iold->second->puser ) last_container->UserLogout(iold->second->puser->id, iold->second->id); // we're logging session.id (call this before table.erase()) DelFromIdIndex(iold->second); request->session = &(*iold->second); table.erase(iold->second); index_time.erase(iold); table_size -= 1; request->session = 0; log << log3 << "SC: deleted index_time for session id: " << id << logend; log << log3 << "SC: deleted session, id: " << id << logend; } request->session = old_session; } void SessionContainer::DelFromIdIndex(SessionContainer::Iterator iter) { IndexId::iterator i; for(i = index_id.begin() ; i!=index_id.end() ; ++i) { if( i->second == iter ) { index_id.erase(i); log << log3 << "SC: deleted index_id for session id: " << iter->id << logend; break; } } } void SessionContainer::UpdateLastTime(SessionContainer::Iterator iter, time_t new_time) { IndexTime::iterator i = index_time.lower_bound(iter->last_time); bool found = false; for( ; i != index_time.end() ; ++i) { if( i->second == iter ) { index_time.erase(i); index_time.insert( std::make_pair(new_time, iter) ); iter->last_time = new_time; iter->tm_last_time = Time(new_time); log << log3 << "SC: last time and the time index for session id: " << iter->id << " updated" << logend; found = true; break; } } if( !found ) log << log1 << "SC: cannot update the time, time index not found for session id: " << iter->id << logend; }