/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2012, Tomasz Sowa * All rights reserved. * */ #include "notifythread.h" // first thread (objects are locked) NotifyThread::NotifyThread() { patterns_changed = true; } // first thread (objects are locked) void NotifyThread::SetConfig(Config * pconfig) { config = pconfig; } // first thread (objects are locked) void NotifyThread::SetUsers(Users * pusers) { users = pusers; } // first thread (objects are locked) void NotifyThread::SetNotifyPool(NotifyPool * pool) { notify_pool = pool; } // first thread (objects are locked) void NotifyThread::SetPatterns(Patterns * pat) { pat_global = pat; } // first thread (objects are locked) void NotifyThread::PatternsChanged() { patterns_changed = true; } // first thread (objects are locked) bool NotifyThread::Init() { TemplatesNotifyFunctions::CreateFunctions(); return true; } // first thread (objects are locked) bool NotifyThread::SignalReceived() { if( patterns_changed ) { patterns = *pat_global; patterns_changed = false; } return !notify_pool->Empty(); } // second thread (objects are not locked) // return true if there is something to send from the first queue (notify_pool) bool NotifyThread::AddNextNotify() { Users::Iterator i; bool res = false; Lock(); if( !notify_pool->Empty() ) { TemplatesNotifyFunctions::notify_msg = notify_pool->GetFirst(); notify_pool->DeleteFirst(); if( TemplatesNotifyFunctions::notify_msg.code == WINIX_NOTIFY_CODE_CONFIRM_ACCOUNT || TemplatesNotifyFunctions::notify_msg.code == WINIX_NOTIFY_CODE_RESET_PASSWORD ) { msg.email = TemplatesNotifyFunctions::notify_msg.email; msg.name = TemplatesNotifyFunctions::notify_msg.name; msg.lang = TemplatesNotifyFunctions::notify_msg.lang; notify_user.push_back(msg); res = true; } else { for(i=users->Begin() ; i != users->End() ; ++i) { if( (i->notify & TemplatesNotifyFunctions::notify_msg.code) != 0 ) { msg.name = i->name; msg.email = i->email; msg.lang = config->locale_default_index; // !! IMPROVE ME bedzie osobno dla kazdego uzytkownika notify_user.push_back(msg); res = true; } } } } Unlock(); return res; } // second thread -- here we must use Lock() and Unlock() explicitly void NotifyThread::Do() { NotifyUser::iterator i; bool queue_end; while( AddNextNotify() ) { Lock(); i = notify_user.begin(); queue_end = notify_user.empty(); Unlock(); while( !queue_end ) { Lock(); TemplatesNotifyFunctions::notify_user_msg = *i; log << log3 << "NotifyThread: sending notification to: " << i->name << ", email: " << i->email << logend; Unlock(); SendMail(); Lock(); WaitForSignalSleep(2); // automatically unlock and lock again when returns bool stop = synchro->was_stop_signal; Unlock(); if( stop ) return; Lock(); notify_user.erase(i++); queue_end = (i == notify_user.end()); Unlock(); } } } // second thread void NotifyThread::SendMail() { notify_stream.Clear(); size_t lang_index = TemplatesNotifyFunctions::notify_user_msg.lang; size_t template_index = TemplatesNotifyFunctions::notify_msg.template_index; Lock(); // 'patterns' object can use logger or other stuff so we use Lock() before Ezc::Pattern * pat = patterns.Get(template_index, lang_index); if( !pat ) log << log1 << "NotifyThread: I don't have a template with index: " << template_index << " and locale index: " << lang_index << logend; Unlock(); if( pat ) { generator.RecognizeSpecialChars(true); generator.TrimWhite(true); generator.SkipNewLine(true); generator.Generate(notify_stream, *pat, TemplatesNotifyFunctions::ezc_functions); SendMail(TemplatesNotifyFunctions::notify_user_msg.email, notify_stream.Str()); } } // second thread void NotifyThread::SendMail(const std::wstring & email, const std::wstring & message) { nlog.PutDate(log1); if( !ValidateEmail(email) ) { nlog << log1 << "NotifyThread: email adress: " << email << " is not correct" << logend; return; } sendmail_command = "sendmail "; PT::WideToUTF8(email, sendmail_command, false); FILE * sendmail = popen(sendmail_command.c_str(), "w"); if( !sendmail ) { nlog << log1 << "NotifyThread: can't run sendmail" << logend; return; } SendMail(sendmail, message); pclose(sendmail); nlog << log1 << "NotifyThread: email to: " << email << " has been sent" << logend << logsave; } // second thread void NotifyThread::SendMail(FILE * sendmail, const std::wstring & message) { char buf[10]; size_t len; for(size_t i=0 ; i