- check out the *nix tutorial page. (under contruction)
- some cool things going on here : a session manager perhaps?
The implementation is a little fuzzy right now and this will be revised but it is something worth playing with.
#include <iostream>
#include <map>
#include <string>
#include <exception>
#include <stdexcept>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <mysql++.h>
// implement the Miller-Park PRNG
class MPRand {
private :
static const long _a = 16807L;
static const long _m = 2147483647;
static const long _q = 127773L;
static const long _r = 2836L;
static const long _mask = 123459876;
static const double _inverse_m = (double) (1.0)/_m;
long _t;
public :
MPRand(const long val)
{
if (val == _mask) throw std::invalid_argument("argument must not equal mask value");
else this->_t = val;
}
MPRand() {
long v;
if (v == _mask)
throw std::invalid_argument("argument must not equal mask value");
else {
v = (long) rand();
MPRand((long)v);
}
}
MPRand(const MPRand& ref) { this->_t = ref._t; }
MPRand& operator=(const MPRand& r) {
this->_t = r._t;
return *this;
}
void Srand(long i) {
if (i == _mask)
throw std::invalid_argument("argument must not equal mask value");
else
this->_t = i;
}
friend std::ostream& operator<<(std::ostream& s, const MPRand& r) {
s << r._t;
return s;
}
inline bool operator==(const MPRand& r) const { return r._t == this->_t; }
inline bool operator<(const MPRand& r) const { return r._t < this->_t; }
inline bool operator>(const MPRand& r) const { return r._t > this->_t; }
inline bool operator>=(const MPRand& r) const { return r._t >= this->_t; }
inline bool operator<=(const MPRand& r) const { return r._t <= this->_t; }
inline bool operator!=(const MPRand& r) const { return r._t != this->_t; }
long Rand ()
{
long k;
this->_t ^= _mask;
k = this->_t * _m;
this->_t = _a * (this->_t - (k * _q)) - (_r * k);
if (this->_t < 0l)
this->_t += _m;
this->_t ^= _mask;
return this->_t;
}
};
const char* our_salt = "xxxx"; // need salt for crypt see man 3 crypt
const char* our_database = "";
const char* our_db_host = "localhost";
const char* our_db_user = "";
const char* our_db_pass = "";
// our timeout thread
// not very OO -- but works!
extern "C" void* timeout_thread(void* arg);
pthread_t timeout_thread_id;
// our singleton class
class Session {
public :
static Session* Instance(const time_t timeout);
void set_current(bool v) {
this->_current = v;
}
time_t getTimeout() { return this->_timeout; }
bool isCurrent() { return this->_current; }
private :
time_t _timeout;
static Session* _instance;
bool _current;
protected :
Session (const time_t t) : _timeout(t), _current(true) { }
Session() { Session(60L); }
};
Session* Session::_instance = 0;
Session* Session::Instance(time_t timeout) {
if (_instance == 0)
_instance = new Session(timeout);
return _instance;
}
// instance manage class -- create a new instance of a
// session with a username, crypted password and a timeout
class SessionManager {
private :
std::string _password;
MPRand _rand_id;
Session* _p_session;
long _timeout_val;
static long _ref_count;
mysqlpp::Connection _con;
std::string _username;
std::string _crypt_password;
std::map<MPRand, std::string> _session_hash;
public :
SessionManager(std::string u, std::string pass, MPRand r, long timeout) :
_password(pass), _rand_id(r), _timeout_val(timeout), _username(u)
{
this->_p_session = Session::Instance(timeout);
this->_con = mysqlpp::Connection(our_database, our_db_host, our_db_user, our_db_pass);
this->_crypt_password = std::string( crypt(pass.c_str(), our_salt) );
++_ref_count;
this->_session_hash[this->_rand_id] = this->_username;
}
virtual std::string CryptPassword(const char *password) {
return this->_crypt_password;
}
virtual bool connect_to_db( int argc, char *argv[],
mysqlpp::Connection& con, const char* kdb = 0);
virtual ~SessionManager() {
--_ref_count;
if (_ref_count)
delete this->_p_session;
}
static SessionManager* Instance(std::string name, std::string pass);
friend std::ostream& operator<< (std::ostream& s, const SessionManager& m) {
return s << "(username : " << m._username << " session id : " << m._rand_id;
}
};
The implementation is fairly clear ...