GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4ServerProxy.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4ServerProxy.h"
15 
16 #include <fstream>
17 #include <iostream>
18 #include <map>
19 
20 #include "TRegexp.h"
21 #include "TSystem.h"
22 
23 #include "TGo4Log.h"
24 #include "TGo4Slot.h"
25 #include "TGo4ServerTask.h"
26 
27 // ********************************************************************
28 
29 class TGo4Prefs {
30  protected:
31  std::map<std::string, std::string> fPars;
32  public:
33  TGo4Prefs(const char *hostname)
34  {
35  SetPar("hostname", hostname);
36  #ifdef _MSC_VER
37  SetPar("os", "win32");
38  #elif defined(Darwin)
39  SetPar("os", "mac");
40  #else
41  SetPar("os", "linux");
42  #endif
43  }
44 
45  void AddFile(const char *fname, bool errorout = false)
46  {
47  std::ifstream f(fname);
48  if(!f) {
49  if (errorout) TGo4Log::Debug("ERROR: Preferences file %s not existing",fname);
50  return;
51  }
52 
53  std::string hostname = GetPar("hostname");
54 
55  char formatstring[4096];
56 
57  while (!f.eof()) {
58 
59  f.getline(formatstring, sizeof(formatstring), '\n' );
60  if ((f.gcount() == 0) || (strlen(formatstring) == 0)) continue;
61 
62  const char *sbuf = formatstring;
63 
64  while (*sbuf != 0) {
65  if (*sbuf==' ') { sbuf++; continue; }
66  if (*sbuf=='#') break;
67 
68  const char *separ = strchr(sbuf, ':');
69  if (!separ) break;
70 
71  std::string name(sbuf, separ-sbuf);
72 
73  size_t pos = name.find('=');
74  if (pos!=name.npos) {
75  std::string subname(name, 0, pos);
76  std::string mask(name, pos+1);
77 
78  if (subname.empty() || mask.empty()) break;
79 
80  const char *subvalue = GetPar(subname.c_str());
81 
82  if (!subvalue) break;
83 
84  // if mask didnot match, ignore string
85  // check mask with regular expression
86  TRegexp re(mask.c_str(), kTRUE);
87  Int_t len = 0;
88  if (re.Index(subvalue, &len) != 0) break;
89  if (len != (Int_t) strlen(subvalue)) break;
90 
91  // take rest of buffer for analysis
92  sbuf = separ+1;
93  continue;
94  }
95 
96  if (!HasPar(name.c_str()))
97  SetPar(name.c_str(), separ+1);
98 
99  break;
100  }
101  }
102  }
103 
105  bool IsOk() const { return fPars.size()>2; }
106 
107  void SetPar(const char *name, const char *value, bool force = true)
108  {
109  std::string dname = TString::Format("%s%s%s", "%", name, "%").Data();
110  if (force || (fPars.find(dname) == fPars.end()))
111  fPars[dname] = value;
112  }
113 
114  const char *GetPar(const char *name)
115  {
116  std::string dname = TString::Format("%s%s%s", "%", name, "%").Data();
117  if (fPars.find(dname) == fPars.end()) return nullptr;
118  return fPars[dname].c_str();
119  }
120 
121  bool HasPar(const char *name)
122  {
123  return GetPar(name) != nullptr;
124  }
125 
126  void ReplacePars(std::string& str)
127  {
128  size_t pos;
129  bool isany = false;
130  int cnt = 0;
131 
132  do {
133  isany = false;
134  std::map<std::string,std::string>::iterator iter = fPars.begin();
135  while (iter != fPars.end()) {
136  pos = 0;
137  while ((pos = str.find(iter->first, pos)) != str.npos) {
138  str.replace(pos, iter->first.length(), iter->second);
139  isany = true;
140  }
141  iter++;
142  }
143  if (cnt++>100000) {
144  std::cerr << "Syntax error in go4.prefs files - endless recursion" << std::endl;
145  std::cerr << "Program aborted, please fix an error" << std::endl;
146  exit(-1);
147  }
148  } while (isany);
149  }
150 
151  void ReplaceEnvPars(std::string& str)
152  {
153  size_t pos1, pos2;
154 
155  while ((pos1 = str.find("${")) != str.npos) {
156 
157  pos2 = str.find("}");
158 
159  if ((pos1>pos2) || (pos2==str.npos)) {
160  TGo4Log::Debug("ERROR: Wrong variable parenthesis %s",str.c_str());
161  return;
162  }
163 
164  std::string var(str, pos1+2, pos2-pos1-2);
165 
166  str.erase(pos1, pos2-pos1+1);
167 
168  const char *value = gSystem->Getenv(var.c_str());
169  if (value) str.insert(pos1, value);
170  }
171  }
172 
174  std::string GetOpt(const char *prefix)
175  {
176  const char *opt = GetPar(prefix);
177  if (!opt) return std::string("");
178  std::string res = opt;
179  ReplacePars(res);
180  ReplaceEnvPars(res);
181  return res;
182  }
183 
184 };
185 
186 Bool_t TGo4ServerProxy::GetLaunchString(TString &launchcmd,
187  TString &killcmd,
188  Int_t serverkind,
189  Int_t shellkind,
190  Int_t konsole,
191  const char *name,
192  const char *remotehost,
193  const char *remotedir,
194  const char *remoteexe,
195  Int_t guiport,
196  Int_t exe_kind,
197  const char *exeargs)
198 {
199  const char *serverhost = gSystem->HostName();
200  const char *sdisplay = gSystem->Getenv("DISPLAY");
201  const char *go4sys = TGo4Log::GO4SYS();
202  const char *rootsys = gSystem->Getenv("ROOTSYS");
203  const char *path = gSystem->Getenv("PATH");
204  const char *ldpath = gSystem->Getenv("LD_LIBRARY_PATH");
205 
206  if (!name || (strlen(name) == 0)) name = "UserAnalysis";
207  if (!serverhost || (strlen(serverhost) == 0)) serverhost = "localhost";
208 
209  if (!gSystem->Getenv("GO4OLDLAUNCH")) {
210  TGo4Prefs prefs(remotehost);
211 
212  const char *shellname = "exec";
213  if (shellkind==1) shellname = "rsh"; else
214  if (shellkind==2) shellname = konsole==1 ? "ssh" : "sshX";
215  prefs.SetPar("shellkind", shellname, false);
216  prefs.SetPar("exekind", TString::Format("%d", exe_kind).Data(), false);
217  prefs.SetPar("clientkind", serverkind > 0 ? "Go4Server" : "Go4Client", false);
218 
219  prefs.AddFile("go4.prefs", false);
220  prefs.AddFile(TGo4Log::subGO4SYS("etc/go4.prefs"), true);
221  if (!prefs.IsOk()) {
222  std::cout << "Cannot find prefs file" << std::endl;
223  return kFALSE;
224  }
225 
226  prefs.SetPar("guihost", serverhost, false);
227  //if (!server)
228  prefs.SetPar("guiport", TString::Format("%d", guiport).Data());
229  prefs.SetPar("guigo4sys", go4sys, false);
230  prefs.SetPar("analysisname", name, false);
231  prefs.SetPar("workdir", remotedir, false);
232  prefs.SetPar(exe_kind == 0 ? "exename" : "libname", remoteexe, false);
233 
234  if ((exe_kind == 1) && exeargs && (strlen(exeargs) > 0))
235  prefs.SetPar("userargs", exeargs, false);
236  else
237  prefs.SetPar("userargs", "", false);
238 
239  const char *termname = "qtwindow";
240  if (konsole == 2) termname = "xterm"; else
241  if (konsole == 3) termname = "konsole";
242 
243  // no need to change into local directory with exec and qtwinow - it happens automatically
244  if ((shellkind == 0) && (konsole == 1))
245  prefs.SetPar("cd_workdir", "");
246 
247  std::string executable;
248  bool is_exe = prefs.GetOpt("exekind") != "1";
249  if (is_exe) {
250  if (prefs.GetOpt("exename").empty())
251  executable = prefs.GetOpt("analysis_default_exe");
252  else
253  executable = prefs.GetOpt("analysis_exe");
254  } else {
255  if (prefs.GetOpt("libname").empty())
256  executable = prefs.GetOpt("analysis_default_lib");
257  else
258  executable = prefs.GetOpt("analysis_lib");
259  }
260  prefs.SetPar("analysis", executable.c_str());
261 
262  if (!is_exe) prefs.SetPar("killexename", "go4analysis", false); else {
263  #ifdef _MSC_VER
264  char symbol = '\\';
265  #else
266  char symbol = '/';
267  #endif
268  const char *runname = strrchr(remoteexe, symbol);
269  prefs.SetPar("killexename", runname ? runname+1 : remoteexe, false);
270  }
271 
272  std::string initcmd = prefs.GetOpt(shellkind == 0 ? "execinitcmd" : "shellinitcmd");
273  prefs.SetPar("initcmd", initcmd.c_str());
274 
275  std::string progcmd = prefs.GetOpt((serverkind>0) ? ((serverkind==2) ? "httpcmd" : "servercmd") : "clientcmd");
276  prefs.SetPar("progcmd", progcmd.c_str());
277 
278  std::string hostcmd = prefs.GetOpt(termname);
279  prefs.SetPar("hostcmd", hostcmd.c_str());
280 
281  std::string cmd = prefs.GetOpt(shellname);
282  std::cout << "cmd: " << cmd << std::endl;
283  launchcmd = cmd.c_str();
284 
285  std::string dkill = prefs.GetOpt("kill");
286  prefs.SetPar("hostcmd", dkill.c_str());
287  cmd = prefs.GetOpt(shellname);
288  std::cout << "killcmd: " << cmd << std::endl;
289  killcmd = cmd.c_str();
290 
291  return kTRUE;
292  }
293 
294  if (!go4sys || (strlen(go4sys) == 0)) return kFALSE;
295 
297 
298  std::ifstream launchprefs(filename.Data());
299  if(!launchprefs) {
300  TGo4Log::Debug("Master -- ERROR: Preferences file %s not existing, could not launch client ",
301  filename.Data());
302  return kFALSE;
303  }
304 
305  char formatstring[1000];
306 
307  if ((konsole<1) || (konsole>3)) konsole = 1;
308  Int_t num = konsole;
309  if (serverkind>0) num+=3;
310 
311  for (int n = 0; n < num; n++)
312  launchprefs.getline(formatstring, 1000, '\n');
313 
314  const char *sh_com = "";
315  const char *sh_host = remotehost;
316  TString serverdisplay = "";
317 
318  switch (shellkind) {
319  case 1:
320  sh_com = "rsh -n";
321  serverdisplay = "-display ";
322  serverdisplay += sdisplay;
323  break;
324  case 2:
325  sh_com = (konsole == 0) ? "ssh -x " : "ssh -X ";
326  break;
327  default:
328  sh_com = "";
329  sh_host = "";
330  break;
331  }
332 
333  killcmd = "killall ";
334  killcmd += remoteexe;
335 
336  if((shellkind > 0) && (strcmp(remotehost, gSystem->HostName()) != 0) && (strcmp(remotehost,"localhost") != 0)) {
337  TString precmd = sh_com;
338  precmd += " ";
339  precmd += remotehost;
340  precmd += " ";
341  killcmd.Prepend(precmd);
342  }
343 
344  launchcmd = "";
345 
346  switch(konsole) {
347  case 2: { // xterm
348  launchcmd.Form(formatstring,
349  sh_com, sh_host, serverdisplay.Data(), name, remotehost, go4sys, go4sys, rootsys,
350  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
351  break;
352  }
353 
354  case 3: { // konsole
355  launchcmd.Form(formatstring,
356  sh_com, sh_host, name, go4sys, go4sys, rootsys,
357  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
358  break;
359  }
360 
361  default: { // Qt
362 
363  launchcmd.Form(formatstring,
364  sh_com, sh_host, go4sys, go4sys, rootsys,
365  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
366  break;
367  }
368  }
369 
370  return kTRUE;
371 }
372 
373 // ==============================================================================
374 
376  TGo4Proxy(),
377  fxParentSlot(nullptr),
378  fbAnalysisReady(kFALSE),
379  fbAnalysisSettingsReady(kFALSE),
380  fAnalysisLaunched(0),
381  fNodeName()
382 {
383 }
384 
386 {
387 }
388 
390 {
391  return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Settings");
392 }
393 
395 {
396  return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Ratemeter");
397 }
398 
400 {
401  return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Loginfo");
402 }
403 
405 {
406  return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Debugoutput");
407 }
408 
410 {
411  fInfoStr = "";
412  if (!IsConnected())
413  fInfoStr = "Not connected";
414  else if (IsViewer())
415  fInfoStr = "Observer";
416  else if (IsController())
417  fInfoStr = "Controller";
418  else if (IsAdministrator())
419  fInfoStr = "Administrator";
420  return fInfoStr.Data();
421 }
TGo4Slot * LoginfoSlot()
std::string GetOpt(const char *prefix)
TGo4Slot * FindChild(const char *name) const
Definition: TGo4Slot.cxx:245
virtual ~TGo4ServerProxy()
virtual Bool_t IsViewer() const
static Bool_t GetLaunchString(TString &launchcmd, TString &killcmd, Int_t serverkind, Int_t shellkind, Int_t konsole, const char *name, const char *remotehost, const char *remotedir, const char *remoteexe, Int_t guiport, Int_t exe_kind=0, const char *exeargs=nullptr)
virtual Bool_t IsAdministrator() const
virtual Bool_t IsController() const
TGo4Slot * RatemeterSlot()
static void Debug(const char *text,...) GO4_PRINTF_ARGS
Definition: TGo4Log.cxx:281
static const char * Get_fgcLAUNCHPREFSFILE()
TGo4Slot * DebugOutputSlot()
TGo4Slot * SettingsSlot()
virtual Bool_t IsConnected() const
TGo4Slot * fxParentSlot
void ReplacePars(std::string &str)
void AddFile(const char *fname, bool errorout=false)
const char * GetContainedObjectInfo() override
bool IsOk() const
void ReplaceEnvPars(std::string &str)
static TString subGO4SYS(const char *subdir)
Definition: TGo4Log.cxx:189
bool HasPar(const char *name)
TGo4Prefs(const char *hostname)
static const char * GO4SYS()
Definition: TGo4Log.cxx:156
const char * GetPar(const char *name)
void SetPar(const char *name, const char *value, bool force=true)
std::map< std::string, std::string > fPars