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