GSI Object Oriented Online Offline (Go4)  GO4-6.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4ServerProxy.cxx
Go to the documentation of this file.
1 // $Id: TGo4ServerProxy.cxx 2759 2020-04-16 13:00:41Z linev $
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  #if defined(WIN32)
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==0) 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.length()==0) || (mask.length()==0)) break;
79 
80  const char* subvalue = GetPar(subname.c_str());
81 
82  if (subvalue==0) 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 = Form("%s%s%s", "%", name, "%");
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 = Form("%s%s%s", "%", name, "%");
117  if (fPars.find(dname) == fPars.end()) return 0;
118  return fPars[dname].c_str();
119  }
120 
121  bool HasPar(const char* name)
122  {
123  return GetPar(name)!=0;
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!=0) str.insert(pos1, value);
170  }
171  }
172 
174  std::string GetOpt(const char* prefix)
175  {
176  const char* opt = GetPar(prefix);
177  if (opt==0) 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==0) || (strlen(name)==0)) name = "UserAnalysis";
207  if ((serverhost==0) || (strlen(serverhost)==0)) serverhost = "localhost";
208 
209  if (gSystem->Getenv("GO4OLDLAUNCH")==0) {
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", Form("%d", exe_kind), 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", Form("%d", guiport));
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 
235  if ((exe_kind==1) && (exeargs!=0) && (strlen(exeargs)>0))
236  prefs.SetPar("userargs", Form("%s", exeargs), false);
237  else
238  prefs.SetPar("userargs", "", false);
239 
240 
241  const char* termname = "qtwindow";
242  if (konsole==2) termname = "xterm"; else
243  if (konsole==3) termname = "konsole";
244 
245  // no need to change into local directory with exec and qtwinow - it happens automatically
246  if ((shellkind==0) && (konsole==1))
247  prefs.SetPar("cd_workdir", "");
248 
249  std::string executable;
250  bool is_exe = prefs.GetOpt("exekind") != "1";
251  if (is_exe) {
252  if (prefs.GetOpt("exename").empty())
253  executable = prefs.GetOpt("analysis_default_exe");
254  else
255  executable = prefs.GetOpt("analysis_exe");
256  } else {
257  if (prefs.GetOpt("libname").empty())
258  executable = prefs.GetOpt("analysis_default_lib");
259  else
260  executable = prefs.GetOpt("analysis_lib");
261  }
262  prefs.SetPar("analysis", executable.c_str());
263 
264  if (!is_exe) prefs.SetPar("killexename", "go4analysis", false); else {
265  #ifdef WIN32
266  char symbol = '\\';
267  #else
268  char symbol = '/';
269  #endif
270  const char* runname = strrchr(remoteexe, symbol);
271  prefs.SetPar("killexename", runname ? runname+1 : remoteexe, false);
272  }
273 
274  std::string initcmd = prefs.GetOpt(shellkind==0 ? "execinitcmd" : "shellinitcmd");
275  prefs.SetPar("initcmd", initcmd.c_str());
276 
277  std::string progcmd = prefs.GetOpt((serverkind>0) ? ((serverkind==2) ? "httpcmd" : "servercmd") : "clientcmd");
278  prefs.SetPar("progcmd", progcmd.c_str());
279 
280  std::string hostcmd = prefs.GetOpt(termname);
281  prefs.SetPar("hostcmd", hostcmd.c_str());
282 
283  std::string cmd = prefs.GetOpt(shellname);
284  std::cout << "cmd: " << cmd << std::endl;
285  launchcmd = cmd.c_str();
286 
287  std::string dkill = prefs.GetOpt("kill");
288  prefs.SetPar("hostcmd", dkill.c_str());
289  cmd = prefs.GetOpt(shellname);
290  std::cout << "killcmd: " << cmd << std::endl;
291  killcmd = cmd.c_str();
292 
293  return kTRUE;
294  }
295 
296  if ((go4sys==0) || (strlen(go4sys)==0)) return kFALSE;
297 
299 
300  std::ifstream launchprefs(filename.Data());
301  if(!launchprefs) {
302  TGo4Log::Debug("Master -- ERROR: Preferences file %s not existing, could not launch client ",
303  filename.Data());
304  return kFALSE;
305  }
306 
307  char formatstring[1000];
308 
309  if ((konsole<1) || (konsole>3)) konsole = 1;
310  Int_t num = konsole;
311  if (serverkind>0) num+=3;
312 
313  for(int n=0;n<num;n++)
314  launchprefs.getline(formatstring, 1000, '\n' );
315 
316  const char* sh_com = "";
317  const char* sh_host = remotehost;
318  TString serverdisplay = "";
319 
320  switch (shellkind) {
321  case 1:
322  sh_com = "rsh -n";
323  serverdisplay = "-display ";
324  serverdisplay += sdisplay;
325  break;
326  case 2:
327  sh_com = (konsole == 0) ? "ssh -x " : "ssh -X ";
328  break;
329  default:
330  sh_com = "";
331  sh_host = "";
332  break;
333  }
334 
335  killcmd = "killall ";
336  killcmd += remoteexe;
337 
338  if((shellkind>0) && (strcmp(remotehost, gSystem->HostName())!=0) && (strcmp(remotehost,"localhost")!=0)) {
339  TString precmd = sh_com;
340  precmd += " ";
341  precmd += remotehost;
342  precmd += " ";
343  killcmd.Prepend(precmd);
344  }
345 
346  launchcmd = "";
347 
348  switch(konsole) {
349  case 2: { // xterm
350  launchcmd.Form(formatstring,
351  sh_com, sh_host, serverdisplay.Data(), name, remotehost, go4sys, go4sys, rootsys,
352  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
353  break;
354  }
355 
356  case 3: { // konsole
357  launchcmd.Form(formatstring,
358  sh_com, sh_host, name, go4sys, go4sys, rootsys,
359  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
360  break;
361  }
362 
363  default: { // Qt
364 
365  launchcmd.Form(formatstring,
366  sh_com, sh_host, go4sys, go4sys, rootsys,
367  path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
368  break;
369  }
370  }
371 
372  return kTRUE;
373 }
374 
375 // ==============================================================================
376 
378  TGo4Proxy(),
379  fxParentSlot(0),
380  fbAnalysisReady(kFALSE),
381  fbAnalysisSettingsReady(kFALSE),
382  fAnalysisLaunched(0),
383  fNodeName(),
384  fInfoStr()
385 {
386 }
387 
389 {
390 }
391 
393 {
394  return fxParentSlot==0 ? 0 : fxParentSlot->FindChild("Settings");
395 }
396 
398 {
399  return fxParentSlot==0 ? 0 : fxParentSlot->FindChild("Ratemeter");
400 }
401 
403 {
404  return fxParentSlot==0 ? 0 : fxParentSlot->FindChild("Loginfo");
405 }
406 
408 {
409  return fxParentSlot==0 ? 0 : fxParentSlot->FindChild("Debugoutput");
410 }
411 
413 {
414  fInfoStr = "";
415  if (!IsConnected()) fInfoStr = "Not connected"; else
416  if (IsViewer()) fInfoStr = "Observer"; else
417  if (IsController()) fInfoStr = "Controller"; else
418  if (IsAdministrator()) fInfoStr = "Administrator";
419  return fInfoStr.Data();
420 }
421 
virtual Bool_t IsViewer()
virtual Bool_t IsConnected()
virtual Bool_t IsAdministrator()
TGo4Slot * LoginfoSlot()
std::string GetOpt(const char *prefix)
virtual ~TGo4ServerProxy()
bool IsOk() const
TGo4Slot * RatemeterSlot()
static const char * Get_fgcLAUNCHPREFSFILE()
TGo4Slot * DebugOutputSlot()
TGo4Slot * FindChild(const char *name)
Definition: TGo4Slot.cxx:259
virtual const char * GetContainedObjectInfo()
TGo4Slot * SettingsSlot()
TGo4Slot * fxParentSlot
virtual Bool_t IsController()
void ReplacePars(std::string &str)
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=0)
void AddFile(const char *fname, bool errorout=false)
void ReplaceEnvPars(std::string &str)
static TString subGO4SYS(const char *subdir)
Definition: TGo4Log.cxx:190
bool HasPar(const char *name)
TGo4Prefs(const char *hostname)
static const char * GO4SYS()
Definition: TGo4Log.cxx:157
const char * GetPar(const char *name)
static void Debug(const char *text,...)
Definition: TGo4Log.cxx:284
void SetPar(const char *name, const char *value, bool force=true)
std::map< std::string, std::string > fPars