GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
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
29class 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())
118 return nullptr;
119 return fPars[dname].c_str();
120 }
121
122 bool HasPar(const char *name)
123 {
124 return GetPar(name) != nullptr;
125 }
126
127 void ReplacePars(std::string& str)
128 {
129 size_t pos;
130 bool isany = false;
131 int cnt = 0;
132
133 do {
134 isany = false;
135 for (auto &entry : fPars) {
136 pos = 0;
137 while ((pos = str.find(entry.first, pos)) != std::string::npos) {
138 str.replace(pos, entry.first.length(), entry.second);
139 isany = true;
140 }
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) str.insert(pos1, value);
169 }
170 }
171
173 std::string GetOpt(const char *prefix)
174 {
175 const char *opt = GetPar(prefix);
176 if (!opt) return std::string("");
177 std::string res = opt;
178 ReplacePars(res);
179 ReplaceEnvPars(res);
180 return res;
181 }
182
183};
184
185Bool_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 || (strlen(name) == 0)) name = "UserAnalysis";
206 if (!serverhost || (strlen(serverhost) == 0)) serverhost = "localhost";
207
208 if (!gSystem->Getenv("GO4OLDLAUNCH")) {
209 TGo4Prefs prefs(remotehost);
210
211 const char *shellname = "exec";
212 if (shellkind == 1)
213 shellname = "rsh";
214 else if (shellkind == 2)
215 shellname = konsole == 1 ? "ssh" : "sshX";
216 prefs.SetPar("shellkind", shellname, false);
217 prefs.SetPar("exekind", TString::Format("%d", exe_kind).Data(), false);
218 prefs.SetPar("clientkind", serverkind > 0 ? "Go4Server" : "Go4Client", false);
219
220 prefs.AddFile("go4.prefs", false);
221 prefs.AddFile(TGo4Log::subGO4SYS("etc/go4.prefs"), true);
222 if (!prefs.IsOk()) {
223 std::cout << "Cannot find prefs file" << std::endl;
224 return kFALSE;
225 }
226
227 prefs.SetPar("guihost", serverhost, false);
228 //if (!server)
229 prefs.SetPar("guiport", TString::Format("%d", guiport).Data());
230 prefs.SetPar("guigo4sys", go4sys, false);
231 prefs.SetPar("analysisname", name, false);
232 prefs.SetPar("workdir", remotedir, false);
233 prefs.SetPar(exe_kind == 0 ? "exename" : "libname", remoteexe, false);
234
235 if ((exe_kind == 1) && exeargs && (strlen(exeargs) > 0))
236 prefs.SetPar("userargs", exeargs, false);
237 else
238 prefs.SetPar("userargs", "", false);
239
240 const char *termname = "qtwindow";
241 if (konsole == 2)
242 termname = "xterm";
243 else if (konsole == 3)
244 termname = "konsole";
245
246 // no need to change into local directory with exec and qtwinow - it happens automatically
247 if ((shellkind == 0) && (konsole == 1))
248 prefs.SetPar("cd_workdir", "");
249
250 std::string executable;
251 bool is_exe = prefs.GetOpt("exekind") != "1";
252 if (is_exe) {
253 if (prefs.GetOpt("exename").empty())
254 executable = prefs.GetOpt("analysis_default_exe");
255 else
256 executable = prefs.GetOpt("analysis_exe");
257 } else {
258 if (prefs.GetOpt("libname").empty())
259 executable = prefs.GetOpt("analysis_default_lib");
260 else
261 executable = prefs.GetOpt("analysis_lib");
262 }
263 prefs.SetPar("analysis", executable.c_str());
264
265 if (!is_exe)
266 prefs.SetPar("killexename", "go4analysis", false);
267 else {
268#ifdef _MSC_VER
269 char symbol = '\\';
270#else
271 char symbol = '/';
272#endif
273 const char *runname = strrchr(remoteexe, symbol);
274 prefs.SetPar("killexename", runname ? runname + 1 : remoteexe, false);
275 }
276
277 std::string initcmd = prefs.GetOpt(shellkind == 0 ? "execinitcmd" : "shellinitcmd");
278 prefs.SetPar("initcmd", initcmd.c_str());
279
280 std::string progcmd = prefs.GetOpt((serverkind>0) ? ((serverkind==2) ? "httpcmd" : "servercmd") : "clientcmd");
281 prefs.SetPar("progcmd", progcmd.c_str());
282
283 std::string hostcmd = prefs.GetOpt(termname);
284 prefs.SetPar("hostcmd", hostcmd.c_str());
285
286 std::string cmd = prefs.GetOpt(shellname);
287 std::cout << "cmd: " << cmd << std::endl;
288 launchcmd = cmd.c_str();
289
290 std::string dkill = prefs.GetOpt("kill");
291 prefs.SetPar("hostcmd", dkill.c_str());
292 cmd = prefs.GetOpt(shellname);
293 std::cout << "killcmd: " << cmd << std::endl;
294 killcmd = cmd.c_str();
295
296 return kTRUE;
297 }
298
299 if (!go4sys || (strlen(go4sys) == 0)) return kFALSE;
300
302
303 std::ifstream launchprefs(filename.Data());
304 if(!launchprefs) {
305 TGo4Log::Debug("Master -- ERROR: Preferences file %s not existing, could not launch client ",
306 filename.Data());
307 return kFALSE;
308 }
309
310 char formatstring[1000];
311
312 if ((konsole<1) || (konsole>3)) konsole = 1;
313 Int_t num = konsole;
314 if (serverkind>0) num+=3;
315
316 for (int n = 0; n < num; n++)
317 launchprefs.getline(formatstring, 1000, '\n');
318
319 const char *sh_com = "";
320 const char *sh_host = remotehost;
321 TString serverdisplay = "";
322
323 switch (shellkind) {
324 case 1:
325 sh_com = "rsh -n";
326 serverdisplay = "-display ";
327 serverdisplay += sdisplay;
328 break;
329 case 2:
330 sh_com = (konsole == 0) ? "ssh -x " : "ssh -X ";
331 break;
332 default:
333 sh_com = "";
334 sh_host = "";
335 break;
336 }
337
338 killcmd = "killall ";
339 killcmd += remoteexe;
340
341 if((shellkind > 0) && (strcmp(remotehost, gSystem->HostName()) != 0) && (strcmp(remotehost,"localhost") != 0)) {
342 TString precmd = sh_com;
343 precmd += " ";
344 precmd += remotehost;
345 precmd += " ";
346 killcmd.Prepend(precmd);
347 }
348
349 launchcmd = "";
350
351 switch(konsole) {
352 case 2: { // xterm
353 launchcmd.Form(formatstring,
354 sh_com, sh_host, serverdisplay.Data(), name, remotehost, go4sys, go4sys, rootsys,
355 path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
356 break;
357 }
358
359 case 3: { // konsole
360 launchcmd.Form(formatstring,
361 sh_com, sh_host, name, go4sys, go4sys, rootsys,
362 path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
363 break;
364 }
365
366 default: { // Qt
367
368 launchcmd.Form(formatstring,
369 sh_com, sh_host, go4sys, go4sys, rootsys,
370 path, ldpath, remotedir, remoteexe, name, serverhost, guiport, remotehost);
371 break;
372 }
373 }
374
375 return kTRUE;
376}
377
378// ==============================================================================
379
381 TGo4Proxy(),
382 fxParentSlot(nullptr),
383 fbAnalysisReady(kFALSE),
386 fNodeName()
387{
388}
389
393
395{
396 return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Settings");
397}
398
400{
401 return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Ratemeter");
402}
403
405{
406 return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Loginfo");
407}
408
410{
411 return !fxParentSlot ? nullptr : fxParentSlot->FindChild("Debugoutput");
412}
413
415{
416 fInfoStr = "";
417 if (!IsConnected())
418 fInfoStr = "Not connected";
419 else if (IsViewer())
420 fInfoStr = "Observer";
421 else if (IsController())
422 fInfoStr = "Controller";
423 else if (IsAdministrator())
424 fInfoStr = "Administrator";
425 return fInfoStr.Data();
426}
static TString subGO4SYS(const char *subdir)
Return subdirectory in the GO4SYS.
Definition TGo4Log.cxx:189
static const char * GO4SYS()
Return GO4SYS environment variable or Go4 top directory during compile (if GO4SYS) not set.
Definition TGo4Log.cxx:156
static void Debug(const char *text,...) GO4_PRINTF_ARGS
User shortcut for message with prio 0.
Definition TGo4Log.cxx:281
std::map< std::string, std::string > fPars
TGo4Prefs(const char *hostname)
bool HasPar(const char *name)
void SetPar(const char *name, const char *value, bool force=true)
bool IsOk() const
Return true if more than two parameter exists, hostname and os is default.
std::string GetOpt(const char *prefix)
return option value with parameters replaced
void ReplacePars(std::string &str)
void AddFile(const char *fname, bool errorout=false)
const char * GetPar(const char *name)
void ReplaceEnvPars(std::string &str)
const char * GetContainedObjectInfo() override
TGo4Slot * LoginfoSlot()
TString fNodeName
0 - not launched, 1 - external shell, 2 - in qt shell
virtual Bool_t IsConnected() const
TGo4Slot * fxParentSlot
TString fInfoStr
name of remote node
TGo4ServerProxy()
contained object info
Bool_t fbAnalysisSettingsReady
true if analysis is connected and get first info
TGo4Slot * DebugOutputSlot()
TGo4Slot * RatemeterSlot()
virtual Bool_t IsController() const
TGo4Slot * SettingsSlot()
virtual Bool_t IsAdministrator() const
Int_t fAnalysisLaunched
true when settings are specified
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 IsViewer() const
static const char * Get_fgcLAUNCHPREFSFILE()