3 #include <boost/filesystem.hpp> 22 const int n = (55-txt.length())/2;
26 out << setw(n) << fill <<
' ';
28 out <<
' ' << setw(n) << fill;
30 if (2*n+txt.length()+2 != 57)
56 msg += to_string(scriptdepth);
58 msg +=
":"+scriptfile+
"["+user+
":"+to_string(getpid())+
"]";
66 SetCurrentState(qos+4, msg.c_str());
68 return GetCurrentState();
96 if (imp.
GetSize()==0 || opt.size()==0 || opt[0]==0)
98 Error(
"File name missing in DIM_CONTROL/START");
99 return GetCurrentState();
103 Debug(
"Start '"+opt+
"' received.");
108 const auto user = data.find(
"user");
109 fScriptUser = user==data.end() ? fUser : user->second;
113 for (
auto it=data.begin(); it!=data.end(); it++)
114 Debug(
" Arg: "+it->first+
" = "+it->second);
119 emit += fArgumentsJS;
122 return GetCurrentState();
129 string msg(
"Stop received");
130 msg +=
str.empty() ?
"." :
" ["+
str+
"]";
136 return GetCurrentState();
147 if (!fInterruptHandler)
148 return GetCurrentState();
152 const size_t p = str.find_last_of(
'\n');
156 if (GetCurrentState()<3)
158 Warn(
"Interrupt request received ["+str+
"]... but no running script.");
159 return GetCurrentState();
162 Info(
"Interrupt request received ["+str+
"]");
163 return fInterruptHandler(evt);
168 const lock_guard<mutex> guard(fMutex);
170 if (fServerList.find(server)==fServerList.end())
171 throw runtime_error(
"SendDimCommand - Server '"+server+
"' not online.");
176 size_t p0 = str.find_first_of(
' ');
177 if (p0==string::npos)
181 const string name = str.substr(0, p0);
184 for (
auto is=fServiceList.begin(); is!=fServiceList.end(); is++)
186 if (str.empty() && is->server==server)
189 if (is->server!=server || is->service!=name)
193 throw runtime_error(
"'"+server+
"/"+name+
" not a command.");
202 const Converter conv(sout, is->format,
false);
204 const Converter conv(lout, is->format,
false);
207 throw runtime_error(
"Couldn't properly parse the format... ignored.");
210 lout <<
kBlue << server <<
'/' << name;
212 const vector<char> v = conv.
GetVector(str.substr(p0));
214 lout <<
kBlue <<
" [" << v.size() <<
"]" << endl;
216 const string cmd = server +
'/' + name;
219 throw runtime_error(
"ERROR - Sending command "+cmd+
" failed.");
225 throw runtime_error(
"SendDimCommand - Format information for "+server+
"/"+name+
" not yet available.");
232 const lock_guard<mutex> guard(fMutex);
235 for (
auto it=fServerList.begin(); it!=fServerList.end(); it++)
237 if (!serv.empty() && *it!=serv)
240 out <<
kRed <<
"----- " << *it <<
" -----" << endl;
243 for (
auto is=fStateDescriptionList.begin(); is!=fStateDescriptionList.end(); is++)
245 const string &server = is->first.first;
250 const int32_t &state = is->first.second;
251 const string &name = is->second.first;
252 const string &comment = is->second.second;
254 out <<
kBold << setw(5) << state <<
kReset <<
": ";
256 if (!comment.empty())
257 out <<
kBlue <<
" (" << comment <<
")";
264 out <<
" <no states>" << endl;
276 const lock_guard<mutex> guard(fMutex);
279 for (
auto it=fServerList.begin(); it!=fServerList.end(); it++)
281 if (!serv.empty() && *it!=serv)
284 out <<
kRed <<
"----- " << *it <<
" -----" << endl << endl;
286 for (
auto is=fServiceList.begin(); is!=fServiceList.end(); is++)
291 if (!service.empty() && is->service!=service)
294 if (is->iscmd!=iscmd)
299 out <<
" " << is->service;
300 if (!is->format.empty())
301 out <<
'[' << is->format <<
']';
303 const auto id = fServiceDescriptionList.find(*it+
"/"+is->service);
304 if (
id!=fServiceDescriptionList.end())
306 const vector<Description> &v =
id->second;
308 for (
auto j=v.begin()+1; j!=v.end(); j++)
309 out <<
" <" << j->name <<
">";
312 if (!v[0].comment.empty())
313 out <<
" " << v[0].comment << endl;
315 for (
auto j=v.begin()+1; j!=v.end(); j++)
317 out <<
" " <<
kGreen << j->name;
318 if (!j->comment.empty())
320 if (!j->unit.empty())
321 out <<
kYellow <<
" [" << j->unit <<
"]";
338 fCurrentStateList[server] = state;
341 fStateCallback(server, state);
343 return GetCurrentState();
348 const lock_guard<mutex> guard(fMutex);
350 const auto it = fCurrentStateList.find(server);
351 return it==fCurrentStateList.end() ?
State() : it->second;
356 const lock_guard<mutex> guard(fMutex);
358 const auto is = fCurrentStateList.find(server);
359 for (
auto it=dim->
states.begin(); it!=dim->
states.end(); it++)
361 fStateDescriptionList[make_pair(server, it->index)] = make_pair(it->name, it->comment);
362 if (is==fCurrentStateList.end())
365 State &s = is->second;
366 if (s.
index==it->index)
373 return GetCurrentState();
378 const lock_guard<mutex> guard(fMutex);
381 fServiceDescriptionList[it->front().name].assign(it->begin(), it->end());
383 return GetCurrentState();
388 const lock_guard<mutex> guard(fMutex);
390 const auto it = fServiceDescriptionList.find(service);
391 return it==fServiceDescriptionList.end() ? vector<Description>() : it->second;
396 if (server!=
"DIS_DNS")
400 Find(
const string &ref) : string(ref) { }
404 if (find_if(fDimDescriptionsList.begin(), fDimDescriptionsList.end(),
405 Find(server))==fDimDescriptionsList.end())
409 fDimDescriptionsList.push_back(d);
420 const lock_guard<mutex> guard(fMutex);
421 fServerList.insert(server);
423 return GetCurrentState();
428 const lock_guard<mutex> guard(fMutex);
429 fServerList.erase(server);
431 return GetCurrentState();
438 const lock_guard<mutex> guard(fMutex);
440 rc.reserve(fServerList.size());
441 for (
auto it=fServerList.begin(); it!=fServerList.end(); it++)
449 const lock_guard<mutex> guard(fMutex);
451 const string s = server.substr(0, server.length()-1);
453 if (fServerList.find(s)==fServerList.end())
454 return vector<string>();
458 for (
auto it=fServiceList.begin(); it!=fServiceList.end(); it++)
459 if (it->iscmd && it->server==s)
460 rc.push_back(server+it->service);
469 const lock_guard<mutex> guard(fMutex);
471 for (
auto it=fServiceList.begin(); it!=fServiceList.end(); it++)
473 rc.push_back(it->server+
"/"+it->service);
480 const lock_guard<mutex> guard(fMutex);
486 const lock_guard<mutex> guard(fMutex);
490 for (
auto it=fStateDescriptionList.begin(); it!=fStateDescriptionList.end(); it++)
492 if (it->first.first!=server)
495 rc.emplace_back(it->first.second, it->second.first, it->second.second);
506 const lock_guard<mutex> guard(fMutex);
507 fServiceList.insert(svc);
509 return GetCurrentState();
514 const lock_guard<mutex> guard(fMutex);
515 return fServerList.find(server)!=fServerList.end();
528 AddStateName(0,
"Idle",
"No script currently in processing.");
530 AddStateName(2,
"Compiling",
"JavaScript is compiling.");
535 (
"Start a JavaScript");
539 (
"Execute a batch script");
543 (
"Stop a runnning batch script or JavaScript");
547 (
"Send an interrupt request (IRQ) to a running JavaScript");
564 const map<string, string> &js = conf.
GetOptions<
string>(
"JavaScript.");
565 for (
auto it=js.begin(); it!=js.end(); it++)
567 string key = it->first;
568 string val = it->second;
571 boost::replace_all(key,
"\\",
"\\\\");
572 boost::replace_all(key,
"'",
"\\'");
573 boost::replace_all(key,
"\"",
"\\\"");
576 boost::replace_all(val,
"\\",
"\\\\");
577 boost::replace_all(val,
"'",
"\\'");
578 boost::replace_all(val,
"\"",
"\\\"");
591 #if BOOST_VERSION < 104600 592 const string fname = boost::filesystem::path(conf.
GetName()).filename();
594 const string fname = boost::filesystem::path(conf.
GetName()).filename().string();
597 if (fname==
"dimserver")
600 if (conf.
Get<
bool>(
"stop"))
603 if (conf.
Has(
"interrupt"))
606 if (conf.
Has(
"start"))
609 if (conf.
Has(
"batch"))
610 return !
Dim::SendCommand(
"DIM_CONTROL/EXECUTE", conf.
Get<
string>(
"batch")+
" user='"+fUser+
"'");
615 if (conf.
Has(
"restart"))
EventImp & AddEvent(const std::string &name, const std::string &states, const std::string &fmt)
void Stop(int code=0)
Request to stop the mainloop.
static int sendCommand(const char *name, int data)
virtual void Stop(int code=0)
Request to stop the mainloop.
A general base-class describing events issues in a state machine.
int HandleAddService(const Service &svc)
std::string comment
Name (e.g. 'Connected')
bool SendDimCommand(const std::string &server, std::string str, std::ostream &lout)
Adds some functionality to boost::posix_time::ptime for our needs.
int HandleStates(const std::string &server, DimDescriptions *state)
T Get(const std::string &var)
static int GetScriptDepth()
std::vector< State > states
int EvalOptions(Configuration &conf)
const std::map< std::string, T > GetOptions(const std::string &opt)
const int32_t & state() const
StateMachineDimControl(std::ostream &out=std::cout)
int PrintDescription(std::ostream &out, bool iscmd, const std::string &serv="", const std::string &service="")
std::string GetString() const
int HandleDescriptions(DimDescriptions *state)
State description() const
int PrintStates(std::ostream &out, const std::string &serv="")
int HandleStateChange(const std::string &server, DimDescriptions *state)
bool SendCommand(const std::string &command)
void SetCallbackStates(const callback_desc &cb)
bool Has(const std::string &var)
std::set< Service > GetServiceList()
std::string fArgumentsJS
Default arguments provided to very java script.
void SetCallbackServiceAdd(const callback_svc &cb)
std::vector< std::string > GetServerList()
Commandline parsing, resource file parsing and database access.
static void SetExternalInput(const std::string &inp)
State GetServerState(const std::string &server)
void SetCallbackServerRemove(const callback_srv &cb)
DimDnsServiceList fDimList
std::vector< std::vector< Description > > descriptions
int HandleServerRemove(const std::string &server)
int StartScript(const EventImp &imp, const std::string &cmd)
std::string Line(const std::string &txt, char fill)
virtual void Subscribe(StateMachineImp &imp)
int ChangeState(int qos, const Time &time, int scriptdepth, std::string scriptfile, std::string user)
std::vector< Description > GetDescription(const std::string &service)
int HandleServerAdd(const std::string &server)
Class for a state machine implementation within a DIM network.
std::vector< State > GetStates(const std::string &server)
void SetCallbackDescriptions(const callback_desc &cb)
std::vector< DimDescriptions * > fDimDescriptionsList
~StateMachineDimControl()
std::vector< std::string > GetCommandList()
std::string name
Index (e.g. 1)
std::pair< Time, int32_t > cur
int StopScript(const EventImp &imp)
int InterruptScript(const EventImp &imp)
bool HasServer(const std::string &server)
virtual void Subscribe(StateMachineImp &imp)
void SetCallbackServerAdd(const callback_srv &cb)
A compiler for the DIM data format string.
bool AddStateName(const int state, const std::string &name, const std::string &doc="")
void SetCallback(const callback &cb)
static std::string GetScript()
const std::string & GetName() const
void Subscribe(StateMachineImp &imp)
std::vector< char > GetVector(const void *d, size_t size) const
virtual size_t GetSize() const