ROOT logo
/**
 * @file   ParUtilities.C
 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
 * @date   Tue Oct 16 17:51:10 2012
 * 
 * @brief  PAR file utilities 
 * 
 * @ingroup pwglf_forward_trains_util
 * 
 */
#ifndef PARHELPER_C
#define PARHELPER_C
#ifndef __CINT__
# include <TString.h>
# include <TProof.h>
# include <TSystem.h>
# include <TError.h>
# include <TFile.h>
# include <TSystem.h>
# include <TROOT.h>
# include <fstream>
# include <cstdlib>
# include "Railway.C"
#else
class TString;
class Railway;
#endif

// ===================================================================
/**
 * Railway to set-up and load PARs
 *
 * @ingroup pwglf_forward_trains_util
 */
struct ParUtilities
{
  /** 
   * Find PAR file (either in current or parent directory or directly 
   * in $ALICE_ROOT), and link it here
   * 
   * @param what PAR file name (sans .par)
   * 
   * @return true on success
   */
  static Bool_t Find(const TString& what)
  {
    if (what.IsNull()) return false;
    
    TString parFile(what);
    if (!parFile.EndsWith(".par")) parFile.Append(".par");
    if (gSystem->AccessPathName(parFile.Data())) { 
      // If not found
      TString src;
      if (gSystem->AccessPathName(Form("../%s", parFile.Data())) == 0) 
	src.Form("../%s", parFile.Data());
      else {
	// If not found 
	TString aliParFile = 
	  gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
	if (gSystem->AccessPathName(aliParFile.Data()) == 0) 
	  src = aliParFile;
      }
      if (src.IsNull()) {
	Error("ParUtilities::Find", 
	      "PAR file %s not found in current or parent "
	      "directory nor in $(ALICE_ROOT)", parFile.Data());
	return false;
      }
      // Copy to current directory 
      // TFile::Copy(aliParFile, parFile);
      Info("", "Found PAR %s at %s", what.Data(), src.Data());
      if (gSystem->Exec(Form("ln -s %s %s", src.Data(), parFile.Data())) != 0){
	Error("ParUtilities::Find", "Failed to symlink %s to %s", 
	      src.Data(), parFile.Data());
	return false;
      }
    }
    return true;
  }
  /** 
   * Unpack and load a PAR file previously found with Find.
   * 
   * @param name PAR file name 
   * @deprecated Use Find  and Build instead
   * @return true on success
   */
  static Bool_t Load(const TString& name) 
  {
    if (name.IsNull()) return true;
    if (!gProof) { 
      Error("ParUtilities::Load", "No connection to a Proof cluster");
      return false;
    }

    // Load par library 
    TString fn(name);
    Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data());
    
