]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/trains/ParUtilities.C
Fixed wrong filename when finding PAR file
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / trains / ParUtilities.C
1 /**
2  * @file   ParUtilities.C
3  * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4  * @date   Tue Oct 16 17:51:10 2012
5  * 
6  * @brief  PAR file utilities 
7  * 
8  * @ingroup pwglf_forward_trains_util
9  * 
10  */
11 #ifndef PARHELPER_C
12 #define PARHELPER_C
13 #ifndef __CINT__
14 # include <TString.h>
15 # include <TProof.h>
16 # include <TSystem.h>
17 # include <TError.h>
18 # include <TFile.h>
19 # include <TSystem.h>
20 # include <TROOT.h>
21 # include <fstream>
22 # include <cstdlib>
23 # include "Helper.C"
24 #else
25 class TString;
26 class Helper;
27 #endif
28
29 // ===================================================================
30 /**
31  * Helper to set-up and load PARs
32  *
33  * @ingroup pwglf_forward_trains_util
34  */
35 struct ParUtilities
36 {
37   /** 
38    * Find PAR file (either in current or parent directory or directly 
39    * in $ALICE_ROOT), and link it here
40    * 
41    * @param what PAR file name (sans .par)
42    * 
43    * @return true on success
44    */
45   static Bool_t Find(const TString& what)
46   {
47     if (what.IsNull()) return false;
48     
49     TString parFile(what);
50     if (!parFile.EndsWith(".par")) parFile.Append(".par");
51     if (gSystem->AccessPathName(parFile.Data())) { 
52       // If not found
53       TString src;
54       if (gSystem->AccessPathName(Form("../%s", parFile.Data())) == 0) 
55         src.Form("../%s", parFile.Data());
56       else {
57         // If not found 
58         TString aliParFile = 
59           gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
60         if (gSystem->AccessPathName(aliParFile.Data()) == 0) 
61           src = aliParFile;
62       }
63       if (src.IsNull()) {
64         Error("ParUtilities::Find", 
65               "PAR file %s not found in current or parent "
66               "directory nor in $(ALICE_ROOT)", parFile.Data());
67         return false;
68       }
69       // Copy to current directory 
70       // TFile::Copy(aliParFile, parFile);
71       Info("", "Found PAR %s at %s", what.Data(), src.Data());
72       if (gSystem->Exec(Form("ln -s %s %s", src.Data(), parFile.Data())) != 0){
73         Error("ParUtilities::Find", "Failed to symlink %s to %s", 
74               src.Data(), parFile.Data());
75         return false;
76       }
77     }
78     return true;
79   }
80   /** 
81    * Unpack and load a PAR file previously found with Find.
82    * 
83    * @param name PAR file name 
84    * @deprecated Use Find  and Build instead
85    * @return true on success
86    */
87   static Bool_t Load(const TString& name) 
88   {
89     if (name.IsNull()) return true;
90     if (!gProof) { 
91       Error("ParUtilities::Load", "No connection to a Proof cluster");
92       return false;
93     }
94
95     // Load par library 
96     TString fn(name);
97     Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data());
98     
99     // First check in current directory
100     Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld);
101     
102     if (ret < 0)  {
103       // IF not found there, then check parent directory 
104       fn.Prepend("../");
105       gSystem->ExpandPathName(fn);
106       ret = gProof->UploadPackage(fn);
107     }
108
109     if (ret < 0) {      
110       // If not found in current or parent directory, try the 
111       // the ALICE_ROOT directory 
112       fn  = Form("$ALICE_ROOT/%s.par", name.Data());
113       gSystem->ExpandPathName(fn);
114       ret = gProof->UploadPackage(fn);
115     }
116     
117     if (ret < 0) {
118       // IF not found, bark 
119       Error("ParUtilities::Load", 
120             "Could not find module %s.par in current or parent directory "
121             "nor in $ALICE_ROOT", name.Data());
122       return false;
123     }
124     
125     ret = gProof->EnablePackage(name);
126     Info("ParUtilities::Load", "Enabled package %s (from %s)", 
127          name.Data(), fn.Data());
128     
129     return true;
130   }
131   /** 
132    * Unpack, build, and load a PAR file. 
133    * 
134    * @param what Which PAR file 
135    * 
136    * @return 
137    */
138   static Bool_t Build(const TString& what)
139   {
140     if (what.IsNull()) return false;
141     
142     TString parFile(what);
143     if (!parFile.EndsWith(".par")) parFile.Append(".par");
144
145     // Extract archive 
146     gSystem->Exec(Form("tar xzf %s", parFile.Data()));
147     
148     // Change directory into par archive
149     TString cwd = gSystem->WorkingDirectory();
150     
151     TString dir(what);
152     if (dir.EndsWith(".par")) dir.ReplaceAll(".par", "");
153     if (!gSystem->ChangeDirectory(dir)) { 
154       Error("ParUtilities::Setup", "Failed to change directory to %s", 
155             dir.Data());
156       return false;
157     }
158     
159     // Test the build 
160     if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
161       Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data());
162       if (gSystem->Exec("PROOF-INF/BUILD.sh")) { 
163         Error("ParUtilities::Setup", "Failed to build in PAR directory %s", 
164               dir.Data());
165         gSystem->ChangeDirectory(cwd.Data());
166         return false;
167       }
168     }
169
170     // We need to make sure the current directory is in the load path 
171     gSystem->SetDynamicPath(Form("%s:%s", gSystem->WorkingDirectory(), 
172                                  gSystem->GetDynamicPath()));
173     // Check for setup script
174     if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
175       // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what);
176       gROOT->Macro("PROOF-INF/SETUP.C");
177     }
178     if (!gSystem->ChangeDirectory(cwd.Data())) return false;
179
180     return true;
181   }
182   //__________________________________________________________________
183   /** 
184    * @{ 
185    * @name PAR generation from script 
186    */
187   /** 
188    * Service function to make a PAR out of a script.  
189    * 
190    * The script should contain can contain a sub-class of AliAnalysisTask. 
191    * The script will be compiled on the slaves before loading the 
192    * AliAnalysisManager.  Parts to (not) be compiled can be protected like 
193    * 
194    * @code 
195    * #ifdef BUILD_PAR
196    * // This will _only_ be compiled in the servers 
197    * #endif
198    * #ifndef BUILD_PAR
199    * // This will not be compiled in the servers 
200    * #endif
201    * @endcode
202    * 
203    * @param script  Script to upload and compile in the PAR
204    * @param deps    Dependency pars 
205    * @param isLocal Local build 
206    * @param helper  Helper 
207    * 
208    * @return true on success. 
209    */
210   static Bool_t MakeScriptPAR(Bool_t         isLocal, 
211                               const TString& script, 
212                               const TString& deps, 
213                               Helper*        helper)
214   {
215     TObjArray* depList = deps.Tokenize(", ");
216     
217     // --- In local mode, just AcLic and load ------------------------
218     if (isLocal) { 
219       // Load dependencies 
220       TIter       next(depList);
221       TObject*    dep = 0;
222       while ((dep = next())) 
223         helper->LoadLibrary(dep->GetName());
224       
225       // AcLic and load 
226       Info("ParUtilities::MakeScriptPAR", "Loading macro %s", script.Data());
227       if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0) {
228         Error("ParUtilities::MakeScriptPAR", 
229               "Failed to build local library %s", script.Data());
230         return false;
231       }
232       return true;
233     }
234
235     // --- Get the base name -----------------------------------------
236     Info("ParUtilities::MakeScriptPAR", "Making par file for %s", 
237          script.Data());
238     TString base(gSystem->BaseName(script));
239     Int_t   idx = base.Last('.');
240     if (idx != kNPOS) base.Remove(idx);
241
242     // --- Check name of script file ---------------------------------
243     TString scr(script);
244     TString ext;
245     if      (script.EndsWith(".C"))   ext = "C"; 
246     else if (script.EndsWith(".cxx")) ext = "cxx";
247     else                              { ext = "C"; scr.Append(".C"); }
248     
249     // --- Check if we can access the file ---------------------------
250     TString path = TString::Format(".:%s", TROOT::GetMacroPath());
251     char*   loc  = gSystem->Which(path, scr);
252     if (!loc) {
253       Error("ParUtilities::MakeScriptPAR", 
254             "Script %s not found in %s", scr.Data(), path.Data());
255       return false;
256     }
257     TString full(loc);
258
259     // --- Create our temporary directory ----------------------------
260     TString tmpdir(gSystem->TempDirectory());
261     int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
262     char*   templ  = new char[ltempl];
263     snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
264     if (!mkdtemp(templ)) {
265       Error("ParUtilities::MakeScriptPAR", 
266             "Failed to generate temporary directory from template %s", 
267             templ);
268       return false;
269     }
270     Info("", "Building PAR in %s", templ);
271
272     Bool_t retVal = false;
273     try {
274       // --- Make directories for package ------------------------------
275       TString dir = TString::Format("%s/%s", templ, base.Data());
276       // Set-up directories 
277       if (gSystem->MakeDirectory(dir) < 0) 
278         throw TString::Format("Could not make directory '%s'", base.Data());
279       if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
280         throw TString::Format("Could not make directory %s/PROOF-INF", 
281                               base.Data());
282       Info("", "Made directory %s", dir.Data());
283
284       // --- Copy the script to the setup directory --------------------
285       TString dest = TString::Format("%s/%s.%s", dir.Data(),
286                                      base.Data(), ext.Data());
287       Int_t ret = gSystem->CopyFile(full, dest, true);
288       switch (ret) { 
289       case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
290       case -2: throw TString::Format("File %s exists", dest.Data());
291       case -3: throw TString::Format("Error while copying %s", scr.Data());
292       }
293       
294       // --- Make scripts, etc. ----------------------------------------
295       if (!MakeScriptBuildScript(dir, base)) 
296         throw TString::Format("Failed to make build script");
297       if (!MakeScriptUtilityScript(dir)) 
298         throw TString::Format("Failed to make utility script");
299       if (!MakeScriptBuildMacro(dir, base, ext, depList)) 
300         throw TString::Format("Failed to make build macro");
301       if (!MakeScriptSetupMacro(dir, base, ext, depList)) 
302         throw TString::Format("Failed to setup macro");
303
304       // --- Pack up the archive ---------------------------------------
305       ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)", 
306                                templ, base.Data(),base.Data()));
307       if (ret != 0) 
308         throw TString::Format("Failed to create PAR file %s.PAR from %s", 
309                               base.Data(), dir.Data());
310       
311       Info("", "Made par archive %s/%s.par - moving here", 
312            templ, base.Data());
313       // --- Move PAR file to here -------------------------------------
314       ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(), 
315                                base.Data()));
316       if (ret != 0) 
317         throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
318                               templ, base.Data(), base.Data(), 
319                               gSystem->GetError());
320       retVal = true;
321     }
322     catch (TString& e) {
323       Error("ParUtilities::MakeScriptPAR", "%s", e.Data());
324       retVal = false;
325     }
326     
327     // --- Remove temporary directory --------------------------------
328     gSystem->Exec(Form("rm -rf %s", templ));
329
330     return retVal;
331   }
332   /** 
333    * Write a build script
334    * 
335    * @param dir Directory to put it in
336    * @param base Base name 
337    * 
338    * @return true on success
339    */
340   static Bool_t MakeScriptBuildScript(const TString& dir, 
341                                       const TString& base)
342   {
343     // Make our build file 
344     std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
345     if (!out) {
346       Error("ParUtilities::MakeScriptBuildScript", 
347             "Failed to open out shell script");
348       return false;
349     }
350     out << "#!/bin/sh\n"
351         << "if test x$ALICE_ROOT != x ; then\n"
352         << "  if test x$ALICE_TARGET = x ; then\n"
353         << "    export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n"
354         << "  fi\n"
355         << "  export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"
356         << "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n"
357         << "fi\n"
358         << "echo BUILD.sh@`hostname`: Building " << base << "\n"
359         << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee " 
360         << base << ".log\n"
361         << "echo BUILD.sh@`hostname`: done: $?\n"
362         << std::endl;
363     out.close();
364     if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
365       Error("ParUtilities::MakeScriptBuildScript", 
366             "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
367             dir.Data());
368       return false;
369     }
370     return true;
371   }
372   /** 
373    * Write a build macro 
374    * 
375    * @param dir   Directory to put macro in
376    * @param deps  Dependencies
377    * @param base  Base name of script to compile
378    * @param ext   `extension' - last part of file name 
379    * 
380    * @return true on success
381    */
382   static Bool_t MakeScriptBuildMacro(const TString& dir, 
383                                      const TString& base, 
384                                      const TString& ext,
385                                      const TCollection* deps)  {
386     std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
387     if (!out) {
388       Error("ParUtilities::MakeScriptBuildMacro","Failed to open build script");
389       return false;
390     }
391     out << "void BUILD() {\n"
392         << "  gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
393         << "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
394         << "  LoadROOTLibs();\n"
395         << "  AddAliROOT();\n";
396     if (deps) {
397       TIter       next(deps);
398       TObject*    dep = 0;
399       while ((dep = next())) {
400         out << "  AddDep(\"" << dep->GetName() << "\");\t"
401             << "  LoadDep(\"" << dep->GetName() << "\");\n";
402       }
403     }
404     out << "  // gDebug = 5;\n"
405         << "  int ret = gROOT->LoadMacro(\"" 
406         << base << "." << ext << "++g\");\n"
407         << "  if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
408         << "  // else Info(\"BUILD\", \"Made " << base << "\");\n"
409         << "}\n"
410         << std::endl;
411     out.close();
412
413     return true;
414   }
415   /** 
416    * Make a utility macro 
417    * 
418    * @param dir Directory to put the macro in
419    * 
420    * @return true on success
421    */
422   static Bool_t MakeScriptUtilityScript(const TString& dir)
423   {
424     std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
425     if (!out) {
426       Error("ParUtilities::MakeScriptUtilityScript", 
427             "Failed to open utility script");
428       return false;
429     }
430     out << "void LoadROOTLibs() {\n"
431         << "  gSystem->Load(\"libVMC\");\n"
432         << "  gSystem->Load(\"libNet\");\n"
433         << "  gSystem->Load(\"libTree\");\n"
434         << "  gSystem->Load(\"libPhysics\");\n"
435         << "  gSystem->Load(\"libMinuit\");\n"
436         << "}\n\n"
437         << "void AddAliROOT() {\n"
438         << "  TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
439         << "  if (val.IsNull())\n"
440         << "    Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
441         << "  else\n"
442         << "    gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
443         << "}\n\n"
444         << "void AddDep(const char* env) {\n"
445         << "  TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
446         << "  if (val.IsNull())\n"
447         << "    Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
448         << "  else {\n"
449         << "    gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
450         << "  }\n"
451         << "}\n\n"
452         << "void LoadDep(const char* name) {\n"
453         << "  gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
454         << "  char* full = gSystem->DynamicPathName(name,true);\n"
455         << "  if (!full) \n"
456         << "   full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
457         << "  if (!full) \n"
458         << "   full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
459         << "  if (!full) {\n"
460         << "    Warning(\"LoadDep\",\"Module %s not found\", name);\n"
461         << "    return;\n"
462         << "  }\n"
463         << "  gSystem->Load(full);\n"
464         << "}\n"
465         << std::endl;
466     out.close();
467     return true;
468   }
469   /** 
470    * Make a setup script 
471    * 
472    * @param dir   Directory to put it in 
473    * @param base  Base name of target script 
474    * @param ext   Extension of target script 
475    * @param deps  Dependencies 
476    * 
477    * @return true on success
478    */
479   static Bool_t MakeScriptSetupMacro(const TString& dir, 
480                                      const TString& base, 
481                                      const TString& ext,
482                                      const TCollection* deps)
483   {
484     // Make our set-up script 
485     std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
486     if (!out) {
487       Error("ParUtilities::MakeScriptSetupMacro", 
488             "Failed to open setup script");
489       return false;
490     }
491     out << "void SETUP() {\n"
492         << "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
493         << "  LoadROOTLibs();\n"
494         << "  // Info(\"SETUP\",\"Loading libraries\");\n";
495     if (deps) {
496       TIter next(deps);
497       TObject* dep = 0;
498       while ((dep = next())) 
499         out << "  LoadDep(\"" << dep->GetName() << "\");\n";
500     }
501     out << "  // gDebug = 5;\n"
502         << "  // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
503         << "  gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
504         << "  // gDebug = 0;\n"
505         << "  gROOT->ProcessLine(\".include " << base << "\");\n"
506         << "  gSystem->Setenv(\"" << base << "_INCLUDE\",\"" 
507         << base << "\");\n"
508         << "  // Info(\"SETUP\", \"Done\");\n"
509         << "}\n"
510         << std::endl;
511     out.close();
512     return true;
513   }
514   /* @} */
515   //__________________________________________________________________
516   /** 
517    * @{ 
518    * @name PAR generation from aux file list
519    */
520   static Bool_t MakeAuxFilePAR(const TList& files, 
521                                const TString& name,
522                                Bool_t verbose=false)
523   {
524     // --- Check input -----------------------------------------------
525     if (files.GetEntries() <= 0) return true;
526
527     // --- Create our temporary directory ----------------------------
528     Bool_t  retval = true;
529     TString tmpdir(gSystem->TempDirectory());
530     int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
531     char*   templ  = new char[ltempl];
532     snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
533     if (!mkdtemp(templ)) {
534       Error("ParUtilities::MakeAuxFilePAR", 
535             "Failed to generate temporary directory from template %s", 
536             templ);
537       return false;
538     }
539     if (verbose) Printf("Preparing PAR file in %s", templ);
540     
541     try {
542       // --- Make directories for package ------------------------------
543       TString dir = TString::Format("%s/%s", templ, name.Data());
544       // Set-up directories 
545       if (gSystem->MakeDirectory(dir) < 0) 
546         throw TString::Format("Could not make directory '%s'", name.Data());
547       if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
548         throw TString::Format("Could not make directory %s/PROOF-INF", 
549                               name.Data());
550
551       TIter next(&files);
552       TObject* o = 0;
553       while ((o = next())) { 
554         TString fn(o->GetName());
555         if (verbose) Printf("Got %s", fn.Data());
556         if (fn.BeginsWith("/")) {
557           Warning("MakeAuxFilePAR", "Will not include absolute path %s",
558                   fn.Data());
559           continue; // absolute path 
560         }
561         
562         if (gSystem->AccessPathName(fn.Data())) {
563           Warning("MakeAuxFilePAR", "Cannot access %s", fn.Data());
564           continue; // non-exist
565         }
566         // Loop over path components and make directories as needed 
567         TObjArray*  comps = fn.Tokenize("/");
568         TString     cur   = dir;
569         Int_t       n     = comps->GetEntriesFast();
570         if (verbose) Printf("Got %d path components in %s", n-1, fn.Data());
571         Int_t       lvl   = 0;
572         for (Int_t i = 0; i < n-1; i++) {
573           TObjString* comp = static_cast<TObjString*>(comps->At(i));
574           TString&    c    = comp->String();
575           if (c.IsNull()) continue;
576           if (c.EqualTo(".")) continue;
577           
578           Bool_t doMake = true;
579           if (c.EqualTo("..")) { doMake = false; lvl--; }
580           
581           cur = gSystem->ConcatFileName(cur, c);
582           if (lvl < 0) {
583             Warning("MakeAuxFilePAR", "Path %s points outside archive, ignored",
584                     cur.Data());
585             break;
586           }
587
588           if (doMake) { 
589             lvl++;
590             if (!gSystem->AccessPathName(cur)) continue;
591             if (verbose) Printf("Making directory %s", cur.Data());
592             gSystem->MakeDirectory(cur);
593           }
594         } // for(i)
595         if (verbose) Printf("cur=%s for %s lvl=%d", cur.Data(), fn.Data(), lvl);
596         comps->Delete();
597         if (lvl < 0) continue;
598
599         TString dest = TString::Format("%s/%s", cur.Data(), 
600                                        gSystem->BaseName(fn.Data()));
601         if (verbose) Printf("%s -> %s", fn.Data(), dest.Data());
602         Int_t ret = gSystem->CopyFile(fn, dest, true);
603         switch (ret) { 
604         case -1: throw TString::Format("Couldn't open %s for copy", fn.Data());
605         case -2: throw TString::Format("File %s exists", dest.Data());
606         case -3: throw TString::Format("Error while copying %s", fn.Data());
607         }
608       }
609
610       {
611         // Make our build file 
612         if (verbose) Printf("Making build script");
613         std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
614         if (!out) {
615           Error("ParUtilities::MakeAuxFilePAR", 
616                 "Failed to open out shell script");
617           return false;
618         }
619         out << "#!/bin/sh\n\n"
620             << "echo \"Nothing to be done\"\n\n"
621             << "# EOF" << std::endl;
622         out.close();
623         if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755)) {
624           Error("ParUtilities::MakeAuxFilePAR", 
625                 "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
626                 dir.Data());
627           return false;
628         }
629       }
630       {
631         if (verbose) Printf("Making setup script");
632         // Make our setup file 
633         std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
634         if (!out) {
635           Error("ParUtilities::MakeAuxFilePAR", 
636                 "Failed to open out ROOT script");
637           return false;
638         }
639         // The SETUP script is executed in the package's directory in
640         // the package cache - not in the session directory.  Hence,
641         // we take special care to get a link to the session directory
642         // from the package cache directory
643         out << "void SETUP()\n"
644             << "{\n"
645             << "  TString oldDir(gSystem->WorkingDirectory());\n"
646             << "  TSystemDirectory* dir = new TSystemDirectory(\".\",\".\");\n"
647             << "  TList*  files = dir->GetListOfFiles();\n"
648             << "  if (!gSystem->ChangeDirectory(oldDir)) {\n"
649             << "    Error(\"SETUP\", \"Failed to go back to %s\",\n"
650             << "          oldDir.Data());\n"
651             << "    return;\n"
652             << "  }\n"
653             << "  if (!files) {\n"
654             << "    Warning(\"SETUP\", \"No files\");\n"
655             << "    gSystem->Exec(\"pwd; ls -al\");\n"
656             << "    return;\n"
657             << "  }\n"
658             << "  files->Sort();\n"
659             << "  TString pkgDir = gSystem->WorkingDirectory();\n"
660             << "  TString sesDir = gProofServ->GetSessionDir();\n"
661             << "  Info(\"\",\"Session dir: %s\",sesDir);\n"
662             << "  TIter next(files);\n"
663             << "  TSystemFile* file = 0;\n"
664             << "  while ((file = static_cast<TSystemFile*>(next()))) {\n"
665             << "    TString name(file->GetName());\n"
666             << "    if (name == \".\" || name == \"..\") continue;\n"
667             << "    TString title(file->GetTitle());\n"
668             << "    TString full(gSystem->ConcatFileName(pkgDir.Data(),\n"
669             << "                                         name.Data()));\n"
670             << "    TString tgt(gSystem->ConcatFileName(sesDir.Data(),\n"
671             << "                                        name.Data()));\n"
672             << "    if (file->IsA()->InheritsFrom(TSystemDirectory::Class())){\n"
673             << "      gSystem->mkdir(tgt.Data(), true);\n"
674             << "      continue;\n"
675             << "    }\n"
676             << "    Info(\"\",\"Linking %s to %s\",full.Data(),tgt.Data());\n"
677             << "    gSystem->Symlink(full, tgt);\n"
678             << "  }\n"
679             << "}\n"
680             << "// EOF " << std::endl;
681         out.close();
682       }
683       if (verbose) Printf("Packing up");
684       Int_t ret = 0;
685       ret = gSystem->Exec(Form("(cd %s && tar -c%szf %s.par %s)", 
686                                templ, (verbose ? "v" : ""), 
687                                name.Data(),name.Data()));
688       if (ret != 0) 
689         throw TString::Format("Failed to create PAR file %s.PAR from %s", 
690                               name.Data(), name.Data());
691
692       // --- Move PAR file to here -------------------------------------
693       if (verbose) Printf("Move here");
694       ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, name.Data(), 
695                                name.Data()));
696       if (ret != 0) 
697         throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
698                               templ, name.Data(), name.Data(), 
699                               gSystem->GetError());
700
701
702       if (verbose) {
703         Printf("List content");
704         gSystem->Exec(Form("tar tzf %s.par", name.Data()));
705       }
706       retval = true;
707     }
708     catch (TString& e) {
709       Error("ParUtilities::MakeAuxFilePAR", "%s", e.Data());
710       retval = false;
711     }
712     
713     // --- Remove temporary directory --------------------------------
714     gSystem->Exec(Form("rm -rf %s", templ));
715     
716     return retval;
717   }
718 };
719 #endif
720 // 
721 // EOF
722 //