6 #include "../../../user.h"
 
  28 //-----------------------------------------------------------------------------
 
  29 //-----------------------------------------------------------------------------
 
  30 //-----------------------------------------------------------------------------
 
  32 //-----------------------------------------------------------------------------
 
  33 //-----------------------------------------------------------------------------
 
  34 //-----------------------------------------------------------------------------
 
  35 // ëÌÁÓÓ ÄÌÑ ÐÏÉÓËÁ ÀÚÅÒÁ × ÓÐÉÓËÅ ÎÏÔÉÆÉËÁÔÏÒÏ×
 
  36 template <typename varType>
 
  37 class IS_CONTAINS_USER: public binary_function<varType, user_iter, bool>
 
  40     bool operator()(varType notifier, user_iter user) const
 
  42         return notifier.GetUser() == user;
 
  45 //-----------------------------------------------------------------------------
 
  46 //-----------------------------------------------------------------------------
 
  47 //-----------------------------------------------------------------------------
 
  48 BASE_PLUGIN * GetPlugin()
 
  50 return pc.GetPlugin();
 
  52 //-----------------------------------------------------------------------------
 
  53 //-----------------------------------------------------------------------------
 
  54 //-----------------------------------------------------------------------------
 
  55 PING_SETTINGS::PING_SETTINGS()
 
  60 //-----------------------------------------------------------------------------
 
  61 int PING_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
 
  64 vector<PARAM_VALUE>::const_iterator pvi;
 
  66 pv.param = "PingDelay";
 
  67 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
  68 if (pvi == s.moduleParams.end())
 
  70     errorStr = "Parameter \'PingDelay\' not found.";
 
  71     printfd(__FILE__, "Parameter 'PingDelay' not found\n");
 
  74 if (ParseIntInRange(pvi->value[0], 5, 3600, &pingDelay))
 
  76     errorStr = "Cannot parse parameter \'PingDelay\': " + errorStr;
 
  77     printfd(__FILE__, "Canot parse parameter 'PingDelay'\n");
 
  83 //-----------------------------------------------------------------------------
 
  84 int PING_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
 
  86 if (str2x(str.c_str(), *val))
 
  88     errorStr = "Incorrect value \'" + str + "\'.";
 
  91 if (*val < min || *val > max)
 
  93     errorStr = "Value \'" + str + "\' out of range.";
 
  98 //-----------------------------------------------------------------------------
 
 101 pthread_mutex_init(&mutex, NULL);
 
 104 //-----------------------------------------------------------------------------
 
 107 pthread_mutex_destroy(&mutex);
 
 109 //-----------------------------------------------------------------------------
 
 110 const string PING::GetVersion() const
 
 112 return "Pinger v.1.01";
 
 114 //-----------------------------------------------------------------------------
 
 115 void PING::SetSettings(const MODULE_SETTINGS & s)
 
 119 //-----------------------------------------------------------------------------
 
 120 int PING::ParseSettings()
 
 122 int ret = pingSettings.ParseSettings(settings);
 
 124     errorStr = pingSettings.GetStrError();
 
 127 //-----------------------------------------------------------------------------
 
 128 void PING::SetUsers(USERS * u)
 
 132 //-----------------------------------------------------------------------------
 
 133 const string & PING::GetStrError() const
 
 137 //-----------------------------------------------------------------------------
 
 142 onAddUserNotifier.SetPinger(this);
 
 143 onDelUserNotifier.SetPinger(this);
 
 144 users->AddNotifierUserAdd(&onAddUserNotifier);
 
 145 users->AddNotifierUserDel(&onDelUserNotifier);
 
 149 pinger.SetDelayTime(pingSettings.GetPingDelay());
 
 152 if (pthread_create(&thread, NULL, Run, this))
 
 154     errorStr = "Cannot start thread.";
 
 155     printfd(__FILE__, "Cannot start thread\n");
 
 161 //-----------------------------------------------------------------------------
 
 164 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 171 //5 seconds to thread stops itself
 
 172 for (int i = 0; i < 25; i++)
 
 180 //after 5 seconds waiting thread still running. now kill it
 
 183     printfd(__FILE__, "kill PING thread.\n");
 
 184     if (pthread_kill(thread, SIGINT))
 
 186         errorStr = "Cannot kill PING thread.";
 
 187         printfd(__FILE__, "Cannot kill PING thread.\n");
 
 190     printfd(__FILE__, "PING killed\n");
 
 193 users->DelNotifierUserAdd(&onAddUserNotifier);
 
 194 users->DelNotifierUserDel(&onDelUserNotifier);
 
 196 list<user_iter>::iterator users_iter;
 
 197 users_iter = usersList.begin();
 
 198 while (users_iter != usersList.end())
 
 200     UnSetUserNotifiers(*users_iter);
 
 206 //-----------------------------------------------------------------------------
 
 207 bool PING::IsRunning()
 
 211 //-----------------------------------------------------------------------------
 
 212 void * PING::Run(void * d)
 
 214 PING * ping = (PING*)d;
 
 215 ping->isRunning = true;
 
 216 list<user_iter>::iterator iter;
 
 220 while (ping->nonstop)
 
 222     iter = ping->usersList.begin();
 
 224         STG_LOCKER lock(&ping->mutex, __FILE__, __LINE__);
 
 225         while (iter != ping->usersList.end())
 
 227             if ((*iter)->property.ips.ConstData().OnlyOneIP())
 
 229                 ip = (*iter)->property.ips.ConstData()[0].ip;
 
 230                 if (ping->pinger.GetIPTime(ip, &t) == 0)
 
 233                         (*iter)->UpdatePingTime(t);
 
 238                 ip = (*iter)->GetCurrIP();
 
 241                     if (ping->pinger.GetIPTime(ip, &t) == 0)
 
 244                             (*iter)->UpdatePingTime(t);
 
 251     for (int i = 0; i < 100; i++)
 
 255             usleep((10000*ping->pingSettings.GetPingDelay())/3 + 50000);
 
 259 ping->isRunning = false;
 
 262 //-----------------------------------------------------------------------------
 
 263 uint16_t PING::GetStartPosition() const
 
 267 //-----------------------------------------------------------------------------
 
 268 uint16_t PING::GetStopPosition() const
 
 272 //-----------------------------------------------------------------------------
 
 273 void PING::SetUserNotifiers(user_iter u)
 
 275 CHG_CURRIP_NOTIFIER_PING    ChgCurrIPNotifier;
 
 276 CHG_IPS_NOTIFIER_PING       ChgIPNotifier;
 
 278 ChgCurrIPNotifier.SetPinger(this);
 
 279 ChgCurrIPNotifier.SetUser(u);
 
 280 ChgCurrIPNotifierList.push_front(ChgCurrIPNotifier);
 
 282 ChgIPNotifier.SetPinger(this);
 
 283 ChgIPNotifier.SetUser(u);
 
 284 ChgIPNotifierList.push_front(ChgIPNotifier);
 
 286 u->AddCurrIPAfterNotifier(&(*ChgCurrIPNotifierList.begin()));
 
 287 u->property.ips.AddAfterNotifier(&(*ChgIPNotifierList.begin()));
 
 289 //-----------------------------------------------------------------------------
 
 290 void PING::UnSetUserNotifiers(user_iter u)
 
 293 IS_CONTAINS_USER<CHG_CURRIP_NOTIFIER_PING>   IsContainsUserCurrIP;
 
 294 IS_CONTAINS_USER<CHG_IPS_NOTIFIER_PING>      IsContainsUserIP;
 
 296 list<CHG_CURRIP_NOTIFIER_PING>::iterator     currIPter;
 
 297 list<CHG_IPS_NOTIFIER_PING>::iterator        IPIter;
 
 299 currIPter = find_if(ChgCurrIPNotifierList.begin(),
 
 300                     ChgCurrIPNotifierList.end(),
 
 301                     bind2nd(IsContainsUserCurrIP, u));
 
 303 if (currIPter != ChgCurrIPNotifierList.end())
 
 305     currIPter->GetUser()->DelCurrIPAfterNotifier(&(*currIPter));
 
 306     ChgCurrIPNotifierList.erase(currIPter);
 
 308 // ---         CurrIP end          ---
 
 311 IPIter = find_if(ChgIPNotifierList.begin(),
 
 312                  ChgIPNotifierList.end(),
 
 313                  bind2nd(IsContainsUserIP, u));
 
 315 if (IPIter != ChgIPNotifierList.end())
 
 317     IPIter->GetUser()->property.ips.DelAfterNotifier(&(*IPIter));
 
 318     ChgIPNotifierList.erase(IPIter);
 
 322 //-----------------------------------------------------------------------------
 
 323 void PING::GetUsers()
 
 325 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 328 int h = users->OpenSearch();
 
 331     printfd(__FILE__, "users->OpenSearch() error\n");
 
 335 while (users->SearchNext(h, &u) == 0)
 
 337     usersList.push_back(u);
 
 339     if (u->property.ips.ConstData().OnlyOneIP())
 
 341         pinger.AddIP(u->property.ips.ConstData()[0].ip);
 
 345         uint32_t ip = u->GetCurrIP();
 
 353 users->CloseSearch(h);
 
 355 //-----------------------------------------------------------------------------
 
 356 void PING::AddUser(user_iter u)
 
 358 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 361 usersList.push_back(u);
 
 363 //-----------------------------------------------------------------------------
 
 364 void PING::DelUser(user_iter u)
 
 366 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 368 UnSetUserNotifiers(u);
 
 370 list<user_iter>::iterator users_iter;
 
 371 users_iter = usersList.begin();
 
 373 while (users_iter != usersList.end())
 
 375     if (u == *users_iter)
 
 377         usersList.erase(users_iter);
 
 383 //-----------------------------------------------------------------------------
 
 384 void CHG_CURRIP_NOTIFIER_PING::Notify(const uint32_t & oldIP, const uint32_t & newIP)
 
 386 ping->pinger.DelIP(oldIP);
 
 389     ping->pinger.AddIP(newIP);
 
 392 //-----------------------------------------------------------------------------
 
 393 void CHG_IPS_NOTIFIER_PING::Notify(const USER_IPS & oldIPS, const USER_IPS & newIPS)
 
 395 if (oldIPS.OnlyOneIP())
 
 397     ping->pinger.DelIP(oldIPS[0].ip);
 
 400 if (newIPS.OnlyOneIP())
 
 402     ping->pinger.AddIP(newIPS[0].ip);
 
 405 //-----------------------------------------------------------------------------
 
 406 void ADD_USER_NONIFIER_PING::Notify(const user_iter & user)
 
 410 //-----------------------------------------------------------------------------
 
 411 void DEL_USER_NONIFIER_PING::Notify(const user_iter & user)
 
 415 //-----------------------------------------------------------------------------