    // First check in current directory
    Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld);
    
    if (ret < 0)  {
      // IF not found there, then check parent directory 
      fn.Prepend("../");
      gSystem->ExpandPathName(fn);
      ret = gProof->UploadPackage(fn);
    }

    if (ret < 0) {	
      // If not found in current or parent directory, try the 
      // the ALICE_ROOT directory 
      fn  = Form("$ALICE_ROOT/%s.par", name.Data());
      gSystem->ExpandPathName(fn);
      ret = gProof->UploadPackage(fn);
    }
    
    if (ret < 0) {
      // IF not found, bark 
      Error("ParUtilities::Load", 
	    "Could not find module %s.par in current or parent directory "
	    "nor in $ALICE_ROOT", name.Data());
      return false;
    }
    
    ret = gProof->EnablePackage(name);
    Info("ParUtilities::Load", "Enabled package %s (from %s)", 
	 name.Data(), fn.Data());
    
    return true;
  }
  /** 
   * Unpack, build, and load a PAR file. 
   * 
   * @param what Which PAR file 
   * 
   * @return 
   */
  static Bool_t Build(const TString& what)
  {
    if (what.IsNull()) return false;
    
    TString parFile(what);
    if (!parFile.EndsWith(".par")) parFile.Append(".par");

    // Extract archive 
    gSystem->Exec(Form("tar xzf %s", parFile.Data()));
    
    // Change directory into par archive
    TString cwd = gSystem->WorkingDirectory();
    
    TString dir(what);
    if (dir.EndsWith(".par")) dir.ReplaceAll(".par", "");
    if (!gSystem->ChangeDirectory(dir)) { 
      Error("ParUtilities::Setup", "Failed to change directory to %s", 
	    dir.Data());
      return false;
    }
    
    // Test the build 
    if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
      Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data());
      if (gSystem->Exec("PROOF-INF/BUILD.sh")) { 
	Error("ParUtilities::Setup", "Failed to build in PAR directory %s", 
	      dir.Data());
	gSystem->ChangeDirectory(cwd.Data());
	return false;
      }
    }

    // We need to make sure the current directory is in the load path 
    gSystem->SetDynamicPath(Form("%s:%s", gSystem->WorkingDirectory(), 
				 gSystem->GetDynamicPath()));
    // Check for setup script
    if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
      // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what);
      gROOT->Macro("PROOF-INF/SETUP.C");
    }
    if (!gSystem->ChangeDirectory(cwd.Data())) return false;

    return true;
  }
  //__________________________________________________________________
  /** 
   * @{ 
   * @name PAR generation from script 
   */
  /** 
   * Service function to make a PAR out of a script.  
   * 
   * The script should contain can contain a sub-class of AliAnalysisTask. 
   * The script will be compiled on the slaves before loading the 
   * AliAnalysisManager.  Parts to (not) be compiled can be protected like 
   * 
   * @code 
   * #ifdef BUILD_PAR
   * // This will _only_ be compiled in the servers 
   * #endif
   * #ifndef BUILD_PAR
   * // This will not be compiled in the servers 
   * #endif
   * @endcode
   * 
   * @param script  Script to upload and compile in the PAR
   * @param deps    Dependency pars 
   * @param isLocal Local build 
   * @param helper  Railway 
   * 
   * @return true on success. 
   */
  static Bool_t MakeScriptPAR(Bool_t         isLocal, 
			      const TString& script, 
			      const TString& deps, 
			      Railway*        helper)
  {
    TObjArray* depList = deps.Tokenize(", ");
    
    // --- In local mode, just AcLic and load ------------------------
    if (isLocal) { 
      // Load dependencies 
      TIter       next(depList);
      TObject*    dep = 0;
      while ((dep = next())) 
	helper->LoadLibrary(dep->GetName());
      
      // AcLic and load 
      Info("ParUtilities::MakeScriptPAR", "Loading macro %s", script.Data());
      if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0) {
	Error("ParUtilities::MakeScriptPAR", 
	      "Failed to build local library %s", script.Data());
	return false;
      }
      return true;
    }

    // --- Get the base name -----------------------------------------
    Info("ParUtilities::MakeScriptPAR", "Making par file for %s", 
	 script.Data());
    TString base(gSystem->BaseName(script));
    Int_t   idx = base.Last('.');
    if (idx != kNPOS) base.Remove(idx);

    // --- Check name of script file ---------------------------------
    TString scr(script);
    TString ext;
    if      (script.EndsWith(".C"))   ext = "C"; 
    else if (script.EndsWith(".cxx")) ext = "cxx";
    else                              { ext = "C"; scr.Append(".C"); }
    
    // --- Check if we can access the file ---------------------------
    TString path = TString::Format(".:%s", TROOT::GetMacroPath());
    char*   loc  = gSystem->Which(path, scr);
    if (!loc) {
      Error("ParUtilities::MakeScriptPAR", 
	    "Script %s not found in %s", scr.Data(), path.Data());
      return false;
    }
    TString full(loc);

    // --- Create our temporary directory ----------------------------
    TString tmpdir(gSystem->TempDirectory());
    int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
    char*   templ  = new char[ltempl];
    snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
    if (!mkdtemp(templ)) {
      Error("ParUtilities::MakeScriptPAR", 
	    "Failed to generate temporary directory from template %s", 
	    templ);
      return false;
    }
    Info("", "Building PAR in %s", templ);

    Bool_t retVal = false;
    try {
      // --- Make directories for package ------------------------------
      TString dir = TString::Format("%s/%s", templ, base.Data());
      // Set-up directories 
      if (gSystem->MakeDirectory(dir) < 0) 
	throw TString::Format("Could not make directory '%s'", base.Data());
      if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
	throw TString::Format("Could not make directory %s/PROOF-INF", 
			      base.Data());
      Info("", "Made directory %s", dir.Data());

      // --- Copy the script to the setup directory --------------------
      TString dest = TString::Format("%s/%s.%s", dir.Data(),
				     base.Data(), ext.Data());
      Int_t ret = gSystem->CopyFile(full, dest, true);
      switch (ret) { 
      case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
      case -2: throw TString::Format("File %s exists", dest.Data());
      case -3: throw TString::Format("Error while copying %s", scr.Data());
      }
      
      // --- Make scripts, etc. ----------------------------------------
      if (!MakeScriptBuildScript(dir, base)) 
	throw TString::Format("Failed to make build script");
      if (!MakeScriptUtilityScript(dir)) 
	throw TString::Format("Failed to make utility script");
      if (!MakeScriptBuildMacro(dir, base, ext, depList)) 
	throw TString::Format("Failed to make build macro");
      if (!MakeScriptSetupMacro(dir, base, ext, depList)) 
	throw TString::Format("Failed to setup macro");

      // --- Pack up the archive ---------------------------------------
      ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)", 
			       templ, base.Data(),base.Data()));
      if (ret != 0) 
	throw TString::Format("Failed to create PAR file %s.PAR from %s", 
			      base.Data(), dir.Data());
      
      Info("", "Made par archive %s/%s.par - moving here", 
	   templ, base.Data());
      // --- Move PAR file to here -------------------------------------
      ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(), 
			       base.Data()));
      if (ret != 0) 
	throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
			      templ, base.Data(), base.Data(), 
			      gSystem->GetError());
      retVal = true;
    }
    catch (TString& e) {
      Error("ParUtilities::MakeScriptPAR", "%s", e.Data());
      retVal = false;
    }
    
    // --- Remove temporary directory --------------------------------
    gSystem->Exec(Form("rm -rf %s", templ));

    return retVal;
  }
  /** 
   * Write a build script
   * 
   * @param dir Directory to put it in
   * @param base Base name 
   * 
   * @return true on success
   */
  static Bool_t MakeScriptBuildScript(const TString& dir, 
				      const TString& base)
  {
    // Make our build file 
    std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
    if (!out) {
      Error("ParUtilities::MakeScriptBuildScript", 
	    "Failed to open out shell script");
      return false;
    }
    out << "#!/bin/sh\n"
	<< "if test x$ALICE_ROOT != x ; then\n"
	<< "  if test x$ALICE_TARGET = x ; then\n"
	<< "    export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n"
	<< "  fi\n"
	<< "  export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"
	<< "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n"
	<< "fi\n"
	<< "# printenv | sort -u\n"
	<< "echo BUILD.sh@`hostname`: Building " << base << "\n"
	<< "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee " 
	<< base << ".log\n"
	<< "echo BUILD.sh@`hostname`: done: $?\n"
	<< std::endl;
    out.close();
    if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
      Error("ParUtilities::MakeScriptBuildScript", 
	    "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
	    dir.Data());
      return false;
    }
    return true;
  }
  /** 
   * Write a build macro 
   * 
   * @param dir   Directory to put macro in
   * @param deps  Dependencies
   * @param base  Base name of script to compile
   * @param ext   `extension' - last part of file name 
   * 
   * @return true on success
   */
  static Bool_t MakeScriptBuildMacro(const TString& dir, 
				     const TString& base, 
				     const TString& ext,
				     const TCollection* deps)  {
    std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
    if (!out) {
      Error("ParUtilities::MakeScriptBuildMacro","Failed to open build script");
      return false;
    }
    out << "void BUILD() {\n"
	<< "  gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
	<< "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
	<< "  LoadROOTLibs();\n"
	<< "  AddAliROOT();\n";
    if (deps) {
      TIter       next(deps);
      TObject*    dep = 0;
      while ((dep = next())) {
	out << "  AddDep(\"" << dep->GetName() << "\");\t"
	    << "  LoadDep(\"" << dep->GetName() << "\");\n";
      }
    }
    out << "  // gDebug = 5;\n"
	<< "  // gSystem->ListLibraries();\n"
	<< "  int ret = gROOT->LoadMacro(\"" 
	<< base << "." << ext << "++g\");\n"
	<< "  if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
	<< "  // else Info(\"BUILD\", \"Made " << base << "\");\n"
	<< "}\n"
	<< std::endl;
    out.close();

    return true;
  }
  /** 
   * Make a utility macro 
   * 
   * @param dir Directory to put the macro in
   * 
   * @return true on success
   */
  static Bool_t MakeScriptUtilityScript(const TString& dir)
  {
    std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
    if (!out) {
      Error("ParUtilities::MakeScriptUtilityScript", 
	    "Failed to open utility script");
      return false;
    }
    out << "void LoadROOTLibs() {\n"
	<< "  gSystem->Load(\"libVMC\");\n"
	<< "  gSystem->Load(\"libNet\");\n"
	<< "  gSystem->Load(\"libTree\");\n"
	<< "  gSystem->Load(\"libPhysics\");\n"
	<< "  gSystem->Load(\"libMinuit\");\n"
	<< "}\n\n"
	<< "void AddAliROOT() {\n"
	<< "  TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
	<< "  if (val.IsNull())\n"
	<< "    Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
	<< "  else\n"
	<< "    gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
	<< "}\n\n"
	<< "void AddDep(const char* env) {\n"
	<< "  TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
	<< "  if (val.IsNull())\n"
	<< "    Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
	<< "  else {\n"
	<< "    // gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
	<< "    // Prepend to include path\n"
	<< "    TString incPath(gSystem->GetIncludePath());\n"
	<< "    incPath.Prepend(Form(\"-I../%s \",val.Data()));\n"
	<< "    gSystem->SetIncludePath(incPath);\n"
	<< "    // Printf(\"Include path: %s\",incPath.Data());\n"
	<< "  }\n"
	<< "}\n\n"
	<< "void LoadDep(const char* name) {\n"
	<< "  // Printf(\"Loading dependency \\\"%s\\\" ...\",name);\n"
	<< "  // gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
	<< "  // Prepend to dynamic path\n"
	<< "  TString dynPath(gSystem->GetDynamicPath());\n"
	<< "  dynPath.Prepend(Form(\"../%s:\",name));\n"
	<< "  gSystem->SetDynamicPath(dynPath);\n"
	<< "  // Printf(\"Dynamic path: %s\",dynPath.Data());\n"
	<< "  char* full = gSystem->DynamicPathName(name,true);\n"
	<< "  if (!full) \n"
	<< "   full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
	<< "  if (!full) \n"
	<< "   full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
	<< "  if (!full) \n"
	<< "   full = gSystem->DynamicPathName(Form(\"%s_C.so\",name),true);\n"
	<< "  if (!full) \n"
	<< "   full = gSystem->DynamicPathName(Form(\"%s_h.so\",name),true);\n"
	<< "  if (!full) {\n"
	<< "    Warning(\"LoadDep\",\"Module %s not found\", name);\n"
	<< "    return;\n"
	<< "  }\n"
	<< "  Printf(\"Loading \\\"%s\\\" for \\\"%s\\\"\",full,name);\n"
	<< "  gSystem->Load(full);\n"
	<< "}\n"
	<< std::endl;
    out.close();
    return true;
  }
  /** 
   * Make a setup script 
   * 
   * @param dir   Directory to put it in 
   * @param base  Base name of target script 
   * @param ext   Extension of target script 
   * @param deps  Dependencies 
   * 
   * @return true on success
   */
  static Bool_t MakeScriptSetupMacro(const TString& dir, 
				     const TString& base, 
				     const TString& ext,
				     const TCollection* deps)
  {
    // Make our set-up script 
    std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
    if (!out) {
      Error("ParUtilities::MakeScriptSetupMacro", 
	    "Failed to open setup script");
      return false;
    }
    out << "void SETUP() {\n"
	<< "  gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
	<< "  Printf(\"Loading \\\"" << base << "\\\" ...\");\n"
	<< "  LoadROOTLibs();\n"
	<< "  // Info(\"SETUP\",\"Loading libraries\");\n";
    if (deps) {
      TIter next(deps);
      TObject* dep = 0;
      while ((dep = next())) 
	out << "  LoadDep(\"" << dep->GetName() << "\");\n";
    }
    out << "  // gDebug = 5;\n"
	<< "  // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
	<< "  gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
	<< "  // gDebug = 0;\n"
	<< "  gROOT->ProcessLine(\".include " << base << "\");\n"
	<< "  gSystem->Setenv(\"" << base << "_INCLUDE\",\"" 
	<< base << "\");\n"
	<< "  // Info(\"SETUP\", \"Done\");\n"
	<< "}\n"
	<< std::endl;
    out.close();
    return true;
  }
  /* @} */
  //__________________________________________________________________
  /** 
   * @{ 
   * @name PAR generation from aux file list
   */
  static Bool_t MakeAuxFilePAR(const TList& files, 
			       const TString& name,
			       Bool_t verbose=false)
  {
    // --- Check input -----------------------------------------------
    if (files.GetEntries() <= 0) return true;

    // --- Create our temporary directory ----------------------------
    Bool_t  retval = true;
    TString tmpdir(gSystem->TempDirectory());
    int     ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
    char*   templ  = new char[ltempl];
    snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
    if (!mkdtemp(templ)) {
      Error("ParUtilities::MakeAuxFilePAR", 
	    "Failed to generate temporary directory from template %s", 
	    templ);
      return false;
    }
    if (verbose) Printf("Preparing PAR file in %s", templ);
    
    try {
      // --- Make directories for package ------------------------------
      TString dir = TString::Format("%s/%s", templ, name.Data());
      // Set-up directories 
      if (gSystem->MakeDirectory(dir) < 0) 
	throw TString::Format("Could not make directory '%s'", name.Data());
      if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data()))) 
	throw TString::Format("Could not make directory %s/PROOF-INF", 
			      name.Data());

      TIter next(&files);
      TObject* o = 0;
      while ((o = next())) { 
	TString fn(o->GetName());
	if (verbose) Printf("Got %s", fn.Data());
	if (fn.BeginsWith("/")) {
	  Warning("MakeAuxFilePAR", "Will not include absolute path %s",
		  fn.Data());
	  continue; // absolute path 
	}
	
	if (gSystem->AccessPathName(fn.Data())) {
	  Warning("MakeAuxFilePAR", "Cannot access %s", fn.Data());
	  continue; // non-exist
	}
	// Loop over path components and make directories as needed 
	TObjArray*  comps = fn.Tokenize("/");
	TString     cur   = dir;
	Int_t       n     = comps->GetEntriesFast();
	if (verbose) Printf("Got %d path components in %s", n-1, fn.Data());
	Int_t       lvl   = 0;
	for (Int_t i = 0; i < n-1; i++) {
	  TObjString* comp = static_cast<TObjString*>(comps->At(i));
	  TString&    c    = comp->String();
	  if (c.IsNull()) continue;
	  if (c.EqualTo(".")) continue;
	  
	  Bool_t doMake = true;
	  if (c.EqualTo("..")) { doMake = false; lvl--; }
	  
	  cur = gSystem->ConcatFileName(cur, c);
	  if (lvl < 0) {
	    Warning("MakeAuxFilePAR", "Path %s points outside archive, ignored",
		    cur.Data());
	    break;
	  }

	  if (doMake) { 
	    lvl++;
	    if (!gSystem->AccessPathName(cur)) continue;
	    if (verbose) Printf("Making directory %s", cur.Data());
	    gSystem->MakeDirectory(cur);
	  }
	} // for(i)
	if (verbose) Printf("cur=%s for %s lvl=%d", cur.Data(), fn.Data(), lvl);
	comps->Delete();
	if (lvl < 0) continue;

	TString dest = TString::Format("%s/%s", cur.Data(), 
				       gSystem->BaseName(fn.Data()));
	if (verbose) Printf("%s -> %s", fn.Data(), dest.Data());
	Int_t ret = gSystem->CopyFile(fn, dest, true);
	switch (ret) { 
	case -1: throw TString::Format("Couldn't open %s for copy", fn.Data());
	case -2: throw TString::Format("File %s exists", dest.Data());
	case -3: throw TString::Format("Error while copying %s", fn.Data());
	}
      }

      {
	// Make our build file 
	if (verbose) Printf("Making build script");
	std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
	if (!out) {
	  Error("ParUtilities::MakeAuxFilePAR", 
		"Failed to open out shell script");
	  return false;
	}
	out << "#!/bin/sh\n\n"
	    << "echo \"Nothing to be done\"\n\n"
	    << "# EOF" << std::endl;
	out.close();
	if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755)) {
	  Error("ParUtilities::MakeAuxFilePAR", 
		"Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh", 
		dir.Data());
	  return false;
	}
      }
      {
	if (verbose) Printf("Making setup script");
	// Make our setup file 
	std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
	if (!out) {
	  Error("ParUtilities::MakeAuxFilePAR", 
		"Failed to open out ROOT script");
	  return false;
	}
	// The SETUP script is executed in the package's directory in
	// the package cache - not in the session directory.  Hence,
	// we take special care to get a link to the session directory
	// from the package cache directory
	out << "void SETUP()\n"
	    << "{\n"
	    << "  TString oldDir(gSystem->WorkingDirectory());\n"
	    << "  TSystemDirectory* dir = new TSystemDirectory(\".\",\".\");\n"
	    << "  TList*  files = dir->GetListOfFiles();\n"
	    << "  if (!gSystem->ChangeDirectory(oldDir)) {\n"
	    << "    Error(\"SETUP\", \"Failed to go back to %s\",\n"
	    << "          oldDir.Data());\n"
	    << "    return;\n"
	    << "  }\n"
	    << "  if (!files) {\n"
	    << "    Warning(\"SETUP\", \"No files\");\n"
	    << "    gSystem->Exec(\"pwd; ls -al\");\n"
	    << "    return;\n"
	    << "  }\n"
	    << "  files->Sort();\n"
	    << "  TString pkgDir = gSystem->WorkingDirectory();\n"
	    << "  TString sesDir = gProofServ->GetSessionDir();\n"
	    << "  Info(\"\",\"Session dir: %s\",sesDir);\n"
	    << "  TIter next(files);\n"
	    << "  TSystemFile* file = 0;\n"
	    << "  while ((file = static_cast<TSystemFile*>(next()))) {\n"
	    << "    TString name(file->GetName());\n"
	    << "    if (name == \".\" || name == \"..\") continue;\n"
	    << "    TString title(file->GetTitle());\n"
	    << "    TString full(gSystem->ConcatFileName(pkgDir.Data(),\n"
	    << "                                         name.Data()));\n"
	    << "    TString tgt(gSystem->ConcatFileName(sesDir.Data(),\n"
	    << "                                        name.Data()));\n"
	    << "    if (file->IsA()->InheritsFrom(TSystemDirectory::Class())){\n"
	    << "      gSystem->mkdir(tgt.Data(), true);\n"
	    << "      continue;\n"
	    << "    }\n"
	    << "    Info(\"\",\"Linking %s to %s\",full.Data(),tgt.Data());\n"
	    << "    gSystem->Symlink(full, tgt);\n"
	    << "  }\n"
	    << "}\n"
	    << "// EOF " << std::endl;
	out.close();
      }
      if (verbose) Printf("Packing up");
      Int_t ret = 0;
      ret = gSystem->Exec(Form("(cd %s && tar -c%szf %s.par %s)", 
			       templ, (verbose ? "v" : ""), 
			       name.Data(),name.Data()));
      if (ret != 0) 
	throw TString::Format("Failed to create PAR file %s.PAR from %s", 
			      name.Data(), name.Data());

      // --- Move PAR file to here -------------------------------------
      if (verbose) Printf("Move here");
      ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, name.Data(), 
			       name.Data()));
      if (ret != 0) 
	throw TString::Format("Failed to rename %s/%s.par to %s.par: %s", 
			      templ, name.Data(), name.Data(), 
			      gSystem->GetError());


      if (verbose) {
	Printf("List content");
	gSystem->Exec(Form("tar tzf %s.par", name.Data()));
      }
      retval = true;
    }
    catch (TString& e) {
      Error("ParUtilities::MakeAuxFilePAR", "%s", e.Data());
      retval = false;
    }
    
    // --- Remove temporary directory --------------------------------
    gSystem->Exec(Form("rm -rf %s", templ));
    
    return retval;
  }
};
#endif
// 
// EOF
//
 ParUtilities.C:1
 ParUtilities.C:2
 ParUtilities.C:3
 ParUtilities.C:4
 ParUtilities.C:5
 ParUtilities.C:6
 ParUtilities.C:7
 ParUtilities.C:8
 ParUtilities.C:9
 ParUtilities.C:10
 ParUtilities.C:11
 ParUtilities.C:12
 ParUtilities.C:13
 ParUtilities.C:14
 ParUtilities.C:15
 ParUtilities.C:16
 ParUtilities.C:17
 ParUtilities.C:18
 ParUtilities.C:19
 ParUtilities.C:20
 ParUtilities.C:21
 ParUtilities.C:22
 ParUtilities.C:23
 ParUtilities.C:24
 ParUtilities.C:25
 ParUtilities.C:26
 ParUtilities.C:27
 ParUtilities.C:28
 ParUtilities.C:29
 ParUtilities.C:30
 ParUtilities.C:31
 ParUtilities.C:32
 ParUtilities.C:33
 ParUtilities.C:34
 ParUtilities.C:35
 ParUtilities.C:36
 ParUtilities.C:37
 ParUtilities.C:38
 ParUtilities.C:39
 ParUtilities.C:40
 ParUtilities.C:41
 ParUtilities.C:42
 ParUtilities.C:43
 ParUtilities.C:44
 ParUtilities.C:45
 ParUtilities.C:46
 ParUtilities.C:47
 ParUtilities.C:48
 ParUtilities.C:49
 ParUtilities.C:50
 ParUtilities.C:51
 ParUtilities.C:52
 ParUtilities.C:53
 ParUtilities.C:54
 ParUtilities.C:55
 ParUtilities.C:56
 ParUtilities.C:57
 ParUtilities.C:58
 ParUtilities.C:59
 ParUtilities.C:60
 ParUtilities.C:61
 ParUtilities.C:62
 ParUtilities.C:63
 ParUtilities.C:64
 ParUtilities.C:65
 ParUtilities.C:66
 ParUtilities.C:67
 ParUtilities.C:68
 ParUtilities.C:69
 ParUtilities.C:70
 ParUtilities.C:71
 ParUtilities.C:72
 ParUtilities.C:73
 ParUtilities.C:74
 ParUtilities.C:75
 ParUtilities.C:76
 ParUtilities.C:77
 ParUtilities.C:78
 ParUtilities.C:79
 ParUtilities.C:80
 ParUtilities.C:81
 ParUtilities.C:82
 ParUtilities.C:83
 ParUtilities.C:84
 ParUtilities.C:85
 ParUtilities.C:86
 ParUtilities.C:87
 ParUtilities.C:88
 ParUtilities.C:89
 ParUtilities.C:90
 ParUtilities.C:91
 ParUtilities.C:92
 ParUtilities.C:93
 ParUtilities.C:94
 ParUtilities.C:95
 ParUtilities.C:96
 ParUtilities.C:97
 ParUtilities.C:98
 ParUtilities.C:99
 ParUtilities.C:100
 ParUtilities.C:101
 ParUtilities.C:102
 ParUtilities.C:103
 ParUtilities.C:104
 ParUtilities.C:105
 ParUtilities.C:106
 ParUtilities.C:107
 ParUtilities.C:108
 ParUtilities.C:109
 ParUtilities.C:110
 ParUtilities.C:111
 ParUtilities.C:112
 ParUtilities.C:113
 ParUtilities.C:114
 ParUtilities.C:115
 ParUtilities.C:116
 ParUtilities.C:117
 ParUtilities.C:118
 ParUtilities.C:119
 ParUtilities.C:120
 ParUtilities.C:121
 ParUtilities.C:122
 ParUtilities.C:123
 ParUtilities.C:124
 ParUtilities.C:125
 ParUtilities.C:126
 ParUtilities.C:127
 ParUtilities.C:128
 ParUtilities.C:129
 ParUtilities.C:130
 ParUtilities.C:131
 ParUtilities.C:132
 ParUtilities.C:133
 ParUtilities.C:134
 ParUtilities.C:135
 ParUtilities.C:136
 ParUtilities.C:137
 ParUtilities.C:138
 ParUtilities.C:139
 ParUtilities.C:140
 ParUtilities.C:141
 ParUtilities.C:142
 ParUtilities.C:143
 ParUtilities.C:144
 ParUtilities.C:145
 ParUtilities.C:146
 ParUtilities.C:147
 ParUtilities.C:148
 ParUtilities.C:149
 ParUtilities.C:150
 ParUtilities.C:151
 ParUtilities.C:152
 ParUtilities.C:153
 ParUtilities.C:154
 ParUtilities.C:155
 ParUtilities.C:156
 ParUtilities.C:157
 ParUtilities.C:158
 ParUtilities.C:159
 ParUtilities.C:160
 ParUtilities.C:161
 ParUtilities.C:162
 ParUtilities.C:163
 ParUtilities.C:164
 ParUtilities.C:165
 ParUtilities.C:166
 ParUtilities.C:167
 ParUtilities.C:168
 ParUtilities.C:169
 ParUtilities.C:170
 ParUtilities.C:171
 ParUtilities.C:172
 ParUtilities.C:173
 ParUtilities.C:174
 ParUtilities.C:175
 ParUtilities.C:176
 ParUtilities.C:177
 ParUtilities.C:178
 ParUtilities.C:179
 ParUtilities.C:180
 ParUtilities.C:181
 ParUtilities.C:182
 ParUtilities.C:183
 ParUtilities.C:184
 ParUtilities.C:185
 ParUtilities.C:186
 ParUtilities.C:187
 ParUtilities.C:188
 ParUtilities.C:189
 ParUtilities.C:190
 ParUtilities.C:191
 ParUtilities.C:192
 ParUtilities.C:193
 ParUtilities.C:194
 ParUtilities.C:195
 ParUtilities.C:196
 ParUtilities.C:197
 ParUtilities.C:198
 ParUtilities.C:199
 ParUtilities.C:200
 ParUtilities.C:201
 ParUtilities.C:202
 ParUtilities.C:203
 ParUtilities.C:204
 ParUtilities.C:205
 ParUtilities.C:206
 ParUtilities.C:207
 ParUtilities.C:208
 ParUtilities.C:209
 ParUtilities.C:210
 ParUtilities.C:211
 ParUtilities.C:212
 ParUtilities.C:213
 ParUtilities.C:214
 ParUtilities.C:215
 ParUtilities.C:216
 ParUtilities.C:217
 ParUtilities.C:218
 ParUtilities.C:219
 ParUtilities.C:220
 ParUtilities.C:221
 ParUtilities.C:222
 ParUtilities.C:223
 ParUtilities.C:224
 ParUtilities.C:225
 ParUtilities.C:226
 ParUtilities.C:227
 ParUtilities.C:228
 ParUtilities.C:229
 ParUtilities.C:230
 ParUtilities.C:231
 ParUtilities.C:232
 ParUtilities.C:233
 ParUtilities.C:234
 ParUtilities.C:235
 ParUtilities.C:236
 ParUtilities.C:237
 ParUtilities.C:238
 ParUtilities.C:239
 ParUtilities.C:240
 ParUtilities.C:241
 ParUtilities.C:242
 ParUtilities.C:243
 ParUtilities.C:244
 ParUtilities.C:245
 ParUtilities.C:246
 ParUtilities.C:247
 ParUtilities.C:248
 ParUtilities.C:249
 ParUtilities.C:250
 ParUtilities.C:251
 ParUtilities.C:252
 ParUtilities.C:253
 ParUtilities.C:254
 ParUtilities.C:255
 ParUtilities.C:256
 ParUtilities.C:257
 ParUtilities.C:258
 ParUtilities.C:259
 ParUtilities.C:260
 ParUtilities.C:261
 ParUtilities.C:262
 ParUtilities.C:263
 ParUtilities.C:264
 ParUtilities.C:265
 ParUtilities.C:266
 ParUtilities.C:267
 ParUtilities.C:268
 ParUtilities.C:269
 ParUtilities.C:270
 ParUtilities.C:271
 ParUtilities.C:272
 ParUtilities.C:273
 ParUtilities.C:274
 ParUtilities.C:275
 ParUtilities.C:276
 ParUtilities.C:277
 ParUtilities.C:278
 ParUtilities.C:279
 ParUtilities.C:280
 ParUtilities.C:281
 ParUtilities.C:282
 ParUtilities.C:283
 ParUtilities.C:284
 ParUtilities.C:285
 ParUtilities.C:286
 ParUtilities.C:287
 ParUtilities.C:288
 ParUtilities.C:289
 ParUtilities.C:290
 ParUtilities.C:291
 ParUtilities.C:292
 ParUtilities.C:293
 ParUtilities.C:294
 ParUtilities.C:295
 ParUtilities.C:296
 ParUtilities.C:297
 ParUtilities.C:298
 ParUtilities.C:299
 ParUtilities.C:300
 ParUtilities.C:301
 ParUtilities.C:302
 ParUtilities.C:303
 ParUtilities.C:304
 ParUtilities.C:305
 ParUtilities.C:306
 ParUtilities.C:307
 ParUtilities.C:308
 ParUtilities.C:309
 ParUtilities.C:310
 ParUtilities.C:311
 ParUtilities.C:312
 ParUtilities.C:313
 ParUtilities.C:314
 ParUtilities.C:315
 ParUtilities.C:316
 ParUtilities.C:317
 ParUtilities.C:318
 ParUtilities.C:319
 ParUtilities.C:320
 ParUtilities.C:321
 ParUtilities.C:322
 ParUtilities.C:323
 ParUtilities.C:324
 ParUtilities.C:325
 ParUtilities.C:326
 ParUtilities.C:327
 ParUtilities.C:328
 ParUtilities.C:329
 ParUtilities.C:330
 ParUtilities.C:331
 ParUtilities.C:332
 ParUtilities.C:333
 ParUtilities.C:334
 ParUtilities.C:335
 ParUtilities.C:336
 ParUtilities.C:337
 ParUtilities.C:338
 ParUtilities.C:339
 ParUtilities.C:340
 ParUtilities.C:341
 ParUtilities.C:342
 ParUtilities.C:343
 ParUtilities.C:344
 ParUtilities.C:345
 ParUtilities.C:346
 ParUtilities.C:347
 ParUtilities.C:348
 ParUtilities.C:349
 ParUtilities.C:350
 ParUtilities.C:351
 ParUtilities.C:352
 ParUtilities.C:353
 ParUtilities.C:354
 ParUtilities.C:355
 ParUtilities.C:356
 ParUtilities.C:357
 ParUtilities.C:358
 ParUtilities.C:359
 ParUtilities.C:360
 ParUtilities.C:361
 ParUtilities.C:362
 ParUtilities.C:363
 ParUtilities.C:364
 ParUtilities.C:365
 ParUtilities.C:366
 ParUtilities.C:367
 ParUtilities.C:368
 ParUtilities.C:369
 ParUtilities.C:370
 ParUtilities.C:371
 ParUtilities.C:372
 ParUtilities.C:373
 ParUtilities.C:374
 ParUtilities.C:375
 ParUtilities.C:376
 ParUtilities.C:377
 ParUtilities.C:378
 ParUtilities.C:379
 ParUtilities.C:380
 ParUtilities.C:381
 ParUtilities.C:382
 ParUtilities.C:383
 ParUtilities.C:384
 ParUtilities.C:385
 ParUtilities.C:386
 ParUtilities.C:387
 ParUtilities.C:388
 ParUtilities.C:389
 ParUtilities.C:390
 ParUtilities.C:391
 ParUtilities.C:392
 ParUtilities.C:393
 ParUtilities.C:394
 ParUtilities.C:395
 ParUtilities.C:396
 ParUtilities.C:397
 ParUtilities.C:398
 ParUtilities.C:399
 ParUtilities.C:400
 ParUtilities.C:401
 ParUtilities.C:402
 ParUtilities.C:403
 ParUtilities.C:404
 ParUtilities.C:405
 ParUtilities.C:406
 ParUtilities.C:407
 ParUtilities.C:408
 ParUtilities.C:409
 ParUtilities.C:410
 ParUtilities.C:411
 ParUtilities.C:412
 ParUtilities.C:413
 ParUtilities.C:414
 ParUtilities.C:415
 ParUtilities.C:416
 ParUtilities.C:417
 ParUtilities.C:418
 ParUtilities.C:419
 ParUtilities.C:420
 ParUtilities.C:421
 ParUtilities.C:422
 ParUtilities.C:423
 ParUtilities.C:424
 ParUtilities.C:425
 ParUtilities.C:426
 ParUtilities.C:427
 ParUtilities.C:428
 ParUtilities.C:429
 ParUtilities.C:430
 ParUtilities.C:431
 ParUtilities.C:432
 ParUtilities.C:433
 ParUtilities.C:434
 ParUtilities.C:435
 ParUtilities.C:436
 ParUtilities.C:437
 ParUtilities.C:438
 ParUtilities.C:439
 ParUtilities.C:440
 ParUtilities.C:441
 ParUtilities.C:442
 ParUtilities.C:443
 ParUtilities.C:444
 ParUtilities.C:445
 ParUtilities.C:446
 ParUtilities.C:447
 ParUtilities.C:448
 ParUtilities.C:449
 ParUtilities.C:450
 ParUtilities.C:451
 ParUtilities.C:452
 ParUtilities.C:453
 ParUtilities.C:454
 ParUtilities.C:455
 ParUtilities.C:456
 ParUtilities.C:457
 ParUtilities.C:458
 ParUtilities.C:459
 ParUtilities.C:460
 ParUtilities.C:461
 ParUtilities.C:462
 ParUtilities.C:463
 ParUtilities.C:464
 ParUtilities.C:465
 ParUtilities.C:466
 ParUtilities.C:467
 ParUtilities.C:468
 ParUtilities.C:469
 ParUtilities.C:470
 ParUtilities.C:471
 ParUtilities.C:472
 ParUtilities.C:473
 ParUtilities.C:474
 ParUtilities.C:475
 ParUtilities.C:476
 ParUtilities.C:477
 ParUtilities.C:478
 ParUtilities.C:479
 ParUtilities.C:480
 ParUtilities.C:481
 ParUtilities.C:482
 ParUtilities.C:483
 ParUtilities.C:484
 ParUtilities.C:485
 ParUtilities.C:486
 ParUtilities.C:487
 ParUtilities.C:488
 ParUtilities.C:489
 ParUtilities.C:490
 ParUtilities.C:491
 ParUtilities.C:492
 ParUtilities.C:493
 ParUtilities.C:494
 ParUtilities.C:495
 ParUtilities.C:496
 ParUtilities.C:497
 ParUtilities.C:498
 ParUtilities.C:499
 ParUtilities.C:500
 ParUtilities.C:501
 ParUtilities.C:502
 ParUtilities.C:503
 ParUtilities.C:504
 ParUtilities.C:505
 ParUtilities.C:506
 ParUtilities.C:507
 ParUtilities.C:508
 ParUtilities.C:509
 ParUtilities.C:510
 ParUtilities.C:511
 ParUtilities.C:512
 ParUtilities.C:513
 ParUtilities.C:514
 ParUtilities.C:515
 ParUtilities.C:516
 ParUtilities.C:517
 ParUtilities.C:518
 ParUtilities.C:519
 ParUtilities.C:520
 ParUtilities.C:521
 ParUtilities.C:522
 ParUtilities.C:523
 ParUtilities.C:524
 ParUtilities.C:525
 ParUtilities.C:526
 ParUtilities.C:527
 ParUtilities.C:528
 ParUtilities.C:529
 ParUtilities.C:530
 ParUtilities.C:531
 ParUtilities.C:532
 ParUtilities.C:533
 ParUtilities.C:534
 ParUtilities.C:535
 ParUtilities.C:536
 ParUtilities.C:537
 ParUtilities.C:538
 ParUtilities.C:539
 ParUtilities.C:540
 ParUtilities.C:541
 ParUtilities.C:542
 ParUtilities.C:543
 ParUtilities.C:544
 ParUtilities.C:545
 ParUtilities.C:546
 ParUtilities.C:547
 ParUtilities.C:548
 ParUtilities.C:549
 ParUtilities.C:550
 ParUtilities.C:551
 ParUtilities.C:552
 ParUtilities.C:553
 ParUtilities.C:554
 ParUtilities.C:555
 ParUtilities.C:556
 ParUtilities.C:557
 ParUtilities.C:558
 ParUtilities.C:559
 ParUtilities.C:560
 ParUtilities.C:561
 ParUtilities.C:562
 ParUtilities.C:563
 ParUtilities.C:564
 ParUtilities.C:565
 ParUtilities.C:566
 ParUtilities.C:567
 ParUtilities.C:568
 ParUtilities.C:569
 ParUtilities.C:570
 ParUtilities.C:571
 ParUtilities.C:572
 ParUtilities.C:573
 ParUtilities.C:574
 ParUtilities.C:575
 ParUtilities.C:576
 ParUtilities.C:577
 ParUtilities.C:578
 ParUtilities.C:579
 ParUtilities.C:580
 ParUtilities.C:581
 ParUtilities.C:582
 ParUtilities.C:583
 ParUtilities.C:584
 ParUtilities.C:585
 ParUtilities.C:586
 ParUtilities.C:587
 ParUtilities.C:588
 ParUtilities.C:589
 ParUtilities.C:590
 ParUtilities.C:591
 ParUtilities.C:592
 ParUtilities.C:593
 ParUtilities.C:594
 ParUtilities.C:595
 ParUtilities.C:596
 ParUtilities.C:597
 ParUtilities.C:598
 ParUtilities.C:599
 ParUtilities.C:600
 ParUtilities.C:601
 ParUtilities.C:602
 ParUtilities.C:603
 ParUtilities.C:604
 ParUtilities.C:605
 ParUtilities.C:606
 ParUtilities.C:607
 ParUtilities.C:608
 ParUtilities.C:609
 ParUtilities.C:610
 ParUtilities.C:611
 ParUtilities.C:612
 ParUtilities.C:613
 ParUtilities.C:614
 ParUtilities.C:615
 ParUtilities.C:616
 ParUtilities.C:617
 ParUtilities.C:618
 ParUtilities.C:619
 ParUtilities.C:620
 ParUtilities.C:621
 ParUtilities.C:622
 ParUtilities.C:623
 ParUtilities.C:624
 ParUtilities.C:625
 ParUtilities.C:626
 ParUtilities.C:627
 ParUtilities.C:628
 ParUtilities.C:629
 ParUtilities.C:630
 ParUtilities.C:631
 ParUtilities.C:632
 ParUtilities.C:633
 ParUtilities.C:634
 ParUtilities.C:635
 ParUtilities.C:636
 ParUtilities.C:637
 ParUtilities.C:638
 ParUtilities.C:639
 ParUtilities.C:640
 ParUtilities.C:641
 ParUtilities.C:642
 ParUtilities.C:643
 ParUtilities.C:644
 ParUtilities.C:645
 ParUtilities.C:646
 ParUtilities.C:647
 ParUtilities.C:648
 ParUtilities.C:649
 ParUtilities.C:650
 ParUtilities.C:651
 ParUtilities.C:652
 ParUtilities.C:653
 ParUtilities.C:654
 ParUtilities.C:655
 ParUtilities.C:656
 ParUtilities.C:657
 ParUtilities.C:658
 ParUtilities.C:659
 ParUtilities.C:660
 ParUtilities.C:661
 ParUtilities.C:662
 ParUtilities.C:663
 ParUtilities.C:664
 ParUtilities.C:665
 ParUtilities.C:666
 ParUtilities.C:667
 ParUtilities.C:668
 ParUtilities.C:669
 ParUtilities.C:670
 ParUtilities.C:671
 ParUtilities.C:672
 ParUtilities.C:673
 ParUtilities.C:674
 ParUtilities.C:675
 ParUtilities.C:676
 ParUtilities.C:677
 ParUtilities.C:678
 ParUtilities.C:679
 ParUtilities.C:680
 ParUtilities.C:681
 ParUtilities.C:682
 ParUtilities.C:683
 ParUtilities.C:684
 ParUtilities.C:685
 ParUtilities.C:686
 ParUtilities.C:687
 ParUtilities.C:688
 ParUtilities.C:689
 ParUtilities.C:690
 ParUtilities.C:691
 ParUtilities.C:692
 ParUtilities.C:693
 ParUtilities.C:694
 ParUtilities.C:695
 ParUtilities.C:696
 ParUtilities.C:697
 ParUtilities.C:698
 ParUtilities.C:699
 ParUtilities.C:700
 ParUtilities.C:701
 ParUtilities.C:702
 ParUtilities.C:703
 ParUtilities.C:704
 ParUtilities.C:705
 ParUtilities.C:706
 ParUtilities.C:707
 ParUtilities.C:708
 ParUtilities.C:709
 ParUtilities.C:710
 ParUtilities.C:711
 ParUtilities.C:712
 ParUtilities.C:713
 ParUtilities.C:714
 ParUtilities.C:715
 ParUtilities.C:716
 ParUtilities.C:717
 ParUtilities.C:718
 ParUtilities.C:719
 ParUtilities.C:720
 ParUtilities.C:721
 ParUtilities.C:722
 ParUtilities.C:723
 ParUtilities.C:724
 ParUtilities.C:725
 ParUtilities.C:726
 ParUtilities.C:727
 ParUtilities.C:728
 ParUtilities.C:729
 ParUtilities.C:730
 ParUtilities.C:731
 ParUtilities.C:732
 ParUtilities.C:733
 ParUtilities.C:734
 ParUtilities.C:735
 ParUtilities.C:736
 ParUtilities.C:737
 ParUtilities.C:738
 ParUtilities.C:739
 ParUtilities.C:740
 ParUtilities.C:741
 ParUtilities.C:742