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