]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/trains/ParUtilities.C
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[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         << "# printenv | sort -u\n"
359         << "echo BUILD.sh@`hostname`: Building " << base << "\n"
360         << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee " 
361         << base << ".log\n"
362         << "echo BUILD.sh@`hostname`: done: $?\n"
363         << std::endl;
364     out.close();
365     if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
366       Error("ParUtilities::MakeScriptBuildScript", 
367             "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
368             dir.Data());
369       return false;
370     }
371     return true;
372   }
373   /** 
374    * Write a build macro 
375    * 
376    * @param dir   Directory to put macro in
377    * @param deps  Dependencies
378    * @param base  Base name of script to compile
379    * @param ext   `extension' - last part of file name 
380    * 
381    * @return true on success
382    */
383   static Bool_t MakeScriptBuildMacro(const TString& dir, 
384                                      const TString& base, 
385                                      const TString& ext,
386                                      const TCollection* deps)  {
387     std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
388     if (!out) {
389       Error("ParUtilities::MakeScriptBuildMacro","Failed to open build script");
390       return false;
391     }
392     out << "void BUILD() {\n"
393         << "  gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
394         << "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
395         << "  LoadROOTLibs();\n"
396         << "  AddAliROOT();\n";
397     if (deps) {
398       TIter       next(deps);
399       TObject*    dep = 0;
400       while ((dep = next())) {
401         out << "  AddDep(\"" << dep->GetName() << "\");\t"
402             << "  LoadDep(\"" << dep->GetName() << "\");\n";
403       }
404     }
405     out << "  // gDebug = 5;\n"
406         << "  // gSystem->ListLibraries();\n"
407         << "  int ret = gROOT->LoadMacro(\"" 
408         << base << "." << ext << "++g\");\n"
409         << "  if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
410         << "  // else Info(\"BUILD\", \"Made " << base << "\");\n"
411         << "}\n"
412         << std::endl;
413     out.close();
414
415     return true;
416   }
417   /** 
418    * Make a utility macro 
419    * 
420    * @param dir Directory to put the macro in
421    * 
422    * @return true on success
423    */
424   static Bool_t MakeScriptUtilityScript(const TString& dir)
425   {
426     std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
427     if (!out) {
428       Error("ParUtilities::MakeScriptUtilityScript", 
429             "Failed to open utility script");
430       return false;
431     }
432     out << "void LoadROOTLibs() {\n"
433         << "  gSystem->Load(\"libVMC\");\n"
434         << "  gSystem->Load(\"libNet\");\n"
435         << "  gSystem->Load(\"libTree\");\n"
436         << "  gSystem->Load(\"libPhysics\");\n"
437         << "  gSystem->Load(\"libMinuit\");\n"
438         << "}\n\n"
439         << "void AddAliROOT() {\n"
440         << "  TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
441         << "  if (val.IsNull())\n"
442         << "    Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
443         << "  else\n"
444         << "    gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
445         << "}\n\n"
446         << "void AddDep(const char* env) {\n"
447         << "  TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
448         << "  if (val.IsNull())\n"
449         << "    Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
450         << "  else {\n"
451         << "    // gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
452         << "    // Prepend to include path\n"
453         << "    TString incPath(gSystem->GetIncludePath());\n"
454         << "    incPath.Prepend(Form(\"-I../%s \",val.Data()));\n"
455         << "    gSystem->SetIncludePath(incPath);\n"
456         << "    // Printf(\"Include path: %s\",incPath.Data());\n"
457         << "  }\n"
458         << "}\n\n"
459         << "void LoadDep(const char* name) {\n"
460         << "  // Printf(\"Loading dependency \\\"%s\\\" ...\",name);\n"
461         << "  // gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
462         << "  // Prepend to dynamic path\n"
463         << "  TString dynPath(gSystem->GetDynamicPath());\n"
464         << "  dynPath.Prepend(Form(\"../%s:\",name));\n"
465         << "  gSystem->SetDynamicPath(dynPath);\n"
466         << "  // Printf(\"Dynamic path: %s\",dynPath.Data());\n"
467         << "  char* full = gSystem->DynamicPathName(name,true);\n"
468         << "  if (!full) \n"
469         << "   full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
470         << "  if (!full) \n"
471         << "   full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
472         << "  if (!full) \n"
473         << "   full = gSystem->DynamicPathName(Form(\"%s_C.so\",name),true);\n"
474         << "  if (!full) \n"
475         << "   full = gSystem->DynamicPathName(Form(\"%s_h.so\",name),true);\n"
476         << "  if (!full) {\n"
477         << "    Warning(\"LoadDep\",\"Module %s not found\", name);\n"
478         << "    return;\n"
479         << "  }\n"
480         << "  Printf(\"Loading \\\"%s\\\" for \\\"%s\\\"\",full,name);\n"
481         << "  gSystem->Load(full);\n"
482         << "}\n"
483         << std::endl;
484     out.close();
485     return true;
486   }
487   /** 
488    * Make a setup script 
489    * 
490    * @param dir   Directory to put it in 
491    * @param base  Base name of target script 
492    * @param ext   Extension of target script 
493    * @param deps  Dependencies 
494    * 
495    * @return true on success
496    */
497   static Bool_t MakeScriptSetupMacro(const TString& dir, 
498                                      const TString& base, 
499                                      const TString& ext,
500                                      const TCollection* deps)
501   {
502     // Make our set-up script 
503     std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
504     if (!out) {
505       Error("ParUtilities::MakeScriptSetupMacro", 
506             "Failed to open setup script");
507       return false;
508     }
509     out << "void SETUP() {\n"
510         << "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
511         << "  Printf(\"Loading \\\"" << base << "\\\" ...\");\n"
512         << "  LoadROOTLibs();\n"
513         << "  // Info(\"SETUP\",\"Loading libraries\");\n";
514     if (deps) {
515       TIter next(deps);
516       TObject* dep = 0;
517       while ((dep = next())) 
518         out << "  LoadDep(\"" << dep->GetName() << "\");\n";
519     }
520     out << "  // gDebug = 5;\n"
521         << "  // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
522         << "  gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
523         << "  // gDebug = 0;\n"
524         << "  gROOT->ProcessLine(\".include " << base << "\");\n"
525         << "  gSystem->Setenv(\"" << base << "_INCLUDE\",\"" 
526         << base << "\");\n"
527         << "  // Info(\"SETUP\", \"Done\");\n"
528         << "}\n"
529         << std::endl;
530     out.close();
531     return true;
532   }
533   /* @} */
534   //__________________________________________________________________
535   /** 
536    * @{ 
537    * @name PAR generation from aux file list
538    */
539   static Bool_t MakeAuxFilePAR(const TList& files, 
540                                const TString& name,
541                                Bool_t verbose=false)
542   {
543     // --- Check input -----------------------------------------------
544     if (files.GetEntries() <= 0) return true;
545
546     // --- Create our temporary directory ----------------------------
547     Bool_t  retval = true;
548     TString tmpdir(gSystem->TempDirectory());
549     int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
550     char*   templ  = new char[ltempl];
551     snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
552     if (!mkdtemp(templ)) {
553       Error("ParUtilities::MakeAuxFilePAR", 
554             "Failed to generate temporary directory from template %s", 
555             templ);
556       return false;
557     }
558     if (verbose) Printf("Preparing PAR file in %s", templ);
559     
560     try {
561       // --- Make directories for package ------------------------------
562       TString dir = TString::Format("%s/%s", templ, name.Data());
563       // Set-up directories 
564       if (gSystem->MakeDirectory(dir) < 0) 
565         throw TString::Format("Could not make directory '%s'", name.Data());
566       if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
567         throw TString::Format("Could not make directory %s/PROOF-INF", 
568                               name.Data());
569
570       TIter next(&files);
571       TObject* o = 0;
572       while ((o = next())) { 
573         TString fn(o->GetName());
574         if (verbose) Printf("Got %s", fn.Data());
575         if (fn.BeginsWith("/")) {
576           Warning("MakeAuxFilePAR", "Will not include absolute path %s",
577                   fn.Data());
578           continue; // absolute path 
579         }
580         
581         if (gSystem->AccessPathName(fn.Data())) {
582           Warning("MakeAuxFilePAR", "Cannot access %s", fn.Data());
583           continue; // non-exist
584         }
585         // Loop over path components and make directories as needed 
586         TObjArray*  comps = fn.Tokenize("/");
587         TString     cur   = dir;
588         Int_t       n     = comps->GetEntriesFast();
589         if (verbose) Printf("Got %d path components in %s", n-1, fn.Data());
590         Int_t       lvl   = 0;
591         for (Int_t i = 0; i < n-1; i++) {
592           TObjString* comp = static_cast<TObjString*>(comps->At(i));
593           TString&    c    = comp->String();
594           if (c.IsNull()) continue;
595           if (c.EqualTo(".")) continue;
596           
597           Bool_t doMake = true;
598           if (c.EqualTo("..")) { doMake = false; lvl--; }
599           
600           cur = gSystem->ConcatFileName(cur, c);
601           if (lvl < 0) {
602             Warning("MakeAuxFilePAR", "Path %s points outside archive, ignored",
603                     cur.Data());
604             break;
605           }
606
607           if (doMake) { 
608             lvl++;
609             if (!gSystem->AccessPathName(cur)) continue;
610             if (verbose) Printf("Making directory %s", cur.Data());
611             gSystem->MakeDirectory(cur);
612           }
613         } // for(i)
614         if (verbose) Printf("cur=%s for %s lvl=%d", cur.Data(), fn.Data(), lvl);
615         comps->Delete();
616         if (lvl < 0) continue;
617
618         TString dest = TString::Format("%s/%s", cur.Data(), 
619                                        gSystem->BaseName(fn.Data()));
620         if (verbose) Printf("%s -> %s", fn.Data(), dest.Data());
621         Int_t ret = gSystem->CopyFile(fn, dest, true);
622         switch (ret) { 
623         case -1: throw TString::Format("Couldn't open %s for copy", fn.Data());
624         case -2: throw TString::Format("File %s exists", dest.Data());
625         case -3: throw TString::Format("Error while copying %s", fn.Data());
626         }
627       }
628
629       {
630         // Make our build file 
631         if (verbose) Printf("Making build script");
632         std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
633         if (!out) {
634           Error("ParUtilities::MakeAuxFilePAR", 
635                 "Failed to open out shell script");
636           return false;
637         }
638         out << "#!/bin/sh\n\n"
639             << "echo \"Nothing to be done\"\n\n"
640             << "# EOF" << std::endl;
641         out.close();
642         if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755)) {
643           Error("ParUtilities::MakeAuxFilePAR", 
644                 "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
645                 dir.Data());
646           return false;
647         }
648       }
649       {
650         if (verbose) Printf("Making setup script");
651         // Make our setup file 
652         std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
653         if (!out) {
654           Error("ParUtilities::MakeAuxFilePAR", 
655                 "Failed to open out ROOT script");
656           return false;
657         }
658         // The SETUP script is executed in the package's directory in
659         // the package cache - not in the session directory.  Hence,
660         // we take special care to get a link to the session directory
661         // from the package cache directory
662         out << "void SETUP()\n"
663             << "{\n"
664             << "  TString oldDir(gSystem->WorkingDirectory());\n"
665             << "  TSystemDirectory* dir = new TSystemDirectory(\".\",\".\");\n"
666             << "  TList*  files = dir->GetListOfFiles();\n"
667             << "  if (!gSystem->ChangeDirectory(oldDir)) {\n"
668             << "    Error(\"SETUP\", \"Failed to go back to %s\",\n"
669             << "          oldDir.Data());\n"
670             << "    return;\n"
671             << "  }\n"
672             << "  if (!files) {\n"
673             << "    Warning(\"SETUP\", \"No files\");\n"
674             << "    gSystem->Exec(\"pwd; ls -al\");\n"
675             << "    return;\n"
676             << "  }\n"
677             << "  files->Sort();\n"
678             << "  TString pkgDir = gSystem->WorkingDirectory();\n"
679             << "  TString sesDir = gProofServ->GetSessionDir();\n"
680             << "  Info(\"\",\"Session dir: %s\",sesDir);\n"
681             << "  TIter next(files);\n"
682             << "  TSystemFile* file = 0;\n"
683             << "  while ((file = static_cast<TSystemFile*>(next()))) {\n"
684             << "    TString name(file->GetName());\n"
685             << "    if (name == \".\" || name == \"..\") continue;\n"
686             << "    TString title(file->GetTitle());\n"
687             << "    TString full(gSystem->ConcatFileName(pkgDir.Data(),\n"
688             << "                                         name.Data()));\n"
689             << "    TString tgt(gSystem->ConcatFileName(sesDir.Data(),\n"
690             << "                                        name.Data()));\n"
691             << "    if (file->IsA()->InheritsFrom(TSystemDirectory::Class())){\n"
692             << "      gSystem->mkdir(tgt.Data(), true);\n"
693             << "      continue;\n"
694             << "    }\n"
695             << "    Info(\"\",\"Linking %s to %s\",full.Data(),tgt.Data());\n"
696             << "    gSystem->Symlink(full, tgt);\n"
697             << "  }\n"
698             << "}\n"
699             << "// EOF " << std::endl;
700         out.close();
701       }
702       if (verbose) Printf("Packing up");
703       Int_t ret = 0;
704       ret = gSystem->Exec(Form("(cd %s && tar -c%szf %s.par %s)", 
705                                templ, (verbose ? "v" : ""), 
706                                name.Data(),name.Data()));
707       if (ret != 0) 
708         throw TString::Format("Failed to create PAR file %s.PAR from %s", 
709                               name.Data(), name.Data());
710
711       // --- Move PAR file to here -------------------------------------
712       if (verbose) Printf("Move here");
713       ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, name.Data(), 
714                                name.Data()));
715       if (ret != 0) 
716         throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
717                               templ, name.Data(), name.Data(), 
718                               gSystem->GetError());
719
720
721       if (verbose) {
722         Printf("List content");
723         gSystem->Exec(Form("tar tzf %s.par", name.Data()));
724       }
725       retval = true;
726     }
727     catch (TString& e) {
728       Error("ParUtilities::MakeAuxFilePAR", "%s", e.Data());
729       retval = false;
730     }
731     
732     // --- Remove temporary directory --------------------------------
733     gSystem->Exec(Form("rm -rf %s", templ));
734     
735     return retval;
736   }
737 };
738 #endif
739 // 
740 // EOF
741 //