FACT++  1.0
timecheck.cc
Go to the documentation of this file.
1 #include "StateMachineDim.h"
2 
3 #include "tools.h"
4 #include "Time.h"
5 #include "Configuration.h"
6 #include "LocalControl.h"
7 
8 using namespace std;
9 
10 // ------------------------------------------------------------------------
11 
12 #include "DimDescriptionService.h"
13 
14 // ========================================================================
15 // ========================================================================
16 // ========================================================================
17 
19 {
20 private:
22 
23  string fServer;
24  uint16_t fInterval;
25 
27 
28  enum
29  {
30  kStateOutOfRange = 1,
31  kStateRunning = 2,
32  };
33 
34  // ------------- Initialize variables before the Dim stuff ------------
35 
36  int Execute()
37  {
38  Time now;
39  if (now-fLastUpdate<boost::posix_time::minutes(fInterval))
40  return kStateRunning;
41 
42  fLastUpdate=now;
43 
44  const string cmd = "ntpdate -q "+fServer;
45 
46  Info("Calling '"+cmd+"'");
47 
48  // !!!!! Warning: this is a blocking operation !!!!!
49  FILE *pipe = popen(cmd.c_str(), "r");
50  if (!pipe)
51  {
52  const string err = strerror(errno);
53  Error("Could not create pipe '"+cmd+"': "+err);
54  return 0x100;
55  }
56 
57  vector<string> args;
58 
59  string line;
60  while (1)
61  {
62  const int rc = fgetc(pipe);
63  if (rc==EOF || rc=='\n')
64  {
65  args.push_back(Tools::Trim(line));
66  break;
67  }
68 
69  if (rc==',')
70  {
71  args.push_back(Tools::Trim(line));
72  line = "";
73  continue;
74  }
75 
76  line += static_cast<unsigned char>(rc);
77  }
78  pclose(pipe);
79 
80  if (args.size()!=4)
81  {
82  Error("First returned line contains other than four arguments (separated by commas)");
83  return 0x100;
84  }
85 
86  if (args[2].substr(0, 7)!="offset ")
87  {
88  Error("Argument 3 '"+args[2]+"' is not what it ought to be.");
89  return 0x100;
90  }
91 
92  try
93  {
94  const float offset = stof(args[2].substr(7));
95  fService.Update(offset);
96 
97  const string msg = "NTP: "+fServer+" returned: "+args[2]+" ms";
98 
99  if (offset>=1000)
100  {
101  Warn(msg);
102  return kStateOutOfRange;
103  }
104 
105  Message(msg);
106 
107  }
108  catch (const exception &e)
109  {
110  Error("Converting offset '"+args[2]+"' to float failed: "+e.what());
111  return 0x100;
112  }
113 
114  return kStateRunning;
115  }
116 
117  int Trigger()
118  {
119  fLastUpdate = Time()-boost::posix_time::minutes(fInterval);
120  return GetCurrentState();
121  }
122 
123 public:
124  StateMachineTimeCheck(ostream &out=cout) : StateMachineDim(out, "TIME_CHECK"),
125  fService("TIME_CHECK/OFFSET", "F:1", "Time offset measured with ntp|offset[ms]:Time offset in milliseconds")
126  {
127  // State names
128  AddStateName(kStateRunning, "Valid", "Last check was valid.");
129  AddStateName(kStateOutOfRange, "OutOfRange", "Last time check exceeded 1s.");
130 
131  AddEvent("TRIGGER");
132  (bind(&StateMachineTimeCheck::Trigger, this))
133  ("Trigger update");
134 
135  }
137  {
138  fServer = conf.Get<string>("ntp-server");
139  fInterval = conf.Get<uint16_t>("interval");
140  if (fInterval==0)
141  fInterval=1;
142 
143  Trigger();
144 
145  return -1;
146  }
147 };
148 
149 // ------------------------------------------------------------------------
150 
151 #include "Main.h"
152 
153 template<class T>
155 {
156  return Main::execute<T, StateMachineTimeCheck>(conf);
157 }
158 
160 {
161  po::options_description control("Time check");
162  control.add_options()
163  ("ntp-server", var<string>("hora.roa.es"), "The ntp server to be queried")
164  ("interval", var<uint16_t>(15), "Interval in minutes the ntp server should be queried")
165  ;
166 
167  conf.AddOptions(control);
168 }
169 
170 /*
171  Extract usage clause(s) [if any] for SYNOPSIS.
172  Translators: "Usage" and "or" here are patterns (regular expressions) which
173  are used to match the usage synopsis in program output. An example from cp
174  (GNU coreutils) which contains both strings:
175  Usage: cp [OPTION]... [-T] SOURCE DEST
176  or: cp [OPTION]... SOURCE... DIRECTORY
177  or: cp [OPTION]... -t DIRECTORY SOURCE...
178  */
180 {
181  /*
182  cout <<
183  "SmartFACT is a tool writing the files needed for the SmartFACT web interface.\n"
184  "\n"
185  "The default is that the program is started without user intercation. "
186  "All actions are supposed to arrive as DimCommands. Using the -c "
187  "option, a local shell can be initialized. With h or help a short "
188  "help message about the usuage can be brought to the screen.\n"
189  "\n"
190  "Usage: smartfact [-c type] [OPTIONS]\n"
191  " or: smartfact [OPTIONS]\n";
192  cout << endl;*/
193 }
194 
195 void PrintHelp()
196 {
197  Main::PrintHelp<StateMachineTimeCheck>();
198 
199  /* Additional help text which is printed after the configuration
200  options goes here */
201 
202  /*
203  cout << "bla bla bla" << endl << endl;
204  cout << endl;
205  cout << "Environment:" << endl;
206  cout << "environment" << endl;
207  cout << endl;
208  cout << "Examples:" << endl;
209  cout << "test exam" << endl;
210  cout << endl;
211  cout << "Files:" << endl;
212  cout << "files" << endl;
213  cout << endl;
214  */
215 }
216 
217 int main(int argc, const char* argv[])
218 {
219  Configuration conf(argv[0]);
222  SetupConfiguration(conf);
223 
224  if (!conf.DoParse(argc, argv, PrintHelp))
225  return 127;
226 
227  if (!conf.Has("console"))
228  return RunShell<LocalStream>(conf);
229 
230  if (conf.Get<int>("console")==0)
231  return RunShell<LocalShell>(conf);
232  else
233  return RunShell<LocalConsole>(conf);
234 
235  return 0;
236 }
int Execute()
Is called continously to execute actions in the current state.
Definition: timecheck.cc:36
StateMachineTimeCheck(ostream &out=cout)
Definition: timecheck.cc:124
void SetupConfiguration(Configuration &conf)
Definition: Main.h:25
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
STL namespace.
void PrintHelp()
Definition: timecheck.cc:195
void PrintUsage()
Definition: timecheck.cc:179
int EvalOptions(Configuration &conf)
Definition: timecheck.cc:136
bool Has(const std::string &var)
void AddOptions(const po::options_description &opt, bool visible=true)
Definition: Configuration.h:92
DimDescribedService fService
Definition: timecheck.cc:26
Commandline parsing, resource file parsing and database access.
Definition: Configuration.h:9
int main(int argc, const char *argv[])
Definition: timecheck.cc:217
Class for a state machine implementation within a DIM network.
Error()
Definition: HeadersFTM.h:197
std::string Trim(const std::string &str)
Definition: tools.cc:68
void SetupConfiguration(Configuration &conf)
Definition: timecheck.cc:159
Definition: fad.cc:31
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
int RunShell(Configuration &conf)
Definition: timecheck.cc:154