Salome HOME
e8dd6845ca01affceceb9bd1e52bdd88e4008dc4
[modules/kernel.git] / bin / runSalome.py
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
4 #
5 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21 #
22 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #
24
25 ## @package runSalome
26 # \brief Module that provides services to launch SALOME
27 #
28
29 import sys, os, string, glob, time, pickle, re
30 import orbmodule
31 import setenv
32 from server import *
33 from launchConfigureParser import verbose
34 from server import process_id
35
36 if sys.platform == "win32":
37     SEP = ";"
38 else:
39     SEP = ":"
40
41 # -----------------------------------------------------------------------------
42
43 from killSalome import killAllPorts
44
45 def killLocalPort():
46     """
47     kill servers from a previous SALOME exection, if needed,
48     on the CORBA port given in args of runSalome
49     """
50     
51     from killSalomeWithPort import killMyPort
52     my_port=str(args['port'])
53     try:
54         killMyPort(my_port)
55     except:
56         print "problem in killLocalPort()"
57         pass
58     pass
59     
60 def givenPortKill(port):
61     """
62     kill servers from a previous SALOME exection, if needed,
63     on the same CORBA port
64     """
65     
66     from killSalomeWithPort import killMyPort
67     my_port=port
68     try:
69         killMyPort(my_port)
70     except:
71         print "problem in LocalPortKill(), killMyPort("<<port<<")"
72         pass
73     pass
74
75 def kill_salome(args):
76     """
77     Kill servers from previous SALOME executions, if needed;
78     depending on args 'killall' or 'portkill', kill all executions,
79     or only execution on the same CORBA port
80     """
81
82     if args['killall']:
83         killAllPorts()
84     elif args['portkill']:
85         givenPortKill(str(args['port']))
86
87 # -----------------------------------------------------------------------------
88 #
89 # Class definitions to launch CORBA Servers
90 #
91
92 class InterpServer(Server):
93     def __init__(self,args):
94         self.args=args
95         if sys.platform != "win32":
96           env_ld_library_path=['env', 'LD_LIBRARY_PATH=' + os.getenv("LD_LIBRARY_PATH")]
97           self.CMD=['xterm', '-e']+ env_ld_library_path + ['python']
98         else:
99           self.CMD=['cmd', '/c', 'start cmd.exe', '/K', 'python']
100        
101     def run(self):
102         global process_id
103         command = self.CMD
104         print "INTERPSERVER::command = ", command
105         if sys.platform == "win32":
106           import win32pm
107           pid = win32pm.spawnpid( string.join(command, " "),'-nc' )
108         else:
109           pid = os.spawnvp(os.P_NOWAIT, command[0], command)
110         process_id[pid]=self.CMD
111         self.PID = pid
112
113 # ---
114
115 def get_cata_path(list_modules,modules_root_dir):
116     """Build a list of catalog paths (cata_path) to initialize the ModuleCatalog server
117     """
118     modules_cata={}
119     cata_path=[]
120
121     for module in list_modules:
122         if modules_root_dir.has_key(module):
123             module_root_dir=modules_root_dir[module]
124             module_cata=module+"Catalog.xml"
125             cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources",module.lower(), module_cata)
126
127             if os.path.exists(cata_file):
128                 cata_path.append(cata_file)
129                 modules_cata[module]=cata_file
130             else:
131                 cata_file=os.path.join(module_root_dir, "share",setenv.salome_subdir, "resources", module_cata)
132                 if os.path.exists(cata_file):
133                     cata_path.append(cata_file)
134                     modules_cata[module]=cata_file
135
136     for path in os.getenv("SALOME_CATALOGS_PATH","").split(SEP):
137         if os.path.exists(path):
138             for cata_file in glob.glob(os.path.join(path,"*Catalog.xml")):
139                 module_name= os.path.basename(cata_file)[:-11]
140                 if not modules_cata.has_key(module_name):
141                     cata_path.append(cata_file)
142                     modules_cata[module_name]=cata_file
143
144     return cata_path
145
146
147
148 class CatalogServer(Server):
149     def __init__(self,args):
150         self.args=args
151         self.initArgs()
152         self.SCMD1=['SALOME_ModuleCatalog_Server','-common']
153         self.SCMD2=[]
154         home_dir=os.getenv('HOME')
155         if home_dir is not None:
156             self.SCMD2=['-personal',os.path.join(home_dir,'Salome/resources/CatalogModulePersonnel.xml')] 
157
158     def setpath(self,modules_list,modules_root_dir):
159         list_modules = modules_list[:]
160         list_modules.reverse()
161         if self.args["gui"] :
162             list_modules = ["KERNEL", "GUI"] + list_modules
163         else :
164             list_modules = ["KERNEL"] + list_modules
165
166         cata_path=get_cata_path(list_modules,modules_root_dir)
167
168         self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
169
170 # ---
171
172 class SalomeDSServer(Server):
173     def __init__(self,args):
174         self.args=args
175         self.initArgs()
176         self.CMD=['SALOMEDS_Server']
177
178 # ---
179
180 class ConnectionManagerServer(Server):
181     def __init__(self,args):
182         self.args=args
183         self.initArgs()
184         self.CMD=['SALOME_ConnectionManagerServer']
185
186 # ---
187
188 class RegistryServer(Server):
189     def __init__(self,args):
190         self.args=args
191         self.initArgs()
192         self.CMD=['SALOME_Registry_Server', '--salome_session','theSession']
193
194 # ---
195
196 class ContainerCPPServer(Server):
197     def __init__(self,args):
198         self.args=args
199         self.initArgs()
200         self.CMD=['SALOME_Container','FactoryServer']
201
202 # ---
203
204 class ContainerPYServer(Server):
205     def __init__(self,args):
206         self.args=args
207         self.initArgs()
208         if sys.platform == "win32":
209           self.CMD=[os.environ["PYTHONBIN"], '\"'+os.environ["KERNEL_ROOT_DIR"] + '/bin/salome/SALOME_ContainerPy.py'+'\"','FactoryServerPy']
210         else:
211           self.CMD=['SALOME_ContainerPy.py','FactoryServerPy']
212
213 # ---
214
215 class LoggerServer(Server):
216     def __init__(self,args):
217         self.args=args
218         self.initArgs()
219         from salome_utils import generateFileName
220         if sys.platform == "win32": dirpath = os.environ["HOME"]
221         else:                       dirpath = "/tmp"
222         logfile = generateFileName( dirpath,
223                                     prefix="logger",
224                                     extension="log",
225                                     with_username=True,
226                                     with_hostname=True,
227                                     with_port=True)
228         print "==========================================================="
229         print "Logger server: put log to the file:"
230         print logfile
231         print "==========================================================="
232         self.CMD=['SALOME_Logger_Server', logfile]
233         pass
234     pass # end of LoggerServer class
235
236 # ---
237
238 class SessionServer(Server):
239     def __init__(self,args,modules_list,modules_root_dir):
240         self.args = args.copy()
241         # Bug 11512 (Problems with runSalome --xterm on Mandrake and Debian Sarge)
242         #self.args['xterm']=0
243         #
244         self.initArgs()
245         self.SCMD1=['SALOME_Session_Server']
246         self.SCMD2=[]
247         if 'registry' in self.args['embedded']:
248             self.SCMD1+=['--with','Registry',
249                          '(','--salome_session','theSession',')']
250         if 'moduleCatalog' in self.args['embedded']:
251             self.SCMD1+=['--with','ModuleCatalog','(','-common']
252             home_dir=os.getenv('HOME')
253             if home_dir is not None:
254                 self.SCMD2+=['-personal',os.path.join(home_dir,'Salome/resources/CatalogModulePersonnel.xml')] 
255             self.SCMD2+=[')']
256         if 'study' in self.args['embedded']:
257             self.SCMD2+=['--with','SALOMEDS','(',')']
258         if 'cppContainer' in self.args['embedded']:
259             self.SCMD2+=['--with','Container','(','FactoryServer',')']
260         if 'SalomeAppEngine' in self.args['embedded']:
261             self.SCMD2+=['--with','SalomeAppEngine','(',')']
262             
263         if 'cppContainer' in self.args['standalone'] or 'cppContainer' in self.args['embedded']:
264             self.SCMD2+=['CPP']
265         if 'pyContainer' in self.args['standalone'] or 'pyContainer' in self.args['embedded']:
266             self.SCMD2+=['PY']
267         if self.args['gui']:
268             session_gui = True
269             if self.args.has_key('session_gui'):
270                 session_gui = self.args['session_gui']
271             if session_gui:
272                 self.SCMD2+=['GUI']
273                 if self.args['splash']:
274                     self.SCMD2+=['SPLASH']
275                     pass
276                 if self.args['study_hdf'] is not None:
277                     self.SCMD2+=['--study-hdf=%s'%self.args['study_hdf']]
278                     pass
279                 pass
280             pass
281         if self.args['noexcepthandler']:
282             self.SCMD2+=['noexcepthandler']
283         if self.args.has_key('user_config'):
284             self.SCMD2+=['--resources=%s'%self.args['user_config']]
285         if self.args.has_key('modules'):
286             list_modules = []
287             #keep only modules with GUI
288             for m in modules_list:
289               if m not in modules_root_dir:
290                 list_modules.insert(0,m)
291               else:
292                 fr1 = os.path.join(modules_root_dir[m],"share","salome","resources",m.lower(),"SalomeApp.xml")
293                 fr2 = os.path.join(modules_root_dir[m],"share","salome","resources","SalomeApp.xml")
294                 if os.path.exists(fr1) or os.path.exists(fr2):
295                   list_modules.insert(0,m)
296             list_modules.reverse()
297             self.SCMD2+=['--modules (%s)' % ":".join(list_modules)]
298
299         if self.args.has_key('pyscript') and len(self.args['pyscript']) > 0:
300             self.SCMD2+=['--pyscript=%s'%(",".join(self.args['pyscript']))]
301
302     def setpath(self,modules_list,modules_root_dir):
303         list_modules = modules_list[:]
304         list_modules.reverse()
305         if self.args["gui"] :
306             list_modules = ["KERNEL", "GUI"] + list_modules
307         else :
308             list_modules = ["KERNEL"] + list_modules
309
310         cata_path=get_cata_path(list_modules,modules_root_dir)
311
312         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
313             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
314             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
315         else:
316             self.CMD=self.SCMD1 + self.SCMD2
317         if self.args.has_key('test'):
318             self.CMD+=['-test'] + self.args['test']
319         elif self.args.has_key('play'):
320             self.CMD+=['-play'] + self.args['play']
321
322         if self.args["gdb_session"] or self.args["ddd_session"]:
323             f = open(".gdbinit4salome", "w")
324             f.write("set args ")
325             args = " ".join(self.CMD[1:])
326             args = args.replace("(", "\(")
327             args = args.replace(")", "\)")
328             f.write(args)
329             f.write("\n")
330             f.close()
331             if self.args["ddd_session"]:
332                 self.CMD = ["ddd", "--command=.gdbinit4salome", self.CMD[0]]
333             elif self.args["gdb_session"]:
334                 self.CMD = ["xterm", "-e", "gdb", "--command=.gdbinit4salome", self.CMD[0]]
335                 pass
336             pass
337         
338         if self.args["valgrind_session"]:
339             l = ["valgrind"]
340             val = os.getenv("VALGRIND_OPTIONS")
341             if val:
342                 l += val.split()
343                 pass
344             self.CMD = l + self.CMD
345             pass
346         
347 # ---
348
349 class LauncherServer(Server):
350     def __init__(self,args):
351         self.args=args
352         self.initArgs()
353         self.SCMD1=['SALOME_LauncherServer']
354         self.SCMD2=[]
355         if args["gui"] :
356             if 'registry' in self.args['embedded']:
357                 self.SCMD1+=['--with','Registry',
358                              '(','--salome_session','theSession',')']
359             if 'moduleCatalog' in self.args['embedded']:
360                 self.SCMD1+=['--with','ModuleCatalog','(','-common']
361                 self.SCMD2+=['-personal',
362                              '${HOME}/Salome/resources/CatalogModulePersonnel.xml',')']
363             if 'study' in self.args['embedded']:
364                 self.SCMD2+=['--with','SALOMEDS','(',')']
365             if 'cppContainer' in self.args['embedded']:
366                 self.SCMD2+=['--with','Container','(','FactoryServer',')']
367
368     def setpath(self,modules_list,modules_root_dir):
369         list_modules = modules_list[:]
370         list_modules.reverse()
371         if self.args["gui"] :
372             list_modules = ["KERNEL", "GUI"] + list_modules
373         else :
374             list_modules = ["KERNEL"] + list_modules
375
376         cata_path=get_cata_path(list_modules,modules_root_dir)
377
378         if (self.args["gui"]) & ('moduleCatalog' in self.args['embedded']):
379             #Use '::' instead ":" because drive path with "D:\" is invalid on windows platform
380             self.CMD=self.SCMD1 + ['"' + string.join(cata_path,'"::"') + '"'] + self.SCMD2
381         else:
382             self.CMD=self.SCMD1 + self.SCMD2
383
384 class NotifyServer(Server):
385     def __init__(self,args,modules_root_dir):
386         self.args=args
387         self.initArgs()
388         self.modules_root_dir=modules_root_dir
389         myLogName = os.environ["LOGNAME"]
390         self.CMD=['notifd','-c',
391                   self.modules_root_dir["KERNEL"] +'/share/salome/resources/kernel/channel.cfg',
392                   '-DFactoryIORFileName=/tmp/'+myLogName+'_rdifact.ior',
393                   '-DChannelIORFileName=/tmp/'+myLogName+'_rdichan.ior',
394                   '-DReportLogFile=/tmp/'+myLogName+'_notifd.report',
395                   '-DDebugLogFile=/tmp/'+myLogName+'_notifd.debug',
396                   ]
397
398 #
399 # -----------------------------------------------------------------------------
400
401 def startGUI(clt):
402     """Salome Session Graphic User Interface activation"""
403     import Engines
404     import SALOME
405     import SALOMEDS
406     import SALOME_ModuleCatalog
407     import SALOME_Session_idl
408     session=clt.waitNS("/Kernel/Session",SALOME.Session)
409     session.GetInterface()
410   
411 # -----------------------------------------------------------------------------
412
413 def startSalome(args, modules_list, modules_root_dir):
414     """Launch all SALOME servers requested by args"""
415     init_time = os.times()
416
417     if verbose(): print "startSalome ", args
418     
419     #
420     # Wake up session option
421     #
422     if args['wake_up_session']:
423         if "OMNIORB_CONFIG" not in os.environ:
424             from salome_utils import generateFileName
425             home  = os.getenv("HOME")
426             appli = os.getenv("APPLI")
427             kwargs={}
428             if appli is not None: 
429                 home = os.path.join(home, appli,"USERS")
430                 kwargs["with_username"] = True
431                 pass
432             last_running_config = generateFileName(home, prefix="omniORB",
433                                                    suffix="last",
434                                                    extension="cfg",
435                                                    hidden=True,
436                                                    **kwargs)
437             os.environ['OMNIORB_CONFIG'] = last_running_config
438             pass
439         pass
440     
441     #
442     # Initialisation ORB and Naming Service
443     #
444    
445     clt=orbmodule.client(args)
446
447     #
448     # Wake up session option
449     #
450     if args['wake_up_session']:
451         import Engines
452         import SALOME
453         import SALOMEDS
454         import SALOME_ModuleCatalog
455         import SALOME_Session_idl
456         session = clt.waitNS("/Kernel/Session",SALOME.Session)
457         status = session.GetStatSession()
458         if status.activeGUI:
459             from salome_utils import getPortNumber
460             port = getPortNumber()
461             msg  = "Warning :"
462             msg += "\n"
463             msg += "Session GUI for port number %s is already active."%(port)
464             msg += "\n"
465             msg += "If you which to wake up another session,"
466             msg += "\n"
467             msg += "please use variable OMNIORB_CONFIG"
468             msg += "\n"
469             msg += "to get the correct session object in naming service."
470             sys.stdout.write(msg+"\n")
471             sys.stdout.flush()
472             return clt
473         session.GetInterface()
474         args["session_object"] = session
475         return clt
476     
477     # Save Naming service port name into
478     # the file args["ns_port_log_file"]
479     if args.has_key('ns_port_log_file'):
480       home = os.environ['HOME']
481       appli= os.environ.get("APPLI")
482       if appli is not None:
483         home='%s/%s'%(home,appli)
484         pass
485       file_name= '%s/%s'%(home, args["ns_port_log_file"])
486       f = open(file_name, "w")
487       f.write(os.environ['NSPORT'])
488       f.close()
489
490     # Launch Logger Server (optional)
491     # and wait until it is registered in naming service
492     #
493
494     if args['logger']:
495         myServer=LoggerServer(args)
496         myServer.run()
497         clt.waitLogger("Logger")
498
499     # Notify Server launch
500     #
501
502     if sys.platform != "win32":
503       if verbose(): print "Notify Server to launch"
504     
505       myServer=NotifyServer(args,modules_root_dir)
506       myServer.run()
507
508     # Launch  Session Server (to show splash ASAP)
509     #
510
511     if args["gui"]:
512         mySessionServ = SessionServer(args,args['modules'],modules_root_dir)
513         mySessionServ.setpath(modules_list,modules_root_dir)
514         mySessionServ.run()
515
516     #
517     # Launch Registry Server,
518     # and wait until it is registered in naming service
519     #
520
521     if ('registry' not in args['embedded']) | (args["gui"] == 0) :
522         myServer=RegistryServer(args)
523         myServer.run()
524         if sys.platform == "win32":
525           clt.waitNS("/Registry")
526         else:
527           clt.waitNSPID("/Registry",myServer.PID)
528
529     #
530     # Launch Catalog Server,
531     # and wait until it is registered in naming service
532     #
533
534     if ('moduleCatalog' not in args['embedded']) | (args["gui"] == 0):
535         cataServer=CatalogServer(args)
536         cataServer.setpath(modules_list,modules_root_dir)
537         cataServer.run()
538         import SALOME_ModuleCatalog
539         if sys.platform == "win32":
540           clt.waitNS("/Kernel/ModulCatalog",SALOME_ModuleCatalog.ModuleCatalog)
541         else:
542           clt.waitNSPID("/Kernel/ModulCatalog",cataServer.PID,SALOME_ModuleCatalog.ModuleCatalog)
543
544     #
545     # Launch SalomeDS Server,
546     # and wait until it is registered in naming service
547     #
548
549     #print "ARGS = ",args
550     if ('study' not in args['embedded']) | (args["gui"] == 0):
551         print "RunStudy"
552         myServer=SalomeDSServer(args)
553         myServer.run()
554         if sys.platform == "win32":
555           clt.waitNS("/myStudyManager")
556         else:
557           clt.waitNSPID("/myStudyManager",myServer.PID)
558
559     #
560     # Launch LauncherServer
561     #
562     
563     myCmServer = LauncherServer(args)
564     myCmServer.setpath(modules_list,modules_root_dir)
565     myCmServer.run()
566
567     #
568     # Launch ConnectionManagerServer
569     #
570
571     myConnectionServer = ConnectionManagerServer(args)
572     myConnectionServer.run()
573
574
575     from Utils_Identity import getShortHostName
576     
577     if os.getenv("HOSTNAME") == None:
578         if os.getenv("HOST") == None:
579             os.environ["HOSTNAME"]=getShortHostName()
580         else:
581             os.environ["HOSTNAME"]=os.getenv("HOST")
582
583     theComputer = getShortHostName()
584     
585     #
586     # Launch local C++ Container (FactoryServer),
587     # and wait until it is registered in naming service
588     #
589
590     if ('cppContainer' in args['standalone']) | (args["gui"] == 0) : 
591         myServer=ContainerCPPServer(args)
592         myServer.run()
593         if sys.platform == "win32":
594           clt.waitNS("/Containers/" + theComputer + "/FactoryServer")
595         else:
596           clt.waitNSPID("/Containers/" + theComputer + "/FactoryServer",myServer.PID)
597
598     #
599     # Launch local Python Container (FactoryServerPy),
600     # and wait until it is registered in naming service
601     #
602
603     if 'pyContainer' in args['standalone']:
604         myServer=ContainerPYServer(args)
605         myServer.run()
606         if sys.platform == "win32":
607           clt.waitNS("/Containers/" + theComputer + "/FactoryServerPy")
608         else:
609           clt.waitNSPID("/Containers/" + theComputer + "/FactoryServerPy",myServer.PID)
610
611     #
612     # Wait until Session Server is registered in naming service
613     #
614     
615     if args["gui"]:
616 ##----------------        
617         import Engines
618         import SALOME
619         import SALOMEDS
620         import SALOME_ModuleCatalog
621         import SALOME_Session_idl
622         if sys.platform == "win32":
623           session=clt.waitNS("/Kernel/Session",SALOME.Session)
624         else:
625           session=clt.waitNSPID("/Kernel/Session",mySessionServ.PID,SALOME.Session)
626         args["session_object"] = session
627     end_time = os.times()
628     if verbose(): print
629     print "Start SALOME, elapsed time : %5.1f seconds"% (end_time[4]
630                                                          - init_time[4])
631
632     # ASV start GUI without Loader
633     #if args['gui']:
634     #    session.GetInterface()
635
636     #
637     # additionnal external python interpreters
638     #
639     nbaddi=0
640     
641     try:
642         if 'interp' in args:
643             nbaddi = args['interp']
644     except:
645         import traceback
646         traceback.print_exc()
647         print "-------------------------------------------------------------"
648         print "-- to get an external python interpreter:runSalome --interp=1"
649         print "-------------------------------------------------------------"
650         
651     if verbose(): print "additional external python interpreters: ", nbaddi
652     if nbaddi:
653         for i in range(nbaddi):
654             print "i=",i
655             anInterp=InterpServer(args)
656             anInterp.run()
657
658     # set PYTHONINSPECT variable (python interpreter in interactive mode)
659     if args['pinter']:
660         os.environ["PYTHONINSPECT"]="1"
661         try:
662             import readline
663         except ImportError:
664             pass
665         
666     return clt
667
668 # -----------------------------------------------------------------------------
669
670 def useSalome(args, modules_list, modules_root_dir):
671     """
672     Launch all SALOME servers requested by args,
673     save list of process, give info to user,
674     show registered objects in Naming Service.
675     """
676     global process_id
677     
678     clt=None
679     try:
680         clt = startSalome(args, modules_list, modules_root_dir)
681     except:
682         import traceback
683         traceback.print_exc()
684         print
685         print
686         print "--- Error during Salome launch ---"
687         
688     #print process_id
689
690     from addToKillList import addToKillList
691     from killSalomeWithPort import getPiDict
692
693     filedict = getPiDict(args['port'])
694     for pid, cmd in process_id.items():
695         addToKillList(pid, cmd, args['port'])
696         pass
697
698     if verbose(): print """
699     Saving of the dictionary of Salome processes in %s
700     To kill SALOME processes from a console (kill all sessions from all ports):
701       python killSalome.py 
702     To kill SALOME from the present interpreter, if it is not closed :
703       killLocalPort()      --> kill this session
704                                (use CORBA port from args of runSalome)
705       givenPortKill(port)  --> kill a specific session with given CORBA port 
706       killAllPorts()       --> kill all sessions
707     
708     runSalome, with --killall option, starts with killing
709     the processes resulting from the previous execution.
710     """%filedict
711     
712     #
713     #  Print Naming Service directory list
714     #
715     
716     if clt != None:
717         if verbose():
718             print
719             print " --- registered objects tree in Naming Service ---"
720             clt.showNS()
721             pass
722         
723         if not args['gui'] or not args['session_gui']:
724             if args['shutdown_servers']:
725                 class __utils__(object):
726                     def __init__(self, port):
727                         self.port = port
728                         import killSalomeWithPort
729                         self.killSalomeWithPort = killSalomeWithPort
730                         return
731                     def __del__(self):
732                         self.killSalomeWithPort.killMyPort(self.port)
733                         return
734                     pass
735                 args['shutdown_servers'] = __utils__(args['port'])
736                 pass
737             pass
738         
739         # run python scripts, passed via --execute option
740         toimport = []
741         if args.has_key('pyscript'):
742             if args.has_key('gui') and args.has_key('session_gui'):
743                 if not args['gui'] or not args['session_gui']:
744                     toimport = args['pyscript']
745
746         for srcname in toimport :
747             if srcname == 'killall':
748                 clt.showNS()
749                 killAllPorts()
750                 sys.exit(0)
751             else:
752                 if os.path.isabs(srcname):
753                     if os.path.exists(srcname):
754                         execScript(srcname)
755                     elif os.path.exists(srcname+".py"):
756                         execScript(srcname+".py")
757                     else:
758                         print "Can't execute file %s" % srcname
759                     pass
760                 else:
761                     found = False
762                     for path in [os.getcwd()] + sys.path:
763                         if os.path.exists(os.path.join(path,srcname)):
764                             execScript(os.path.join(path,srcname))
765                             found = True
766                             break
767                         elif os.path.exists(os.path.join(path,srcname+".py")):
768                             execScript(os.path.join(path,srcname+".py"))
769                             found = True
770                             break
771                         pass
772                     if not found:
773                         print "Can't execute file %s" % srcname
774                         pass
775                     pass
776                 pass
777             pass
778         pass
779     return clt
780     
781 def execScript(script_path):
782     print 'executing', script_path
783     sys.path.insert(0, os.path.dirname(script_path))
784     execfile(script_path,globals())
785     del sys.path[0]
786
787 # -----------------------------------------------------------------------------
788
789 def registerEnv(args, modules_list, modules_root_dir):
790     """
791     Register args, modules_list, modules_root_dir in a file
792     for further use, when SALOME is launched embedded in an other application.
793     """
794     if sys.platform == "win32":
795       fileEnv = os.getenv('TEMP')
796     else:
797       fileEnv = '/tmp/'
798
799     fileEnv += os.getenv('USER') + "_" + str(args['port']) \
800             + '_' + args['appname'].upper() + '_env'
801     fenv=open(fileEnv,'w')
802     pickle.dump((args, modules_list, modules_root_dir),fenv)
803     fenv.close()
804     os.environ["SALOME_LAUNCH_CONFIG"] = fileEnv
805
806 # -----------------------------------------------------------------------------
807
808 def searchFreePort(args, save_config=1):
809     print "Searching for a free port for naming service:",
810     #
811     if sys.platform == "win32":
812         tmp_file = os.getenv('TEMP');
813     else:
814         tmp_file = '/tmp'
815     tmp_file = os.path.join(tmp_file, '.netstat_%s'%os.getpid())
816     #
817     ###status = os.system("netstat -ltn | grep -E :%s > /dev/null 2>&1"%(NSPORT))
818     os.system( "netstat -a -n > %s" % tmp_file );
819     f = open( tmp_file, 'r' );
820     ports = f.readlines();
821     f.close();
822     os.remove( tmp_file );
823     #
824     def portIsUsed(port, data):
825         regObj = re.compile( ".*tcp.*:([0-9]+).*:.*listen", re.IGNORECASE );
826         for item in data:
827             try:
828                 p = int(regObj.match(item).group(1))
829                 if p == port: return True
830                 pass
831             except:
832                 pass
833             pass
834         return False
835     #
836     NSPORT=2810
837     limit=NSPORT+100
838     #
839     while 1:
840         if not portIsUsed(NSPORT, ports):
841             print "%s - OK"%(NSPORT)
842             #
843             from salome_utils import generateFileName, getHostName
844             hostname = getHostName()
845             #
846             home  = os.getenv("HOME")
847             appli = os.getenv("APPLI")
848             kwargs={}
849             if appli is not None: 
850               home = os.path.join(home, appli,"USERS")
851               kwargs["with_username"]=True
852             #
853             omniorb_config = generateFileName(home, prefix="omniORB",
854                                               extension="cfg",
855                                               hidden=True,
856                                               with_hostname=True,
857                                               with_port=NSPORT,
858                                               **kwargs)
859             orbdata = []
860             initref = "NameService=corbaname::%s:%s"%(hostname, NSPORT)
861             from omniORB import CORBA
862             if CORBA.ORB_ID == "omniORB4":
863                 orbdata.append("InitRef = %s"%(initref))
864                 orbdata.append("giopMaxMsgSize = 2097152000  # 2 GBytes")
865                 orbdata.append("traceLevel = 0 # critical errors only")
866             else:
867                 orbdata.append("ORBInitRef %s"%(initref))
868                 orbdata.append("ORBgiopMaxMsgSize = 2097152000  # 2 GBytes")
869                 orbdata.append("ORBtraceLevel = 0 # critical errors only")
870                 pass
871             orbdata.append("")
872             f = open(omniorb_config, "w")
873             f.write("\n".join(orbdata))
874             f.close()
875             #
876             os.environ['OMNIORB_CONFIG'] = omniorb_config
877             os.environ['NSPORT'] = "%s"%(NSPORT)
878             os.environ['NSHOST'] = "%s"%(hostname)
879             args['port'] = os.environ['NSPORT']
880             #
881             if save_config:
882                 last_running_config = generateFileName(home, prefix="omniORB",
883                                                        suffix="last",
884                                                        extension="cfg",
885                                                        hidden=True,
886                                                        **kwargs)
887                 try:
888                     if sys.platform == "win32":
889                         import shutil       
890                         shutil.copyfile(omniorb_config, last_running_config)
891                     else:
892                         try:
893                             os.remove(last_running_config)
894                         except OSError:
895                             pass
896                         os.symlink(omniorb_config, last_running_config)
897                         pass
898                     pass
899                 except:
900                     pass
901             break
902         print "%s"%(NSPORT),
903         if NSPORT == limit:
904             msg  = "\n"
905             msg += "Can't find a free port to launch omniNames\n"
906             msg += "Try to kill the running servers and then launch SALOME again.\n"
907             raise RuntimeError, msg
908         NSPORT=NSPORT+1
909         pass
910     return
911     
912 # -----------------------------------------------------------------------------
913
914 def no_main():
915     """Salome Launch, when embedded in other application"""
916     fileEnv = os.environ["SALOME_LAUNCH_CONFIG"]
917     fenv=open(fileEnv,'r')
918     args, modules_list, modules_root_dir = pickle.load(fenv)
919     fenv.close()
920     kill_salome(args)
921     searchFreePort(args, 0)
922     clt = useSalome(args, modules_list, modules_root_dir)
923     return clt
924
925 # -----------------------------------------------------------------------------
926
927 def main():
928     """Salome launch as a main application"""
929     from salome_utils import getHostName
930     print "runSalome running on %s" % getHostName()
931     args, modules_list, modules_root_dir = setenv.get_config()
932     kill_salome(args)
933     save_config = True
934     if args.has_key('save_config'):
935         save_config = args['save_config']
936     # --
937     test = True
938     if args['wake_up_session']:
939         test = False
940         pass
941     if test:
942         searchFreePort(args, save_config)
943         pass
944     # --
945     #setenv.main()
946     setenv.set_env(args, modules_list, modules_root_dir)
947     clt = useSalome(args, modules_list, modules_root_dir)
948     return clt,args
949
950 # -----------------------------------------------------------------------------
951
952 def foreGround(clt, args):
953     # --
954     if "session_object" not in args:
955         return
956     session = args["session_object"]
957     # --
958     # Wait until gui is arrived
959     # tmax = nbtot * dt
960     # --
961     gui_detected = False
962     dt = 0.1
963     nbtot = 100
964     nb = 0
965     while 1:
966         try:
967             status = session.GetStatSession()
968             gui_detected = status.activeGUI
969         except:
970             pass
971         if gui_detected:
972             break
973         from time import sleep
974         sleep(dt)
975         nb += 1
976         if nb == nbtot:
977             break
978         pass
979     # --
980     if not gui_detected:
981         return
982     # --
983     from salome_utils import getPortNumber
984     port = getPortNumber()
985     # --
986     server = Server({})
987     if sys.platform == "win32":
988       server.CMD = [os.getenv("PYTHONBIN"), "-m", "killSalomeWithPort", "--spy", "%s"%(os.getpid()), "%s"%(port)]
989     else:
990       server.CMD = ["killSalomeWithPort.py", "--spy", "%s"%(os.getpid()), "%s"%(port)]
991     server.run()   
992     # os.system("killSalomeWithPort.py --spy %s %s &"%(os.getpid(), port))
993     # --
994     dt = 1.0
995     try:
996         while 1:
997             try:
998                 status = session.GetStatSession()
999                 assert status.activeGUI
1000             except:
1001                 break
1002             from time import sleep
1003             sleep(dt)
1004             pass
1005         pass
1006     except KeyboardInterrupt:
1007         from killSalomeWithPort import killMyPort
1008         killMyPort(port)
1009         pass
1010     return
1011
1012 # -----------------------------------------------------------------------------
1013
1014 if __name__ == "__main__":
1015     import user
1016     clt,args = main()
1017     # --
1018     test = args['gui'] and args['session_gui']
1019     test = test or args['wake_up_session']
1020     # --
1021     # The next test covers the --pinter option or var PYTHONINSPECT setted
1022     # --
1023     test = test and not os.environ.get('PYTHONINSPECT')
1024     # --
1025     # The next test covers the python -i $KERNEL_ROOT_DIR/bin/salome/runSalome.py case
1026     # --
1027     try:
1028         from ctypes import POINTER, c_int, cast, pythonapi
1029         iflag_ptr = cast(pythonapi.Py_InteractiveFlag, POINTER(c_int))
1030         test = test and not iflag_ptr.contents.value
1031     except:
1032         pass
1033     # --
1034     test = test and os.getenv("SALOME_TEST_MODE", "0") != "1"
1035     test = test and args['foreground']
1036     # --
1037     if test:
1038         foreGround(clt, args)
1039         pass
1040     # --
1041     pass